Quick Start Create Demo 1 2 3 mkdir demo cd demo npm init #Confirm generating package.json
Use the yarn command to install hardhat project package
Install the openzeppelin library 1 2 yarn add @openzeppelin/contracts yarn add @openzeppelin/hardhat-upgrades
Install the test plugin
Install the ethers
Install the ethereum-waffle 1 npm install --save-dev ethereum-waffle
After the above is successfully installed,you can write smart contract. View hardhat operation commands by executing npx hardhat —help 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 npx hardhat --help 全局选项 --config 一个安全帽配置文件. --emoji 在信息中使用表情符号. --help 显示此消息,如果提供了任务名称,则显示任务的帮助 --max-memory 安全帽可以使用的最大内存量 --network 要连接到的网络. --show-stack-traces 显示堆栈跟踪. --tsconfig 保留的安全帽参数. --verbose 支持安全帽详细日志记录 --version 版本显示安全帽的版本 可用任务 check 检查你需要的任何东西 clean 清除缓存并删除所有工件 compile 编译编译整个项目,构建所有工件 console 控制台打开安全帽控制台 flatten 展平并打印合同及其依赖项 help 帮助 node 在Hardhat网络上启动JSON-RPC服务器 run 在编译项目后运行用户定义的脚本 test 运行摩卡测试
Run npx hardhat command(select Create an empty hardhat config.js) 1 2 3 4 5 6 7 8 9 npx hardhat Welcome to Hardhat v2.6.8 ? What do you want to do? … Create a basic sample project Create an advanced sample project Create an advanced sample project that uses TypeScript ▸ Create an empty hardhat.config.js Quit
Open config.js and change setting 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 require ("@nomiclabs/hardhat-waffle" );require ('@openzeppelin/hardhat-upgrades' );module .exports = { solidity : "0.8.4" , networks : { local : { url : 'http://127.0.0.1:8545' , accounts : [ '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' , '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d' , '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a' , '0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6' , '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a' , ] } } };
Create a contracts directory under the demo directory for writing smart contract
Create a test directory under the demo directory for writing unit test
Create a scripts directory under the demo directory for writing script
Create a Demo.sol file under the contracts for writing smart contract 1 2 touch Demo.sol vim Demo.sol
Edit Demo.sol first write simplest a smart contract 1 2 3 4 5 6 // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; contract Demo { uint256 public score = 0; }
Edit demo-deploy.js deploy script under scripts directory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ touch demo-deploy.js $ vim demo-deploy.js const { ethers } = require ("hardhat" );async function main ( ) { const Demo = await ethers.getContractFactory ("Demo" ); const demo = await Demo .deploy () console .log (demo.address ) }main ().then (() => process.exit (0 )).catch (error => { console .error (error); process.exit (1 ); });
Deploy Smart Contract (method one) 1 npx hardhat run scripts/demo-deploy.js
Deploy Smart Contract (method two) setting rpc network 1 npx hardhat run scripts/demo-deploy.js --network local
interact with the Demo contract for testing 1: Create a demo.test.js under test directory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 touch demo.test .js $ vim demo.test .js const { expect } = require ('chai' ) const { ethers} = require ('hardhat' ) describe ('Demo合约测试' , () => { before (async function ( ) { this .Demo = await ethers.getContractFactory ('Demo' ) this .demo = await this .Demo .deploy () }) it ('测试score等于0' , async function ( ) { const score = await this .demo .score () expect (score.toString ()).to .be .equal ('0' ) }) })
Execute Test 1 npx hardhat test test/demo.test.js --network local
So far,a simple process of smart contract writing,deployment,and testing has been completed,but this is just a start. Now our smart contract only has the function of reading score,now we need to add functions to the smart contract Next, we have another demo ,which is to add a setScore method,which can change the value of score 1 2 3 4 5 6 7 8 9 10 11 12 // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; //Demo合约 contract Demo { uint256 public score = 0; //修改score的状态 function setScore(uint256 newScore) public returns(bool) { score = newScore; return true; } }
Added setScore contract method adds test cases 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 const { expect } = require ('chai' ) const { ethers} = require ('hardhat' ) describe ('Demo合约测试' , () => { before (async () => { this .Demo = await ethers.getContractFactory ('Demo' ) this .demo = await this .Demo .deploy () }); it ('测试score等于0' , async () => { const score = await this .demo .score () expect (score.toString ()).to .be .equal ('0' ) }) it ('修改score等于100' , async () => { await this .demo .setScore (100 ) const score = await this .demo .score () expect (score.toString ()).to .be .equal ('100' ) }) })
Execute new test cases 1 npx hardhat test test/demo.test.js --network local
Now we can develop the contract by writing the Demo.sol file Write upgradable smart contract create a demo-upgradeable-deploy.js under scripts directory 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const { ethers, upgrades } = require ("hardhat" )async function main ( ) { const Demo = await ethers.getContractFactory ('Demo' ) console .log ('Deploying Demo...' ) const demo = await upgrades.deployProxy (Demo , [300 ], { initializer : setScore' }) await demo.deployed() console.log(' Demo to :', demo.address) } //执行可升级合约部署 main().then(() => process.exit(0)).catch(error => { console.error(error) process.exit(1) });
Execute upgradable deploy contract 1 2 3 4 npx hardhat run scripts/demo-upgradeable-deploy.js --network local Deploying Demo... Demo to: 0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1
After the devlopment is complete, we need to save our contract address,witch will be the user-oriented contract interaction address in the future.
Every time upgrade the contract,need this address as the proxy contract address to bind with the newly upgraded contract
Start writing the upgrade contract DemoV2.sol,Added the increment method to the upgraded contract,and the score value is increased by 1 every time it’s called. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // contracts/DemoV2.sol // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; //Demo合约 contract DemoV2 { uint256 public score; //修改score的状态 function setScore(uint256 newScore) public { score = newScore; } //分值加1 function increment() public { score = score + 1; } }
Edit deploy upgradable contract script 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const { ethers, upgrades } = require ("hardhat" );async function main ( ) { const upgradeContractName = 'DemoV2' const proxyContractAddress = '0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1' const DemoUpgrade = await ethers.getContractFactory (upgradeContractName) console .log ('Upgrading Demo...' ) await upgrades.upgradeProxy (proxyContractAddress, DemoUpgrade ) console .log ('Demo upgraded' ) }main ().then (() => process.exit (0 )).catch (error => { console .error (error) process.exit (1 ) })
Execute contract upgraded 1 npx hardhat run scripts/demo-upgrade.js --network local
Verify the upgrade contract through the hardhat console. 1 npx hardhat console --network local
Upgrade contract write test cases 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 const { expect } = require ('chai' ) const { ethers, upgrades} = require ('hardhat' ) describe ('DemoV2升级合约测试' , () => { before (async () => { const DemoContract = await ethers.getContractFactory ('Demo' ) const demoProxy = await upgrades.deployProxy (DemoContract , [300 ], { initializer : 'setScore' }) this .demo = await demoProxy.deployed () }); it ('测试score等于300' , async () => { const score = await this .demo .score () expect (score.toString ()).to .be .equal ('300' ) }) it ('修改score等于100' , async () => { await this .demo .setScore (100 ) const score = await this .demo .score () expect (score.toString ()).to .be .equal ('100' ) }) it ('increment计数器测试' , async () => { const upgradeContractName = 'DemoV2' const proxyContractAddress = this .demo .address const DemoUpgrade = await ethers.getContractFactory (upgradeContractName) const demoV2 = await upgrades.upgradeProxy (proxyContractAddress, DemoUpgrade ) await this .demo .setScore (800 ) await demoV2.increment () const newScore = (await this .demo .score ()).toString () expect (newScore).to .be .equal ('801' ) }) })
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !