使用ethers.js执行读函数与写函数

    ethers.js是一个简洁的以太坊操作库,使用它非常方便的执行读函数、写函数。下面介绍使用ethers.js执行CountOne.sol里的读写函数。

1、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合约部署请参考这篇文章

2、创建测试工程ethersDemo

2.1 创建文件夹并初始化

## 创建工程并初始化
mkdri ethersDemo
cd ethersDemo
npm init -y
truffle init

## 创建2个文件
touch .infuraKey
touch .secret

2.2 修改package.json文件

    修改好的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.5.0",
    "web3": "^1.3.0",
    "ethereumjs-tx": "^1.3.7",
    "ethers": "^5.4.7"
  },
  "devDependencies": {
    "@babel/core": "^7.12.3",
    "@babel/preset-env": "^7.12.1"
  }
}

2.3 安装依赖包

npm install

2.4 修改solidity的版本

    在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",  
    }
  } 

2.5 启动ganache

    在ganache里设置IP为127.0.0.1,端口为8545,重启ganache

2.6 拷贝合约

    将第1章的CountOne.sol拷贝到ethersDemo/contracts目录下

3 编译合约,并导出abi

3.1 使用truffle编译合约

cd ethersDemo
truffle console
compile

3.2 导出abi

    在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"}]

4、设置infuraKey和私钥

    a) 在 infura.io里创建一个工程,在【设置】页面,就得到Project ID,这个Project ID就是infuraKey,如图(2)所示,把它拷贝到ethersDemo/.infuraKey文件里;

图(2) 在infura.io里获取Project ID

    b) 点击MEtaMask --> 选中某个Account ----> 详情 —> 导出私钥,将其拷贝ethersDemo/.secret文件里

5、工程目录结构

    整个工程目录结构如下:

图(1) ethersDemo的目录结构

6、执行读写函数

6.1 编写测试脚本

    在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,infurakey) {
    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(){
    var privKey = getString(".secret")
    let wallet = new ethers.Wallet(privKey,provider)
    
    var contractAddr = '0x2F70...123D'
    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()

6.2 执行脚本

node test/1.getCount.js

    效果如下:

    count值从3变成4,更新成功。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>