> For the complete documentation index, see [llms.txt](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-ji-cheng-zhi-nan.md).

# 合约集成指南

## 模块

Euler协议是通过模块系统连接在一起的智能合约的集合。每个模块处理协议的特定区域，因此根据您想要做什么，您将与几个不同的合约地址进行交互。

一些模块是全局的，例如：

* [markets](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulermarkets)：激活市场，进入/退出市场，查询各种市场相关信息。
* [exec](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulerexec)：批量请求、流动性延期（即闪电贷款）
* [liquidation](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulerliquidation)：扣押违规用户的资产

其他模块是特定用于资产的：

* [eTokens](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieuleretoken)：代表资产的 ERC20 兼容代币
* [dTokens](https://zenofchain.gitbook.io/euler-wen-dang-+-bai-pi-shu/kai-fa-zhe/he-yue-can-kao#ieulerdtoken)：代表负债的 ERC20 兼容代币

## Deposit and withdraw

为了投资资产以赚取利息，您需要“存入”eToken。

```
// Approve the main euler contract to pull your tokens:
IERC20(underlying).approve(EULER_MAINNET, type(uint).max);

// Use the markets module:
IEulerMarkets markets = IEulerMarkets(EULER_MAINNET_MARKETS);

// Get the eToken address using the markets module:
IEulerEToken eToken = IEulerEToken(markets.underlyingToEToken(underlying));

// Deposit 5.25 underlying tokens (assuming 18 decimal places)
// The "0" argument refers to the sub-account you are depositing to.
eToken.deposit(0, 5.25e18);

eToken.balanceOf(address(this));
// -> internal book-keeping value that doesn't increase over time

eToken.balanceOfUnderlying(address(this));
// -> 5.25e18
// ... but check back next block to see it go up (assuming there are borrowers)

// Later on, withdraw your initial deposit and all earned interest:
eToken.withdraw(0, type(uint).max);
```

## 借入和赎回

如果您想借入一项资产，您必须有足够的抵押品，并“进入”抵押品市场。

```
// Use the markets module:
IEulerMarkets markets = IEulerMarkets(EULER_MAINNET_MARKETS);

// Approve, get eToken addr, and deposit:
IERC20(collateral).approve(EULER_MAINNET, type(uint).max);
IEulerEToken collateralEToken = IEulerEToken(markets.underlyingToEToken(collateral));
collateralEToken.deposit(0, 100e18);

// Enter the collateral market (collateral's address, *not* the eToken address):
markets.enterMarket(0, collateral);

// Get the dToken address of the borrowed asset:
IEulerDToken borrowedDToken = IEulerDToken(markets.underlyingToDToken(borrowed));

// Borrow 2 tokens (assuming 18 decimal places).
// The 2 tokens will be sent to your wallet (ie, address(this)).
// This automatically enters you into the borrowed market.
borrowedDToken.borrow(0, 2e18);

borrowedDToken.balanceOf(address(this));
// -> 2e18
// ... but check back next block to see it go up

// Later on, to repay the 2 tokens plus interest:
IERC20(borrowed).approve(EULER_MAINNET, type(uint).max);
borrowedDToken.repay(0, type(uint).max);
```

## 闪电贷

Euler 将闪电贷内置，作为协议的一个组成部分。有两种方法可以进行闪电贷，一种是低级 Euler 特定的方式，另一种是使用 [EIP-3156](https://eips.ethereum.org/EIPS/eip-3156) 兼容的闪电贷适配器。

### 低级闪电贷

进行闪电贷的低级方法是推迟对您账户进行流动性检查。 Euler 合约将回调到您的合约，您可以在其中执行 `borrow()` 之类的操作，而不必担心违反流动性。只要您的回调使账户处于非违规状态，交易就会成功完成。

由于Euler仅在持有非零时间的贷款时才收取利息，这导致了无费用的快速贷款。

这是一个示例合约，可以证明这一点：

```
contract MyFlashLoanContract {
    struct MyCallbackData {
        uint whatever;
    }

    function somethingThatNeedsFlashLoan() {
        // Setup whatever data you need
        MyCallbackData memory data;
        data.whatever = 1234;

        // Disable the liquidity check for "this" and call-back into onDeferredLiquidityCheck:
        IExec(exec).deferLiquidityCheck(address(this), abi.encode(data));
    }

    function onDeferredLiquidityCheck(bytes memory encodedData) external override {
        MyCallbackData memory data = abi.decode(encodedData, (MyCallbackData));

        // Borrow 10 tokens (assuming 18 decimals):

        IEulerDToken(borrowedDToken).borrow(0, 10e18);

        // ... do whatever you need with the borrowed tokens ...

        // Repay the 10 tokens:

        IERC20(borrowed).approve(EULER_MAINNET, type(uint).max);
        IEulerDToken(borrowedDToken).repay(0, 10e18);
    }
}
```

`encodedData` 是一个传递参数，可让您将数据传输到回调，而无需存储写入。

### EIP-3156 闪电贷

还有一个适配器智能合约，将 Euler 的闪贷功能公开为 [EIP-3156](https://eips.ethereum.org/EIPS/eip-3156) 兼容的 API。

智能合约地址为：[mainnet](https://etherscan.io/address/0x07df2ad9878F8797B4055230bbAE5C808b8259b3)、[ropsten](https://ropsten.etherscan.io/address/0x0e60a8406a94787842f07221d2Fb5Bf19856CeA5)。

如何使用适配器的示例可以在 EIP 文档以及 \[Euler 测试套件]\(<https://github.com/euler-xyz/euler-contracts/blob/master/contracts/test/FlashLoanAdaptorTest> .sol)。费用值始终为 0。
