【笔记】通过Truffle脚手架工具开发智能合约

前言

通过Truffle脚手架工具开发智能合约

安装Truffle

1
npm install -g truffle

初始化项目

通过命令行创建项目

1
2
3
mkdir demo
cd demo
truffle init

通过IDEA插件创建项目

安装插件

创建项目

项目结构

1
2
3
4
5
+ <project_name>
+ contracts // 核心程序
+ migrations // 部署脚本
+ test // 测试程序
- truffle-config.js // 配置文件

项目配置

配置区块链网络

  • 开发阶段配置为本地区块链地址
truffle-config.js
1
2
3
4
5
6
7
8
9
module.exports = {
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 8545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
}
}

配置上链付费账号

  • 如果不指定付费账号,默认将MetaMask首选账号作为上链付费账号

<public_key>:测试链的测试钱包公钥

truffle-config.js
1
2
3
4
5
module.exports = {
advanced: {
from: "<public_key>",
}
}

配置优化

truffle-config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
compilers: {
solc: {
version: "0.8.21", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
settings: { // See the solidity docs for advice about optimization and evmVersion
optimizer: {
enabled: false,
runs: 200
},
evmVersion: "byzantium"
}
}
},
}

创建智能合约

  • 创建一个用于存储用户信息的智能合约

// SPDX-License-Identifier: GPL-3.0:指定合约的开源协议
pragma solidity ^0.8.0;:指定合约运行的编译器版本
UserStorage:合约名必须与文件名保持一致

contracts/UserStorage.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract UserStorage {
string name;
uint age;

function setUser(string memory _name, uint _age) public {
name = _name;
age = _age;
}

function getUser() public view returns (string memory, uint) {
return (name, age);
}
}

创建部署脚本

  • migrations目录下创建以数字开头的js文件
migrations/1_deploy.js
1
2
3
4
5
const Contacts = artifacts.require("UserStorage.sol");

module.exports = function(deployer) {
deployer.deploy(Contacts);
}

编译智能合约

1
truffle compile
  • 编译后会产生一个build目录存放编译后的文件

编译并部署智能合约

  • migrate命令会先编译后部署,包含了compile命令的功能
  • 根据部署脚本编译并部署智能合约
  • 如果包含脚本被部署一次,则再次执行部署将不会运行部署脚本
  • 如果想要部署新的智能合约,可以添加新的部署脚本文件,文件名需要与之前部署过智能合约的脚本文件名不同
1
truffle migrate
  • 部署成功后会消耗燃料费
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
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.


Starting migrations...
======================
> Network name: 'development'
> Network id: 1695793311003
> Block gas limit: 30000000 (0x1c9c380)


1_deploy.js
===========

Deploying 'UserStorage'
-----------------------
> transaction hash: 0x459e458aa8d37e8fe27eeb99a19532251a71979265c3a96f45b1b197db184508
> Blocks: 0 Seconds: 0
> contract address: 0x38214aa6420c38c5EF03e8cd642D137f06a65aC7
> block number: 1
> block timestamp: 1695805238
> account: 0xfCF41f704eE38101F402d48f31F422D756A69a70
> balance: 999.998507524375
> gas used: 442215 (0x6bf67)
> gas price: 3.375 gwei
> value sent: 0 ETH
> total cost: 0.001492475625 ETH

> Saving artifacts
-------------------------------------
> Total cost: 0.001492475625 ETH

Summary
=======
> Total deployments: 1
> Final cost: 0.001492475625 ETH

重新编译并部署智能合约

  • 如果修改了某个已经部署智能合约的脚本内容,而没有修改脚本文件名,则需要通过--reset覆盖之前的编译结果并重新部署智能合约
1
truffle migrate --reset

测试智能合约

通过Truffle控制台测试

进入Truffle控制台

  • 进入Truffle控制台对程序进行简单的测试
1
truffle console

deployed():实例化一个类

1
2
3
truffle(development)> const obj = await UserStorage.deployed();
truffle(development)> console.log(obj);
truffle(development)> console.log(obj.address);

进入Truffle控制台

  • Ctrl+C两次
  • Ctrl+D一次
  • 输入.exit命令并回车执行

通过Mocha测试

通过Truffle脚本测试

编写测试脚本

  • 在测试脚本中内置了artifacts对象和web3对象,可以直接使用
scripts/test.js
1
2
3
4
5
6
7
8
9
10
11
const Contacts = artifacts.require("UserStorage.sol");

module.exports = async function(callback) {

var obj = await Contacts.deployed();
await obj.setUser("", 1);
var res = await obj.getUser();
console.log(res);

callback();
}

执行测试脚本

1
truffle exec ./scripts/test.js

完成

参考文献

哔哩哔哩——千锋教育