1. 编译geth
geth是以太坊开发中最常用的工具,是官方客户端。可以运行以太坊节点、创建和管理账户、发送交易、挖矿、部署智能合约等。
由于我们在以太坊的基础上进行了一些代码的改动。所以环境搭建的时候建议采用直接从源码编译的方式。
从源码编译geth的过程:
- 查看当前go版本,确认go版本1.9及以上。
go version
- git clone 以太坊项目源码,地址:https://github.com/ethereum/go-ethereum.git ,之后我们自己项目的代码地址会另外提供。
git clone https://github.com/ethereum/go-ethereum.git
- 进入到目录$GOPATH/src/github.com/ethereum/go-ethereum目录下
make geth
- 编译成功则geth的可执行文件就会在以太坊目录的build/bin/目录下,为了方便使用,把该路径放入到PATH中。
export PATH=$PATH:$GOPATH/src/github.com/ethereum/go-ethereum/build/bin/
2. 编写创世区块配置
可以从网上随便贴一个创世区块的配置,比方说下面的配置,保存在genesis.json文件中(文件名随意)。
其中
- config为私链的一些相关配置,详见params/config.go中的ChainConfig结构体。修改共识模式等,都是需要修改config中的字段的。
- alloc为预设账号和账号的以太币数量,比方说账号A预设1000以太坊,就在alloc中相应设置。
- 其他字段为区块header中的一些字段,可以暂且不管。
{
"config":{
"chainId":1999,
"homesteadBlock":0,
"eip155Block":0,
"eip158Block":0
},
"nonce": "0x0",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x00",
"gasLimit": "0x8000000",
"difficulty": "0x4000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": { }
}
也可以使用官方的puppeth工具来生成创世区块的配置文件
- 使用前,首先在以太坊源码目录中,进行工具的编译,可以把所有工具都编译出来
make all
或者如果只是要单独make puppeth的话
build/env.sh go run build/ci.go install ./cmd/puppeth
- 使用puppeth按步骤生成创世区块的配置文件
[**********@******]$ puppeth
+-----------------------------------------------------------+
| Welcome to puppeth, your Ethereum private network manager |
| |
| This tool lets you create a new Ethereum network down to |
| the genesis block, bootnodes, miners and ethstats servers |
| without the hassle that it would normally entail. |
| |
| Puppeth uses SSH to dial in to remote servers, and builds |
| its network components out of Docker containers using the |
| docker-compose toolset. |
+-----------------------------------------------------------+
Please specify a network name to administer (no spaces or hyphens, please)
>
输入测试网络的名字,比方说test
> test
Sweet, you can set this via --network=test next time!
INFO [06-19|14:46:08] Administering Ethereum network name=test
WARN [06-19|14:46:08] No previous configurations found path=/Users/yuanzhenxia/.puppeth/test
What would you like to do? (default = stats)
1. Show network stats
2. Configure new genesis
3. Track new remote server
4. Deploy network components
>
配置新的创世区块,选择2
> 2
Which consensus engine to use? (default = clique)
1. Ethash - proof-of-work
2. Clique - proof-of-authority
>
选择共识模式,其中Ethash是PoW共识,Clique是PoA共识,这里可以先选择1
> 1
Which accounts should be pre-funded? (advisable at least one)
> 0x
选择预设账户,这个地方如果已经有账户,可以设,也可以直接按回车。
> 0x
Specify your chain/network ID if you want an explicit one (default = random)
>
选择网络id,可以输入一个整数,也可以直接回车,这一步结束,就是配置完成了。
>
INFO [06-19|14:50:49] Configured new genesis block
What would you like to do? (default = stats)
1. Show network stats
2. Manage existing genesis
3. Track new remote server
4. Deploy network components
配置已经完成,接下来选择2管理创世块配置
> 2
1. Modify existing fork rules
2. Export genesis configuration
3. Remove genesis configuration
>
选择2来导出配置文件
> 2
Which file to save the genesis into? (default = test.json)
>
输入文件名,默认名称为第一步输入的网络名称跟.json。
Which file to save the genesis into? (default = test.json)
>
INFO [06-19|14:53:48] Exported existing genesis block
ctrl+c退出puppeth命令行
3. 初始化并启动节点
3.1 初始化节点
在以太坊节点运行之前,需要运行geth init命令进行初始化操作。其中***.json即为第二步中的生成的创世区块的配置文件。初始化的主要作用是把配置在json文件中的内容,转化成以太坊链的配置,并生成0号区块创世块,将其写到数据库中(可以看下指定目录下应该多了个geth文件夹,进入geth文件夹后可以看到chaindata和lightchaindata两个文件夹)。
geth --datadir=[yourdir] init ***.json
注意到命令中--datadir参数,geth命令又非常多的参数,详见geth help的内容。该处--datadir是将以太坊私链的内容存放到指定的目录的意思。如果不指定,默认是在$HOME/.ethereum目录下。
3.2 启动节点
使用geth命令启动节点,只需要简单的使用geth命令就可以启动节点,如果要自己的需求,只需要跟相应的参数即可
geth --datadir=[yourdir]
3.3 启动web3
如果像3.2中启动节点,则只能看到节点的日志,无法和节点进行交互。我们还需要有个交互用的客户端,以太坊中支持多种交互的方式,其中web3是最常用的方式。
- 启动节点的时候启动web3,可以通过添加console命令在启动节点的时候,直接启动web3
geth --datadir=[yourdir] console
- 如果节点已经启动,可以通过attach命令来启动web3
geth --datadir=[yourdir] attach
4. 挖矿
在挖矿之前必须首先有账号来作为挖矿的收益者。
4.1 新建账号
新建账号有两种方法:
- web3中使用personal.newAccount()来新建账号,按提示输入密码,即可创建账号。
> personal.newAccount()
Passphrase:
Repeat passphrase:
"0x****************************************" //这个就是此次新建的地址
- 使用geth的account new命令来新建账号,同样按提示输密码。
[****@****]$ geth --datadir=./ account new
INFO [06-19|19:51:23] Maximum peer count ETH=25 LES=0 total=25
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {****************************************}
4.2 解锁账号
以太坊中要挖矿,或者要发送交易的时候,账号需要是解锁状态,否则会提示相应的错误。
使用web3的personal.unlockAccount方法,输入密码后可以解锁账号。
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x****************************************
Passphrase:
true
默认是使用eth.accounts中的第一个账号做挖矿者的,如果想要使用其他账号作为矿工,需要使用miner.setEtherbase()进行设置,然后记得解锁相应的账号。
miner.setEtherbase(eth.accounts[1])
4.3 开始挖矿
使用miner.start()可以开始挖矿。
>miner.start()
可以通过eth.blockNumber看到区块号在增加
>eth.blockNumber
4.4 停止挖矿
使用miner.stop()可以停止挖矿。
miner.stop()
5. 发送交易
在没有安装其他智能合约的情况下,以太坊也可以使用eth.sendTransaction进行基本的以太币转账操作(发送者账号必须是解锁状态),如下命令就是账号0向账号1转1个以太币。
eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(1,"ether")})
6. 多个节点的情况
多个节点组成一个以太坊网络需要保证其创世区块是一致的。
- 把创世块的配置文件***.json,拷贝到多台机器,或者多个文件夹。(datadir指定的文件夹只能被一个节点访问,如果同时在一个文件夹试图启动多个节点,会报错)
- 每个文件夹目录下,分别进行geth init 操作。
接下来是启动节点,并使得节点间是相互连通的,这个有两种方法。
6.1 通过bootnodes来保证联通。
- 先启动一个节点。
- 查看这个节点的enode(admin.nodeInfo.enode),这个可以看作是节点的地址。
> admin.nodeInfo.enode
"enode://bafe93edee0c5cfab6a3d12927553abe6f9a3cf31b56b58d65c05e52edf184dcf88f8a2a3d84f3911bc2233c0140188e1e8717c26ff98a0268298c3a933c1855@[::]:30303"
- 其他节点启动的时候,添加--bootnodes参数,并跟上刚才查看到的enode内容。如果是在同一台机器上不同节点要设置成不同的端口号,默认的端口号为30303,端口号通过--port来设置。
geth --datadir=./ --bootnodes=enode://bafe93edee0c5cfab6a3d12927553abe6f9a3cf31b56b58d65c05e52edf184dcf88f8a2a3d84f3911bc2233c0140188e1e8717c26ff98a0268298c3a933c1855@127.0.0.1:30303 --port=31303 console
6.2 通过admin.addPeer来保证联通
如果节点已经启动,或者临时有新的节点想要加入进网络,都可以使用admin.addPeer的方法来添加,参数为上一小节介绍的enode。
admin.addPeer("enode://bafe93edee0c5cfab6a3d12927553abe6f9a3cf31b56b58d65c05e52edf184dcf88f8a2a3d84f3911bc2233c0140188e1e8717c26ff98a0268298c3a933c1855@127.0.0.1:30303")
可以通过admin.peers查看节点情况。
admin.peers
7. 常用的web3指令
web3的详细API参考JavaScript API · ethereum/wiki Wiki ,本文中只介绍常用的API。
7.1 eth相关命令
eth相关命令,主要是用来查看链当前状态,发送交易给链等操作。在web3窗口输入eth可以看到。
其中常用的有:
- eth.accounts,查看当前节点下有哪些账号,相应的账户信息在指定目录的keystore目录下。
- eth.blockNumber,查看当前节点的最新的区块号。
- eth.getBlock(),参数为区块号或者区块hash,可以查看区块的内容。例如eth.getBlock(0)。
- eth.getBalance(),参数为账号地址,可以查看账户的余额(单位为:Wei,一个以太币1 ether=10^18 Wei)。例如eth.getBalance(eth.accounts[0]).
- eth.getTransaction(),参数为transaction hash,可以查看交易详情。
- eth.sendTransaction(),发送交易,直接使用就是转以太币,如果是有合约,用合约调,就是运行合约相应的方法。例如从账户1转1以太币到账户2,eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(1,"ether")})
- eth.mining,查看当前节点是否在挖矿。
- eth.syncing,查看当前节点是否在同步区块。
7.2 miner相关命令
miner即为以太坊中矿工相关的命令。其中常用的有:
- miner.start()启动矿工开始挖矿。
- miner.stop()矿工停止挖矿。
- miner.setEtherbase()设置矿工账号。
7.3 admin相关命令
其中比较常用的有:
- admin.nodeInfo,查看当前节点信息。其中的enode比较重要。
- admin.peers,查看当前节点联通的节点的信息,可以查看网络中节点是否互联。
- admin.addPeer([enode]),添加节点.
7.4 personal相关命令
其中比较常用的有:
- personal.newAccount()新建账号。
- personal.unlockAccount()解锁账号,参数为账号的Address。
7.5 txpool相关命令
txpool主要是用来查看当前交易池状态的命令,当交易发送之后,会首先到交易池中,之后才会被矿工挖矿,然后被打到区块中之后才会从交易池中删除。
7.6 其他工具类命令
- web3.fromAscii将字符串转化为16进制形式的字符数组。如 web3.fromAscii("abc")返回"0x616263"。
- web3.fromDecimal将十进制的数字转化为16进制形式的字符数组。如 web3.fromDecimal(100)返回"0x64"。
- web3.fromWei将以Wei为单位的以太币转化为以ether(通常所说的1以太币指的是1 ether)为单位的以太币,如web3.fromWei(1000000000000000000)返回"1"。
- web3.sha3将数据进行hash,如:web3.sha3("100")返回"0x8c18210df0d9514f2d2e5d8ca7c100978219ee80d3968ad850ab5ead208287b3"。
- web3.toAscii,将16进制形式的字符数组转化为ascii码的字符数组,如 web3.toAscii("0x616263")返回"abc"。
- web3.toDecimal将16进制形式的字符数组转化为十进制的数字。如 web3.toDecimal("0x64")返回100。
- web3.toWei将以太币转化为以Wei为单元,如web3.toWei(1)返回"1000000000000000000"。