开发环境:Ubuntu16.04
以太坊客户端:go-ethereum v1.7.3
第一步:node和npm安装(如果已经安装,请忽略该步骤)
官网下载node-v8.9.3-linux-x64.tar.xz
解压并移动到通用的软件安装目录 /opt/
tar -xJf node-v8.9.3-linux-x64.tar.xz
sudo mv node-v8.9.3-linux-x64 /opt/
安装 npm 和 node 命令到系统命令
sudo ln -s /opt/node-v8.9.3-linux-x64/bin/node /usr/local/bin/node
sudo ln -s /opt/node-v8.9.3-linux-x64/bin/npm /usr/local/bin/npm
通过以下命令验证安装是否成功:
node -v
v8.9.3
npm -v
5.5.1
第二步:安装Truffle框架
sudo npm install -g truffle
通过以下命令验证truffle框架是否安装成功:
truffle version
第三步:使用truffle进行智能合约的开发
(1)初始化一个 Truffle 项目
在用户自定义的目录下执行以下命令:
mkdir test_truffle
cd test_truffle
truffle init
完成后,你将拥有如下目录:
* contracts 智能合约目录
* migrations 发布脚本目录
* test 存放测试文件
* truffle.js Truffle的配置文件
(2)编译合约
进入到刚才的 test_truffle目录,执行"truffle compile",可以将原始代码编译为以太坊认可的字节码。如果需要重新编译全部文件,可以执行"truffle compile --compile-all"命令。
(3)创建一个 合约并编译
在contracts目录中新建一个Hello_mshk_top.sol文件,代码如下:
pragma solidity ^0.4.17;
contract Hello_mshk_top {
//say hello mshk.top
function say() public pure returns (string) {
return "Hello mshk.top";
}
//print name
function print(string name) public pure returns (string) {
return name;
}
}
编辑migrations/1_initial_migration.js部署脚本,将我们刚才创建的Hello_mshk_top.sol文件设置到发布配置文件中,内容如下:
var Migrations = artifacts.require("./Migrations.sol");
var Hello_mshk_top = artifacts.require("./Hello_mshk_top.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
deployer.deploy(Hello_mshk_top);
};
编译后的文件都放在了./build/contracts目录下:“./build/contracts/Hello_mshk_top.json",后面在部署到geth中,我们会用到。
第四步:部署智能合约
编辑truffle.js配置文件,设置我们稍后要部署智能合约的位置,内容如下:
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*"
}
}
};
该文件内容表示,我们在本地启动geth客户端,geth客户端的RPC端口为8545,geth的network_id不做限制。
(1)将智能合约部署到geth私链上
创世区块,使用RPC方式启动geth节点(此处略过)
(2)新建账户、挖矿
(3)在geth中部署合约(执行该步骤之前,需要保证geth节点正常运行)
truffle的智能合约项目部署,使用下面的命令:"truffle migrate",这个命令会执行所有migrations目录下的js文件。使用 "truffle migrate --reset"命令,则会重新执行所有脚本的部署。
如果要部署到指定的网络,可以使用"truffle migrate --network live"命令。
多个网络的配置如下:
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*" // match any network
},
live: {
host: "178.25.19.88", // Random IP for example purposes (do not use)
port: 80,
network_id: 1, // Ethereum public network
// optional config values:
// gas Gas limit used for deploys. Default is 4712388
// gasPrice Gas price used for deploys. Default is 100000000000 (100 Shannon).
// from - default address to use for any transaction Truffle makes during migrations
// provider - web3 provider instance Truffle should use to talk to the Ethereum network.
// - if specified, host and port are ignored.
}
}
如果出现"Saving artifacts...",表示"truffle migrate"命令执行成功。
接下来,需要在geth客户端中执行命令。
这时,我们就要用到刚刚编译后的Hello_mshk_top.json文件了,打开https://www.bejson.com网址,把abi部分取出并进行json压缩。然后在geth中输入以下内容,将json转义后的内容,赋值给mshk_abi变量:
>mshk_abi = [{"constant":true,"inputs":[],"name":"say","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"print","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]
得到以下回复:
[{
constant: true,
inputs: [],
name: "say",
outputs: [{
name: "",
type: "string"
}],
payable: false,
stateMutability: "pure",
type: "function"
}, {
constant: true,
inputs: [{
name: "name",
type: "string"
}],
name: "print",
outputs: [{
name: "",
type: "string"
}],
payable: false,
stateMutability: "pure",
type: "function"
}]
找到Hello_mshk_top.json文件中的bytecode部分,然后在geth中,将值赋值给mshk_bytecode变量,在geth中输入以下内容:
>mshk_bytecode = "0x6060604052341561000f57600080fd5b6102488061001e6000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806311114af114610051578063954ab4b214610127575b600080fd5b341561005c57600080fd5b6100ac600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506101b5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100ec5780820151818401526020810190506100d1565b50505050905090810190601f1680156101195780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561013257600080fd5b61013a6101c5565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017a57808201518184015260208101905061015f565b50505050905090810190601f1680156101a75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101bd610208565b819050919050565b6101cd610208565b6040805190810160405280600e81526020017f48656c6c6f206d73686b2e746f70000000000000000000000000000000000000815250905090565b6020604051908101604052806000815250905600a165627a7a723058203ae06ab41017e0b7aeb1484c4708c9b74fd1ae25a5d24db7c53d8376967d16630029"
评估下创建合约需要的手续费是207296gas:
> web3.eth.estimateGas({data: mshk_bytecode})207296
部署合约,并将合约传递给mshk变量,在geth中输入以下内容:
>acc0 = eth.accounts[0]
>mshk_Contract = web3.eth.contract(mshk_abi);
>mshk_hello = mshk_Contract.new({from:acc0, data:mshk_bytecode, gas:300000})
第四步:测试部署成功的智能合约
> mshk_hello.say()
"Hello mshk.top"
> mshk_hello.print("Hello")
"Hello"
注意点:
1.如果节点中只有一个账户,truffle.js中的配置可以不配置from和gas信息。
2.如果节点中多余一个账户,truffle.js中需要配置from和gas信息,如下所示:
module.exports = {
networks: {
development: {
host: "192.168.1.42",
port: 8545,
network_id: "*", // Match any network id
from: "0x3e43f30bdef44d08f650905350f0ff1a2a9ee1ba",
gas: 3000000
}
}
};