赞
踩
ethers.js是一个简洁的以太坊操作库,使用它非常方便的执行读函数、写函数。下面介绍使用ethers.js执行CountOne.sol里的读写函数。
// CountOne.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; contract CountOne { uint public count; address public owner; constructor() public { count = 0; owner = msg.sender; } function getCount() public view returns(uint) { return count; } function increaseCount() public { require(count + 1 > count,"add is overflow"); count = count + 1; } function decreaseCount() public { require(count >= 1,"sub is overflow"); count = count - 1; } function clearCount() public onlyOwner { count = 0; } modifier onlyOwner() { require(owner == msg.sender,"info: caller is not owner"); _; } }
使用Remix将这个合约部署到Rinkeby测试网,然后编写JS测试脚本,通过contract.count()函数读取值,contract.increaseCount()函数更新值。
Remix合约部署请参考这篇文章
## 创建工程并初始化
mkdri ethersDemo
cd ethersDemo
npm init -y
truffle init
## 创建2个文件
touch .infuraKey
touch .secret
修改好的package.json文件如下:
{ "name": "ethersDemo", "version": "1.0.0", "description": "", "main": "", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@truffle/hdwallet-provider": "^1.7.0", "web3": "^1.6.1", "@ethereumjs/tx": "^3.4.0", "ethers": "^5.5.1" }, "devDependencies": { "@babel/core": "^7.12.3", "@babel/preset-env": "^7.12.1" } }
npm install
在truffle-config.js文件里,将solidity的版本修改为0.6.6,并开启development字段,如下:
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 8545, // Standard Ethereum port
network_id: "*", // Any network (default: none)
},
compilers: {
solc: {
version: "0.6.6",
}
}
在ganache里设置IP为127.0.0.1,端口为8545,重启ganache
将第1章的CountOne.sol拷贝到ethersDemo/contracts目录下
cd ethersDemo
truffle console
compile
在build/contracts目录下,找到CountOne.json,找到abi:字段,在[ 坐标,按Ctrl+Shift+→ 快捷键,即可拷贝整个abi,具体请看这篇文章[json压缩成一行],将其保存到ethersDemo/myabi/countOne_abi.json文件里。
//countOne_abi.json
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"increaseCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decreaseCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clearCount","outputs":[],"stateMutability":"nonpayable","type":"function"}]
a) 在 infura.io里创建一个工程,在【设置】页面,就得到Project ID,这个Project ID就是infuraKey,如图(2)所示,把它拷贝到ethersDemo/.infuraKey文件里;
b) 点击MEtaMask --> 选中某个Account ----> 详情 —> 导出私钥,将其拷贝ethersDemo/.secret文件里
整个工程目录结构如下:
在ethersDemo/test目录,创建一个脚本: 1.getCount.js
cd ethersDmeo
touch 1.getCount.js
//1.getCount.js
const {ethers} = require("ethers") const fs = require('fs') //use rinkeby let network = getNetWork("4") let provider = new ethers.providers.JsonRpcProvider(network) function getNetWork(netId) { let infuraKey = fs.readFileSync(".infuraKey").toString().trim(); //default network is rinkeby let net = 'https://rinkeby.infura.io/v3/'+infuraKey if (netId == "4") { return net } switch (netId) { case "1": net = 'https://mainnet.infura.io/v3/'+infuraKey; break; case "3": net = 'https://ropsten.infura.io/v3/'+infuraKey; break; case "5": net = 'https://goerli.infura.io/v3/'+infuraKey; break; case "42": net = 'https://kovan.infura.io/v3/'+infuraKey; break; } return net; } function getString(prikeyPath) { const privKeyFile = fs.readFileSync(prikeyPath).toString().trim(); const privKey = '0x' + new Buffer.from(privKeyFile); return privKey } async function preGetValue(contract) { let value = await contract.count() let valone = ethers.BigNumber.from(value).toNumber() console.log("curValue=",valone) } async function preSetValue(contract) { let tx = await contract.increaseCount() console.log('tx=',tx.hash) await tx.wait() } async function doValue(){ //privKey = "0x24....89" var privKey = getString(".secret") let wallet = new ethers.Wallet(privKey,provider) var contractAddr = '0x2F70e8A246350ED1fD7b798F7CeDFdc4E645123D' var jsonStr = fs.readFileSync('./myabi/countOne_abi.json') var jsonAbi = JSON.parse(jsonStr) let contract = new ethers.Contract(contractAddr,jsonAbi,wallet) //读取旧值 await preGetValue(contract) //执行更新 await preSetValue(contract) //读取更新后的值 await preGetValue(contract) } doValue()
node test/1.getCount.js
效果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。