通过JavaScript调用智能合约
在本教程中,我们将会看到如何通过JavaScript调用智能合约。 首先读取智能合约的状态(例如:ERC20持有者的余额),然后通过代币转账修改区块链的状态。 你首先需要了解设置JS环境与区块链交互。
在本例中,我们将使用DAI代币,基于测试目的,我们将使用ganache-cli分叉区块链并解锁一个已经拥有很多DAI的地址。
ganache-cli -f https://mainnet.infura.io/v3/[YOUR INFURA KEY] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81
要与智能合约交互,我们需要它的地址和ABI:
1const ERC20TransferABI = [2 {3 constant: false,4 inputs: [5 {6 name: "_to",7 type: "address",8 },9 {10 name: "_value",11 type: "uint256",12 },13 ],14 name: "transfer",15 outputs: [16 {17 name: "",18 type: "bool",19 },20 ],21 payable: false,22 stateMutability: "nonpayable",23 type: "function",24 },25 {26 constant: true,27 inputs: [28 {29 name: "_owner",30 type: "address",31 },32 ],33 name: "balanceOf",34 outputs: [35 {36 name: "balance",37 type: "uint256",38 },39 ],40 payable: false,41 stateMutability: "view",42 type: "function",43 },44]4546const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f"显示全部复制
对于此项目,我们剥离完整的ERC20 ABI ,仅保留balanceOf
和transfer
函数,不过你可以在这里获取完整的ERC20 ABI(opens in a new tab)。
然后我们需要实例化我们的智能合约:
1const web3 = new Web3("http://localhost:8545")23const daiToken = new web3.eth.Contract(ERC20TransferABI, DAI_ADDRESS)复制
我们还会设置两个地址:
- 一个接受转账
- 一个已经解锁并将发送
1const senderAddress = "0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81"2const receiverAddress = "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE"复制
在下一部分中,我们会调用 balance Of
函数来检索当前的代币数量,此时这两个地址的代币数量都被冻结。
调用:从智能合约读取值
第一个例子,将调用“常量(constant)”方法并且在EVM中执行这个智能合约方法,并不发送任何交易。 为此我们将读取一个地址的ECR20余额。 阅读关于 ECR20 代币的文章。
你可以访问为其提供 ABI 的实例化智能合约方法,如下所示:yourContract.methods.methodname
。 通过使用call
函数,你可以接收执行函数的结果。
1daiToken.methods.balanceOf(senderAddress).call(function (err, res) {2 if (err) {3 console.log("An error occured", err)4 return5 }6 console.log("The balance is: ", res)7})复制
请记住,DAI ERC20有18位小数,这意味着你需要移除18个零才能获得正确的数额。 uint256 将以字符串形式返回,因为 Javascript 不处理大数值。 如果不确定,请了解我们关于bignumber.js的教程如何在JS中处理大数(opens in a new tab)。
发送:将交易发送给智能合约函数
对于第二个示例,我们将调用DAI智能合约的transfer函数,发送10个DAI到第二个地址。 transfer函数接受两个参数:收件人地址和转账代币的数量:
1daiToken.methods2 .transfer(receiverAddress, "100000000000000000000")3 .send({ from: senderAddress }, function (err, res) {4 if (err) {5 console.log("An error occured", err)6 return7 }8 console.log("Hash of the transaction: " + res)9 })显示全部复制
调用函数返回将被在区块链中挖矿(mine) 的交易的哈希。 在以太坊中,交易哈希是可以预测的 - 这里是我们在执行前获得交易哈希值的方法(了解如何计算哈希(opens in a new tab))。
因为该函数只向区块链提交交易,除非通过挖矿并包含在区块链中,否则我们无法看到结果。 在下一个教程中,我们将学习如何通过了解其哈希值来等待一个交易在区块链上的执行(opens in a new tab)。
上次修改时间: @pettinarip(opens in a new tab), 2023年11月23日