记录下第一次搭建私链的过程
搭建以太坊私链(单节点,多节点,windows,linux)
Ubuntu16.04 搭建以太坊Ethereum私链
杂谈
以太坊的发展分成了四个阶段:(每个阶段进步到下一个阶段都是通过硬分叉的方式实现的)
- Frontier(前沿):2015年7月30日,以太坊发布了Frontier阶段,此时的软件还不太成熟,但可以进行基本的挖矿测试去中心化应用(Dapps),该阶段参与者主要为开发者。
- HomesteadBlock(家园):在2016年3月14日(圆周率节),以太坊发布了HomesteadBlock阶段。以太坊开始平稳运行,提供了图形界面的钱包,普通用户也可以体验和使用以太坊。
- Metropolis(大都会):Metropolis被分成了两个阶段:
- **Byzantium(拜占庭)**2017.10.16,以太坊拜占庭硬分叉成功,引入了包括:zk-SNARKs(简明非交互零知识证明)、revert功能、return和抽象账户.
- Constantinople (居士坦丁堡)。2019年2月底,以太坊区块链的第7,080,000区块作为激活点正式开启君士坦丁堡硬分叉,点在于将以太坊的共识机制由PoW向PoW+PoS混合机制过渡,从而使整个以太坊网络更加的轻盈、快捷与安全。
- 按官方说法,具体在现有以太坊PoW主网上进行升级的有以下5个方面:
- EIP 145:给EVM增加移位相关指令,包括左移SHL,逻辑右移SHR,算术右移SAR
- EIP 1014:产生合约地址的一种新规则,与状态通道有关。规则为keccak256( 0xff ++ address ++ salt ++ keccak256(init_code)))[12:]
- EIP 1052:为EVM增加EXTCODEHASH指令,这个指令可以获得一个合约bytecode的keccak256的hash值;
- EIP 1283:修改EVM的SSTORE指令gas计算方式,预计会减少许多合约的gas消耗,需要硬分叉支持;
- EIP 1234:将是潜在最有争议的提案,也需要硬分叉支持,它包括难度炸弹(Difficulty Bomb)协议推迟12个月和挖矿奖励调整,难度炸弹使挖矿难度随时间推移越来越高,挖矿奖励调整将挖矿奖励从3个降低到2个;
- Serenity(宁静)
环境准备
首先安装git和geth以太坊客户端
输入以下命令以安装git:
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
输入git --version查看版本号以确定是否安装好
git --version
输入以下命令以安装geth
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
输入geth --help以确定是否安装好geth
geth --help
创世区块
创世区块配置文件gensis. json文件内容如下:
{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x40000",
"extraData" : "",
"gasLimit" : "0xffffffff",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00",
"alloc": { }
}
相关参数作用表如下:
-
chainID
- 指定了独立的区块链网络 ID。网络 ID 在连接到其他节点的时候会用到,以太坊公网的网络 ID 是 1,为了不与公有链网络冲突,运行私有链节点的时候要指定自己的网络 ID。不同 ID 网络的节点无法相互连接
-
homesteadBlock
- 取值为0表示正在使用homesteadBlock版本。
-
eip155Block
- eip是ethereum improvement proposal的缩写,你的链不会因为因为这些提议分叉,故设置为“0”即可
-
eip158Block
- eip是ethereum improvement proposal的缩写,你的链不会因为因为这些提议分叉,故设置为“0”即可
-
mixhash
- 与nonce配合用于挖矿,由上一个区块的一部分生成的哈希。注意它和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
-
nonce
- nonce就是一个64位随机数,用于挖矿注意它和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件。
-
difficulty
- 设置设置当前区块难度,如果难度过大,CPU挖矿就很难
-
alloc
- 给某个账户预分配以太币
-
coinbase
- 矿工帐号
-
timestamp
- 创世块的时间戳
-
parentHash
- 上一个区块的哈希值,由于是创世区块,所以值为0
-
extraData
- 可以写入32Byte大小的任意数据,每个block都会有,由挖出block的miner来决定要不要在里面写什么
-
gasLimit
- 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总量
可以使用工具puppeth
快速构建创世区块配置文件
puppeth
可以配置区块信息
这里的选项分别代表两种不同的共识算法
- Ethhash-POW(proof-of-work)工作量证明
- Clique-POA(proof-of-authority)权威证明
pre-funded - 预筹积累
最后设置网络号
导出创世区块配置json文件到相应文件夹 (默认是当前文件夹)
cst@San:~/chainwork/mychain$ mkdir data
cst@San:~/chainwork/mychain$ geth --datadir ./data init test.json
创建data文件夹保存节点信息并初始化创世节点
geth --http --nodiscover --datadir "./data" --port 30303 --http.api db,eth,net,web3 --http.corsdomain "*" --networkid 1001 --ipcdisable --allow-insecure-unlock console 2>>geth.log
这里对使用的参数作简单介绍:
- 1.console:启动交互式JavaScript环境
- 2.–http:启用HTTP-RPC服务器
- 3.–port value:网卡监听端口(默认值:30303)
- 4.–http.addr value:HTTP-RPC服务器接口地址(默认值:“localhost”)
- 5.–http.corsdomain value:允许跨域请求的域名列表(逗号分隔)(浏览器强制)
- 6.–http.port value:HTTP-RPC服务器监听端口(默认值:8545)
- 7.–wsport value:WS-RPC服务器监听端口(默认值:8546)
- 8.–wsapi value:基于WS-RPC的接口提供的API
- 9.–wsorigins value:websockets请求允许的源
- 10.–syncmode “fast”:同步模式 (“fast”, “full”, or “light”)
- 11.–nodiscover:禁用节点发现机制(手动添加节点)
- 12.–maxpeers value:最大的网络节点数量(如果设置为0,网络将被禁用)(默认值:25)
- 13.–maxpendpeers value:最大尝试连接的数量(如果设置为0,则将使用默认值)(默认值:0)
- 14.–networkid value:网络标识符(整型, 1=Frontier, 2=Morden (弃用), 3=Ropsten, 4=Rinkeby) (默认: 1)
- 15.–datadir “xxx”:数据库和keystore密钥的数据目录
然后开启java命令行可以使用web3命令
WEB3命令
查看账户
eth.accounts
创建账户
输入密码创建账户
personal.newAccount()
启动挖矿
miner.start()
停止挖矿
miner.stop()
挖到一个区块就停止
miner.start();admin.sleepBlocks(1);miner.stop()
查看账户余额
//以wei为单位 1 ETH=10^18wei
eth.getBalance
//化为ETH为单位
web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')
查看区块数
eth.blockNumber
指定coinbase账户
miner.setEtherbase(addr)
转账
amount = web3.toWei(5,'ether')
eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[2],value:amount})
会显示账户未解锁
personal.unlockAccount(eth.accounts[0])
解锁转账账户
personal.unlockAccount(eth.accounts[0], "lyh001", 300)
# "lyh001"是密码, 300是解锁时间,0表示没有限制
转账后需要继续开启挖矿将刚刚进行的交易上链
miner.start()
miner.stop()
会出现这种问题
是由于新版本geth出于安全考虑,默认进制了HTTP通道解锁账户,相关issue:>https://github.com/ethereum/go-ethereum/pull/17037
在启动节点命令中添加
--allow-insecure-unlock
查看待确认交易
eth.getBlock("pending", true).transactions
退出
exit
多节点
注意点
一个是要以通过同一个创世区块创建链
二是要保证rpcport和port参数要和之前存在的节点不同
建立新节点
以相同的创世区块配置文件创建一个新的数据文件夹
mkdir data1
geth --datadir ./data1 init test.json
改用不同的rpcport和port开启节点
geth --http --http.port 8546 --nodiscover --datadir "./data1" --port 30304 --http.api db,eth,net,web3 --http.corsdomain "*" --networkid 1001 --ipcdisable --allow-insecure-unlock console 2>>geth.log
–nodiscover 参数让节点2不会被节点1自动扫描到
–ipcdisable 参数禁用IPC-RPC服务器 没有的话会造成启动失败
一定要保证两个节点都保持开启状态
建立连接
net.peerCount //获得当前连接节点个数
admin.peers //当前区块个数
使用方法admin.nodeInfo.enode
获得之前链的enode信息
再将获得的enode作为参数调用现用链的admin.addPeer()
方法
> admin.nodeInfo.enode
"enode://f86288b555519219d4b4b6262e87e9b5306cd86afcff20c08ce0cef21110728e6f48a30810ef032239d6a4b544e9a5d9e472665e91e086fb1b168ca5614530c0@127.0.0.1:30303?discport=0"
//第一个链
>admin.addPeer("enode://f86288b555519219d4b4b6262e87e9b5306cd86afcff20c08ce0cef21110728e6f48a30810ef032239d6a4b544e9a5d9e472665e91e086fb1b168ca5614530c0@127.0.0.1:30303?discport=0")
true
//第二个链
同步完可以看到节点数增加一 区块个数与前链同步
但是账户信息没有同步 看来账户信息和节点是关联的
远程服务器
#!/bin/bash
geth --http --nodiscover --datadir "./data0" --port 30303 --http.api db,eth,net,web3 --http.corsdomain "*" --http.addr 0.0.0.0 --networkid 1001 --ipcdisable --allow-insecure-unlock console 2>>geth.log
写一个bash文件 并添加属性 http.addr 0.0.0.0 监听收到的rpc服务
本地Remix中选择Web3 Provider然后设置对应的 IP 端口
如果本地私链的话就是默认的localhost 远程的话就是服务器的IP
这里显示了所有账户的信息
对于远程服务器和本地私链节点的连接一直还有问题需要解决
但是目前来说的功能已经够用了
下一步要进一步在私链上搭建合约