> For the complete documentation index, see [llms.txt](https://xiangganzi.gitbook.io/flashloan/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://xiangganzi.gitbook.io/flashloan/shan-dian-dai-jiao-cheng/di-yi-bi-shan-dian-dai.md).

# 开始我的第一个闪电贷

## 第一步，添加所需要的接口

根据自己需求添加:

```
import { ILendingPoolAddressesProvider } from "./ILendingPoolAddressesProvider.sol"; // 通过该接口获取LendingPool地址
import { FlashLoanReceiverBase } from "./FlashLoanReceiverBase.sol";   // 接收闪电贷金额的合约必须通过IFlashLoanReceiver 接口实现的 executeOperation() 
import { ILendingPool } from "./ILendingPool.sol";        // 通过该接口调用flashloan
import { IERC20 } from "./IERC20.sol";                    // 涉及到ERC20代币所需
```

{% hint style="info" %}
请注意闪电贷将扣取一定量的手续费，平台手续费为0.09%
{% endhint %}

## 第二步，设置FlashLoanReceiverBase

{% code title="FlashLoanReceiverBase.sol" %}

```bash

abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
  using SafeERC20 for IERC20;
  using SafeMath for uint256;

  ILendingPoolAddressesProvider public immutable override ADDRESSES_PROVIDER;
  ILendingPool public immutable override LENDING_POOL;

  constructor(ILendingPoolAddressesProvider provider) public {
    ADDRESSES_PROVIDER = provider;
    LENDING_POOL = ILendingPool(provider.getLendingPool());
  }
}
```

{% endcode %}

另请注意，由于欠款将从你的策略同中提取，您的合同必须为 LendingPool 提供补贴以提取这些资金以偿还闪贷债务 + 保费。

## 第三步，完善策略合约

接收闪贷金额的合约必须通过实现相关的 executeOperation() 函数。 在下面的示例中，我们策略将继承FlashLoanReceiverBase。&#x20;

{% hint style="info" %}
以下代码未提供策略代码，仅贷款还款操作，往合约转代币才可成功完成一笔闪电贷。
{% endhint %}

```bash

contract MyfirstFlashLoan is FlashLoanReceiverBase {

    /**
        在你的策略合约收到闪电贷金额后将调用此函数
     */
    function executeOperation(
        address[] calldata assets,
        uint256[] calldata amounts,
        uint256[] calldata premiums,
        address initiator,
        bytes calldata params
    )
        external
        override
        returns (bool)
    {

        // 该策略合约此时已获得所需资金
        // 策略逻辑可以写在这里
        
        // 在上述逻辑的最后，该合约欠闪电贷额度 + 手续费。
        // 因此，请确保您的合同有足够的资金来偿还这些金额。
        
        // 授权 LendingPool 合约提前欠款额度
        for (uint i = 0; i < assets.length; i++) {
            uint amountOwing = amounts[i].add(premiums[i]);
            IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing);
        }
        
        return true;
    }
    
    function myfirstFlashLoanCall() public {
        // 接收贷款地址
        address receiverAddress = address(this);

        // 贷款币币种,仅贷一个币种
        address[] memory assets = new address[](1);
        assets[0] = address(INSERT_ASSET_ONE_ADDRESS);

        // 贷款币数量
        uint256[] memory amounts = new uint256[](1);
        amounts[0] = INSERT_ASSET_ONE_AMOUNT;

        // 贷款模式
        uint256[] memory modes = new uint256[](1);
        modes[0] = INSERT_ASSET_ONE_MODE;

        address onBehalfOf = address(this);
        bytes memory params = "";
        uint16 referralCode = 0;

        LENDING_POOL.flashLoan(
            receiverAddress,
            assets,
            amounts,
            modes,
            onBehalfOf,
            params,
            referralCode
        );
    }
}
```

## 第四步，合约部署

部署工具可自由选择，remix，truffle，hardhat

部署参数初始值设置为LendingPoolAddressesProvider合约地址:

0xF7CeaE542b00d8CBa6D7bcb3a5AbcA7A2E19829a&#x20;

MyfirstFlashLoan合约已部署在heco链上并在浏览器验证，任何人都可以调用，准备好手续费即可

{% embed url="<https://hecoinfo.com/address/0xea58a27da4f1df9cac54207ce82935017af4534a#code>" %}

## 第五步，调用闪电贷

调用myfirstFlashLoanCall(address asset, uint256 num, uint256 mode)函数:

参考交易：

{% embed url="<https://hecoinfo.com/tx/0xc073b742baa262bddd0a5574f658d73a1fa44cdff2006f0da4e6b707bc6257fe>" %}

## 编码和解码参数

如果您想将参数传递到您的闪电贷函数中，您首先需要对它们进行编码，然后在您的 executeOperation() 中对其进行解码。

#### **编码**

如果您要进行编码，则可以使用内置的`abi.encode()`:

```bash
// Encoding an address and a uint
bytes memory params = abi.encode(address(this), 1234);
```

####

如果是链下操作，例如 `web3.js` 可以调用[`abi.encodeParameters()`](https://web3js.readthedocs.io/en/v1.3.0/web3-eth-abi.html?highlight=encodeParameters#encodeparameters):

```javascript
const params = web3.eth.abi.encodeParameters(
	["bytes32"],
	[
		web3.utils.utf8ToHex("some_value")
	]
)
```

#### 解码

在你的 executeOperation() 中解码时，你需要使用 `abi.decode()`:

```javascript
(bytes32 someValue) = abi.decode(params, (bytes32));
```

用法可参考闪电贷清算合约代码

## 预留提币接口

```javascript
function rescueTokens(IERC20 token) external onlyOwner {
    token.transfer(owner(), token.balanceOf(address(this)));
  }
```

##
