上一篇文章我们讲到了使用以太坊官方的web3.js第三方工具和以太坊的truffle框架,以及利用nodejs的express框架实现对以太坊智能合约方法的调用。在这一篇文章中,我们将学习使用以太坊的另一种第三方工具ethers和以太坊的hardhat框架来编译部署合约,并且也实现对以太坊智能合约方法的调用。让我们还是以之前讲过的ERC20合约为示例。

1.首先我们先创建基本的目录结构,选择创建一个javascript工程。

npx hardhat

2.将我们的合约放至contracts目录内,合约名称叫做MyToken.sol。

3.配置hardhat.config.js文件

require("@nomicfoundation/hardhat-toolbox");

const fs = require('fs');

const privateKey = fs.readFileSync(".secret").toString().trim();

module.exports = {

defaultNetwork: "goerli", // 指定哪个网络

networks: {

goerli: {

url: "https://goerli.infura.io/v3/9df29b35c83d4e4c87a8cde2034794f1",

accounts: [privateKey],

}

},

solidity: {

version: "0.8.0",

settings: {

optimizer: {

enabled: true,

runs: 200

}

}

},

paths: {

sources: "./contracts",

tests: "./test",

cache: "./cache",

artifacts: "./artifacts"

},

mocha: {

timeout: 40000

}

};

4.编写部署合约文件 scripts/deploy.js

const hre = require("hardhat");

async function main() {

const MyToken = await hre.ethers.getContractFactory("MyToken");

const myToken = await MyToken.deploy("FIRST-TOKEN","FT");

await myToken.deployed();

console.log("MyToken deployed to:", myToken.address);

}

// We recommend this pattern to be able to use async/await everywhere

// and properly handle errors.

main().catch((error) => {

console.error(error);

process.exitCode = 1;

});

5.添加依赖 package.json

{

"name": "hardhat-project",

"dependencies": {

"@nomicfoundation/hardhat-toolbox": "^2.0.2",

"@openzeppelin/contracts": "^4.8.3",

"bignumber.js": "^9.1.1",

"hardhat": "^2.14.0"

},

"devDependencies": {

"body-parser": "^1.20.2",

"chai": "^4.3.7",

"ethereumjs-tx": "^2.1.2",

"ethers": "^6.3.0",

"express": "^4.18.2",

"fs": "^0.0.1-security",

"web3": "^1.9.0"

}

}

6.编写测试脚本 /test/MyToken.js

const {expect} = require("chai");

const {ethers} = require("hardhat");

describe("Test MyToken", function () {

it("Should return the same name and same symbol", async function () {

const myToken = await ethers.getContractFactory("MyToken");

const mt = await myToken.deploy("FIRST-TOKEN","FT");

await mt.deployed();

// name

expect(await mt.name()).to.equal("FIRST-TOKEN");

console.log("name true!");

// symbol

expect(await mt.symbol()).to.equal("FT");

console.log("symbol true!");

});

});

7.配置好上面的代码后,我们安装依赖,之后再依次编译,部署,测试

npm install npx hardhat compile npx hardhat run ./scripts/deploy.js --network goerli npx hardhat test

此时项目目录为

MyToken

- contracts

- MyToken.sol

- scripts

- deploy.js

- test

- MyToken.t.js

- hardhat.config.js

- package.json

- cache

- ...

- artifacts

- ...

- .secret

上面,我们完成了对代码的编译部署以及测试,接下来,我们使用ethers来调用合约的接口。在上面的代码目录基础上,我们再往下添加目录代码。

我们首先将编译后在artifacts/contracts/MyToken.sol/MyToken.json里的abi文件复制粘贴到我们新建的abis/abi文件中。如下:

abis/abi

[

{

"inputs": [

{

"internalType": "string",

"name": "name",

"type": "string"

},

...

...

...

"stateMutability": "nonpayable",

"type": "function"

}

]

其次,我们编写调用合约的接口文件apis/api.js

const ethers = require('ethers');

const fs = require('fs');

const Tx = require("ethereumjs-tx");// 这个版本一定要1.3.7

const BigNumber = require("bignumber.js");

const abi = JSON.parse(fs.readFileSync("./abis/abi"));

const provider = new ethers.getDefaultProvider('https://goerli.infura.io/v3/9df29b35c83d4e4c87a8cde2034794f1');

const privateKey = fs.readFileSync(".secret").toString().trim();

const wallet = new ethers.Wallet(privateKey, provider);

const ContractAddr = '0xE15d4d98543a2C8847BeFeFB332fe91459B0eC83';

const contract = new ethers.Contract(ContractAddr, abi, provider);

const contractWithSigner = contract.connect(wallet);

module.exports = {

name: async (req, res) => {

let result = await contractWithSigner.name();

console.log("name:" + result + "\n");

// 发送响应数据

res.send({

"msg": "ok",

"name": result,

});

},

// 查询token数量剩余多少

balanceOf: async (req, res) => {

const owner = "0xF8600a900fF30c76807C155bf6B07ba5BE8190A7";

let result = await contractWithSigner.balanceOf(owner);

console.log("balanceOf:" + result + "\n");

const bal = new BigNumber(result);

// 发送响应数据

res.json({

"msg": "ok",

"balanceOf": bal.toFixed(),

});

},

}

最后,我们编写路由文件routers/router.js

const express = require('express');

const app = new express();

const call = require('../apis/api');

const router = express.Router();

const bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({extend: false}));

app.use(bodyParser.json());

app.use(router);

router.get('/name', call.name);

router.get('/balanceOf', call.balanceOf);

app.listen(7070, '127.0.0.1', () => console.log("正在监听端口"));

最终,项目的目录长这样

MyToken

- abis

- abi

- apis

- api.js

- routers

- router.js

- contracts

- MyToken.sol

- scripts

- deploy.js

- test

- MyToken.t.js

- hardhat.config.js

- package.json

- cache

- artifacts

- .secret

所有代码完成后,我们运行 node ./routers/router.js 就可以访问我们的合约接口了。

至此,关于ethers调用和合约接口,以及使用hardhat编译部署合约到以太坊的测试网络,我们就讲完了。下一节,带着大家使用go语言来调用我们的以太坊合约接口。我们下一期再见!

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: