网上已有很多相关教程,但由于geth
从1.6版本移除了编译Solidity
的功能,如链接所述,许多教程中介绍的方法都失效了。本文综合了网上已有的一些教程,介绍了新的可行方法。
I. 安装Ethereum & Solc
本文只介绍Ubuntu
环境下的操作,其他环境下可以类比 1
2
3
4# Install geth
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
Solc 是Solidity的编译器 1
2
3
4# Install Solc
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc
II. 配置私有链
A. 创建创世块
创世块主要根据genesis.json
文件生成,其内容如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17{
"config": {
"chainId": 123456,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"nonce": "0x0000000000000042",
"difficulty": "0x020000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x4c4b40",
"alloc": {}
}
B. 生成创世块
创建data
文件夹,并执行如下命令: 1
geth --datadir data init genesis.json
C. 启动私有链
执行如下命令,其中--datadir
的参数与上面命令相同,--networkid
的参数与genesis.json
中的参数相同: 1
geth --datadir data --networkid 123456 --rpc --rpccorsdomain "*" --nodiscover console
III. Geth中常用命令介绍
- 创建新账号
personal.newAccount()
或者personal.newAccount("123456")
- 查看节点信息
admin.nodeInfo
- 开始挖矿
miner.start(1)
- 停止挖矿
miner.stop()
- 查看当前矿工账号
eth.coinbase
(默认为第一个账户) - 修改矿工账号
miner.setEtherbase(eth.accounts[1])
- 查看账户信息
eth.accounts[0]
- 查看账户余额
eth.getBalance(eth.accounts[0])
- 解锁账号
personal.unlockAccount(eth.accounts[0])
- 转账
eth.sendTransaction({from:eth.accounts[0],to:"addr",value:web3.toWei(3,"ether")})
- 查看区块高度
eth.blockNumber
- 通过区块号查看区块
eth.getBlock(1)
- 通过交易id查看交易
eth.getTransaction("TxId")
A. 链配置
为下文智能合约的调用测试,需要提前生成两个账户,命令如下: 1
2# Geth Console中 执行两次
personal.newAccount()1
2
3# Geth Console中
#第一次执行时会耗费较长时间,以构建DAG
miner.start(1)
IV. 部署智能合约
A. 编写智能合约
采用solidity
语言编写智能合约。命名该文件为Token.sol
, 内容如下: 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
29contract Token {
address issuer;
mapping (address => uint) balances;
event Issue(address account, uint amount);
event Transfer(address from, address to, uint amount);
function Token() {
issuer = msg.sender;
}
function issue(address account, uint amount) {
if (msg.sender != issuer) throw;
balances[account] += amount;
}
function transfer(address to, uint amount) {
if (balances[msg.sender] < amount) throw;
balances[msg.sender] -= amount;
balances[to] += amount;
Transfer(msg.sender, to, amount);
}
function getBalance(address account) constant returns (uint) {
return balances[account];
}
}
- 这份代码实现了一个简单的
Token
合约功能 issue
函数可以向充值以太到合约账户transfer
函数可以向其他账号发送token
getBalance
函数可以获取某个账号的token
余额
B. 编译智能合约
1 | # 非Geth Console中 |
至此,token
智能合约就编译完毕了。在Geth Console
中输入命令token
可以发现此时的token
有transactionHash 但是没有address
,这是因为此时的token还没有发布成功。
C. 发布智能合约
发布智能合约很简单,只需要生成新的区块,就可以把合约发布到链上。命令如下: 1
miner.start(1)
V. 与合约进行交互
A. 充值
1 | # Geth Console中 |
B. 发送 token
1 | # Geth Console中 |
C. 查看余额
1 | # 查看account0的余额 |