环境win10,*64
所有操作都在D:\work\geth里进行
以太坊客户端会在C:\Users\Administrator\AppData下生成ethash的文件夹用来存放运行时信息。etherum-wallet在C:\Users\Administrator\AppData\Roaming里生成临时文件夹etherum wallet,保存信息,初始化钱包需要删除
废话不多说了,趟过了很多坑,开始以太坊私有链搭建。
一.geth,mist 客户端下载
1.这里我给大家介绍下,以太坊客户端,以太坊客户端主要分成两类。一个是后台命令行客户端,如:geth(go语言),parity(Rust语言),他们是一个与以太坊网络交互的命令行客户端。
其余的命令行客户还有 ethereumjs-lib(javascript),pyethapp(python),ruby-ethereum(ruby) ....主要 geth 使用的比较普遍,这里我就使用geth作为命令行客户端。
2.mist 是属于可视化钱包,这么说吧,你在geth 客户端中生成的用户,以太坊币数量可以通过mist 钱包可视化展示。当然mist 不只有这些简单的功能,最重要的是能部署智能合约,发布,调用。其他还有很多轻钱包,如 lightWallet,metamask...
下面是geth和mist下载地址,这里我使用的是windows系统安装。
https://pan.baidu.com/s/1SksXj4siKj2OgX2Dn4TF7A 密码:4sm6
Geth : 版本:1.8.12 (当时最新版)
Mist :0.11.1
安装完geth,可以打开命令行工具:
下载地址:
二.创建以太坊初始区块文件 genesis.json
{
"config": {
"chainId": 101,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc": {},
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x400",
"extraData": "",
"gasLimit": "0xffffffff",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00"
}
chainId : 以太坊区块链网络Id,ethereum主链是1,私有链只用不要与主链冲突即可。此时设置的chainId可以和启动时指定的networdid不一致,以启动时的为主
alloc : 预留账户,一般留空,如下
"alloc":{
"0x0000000000000000000000000000000000000001":{"balance":"121312321"},
"0x0000000000000000000000000000000000000002":{"balance":"121312321"},
}
Coinbase: 矿工账户
Difficulty: 挖矿难度,0x400,这个是简单。
extraData:相当于备注
gasLimit:最小消耗gas
nonce : 64位随机数,用于挖矿,注意他和mixhash的设置需要满足以太坊黄皮书中的要求
parentHash : 上一个区块的Hash值,因为是创世块,石头里蹦出来的,没有在它前面的,所以是0
Timestamp : 时间戳
三.初始化区块节点
geth --datadir data0 init genesis.json
data0 是当前文件夹存储节点数据,位于D:\work\geth\下,可以自动创建
出现如下内容就成功了
Successfully wrote genesis state database=lightchaindatahash=84e71d…97246e
初始化成功后,会在数据目录{dataDir} (d:\work\geth\data0)中生成 geth 和 keystore (存储加密后的账户信息)两个文件夹.
三、启动私有链节点
geth --identity "TestNode1" --datadir "data0" --rpc --rpcapi "db,eth,net,web3" --rpcaddr "127.0.0.1" --rpcport "8486" --port "30304" --networkid "29382" console
选择web3接口连接本地私链时,需要在启动私链时添加如下参数 --rpccorsdomain "*" ,不然链接不上。如下:
geth --identity "TestNode1" --datadir "data0" --rpc --rpcapi "db,eth,net,web3" --rpcaddr "127.0.0.1" --rpccorsdomain "*" --rpcport "8486" --port "30304" --networkid "29382" console
使用命令 geth -h 可以查看geth 相关的帮助文档。这里我说几个常用的属性。
--Identity : 节点身份标识,起个名字
--datadir : 指定节点存在位置,“data0”
--rpc : 启用http-rpc服务器
--rpcapi : 基于http-rpc提供的api接口。eth,net,web3,db...
--rpcaddr : http-rpc服务器接口地址:默认“127.0.0.1”
--rpcport : http-rpc 端口(多节点时,不要重复)
--port : 节点端口号(多节点时,不要重复)
--networkid : 网络标识符 随便指定一个id(确保多节点是统一网络,保持一致)
下图表示启动成功,进入geth命令行客户端:
注意:如果想将Ubuntu作为永久区块链节点使用,当使用nohup命令时,Geth启动参数console必须去掉,否则Geth会自动停止。
启动完成之后进入控制台,这是一个交互式的 JavaScript 执行环境,在这里面可以执行 JavaScript 代码,其中 > 是命令提示符。在这个环境里也内置了一些用来操作以太坊的 JavaScript 对象,可以直接使用这些对象。这些对象主要包括:
eth:包含一些跟操作区块链相关的方法;
net:包含一些查看p2p网络状态的方法;
admin:包含一些与管理节点相关的方法;
miner:包含启动&停止挖矿的一些方法;
personal:主要包含一些管理账户的方法;
txpool:包含一些查看交易内存池的方法;
web3:包含了以上对象,还包含一些单位换算的方法。
>eth.accounts
[]
>
创建账户1:
> personal.newAccount("123456")
"0x1078f82b17790664b3d931b91eb1f17ec109df09"
创建账户2:
> personal.newAccount("654321")
"0x1be3d41d02408d11e13eb5191520f3b2fa002dd1"
>
3、查看账户余额
> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
0
>
查询余额有多种方式,可以通过创建时的16进制码,也可以通过账户下标查询,下标默认从0开始。
启动&停止挖矿
> miner.start(1)
其中 start 的参数表示挖矿使用的线程数。第一次启动挖矿会先生成挖矿所需的 DAG 文件,这个过程有点慢,等进度达到 100% 后,就会开始挖矿,此时屏幕会被挖矿信息刷屏。实际你看到的挖矿速度很快,这是因为我们已经在初始化创世区块时配置为:"nonce": "0x400"。 “0x400”难度能让你在私有测试网链上快速挖以太币。
提示
挖矿时必然有矿工账户,而系统默认使用创建的第一个账号。
停止挖矿
> miner.stop()
挖到一个区块会奖励n个以太币,挖矿所得的奖励会进入矿工的账户,这个账户叫做 coinbase,默认情况下 coinbase 是本地账户中的第一个账户,可以通过 miner.setEtherbase() 将其他账户设置成 coinbase。只要是能产生区块,就有奖励,即使区块中没有任何有用信息。
交易
假如0账户向1账户转账,需要先把0账户锁定,然后才能进行交易
> personal.unlockAccount(eth.accounts[0])
Unlock account0x6594cc2f72908c0fea54d5c9dd297ce68f735411
Passphrase:
true
>
转账 账户0 –> 账户1
> amount = web3.toWei(5,'ether')"
5000000000000000000"
> eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:amount})
INFO [01-18|17:56:14] Submitted transaction fullhash=0x065c698cceaf996ab9ab06c6eddc8b035704defbcff0d65227d32c06a5b17637recipient=0x4BD9F7b3c365D35C50757AF4CC7Bdb1307A083C0"0x065c698cceaf996ab9ab06c6eddc8b035704defbcff0d65227d32c06a5b17637
>
此时如果没有挖矿,用 txpool.status 命令可以看到本地交易池中有一个待确认的交易,可以使用 eth.getBlock("pending", true).transactions 查看当前待确认交易。
> txpool.status
{
pending: 1,
queued: 0
}
查交易和区块
> eth.blockNumber
200
通过交易 Hash 查看交易(Hash 值包含在上面交易返回值中):
>eth.getTransaction("0x65a8278d571d7cf3f2ca36ce721900d61e9d6eadd1ed5f24f39b646c2b194427")
{
blockHash: "0x0101b5f9e9c50ee45156f0631df18a97176aef5215bde40b3e167195d367ed80",
blockNumber: 342,
from: "0x16671cdabbc9b3f0f1b31380d972dcd9725f7d8a",
gas: 90000,
gasPrice: 18000000000,
hash: "0x65a8278d571d7cf3f2ca36ce721900d61e9d6eadd1ed5f24f39b646c2b194427",
input: "0x",
nonce: 1,
r: "0x52b7fce530ebd67527d4fe684cb3b5a4b96909154aeedcc5f371ab27e9e7f1ba",
s: "0x141268e8fef639b79773f6ab7fb778b958be77bd05944f305dc4f1ec68f21962",
to: "0x4bd9f7b3c365d35c50757af4cc7bdb1307a083c0",
transactionIndex: 0,
v: "0x823",
value: 5000000000000000000
}
>
通过区块号查看区块:
> eth.getBlock(0)
{
difficulty: 131072,
extraData: "0x6d6f7475692d32",
gasLimit: 4294967295,
gasUsed: 0,
hash: "0x5117726df3040cb5cbd6e8d59cdaacaaa1cd8df4a20072d0e8242e96ea5c893f",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x0000000000000000000000000000000000000000",
mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: "0x0000000000000042",
number: 0,
parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 515,
stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
timestamp: 0,
totalDifficulty: 131072,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
>
连接远程控制台
geth attach http://127.0.0.1:8486
==================================================
过创始块预分配账户余额
按照上面的步骤将第一节点启动后,创建一个账户,复制地址
编辑genesis.json,在alloc段,增加如下内容:
"alloc": {
"0x81e71d34e8a9e4382c36fd90c3f234549106addd": { "balance": "20000000000000000000" }
}
这里的地址就是刚才创建的地址,后面的balance就是你想预分配的余额
然后将数据目录下的geth目录删掉,重新创建创始块(keystore目录不要动)
rm -rf /data/testchain/geth
然后再重新执行geth init创建创始块的命令,然后再启动geth,就可以在console中查看到账户被预分配的余额了