以太坊-合约交互


介绍

前不久参与开发一个 DApp,此前并没有这方面的经验,给自己加了许多假想的困难。但是开发完这个 DApp 后,发现并没有想象中的困难。 这个 DAPP 主要是与合约(Smart Contract)进行交互,关于合约的介绍留待以后再补充,本文主要介绍如何使用 ethers.js 与合约进行交互。

获取地址

DApp 要想正常使用,首先要获取用户的地址。

const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
return await signer.getAddress()

合约交互

我们以领取 ENS 代币为例,合约地址为:0xc18360217d8f7ab5e7c516566761ea12ce7f9d72,ABI:https://etherscan.io/address/0xc18360217d8f7ab5e7c516566761ea12ce7f9d72#code。关于 ABI ,你可以想象它是我们平常使用的 API。

执行 ABI 中 claimTokens 方法即可领取 ENS 代币:

/\*\*

- @dev Claims airdropped tokens.
- @param amount The amount of the claim being made.
- @param delegate The address the tokenholder wants to delegate their votes to.
- @param merkleProof A merkle proof proving the claim is valid.
\*/
function claimTokens(uint256 amount, address delegate, bytes32[] calldata merkleProof)

首先是使用 ethers.js 组装 data 数据:

// ABI 编码只需要函数声明部分,不用整个实现,而且是传入字符串就好
const ABI = ['function claimTokens(uint256 amount, address delegate, bytes32[] calldata merkleProof)']
const iface = new ethers.utils.Interface(ABI);
const data = iface.encodeFunctionData('claimTokens', [amount, delegate, merkleProof])

接着发送交易:

const params = [
    {
    from,
    to,
    value: '0x0',
    data,
    },
    ]
ethereum
    .request({
        method: 'eth_sendTransaction',
        params,
    })
    .then((txHash: string) => {
    	alert(txHash)
    })
    .catch((err) => console.log(err))

ABI 中也提供了方法判断领取状态

function isClaimed(uint256 index) public view returns (bool)
const provider = new ethers.providers.Web3Provider(window.ethereum)
const erc20 = new ethers.Contract(to, ABI, provider)
const index = getMerkleTreeIndex(address, balance, proof)
const isClaimed = await erc20.isClaimed(index)

总结

DApp 与合约进行交互主要是通过 ABI 实现,而现在也有许多封装好的第三方库帮助我们方便地使用。Web3 这个领域许多代码都是开源的,遇到问题不用愁,看看别人是如何实现的,说不定就有思路了。