赞
踩
上一篇文章我们讲到了使用以太坊官方的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语言来调用我们的以太坊合约接口。我们下一期再见!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。