客户端geth安装
1 | apt-get install software-properties-common // 安装工具包 |
搭建私有链
初始状态文件genesis.json
1 | { |
参数名称 | 参数描述 |
---|---|
mixhash | 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。 |
nonce | nonce就是一个64位随机数,用于挖矿。 |
difficulty | 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度 |
alloc | 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们不需要预置有币的账号,需要的时候自己创建即可以。 |
coinbase | 矿工的账号,随便填 |
timestamp | 设置创世块的时间戳 |
parentHash | 上一个区块的hash值,因为是创世块,所以这个值是0 |
extraData | 附加信息,随便填,可以填你的个性信息 |
gasLimit | 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。 |
初始化区块链
1 | cd privatechain |
--datadir
选项后面跟一个目录名,这里为 data0,表示指定数据存放目录为 data0,genesis.json 是 init
命令的参数。
启动区块链
1 | geth --identity "TestNode" --networkid "99" --rpc --rpccorsdomain "*" --rpcapi "db,eth,net,web3" --rpcport "8545" --datadir data0 --port "30303" --nodiscover console |
参数名称 | 参数描述 |
---|---|
identity | 区块链的标示,随便填写,用于标示目前网络的名字 |
init | 指定创世块文件的位置,并创建初始块 |
datadir | 设置当前区块链网络数据存放的位置 |
port | 网络监听端口 |
rpc | 启动rpc通信,可以进行智能合约的部署和调试 |
rpcapi | 设置允许连接的rpc的客户端,一般为db,eth,net,web3 |
networkid | 设置当前区块链的网络ID,用于区分不同的网络,是一个数字 |
console | 启动命令行模式,可以在Geth中执行命令 |
智能合约部署与调用
创建账号、挖矿
- 创建账号personal.newAccount(),创建的第一个账号为默认coinbase账号,挖矿收入将会进入此账号。‘
- 由于部署合约需要以太坊,使用miner.start()开始挖矿,miner.stop停止挖矿。
- eth.getBalance(eth.accounts[0])查看余额
创建编译智能合约
安装Solidity编译器solc: apt-get install solc
新建一个 Solidity 智能合约文件,命名为
testContract.sol
,该合约包含一个方法multiply()
,将输入的两个数相乘后输出:1
2
3
4
5
6pragma solidity ^0.4.0;
contract testContract {
function multiply(uint a) returns(uint d) {
d = a * 7;
}
}编译智能合约,获得编译后的 EVM 二进制码:
1
2
3
4
5$ solc --bin testContract.sol
======= testContract.sol:TestContract =======
Binary:
608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b60006007820290509190505600a165627a7a7230582002bc42ae50877423d8703fb9201f4e02d335ff56443e697a4c0d9de0dfe6ad160029再用 solc 获取智能合约的 JSON ABI(Application Binary Interface),其中指定了合约接口,包括可调用的合约方法、变量、事件等:
1
2
3
4
5$ solc --abi testContract.sol
======= testContract.sol:TestContract =======
Contract JSON ABI
[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]回到 Geth 的控制台,用变量
code
和abi
记录上面两个值,注意在 code 前加上0x
前缀:
部署智能合约
这里使用账户 0 来部署合约,首先解锁账户:
1
2
3
4> personal.unlockAccount(eth.accounts[0])
Unlock account 0xfb9c00a44223e463016f0b36e1195d2d7a21e0d7
Passphrase:
true发送部署合约的交易:
1
2
3
4> myContract = eth.contract(abi)
...
> contract = myContract.new({from:eth.accounts[0],data:code,gas:1000000})
...此时如果没有挖矿,用
txpool.status
命令可以看到本地交易池中有一个待确认的交易。使用下面的命令查看当前待确认的交易:使用
miner.start()
命令开始挖矿,一段时间后交易会被确认,随新区块进入区块链。
调用智能合约
使用以下命令发送交易,sendTransaction
方法的前几个参数应该与合约中 multiply
方法的输入参数对应。这种情况下,交易会通过挖矿记录到区块链中:
1 | > contract.multiply.sendTransaction(10, {from:eth.accounts[0]}) |
如果只是本地运行该方法查看返回结果,可以采用如下方式:
1 | > contract.multiply.call(10) |
查看节点信息和节点列表
1 | admin.nodeInfo // 查看节点信息 |
添加节点
如果希望多个节点加入到同一个区块链网络,需要注意以下三点
- 节点所在的机器,相互之间可以互联互通
- 它们有相同的创世纪文件
- 有相同的
networkid
第二个节点networkid设置必须与前一致,rpcport 、port不一样。
- 在节点1使用
admin.addPeer(encode)
命令添加节点2,节点2enode
为
“enode://f547fd8925e44fc89c7f71af94ba4d5d8b52e28b4b68cc54fcc5d57be837b24170d1710e884e8be783ac9f07ee35e5c77f2325ba7a5194f53671e7ecd069a365@192.168.213.188:30304”
- 使用
admin.peers
查看节点
- 连接成功后节点2同步区块
节点一中发布交易,看到pending:2
任一节点miner.start()挖矿,其余节点自动同步新区块,且交易被记录进区块。
控制台操作
进入以太坊 Javascript Console 后,就可以使用里面的内置对象做一些操作,这些内置对象提供的功能很丰富,比如查看区块和交易、创建账户、挖矿、发送交易、部署智能合约等。
常用命令有:
- personal.newAccount():创建账户;
- personal.unlockAccount():解锁账户;
- eth.accounts:枚举系统中的账户;
- eth.getBalance():查看账户余额,返回值的单位是 Wei(Wei 是以太坊中最小货币面额单位,类似比特币中的
聪
,1 ether = 10^18 Wei); - eth.blockNumber:列出区块总数;
- eth.getTransaction():获取交易;
- eth.getBlock():获取区块;
- miner.start():开始挖矿;
- miner.stop():停止挖矿;
- web3.fromWei():Wei 换算成以太币;
- web3.toWei():以太币换算成 Wei;
- txpool.status:交易池中的状态;
- admin.addPeer():连接到其他节点;