用JavaScript实现对接Aave协议【DeFi】

夙愿已清 提交于 2020-08-11 01:55:20

不到一个月的时间里,在区块链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池,主要步骤如下:

  1. 载入LendingPoolAddressesProvider合约
  2. 获取LendingPool地址
  3. 载入LendingPool合约
  4. 向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了。具体步骤如下:

  1. 从LendingPool合约获取储备数据
  2. 使用储备数据载入aToken合约
  3. 赎回以太币

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协议对接开发入门 — 汇智网

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!