免责声明:
1、本文版权归原作者所有,仅代表作者本人观点,不代表陀螺财经观点或立场。
2、如发现文章、图片等侵权行为,侵权责任将由作者本人承担。
Buidler(Truffle的替代工具)
Ethers.js(取代Web3.js)
Waffle (Truffle 测试的替代工具)
Typescript
项目设置
$ npm install --save-dev @nomiclabs/buidler
$ npx buidler
$ npx buidler
888 d8b 888 888
888 Y8P 888 888
888 888 888
88888b. 888 888 888 .d88888 888 .d88b. 888d888
888 "88b 888 888 888 d88" 888 888 d8P Y8b 888P"
888 888 888 888 888 888 888 888 88888888 888
888 d88P Y88b 888 888 Y88b 888 888 Y8b. 888
88888P" "Y88888 888 "Y88888 888 "Y8888 888
Welcome to Buidler v1.0.1
? What do you want to do? …
Create a sample project
? Create an empty buidler.config.js
Quit
$ mkdir contracts test scripts
$ npm install --save-dev ts-node typescript @types/node @types/mocha
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist"
},
"include": ["./scripts", "./test"],
"files": [
"./buidler.config.ts"
]
}
mv buidler.config.js buidler.config.ts
import { BuidlerConfig } from "@nomiclabs/buidler/config";
const config: BuidlerConfig = {};
export default config;
创建和编辑合约
pragma solidity 0.5.12;
contract Counter {
uint256 count = 0;
event CountedTo(uint256 number);
function countUp() public returns (uint256) {
uint256 newCount = count + 1;
require(newCount > count, "Uint256 overflow");
count = newCount;
emit CountedTo(count);
return count;
}
function countDown() public returns (uint256) {
uint256 newCount = count - 1;
require(newCount < count, "Uint256 underflow");
count = newCount;
emit CountedTo(count);
return count;
}
}
$ npx buidler compile
Compiling...
Compiled 1 contract successfully
用Ethers和Waffle建立测试环境
$ npm install --save-dev @nomiclabs/buidler-ethers ethers ethereum-waffle chai @types/chai
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"resolveJsonModule": true
},
"include": ["./scripts", "./test"],
"files": [
"./buidler.config.ts",
"node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts",
}
import { BuidlerConfig, usePlugin } from "@nomiclabs/buidler/config";
usePlugin("@nomiclabs/buidler-ethers");
const config: BuidlerConfig = {
solc: {
version: "0.5.12"
}
};
export default config;
设置TypeChain
$ npm install --save-dev typechain typechain-target-ethers
$ ./node_modules/.bin/typechain --target ethers --outDir typechain 'build/*.json'
编写和运行合约测试
import { ethers } from "@nomiclabs/buidler";
import chai from "chai";
import { deployContract, getWallets, solidity } from "ethereum-waffle";
import CounterArtifact from "../build/Counter.json";
import { Counter } from "../typechain/Counter"
chai.use(solidity);
const { expect } = chai;
describe("Counter", () => {
// 1
const provider = ethers.provider;
// 2
let [wallet] = getWallets(provider);
// 3
let counter: Counter;
beforeEach(async () => {
counter = await deployContract(wallet, CounterArtifact) as Counter;
const initialCount = await counter.getCount();
// 4
expect(initialCount).to.eq(0);
expect(counter.address).to.properAddress;
});
// 5
it("should count up", async () => {
await counter.countUp();
let count = await counter.getCount();
expect(count).to.eq(1);
await counter.countUp();
count = await counter.getCount();
expect(count).to.eq(2);
});
it("should count down", async () => {
// 6
await counter.countDown();
const count = await counter.getCount();
expect(count).to.eq(0);
});
});
1.使用从Buidler导入的provider
2.从getWallets功能获取钱包另外请注意,您可以使用此函数对任意数量的钱包进行结构分解,例如:
let [wallet1, wallet2, wallet3] = getWallets(provider);
3.导入Counter类型,并将其用作在beforeEach中部署的变量的类型。
4. Waffle有一些有用的Chai匹配器,用于编写合同测试,例如BigNumber匹配器和以太坊地址匹配器。 在这里查看所有内容。
5.通过简单的测试来计数并确保Counter正常工作。
6.注意的那些人将看到此测试将失败。
$ npx buidler test
All contracts have already been compiled, skipping compilation.
Counter
? should count up (143ms)
1) should count down
1 passing (593ms)
1 failing
1) Counter
should count down:
Error: VM Exception while processing transaction: revert Uint256 underflow
at Counter.countDown (contracts/Counter.sol:24)
部署合约
import { BuidlerConfig, usePlugin } from "@nomiclabs/buidler/config";
import waffleDefaultAccounts from "ethereum-waffle/dist/config/defaultAccounts";
usePlugin("@nomiclabs/buidler-ethers");
const INFURA_API_KEY = "";
const RINKEBY_PRIVATE_KEY = "";
const config: BuidlerConfig = {
solc: {
version: "0.5.12"
},
paths: {
artifacts: "./build"
},
networks: {
buidlerevm: {
accounts: waffleDefaultAccounts.map(acc => ({
balance: acc.balance,
privateKey: acc.secretKey
}))
},
rinkeby: {
url: `https://rinkeby.infura.io/v3/${INFURA_API_KEY}`,
accounts: [RINKEBY_PRIVATE_KEY]
}
}
};
export default config;
import { ethers } from "@nomiclabs/buidler";
async function main() {
const factory = await ethers.getContract("Counter")
// If we had constructor arguments, they would be passed into deploy()
let contract = await factory.deploy();
// The address the Contract WILL have once mined
console.log(contract.address);
// The transaction that was sent to the network to deploy the Contract
console.log(contract.deployTransaction.hash);
// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
$ npx buidler run --network rinkeby scripts/deploy.ts
All contracts have already been compiled, skipping compilation.
0x01FF454Dd078dC7f3cd0905601d093b17E7B9CD7
0x2ae1444920ed76420fb69c9f2fc914c20956efc2ae05c94ab1ea53f224aa0930
收尾
"scripts": {
"build": "npm run compile && npm run typechain",
"compile": "npx buidler compile",
"typechain": "npx buidler compile && typechain --outDir typechain --target ethers 'build/*.json'",
"test": "npx buidler test"
}
$ npm install --save-dev @nomiclabs/buidler-etherscan
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"resolveJsonModule": true
},
"include": ["./scripts", "./test"],
"files": [
"./buidler.config.ts",
"node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts",
"node_modules/@nomiclabs/buidler-etherscan/src/type-extensions.d.ts"
]
}
import { BuidlerConfig, usePlugin } from "@nomiclabs/buidler/config";
import waffleDefaultAccounts from "ethereum-waffle/dist/config/defaultAccounts";
usePlugin("@nomiclabs/buidler-ethers");
usePlugin("@nomiclabs/buidler-etherscan");
const INFURA_API_KEY = "";
const RINKEBY_PRIVATE_KEY = "";
const ETHERSCAN_API_KEY = "";
const config: BuidlerConfig = {
solc: {
version: "0.5.12"
},
paths: {
artifacts: "./build"
},
networks: {
buidlerevm: {
accounts: waffleDefaultAccounts.map(acc => ({
balance: acc.balance,
privateKey: acc.secretKey
}))
},
rinkeby: {
url: `https://rinkeby.infura.io/v3/${INFURA_API_KEY}`,
accounts: [RINKEBY_PRIVATE_KEY]
}
},
etherscan: {
// The url for the Etherscan API you want to use.
url: "https://api-rinkeby.etherscan.io/api",
// Your API key for Etherscan
// Obtain one at https://etherscan.io/
apiKey: ETHERSCAN_API_KEY
}
};
export default config;
$ npx buidler verify-contract --contract-name Counter --address 0xF0E6Ea29799E85fc1A97B7b78382fd034A6d7864
All contracts have already been compiled, skipping compilation.
Successfully submitted contract at 0xF0E6Ea29799E85fc1A97B7b78382fd034A6d7864 for verification on etherscan. Waiting for verification result...
Successfully verified contract on etherscan
本文来源于陀螺财经专栏作家:区块链研究实验室,区块链研究实验室简介:专注区块链技术研发,区块链大学知识培训,区块链技术研发社区和区块链孵化
现已在陀螺财经发布121篇内容,累计总热度10万+。陀螺财经现已开放专栏入驻,详情请见入驻指南:http://www.gfptjs.com.cn/article/detail-27547.html