不到一个月的时间里,在区块链DeFi协议中锁定的资产价值就已经翻了一倍,超过20亿美元。Aave是第五大并且是第一个支持Flash Loan的DeFi平台,在这篇文章中,我们将学习如何在DApp应用中对接Aave协议,实现存入资产、赎回资产等功能。本教程使用的开发语言为JavaScript。
用自己熟悉的语言学习 以太坊DApp开发 : Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart
1、Aave协议简介
Aave目前支持17个市场: ETH, DAI, USDC, SUSD, TUSD, USDT, BUSD, BAT, KNC, LEND, LINK, MANA, MKR, REP, SNX, WBTC以及ZRX。
让我们以LINK为例进行说明Aave的作用。通过将LINK存入Aave协议,即表明你允许协议借出你的资产,并因此获得利息收入。你可以随时取回你存入的加密资产,就像储蓄账户一样。
将你的LINK存入协议后,你可以进行一些其他操作,例如检查目前的利率、借入其他资产等等。
2、Aave协议技术概述
那么上述过程从技术角度是怎样的?与Compound相比,Aave的协议过程会复杂一点,不过还不难掌控。
Aave协议的核心是LendingPools
智能合约,它也是整个Aave协议的入口点。开发者可以利用LendingPool合约的deposit()
方法存入加密资产。此外,开发者也可以获取Aave协议的一些储备数,例如用户的流动性、当前的利率,总体流动性等等。
在Aave协议中,LendingPool合约是可升级的。这意味着其部署地址在将来可能变化。为了让DApp兼容未来的地址,Aave提供了一个LendingPoolAddressesProvider
智能合约来解决这个问题,该合约永远不会升级,可以利用它来获取最新的LendingPool合约的地址。只要我们拿到了最新的LendingPool合约的地址,就可以对接Aave协议了。
不过我们没法用LendingPool合约赎回存入的资产,这需要用到其他一些智能合约,即aTokens
。aTokens是一类ERC-20兼容的智能合约,用于实现与各种标的资产(underlying assets)的兑换。例如,当存入LINK代币后,我们就会收到按当前汇率折算数量的aLink代币,aLink合约则提供redeem()
方法用于赎回之前存入的资产。
总的说来,与Aave协议的交互主要包括以下环节:
- 利用LendingPoolAddressesProvider合约获取最新的LendingPool合约的部署地址
- 利用LendingPool合约存入资产
- 利用aToken类合约赎回资产
上述步骤让Aave协议的对接要比Compound协议复杂一些,因为DApp需要用到若干个不同的智能合约与ABI。
3、向Aave协议存入资产
首先我们先学习如何将ETH资产存入Aave池,主要步骤如下:
- 载入LendingPoolAddressesProvider合约
- 获取LendingPool地址
- 载入LendingPool合约
- 向LendingPool合约存入ETH
3.1 载入LendingPoolAddressesProvider合约
我们需要的第一个ABI是LendingPoolAddressesProvider合约的,该合约在不同网络的部署地址可查阅Aave官方文档,以太坊主网上该合约的部署地址为0x24a42fD28C976A61Df5D00D0599C34c4f90748c8
。
下面的示例代码展示了如何载入Provider合约:
const providerInstance = new web3.eth.Contract(
addressProviderABI,
"0x24a42fD28C976A61Df5D00D0599C34c4f90748c8"
);
3.2 获取LendingPool合约的部署地址
Aave的Provider合约提供了getLendingPool()
方法返回LendingPool合约的最新部署地址。例如下面的示例代码展示了如何调用该方法获取最新的LendingPool合约地址:
const lendingPoolAddress = await providerInstance.methods.getLendingPool().call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
});
3.3 载入LendingPool合约实例
LendingPool ABI 是我们需要使用的第二个ABI。下面的示例代码展示了如何利用前面获得地址载入LendingPool合约实例:
const lendingPoolInstance = new web3.eth.Contract(lendingPoolABI, lendingPoolAddress);
3.4 向LendingPool合约存入以太币
当向Aave协议存入资产时,需要告诉LendingPool我们将存入的资产类型和数量。这需要传入标的资产的储备地址,不同类型资产对应的储备地址清单可以查阅Aave文档。对于ETH而言,其储备地址是0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
。
下面的示例代码展示了如何向LendingPool合约存入ETH:
lendingPoolInstance.methods.deposit("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", supplyValue, 0)
.send({from: account, value: supplyValue})
.once('transactionHash', (hash) => {
// transaction hash
})
.on('confirmation', (number, receipt) => {
// number of confirmations
})
.on('error', (error) => {
console.log(error);
});
在上面的代码中,supplyValue
表示要存入的ETH数量,单位:wei。
下面是到目前为止我们已经实现的与Aave协议对接的全部代码:
// Load the address provider
const providerInstance = new web3.eth.Contract(addressProviderABI, "0x24a42fD28C976A61Df5D00D0599C34c4f90748c8");
// Get lending pool address
const lendingPoolAddress = await providerInstance.methods.getLendingPool().call()
.catch((e) => {
throw Error(`Error getting lendingPool address: ${e.message}`)
});
// Load lending pool
const lendingPoolInstance = new web3.eth.Contract(lendingPoolABI, lendingPoolAddress);
// Deposit funds
lendingPoolInstance.methods.deposit("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", supplyValue, 0)
.send({from: account, value: supplyValue})
.once('transactionHash', (hash) => {
// transaction hash
})
.on('confirmation', (number, receipt) => {
// number of confirmations
})
.on('error', (error) => {
console.log(error);
});
好了,现在已经将ETH存入Aave了,等着赚利息吧!
4、从Aave协议赎回资产
为了赎回之前存入的资产,我们首先需要了解应该使用哪个aToken合约,然后调用该合约的redeem()
方法就可以收到赎回的ETH了。具体步骤如下:
- 从LendingPool合约获取储备数据
- 使用储备数据载入aToken合约
- 赎回以太币
1、获取资产储备数据
储备数据(Reserve Data)描述了所存入资产的信息,例如总体流动性和当前利率。我们可以利用
储备数据获取aToken的地址。下面的代码展示了这一过程:
const reserveData = await lendingPool.methods
.getReserveData("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE")
.call()
.catch((e) => {
throw Error(`Error getting aave reserve data: ${e.message}`)
});
const aTokenAddress = reserveData.aTokenAddress;
2、载入aToken实例
aToken ABI 是我们要用到的最后一个ABI,下面的代码展示了如何载入aToken实例:
const aTokenInstance = new web3.eth.Contract(aTokenABI, aTokenAddress);
3、赎回资产
最后,下面的代码展示了如何赎回标的资产:
aTokenInstance.methods.redeem(withdrawAmount)
.send({from: account})
.once('transactionHash', (hash) => {
// transaction hash
})
.on('confirmation', (number, receipt) => {
// number of confirmations
})
.on('error', (error) => {
console.log(error);
});
withdrawAmount
表示要从Aave协议中赎回的ETH数量,单位还是wei。
下面是Aave协议资产赎回功能的完整代码:
// Get reserve data
const reserveData = await lendingPool.methods
.getReserveData("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE")
.call()
.catch((e) => {
throw Error(`Error getting aave reserve data: ${e.message}`)
});
// Get aToken address
const aTokenAddress = reserveData.aTokenAddress;
// Load aToken
const aTokenInstance = new web3.eth.Contract(aTokenABI, aTokenAddress);
// Redeem asset
aTokenInstance.methods.redeem(withdrawAmount)
.send({from: account})
.once('transactionHash', (hash) => {
// transaction hash
})
.on('confirmation', (number, receipt) => {
// number of confirmations
})
.on('error', (error) => {
console.log(error);
});
5、Aave协议接入教程小结
随着DeFi变得越来越简单易用,学习如何与这些协议交互将迅速成为开发人员工具箱中的有力武器。
原文链接:Aave协议对接开发入门 — 汇智网