ethers.js读写合约里的状态变量
Posted sanqima
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ethers.js读写合约里的状态变量相关的知识,希望对你有一定的参考价值。
在ethers.js里,对合约状态变量的访问有2种方式:只读方式和读写方式。当访问合约里的状态变量时,需要知道该合约的地址、abi、provider(或signer),只读方式,只能读取状态变量;而读写方式,既可以读取状态变量,还可以修改状态变量。格式如下:
//1) 只读方式
contract = new ethers.Contract(contAddress,contAbi,provider)
//2) 读写方式
contract = new ethers.Contract(contAddress,contAbi,signer)
-
Only Read 只读方式
只读方式,不消耗gas,需要提供provider,只能读取状态变量,无法修改状态变量。 -
Read and Write 读写方式
读写方式,消耗gas,需要提供signer,既可以读取状态变量,也可以修改状态变量。
这里以hardhat读取和修改greeter.sol合约里的状态变量greeting为例,进行说明。
1、创建工程tokenhat
1.1 创建文件夹并初始化
mkdir tokenhat
cd tokenhat
npm init -y
1.2 修改package.json文件
修改好的package.json文件如下:
{
"name": "tokenhat",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \\"Error: no test specified\\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"chai": "^4.3.4",
"ethereum-waffle": "^3.4.0",
"ethers": "^5.4.7",
"hardhat": "^2.6.5",
"ethereumjs-abi": "^0.6.8"
}
}
1.3 安装依赖包并初始化hardhat
npm install
npx hardhat
## 选中Create a sample project,然后,一路按Enter键即可。
1.4 修改solidity的版本
在hardhat.config.js文件里,将solidity的版本修改为0.5.12,如下:
require("@nomiclabs/hardhat-waffle");
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.5.12", //修改此处的版本
};
2、创建和部署智能合约
a) 在tokenhat/contracts目录里,修改greeter.sol合约,具体如下:
//greeter.sol
//SPDX-License-Identifier: Unlicense
// pragma solidity ^0.8.0;
pragma solidity ^0.5.0;
import "hardhat/console.sol";
contract Greeter {
string private greeting;
constructor(string memory _greeting) public {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}
b) 新建部署脚本
在tokenhat/script目录下,新建一个部署脚本:1_deploy_greeter.js
// scripts/1_deploy_greeter.js
const hre = require("hardhat");
async function main() {
// We get the contract to deploy
const Greeter = await hre.ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");
await greeter.deployed();
console.log("Greeter deployed to:", greeter.address);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
c) 部署智能合约到本地
// 启动hardhat本地私有链(127.0.0.1:8545)
npx hardhat node
// 编译智能合约
npx hardhat compile
// 部署智能合约到localhost
npx hardhat run scripts\\1_deploy_greeter.js --network localhost
3、读取和修改状态变量
3.1 读取状态变量
在tokenhat/test目录下,新建一个脚本: 4_onlyRead.js,用于读取greeting的值,内容如下:
//4_onlyRead.js
const { expect } = require("chai");
const { ethers } = require("hardhat");
const fs = require("fs");
describe("greeter test",function() {
before(async function() {
this.provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');
// this.signer1 = this.provider.getSigner();
this.contJson = fs.readFileSync("./myabi/greeter_abi.json") //abi文件
this.contAbi = JSON.parse(this.contJson) //转换为json个数
this.contAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3" //合约的地址
this.contract = new ethers.Contract(this.contAddress,this.contAbi,this.provider)
})
//2)开始测试
context("connect smart contract",async function() {
it("getGreete",async function() {
expect(await this.contract.greet()).to.equal("Hello world");
})
});
});
3.2 修改状态变量
在tokenhat/test目录下,新建一个脚本: 5_writeRead.js,内容如下:
//5_writeRead.js
const { expect } = require("chai");
const { ethers } = require("hardhat");
const fs = require("fs");
describe("greeter test",function() {
before(async function() {
this.provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');
this.signer1 = this.provider.getSigner();
// this.contJson = fs.readFileSync("./myabi/greeter_abi.json") //abi文件
// this.contAbi = JSON.parse(this.contJson) //转化为json个数
this.contFile = fs.readFileSync("./artifacts/contracts/Greeter.sol/Greeter.json")
this.contAbi = JSON.parse(this.contFile).abi
this.contAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3" //合约的地址
this.contract = new ethers.Contract(this.contAddress,this.contAbi,this.signer1)
})
//1)开始测试
context("connect smart contract",async function() {
it("setGreete",async function() {
const setGreetingTx = await this.contract.setGreeting("Hello world");
// wait until the transaction is mined
await setGreetingTx.wait();
expect(await this.contract.greet()).to.equal("Hello world");
})
it("getGreete",async function() {
expect(await this.contract.greet()).to.equal("Hello world");
})
});
});
3.3 进行测试
## 进入工程目录
cd tokenhat
## 修改状态变量
npx hardhat test test\\5_writeRead.js
## 读取状态变量
npx hardhat test test\\4_onlyRead.js
效果如下:
参考文献
[1] hardhat以太坊全栈开发
[2] 使用Next.js和Next-Auth-js在Ethreum开发带有社区认证的Dapp
以上是关于ethers.js读写合约里的状态变量的主要内容,如果未能解决你的问题,请参考以下文章