在Ubuntu下使用Geth搭建自己的以太坊私有链
最近开始了解区块链,并开始学习以太坊。以太坊并不是我们单纯了解的可以对以太币进行交易的平台,它是是一个开源的有智能合约功能的公共区块链平台。在这个平台上,借助它专用的加密货币--以太币(ETH)提供了去中心化的以太虚拟机环境处理点对点的合约。作为一个初学者,想要快速进入以太坊的学习门槛,搭建一个以太坊的私有链,不失为一个很好的途径。通过在私有链上创建账户、部署合约并进行交易,完成这一系列操作后..
最近开始了解区块链,并开始学习以太坊。以太坊并不是我们单纯了解的可以对以太币进行交易的平台,它是是一个开源的有智能合约功能的公共区块链平台。在这个平台上,借助它专用的加密货币--以太币(ETH)提供了去中心化的以太虚拟机环境处理点对点的合约。
作为一个初学者,想要快速进入以太坊的学习门槛,搭建一个以太坊的私有链,不失为一个很好的途径。通过在私有链上创建账户、部署合约并进行交易,完成这一系列操作后,对于了解以太坊以及基于以太坊进行开发,就可以初窥门径了。
一、环境准备
为了以后更深入的学习区块链相关技术,以及避免在搭建私链的过程中出现各种莫名其妙的问题,当然,也为了看起来逼格高一些:),我选择在Linux系统下完成私有链的搭建。具体环境如下:
宿主系统:Windows 10专业版
虚拟机: VMware Workstation Pro 12.5.4
操作系统:Ubuntu 18.4.1 64位
二、安装Geth
Geth是以太坊的客户端,其全称是go-ethereum。以太坊的客户端用于接入以太坊网络,进行账户管理、交易、挖矿、智能合约部署开发等相关的操作。目前有多种语言实现的客户端,Geth是用Go语言编写的,支持接入以太坊网络并成为一个完整节点。也可作为一个 HTTP-RPC 服务器对外提供 JSON-RPC 接口。其他常用的以太坊客户端如下:
- Parity:Rust 语言实现
- cpp-ethereum:C++ 语言实现
- ethereumjs-lib:JavaScript 语言实现
- Ethereum(J):Java 语言实现
- ethereumH:Haskell 语言实现
- pyethapp: Python 语言实现
- ruby-ethereum:Ruby 语言实现
Geth的安装有两种方式,一种是直接下载程序进行安装,另一种是通过编译源码安装。这里我选择的是通过下载程序安装。
打开命令行窗口,依次执行以下命令:
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install ethereum
执行完 以上命令后,执行如下命令:
geth --help
会显示Geth的版本和命令参数等信息
附上Geth的Git项目地址和wiki地址
Git:https://github.com/ethereum/Go-ethereum
wiki:https://github.com/ethereum/Go-ethereum/wiki/Building-Ethereum
三、定义创世区块
1、创建工作目录
## 尽量不要在需要管理员权限的路径下创建工作目录,避免出现因权限问题引起的麻烦
mkdir ~/privatechain
## data目录用于存放账户信息和区块数据
mkdir ~/privatechain/data
2、创建创世区块配置文件
在privatechain目录下新建genesis.json文件,文件内容如下:
{
"config": {
"chainId": 10,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x2000",
"extraData" : "",
"gasLimit" : "0xffffffff",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00",
"alloc": {
"08a58f09194e403d02a1928a7bf78646cfc260b0": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"87366ef81db496edd0ea2055ca605e8686eec1e6": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
}
}
}
如果是初次接触以太坊,对文件的内容不了解没有关系。等我们完成了整个私有链的创建,并在链上完成了和账户、合约及交易的相关操作,就会理解其中大部分的含义了。下面的表格对配置文件做简要说明:
参数名 | 描 述 |
---|---|
chainId | 指定了独立的区块链网络 ID。网络 ID 在连接到其他节点的时候会用到,以太坊公网的网络 ID 是 1,为了不与公有链网络冲突,运行私有链节点的时候要指定自己的网络 ID。不同 ID 网络的节点无法相互连接 |
homesteadBlock | 当设置为0表示使用homestead发布该链 |
nonce | nonce就是一个64位随机数,用于挖矿,注意它和mixhash的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件 |
mixhash | 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意它和nonce的设置需要满足以太坊的Yellow paper, 4.3.4. Block Header Validity, (44)章节所描述的条件 |
difficulty | 设置设置当前区块的难度,越大挖矿就越难 |
alloc | 用来预置账号以及账号的以太币数量,因为私有链挖矿比较容易,所以我们也可以不需要预置有币的账号,需要的时候自己创建即可以 |
coinbase | 矿工账号,可以随便写 |
timestamp | 设置创世块的时间戳 |
parentHash | 上一个区块的hash,创世区块的该项参数就为0 |
extraData | 附加信息,可以随便写 |
gasLimit | 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和。我们创建的是私有链,可以填最大 |
3、创建创世区块
cd ~/privatechain
geth --datadir ./data init genesis.json
执行完以上命令,在privatechain下的data目录中会生成两个目录,结构如下:
其中:
geth目录用于保存我们所建私有链的区块数据
keystore目录用于保存用户的账户数据
四、启动私有链
执行如下命令,启动私有链:
## --datadir 表示当前区块链网络数据存放的位置
## --nodiscover 表示该链禁止被其他节点发现
## console 2>>geth.log 表示将日志输出到geth.log。可以打开另外一个控制台执行 tail -f 查看日志
geth --datadir ./data --nodiscover console 2>>geth.log
启动成功后如下图所示:
还有一种启动方式,其作用是启动PRC通信,启动命令如下:
geth --nodiscover --identity "my etherum" --rpc --rpccorsdomain "*" --datadir ./data --port "30303" --rpcapi "db,eth,net,web3" --networkid 10 --allow-insecure-unlock console 2>>geth.log
PRC启动命令的参数含义如下表所示:
参数名 | 描 述 |
---|---|
identity | 区块链的标识,用于标示目前网络的名字 |
nodiscover | 关闭p2p网络的自动发现,需要手动添加节点,这样有利于我们隐藏私有网络 |
init | 指定创世块文件的位置,并创建创世块 |
datadir | 当前区块数据存放的位置 |
port | 网络监听端口,默认30303 |
rpc | 启动rpc通信 |
rpcapi | 设置允许连接rpc的客户端,一般为db,eth,net,web3 |
rpccorsdomain | 指定什么url能连接到你的节点执行rpc定制端任务,如果输入的是“*”,则任何url都可以连接到你的rpc实例 |
rpcaddr | 连接rpc的地址,默认为localhost |
rpcport | 连接rpc的端口,默认为8545 |
networkid | 设置当前区块链的网络ID,用于区分不同的网络,是一个数字 |
console | 启动命令行模式,可以在Geth中执行命令 |
如果在创建创世区块之前已经启动了私有链,在创建了创世区块配置文件后,可以通过以下命令重新进入geth控制台,并使用配置文件更新区块:
geth --datadir data --networkid 10 console
提示:--networkid参数即为创世区块配置文件中的chainId
五、创建账户
为了后期测试方便,我们创建两个账户,用于演示账户之间的转账操作。
启动私有链后,在控制台输入如下命令:
## newAccount的参数为账号密码,这里新账户的密码分别是123456和000000
> personal.newAccount("123456")
> personal.newAccount("000000")
创建账户后会返回遗传hash码,代表的是新建账户的地址
此时查询私链上的账户及账户的余额信息,会返回相应的结果。
下面显示私链上的账户信息
由于还没有开始挖矿,账户中的余额为0
六、挖矿
新创建的账户都是没有余额的,只有通过挖矿赚钱,才能让账户有收入,下面介绍如何开始挖矿。
1、开始挖矿
## start的参数表示挖矿使用的线程数,若不写表示使用最大线程数。返回true或null表示执行成功
> miner.start()
当percentage = 100时,就会开始挖矿
提示:
- 第一次启动挖矿会先生成挖矿所需的 DAG 文件,这个过程有点慢,等进度达到 100% 后,就会开始挖矿
- 如果第一次挖矿遇到一直卡在Commit new mining work,可能是因为创世区块初始化失败,检查初始化genesis.json的指令,排查原因并解决
- 还有一种挖矿失败可能是因为之前存在的链,把~/.ethash删除即可
2、停止挖矿
执行如下命令停止挖矿
> miner.stop()
挖矿结束后再次查看账户余额
挖到一个区块会奖励5个以太币,挖矿所得的奖励会进入矿工的账户,这个账户叫做 coinbase,默认情况下 coinbase 是本地账户中的第一个账户。
此时查看第二个账户的余额仍然为0
我们可以通过miner.setEtherbase() 将其他账户设置成coinbase
重新开始挖矿,过一段时间后,查看第二个账户下的余额,此时账户已经有余额了。
此时显示的账户余额的单位是Wei,如果要转成以太币,可进行如下操作:
可以看出第一个账户和第二个账户的以太币余额分别为5和15,这表明他们分别挖到了1个区块和3个区块。
提示:Wei是以太币的最小单位,1Eth(以太币)= 1,000,000,000,000,000,000 Wei (10的18次方)。通常,大家也使用Gwei作为展示单位。比较常用的就是Eth,Gwei和Wei。以太坊还有其他的单位,他们的换算关系如下:
- Kwei(Babbage) = 1,000 Wei
- Mwei(Lovelace) = 1,000,000 Wei
- Gwei(Shannon) = 1,000,000,000 Wei
- Microether(Szabo) = 1,000,000,000,000 Wei
- Milliether(Finney) = 1,000,000,000,000,000 Wei
- Ether = 1,000,000,000,000,000,000 Wei
七、转账
这一节我们演示转账操作。转账前我们再看一下两个账户的余额:
执行以下转账命令,将第一个账户的2个以太币转到第二个账户下:
> amount = web3.toWei(2,'ether')
> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:amount})
执行后显示如下:
从提示可以看出是账户没有解锁,需要先解锁才能执行转账操作。解锁命令如下:
## 第一个参数为解锁的账户,第二个参数是账户密码
personal.unlockAccount(eth.accounts[0],‘123456’)
返回 true 表示解锁成功
下面重新执行上面的转账操作,返回结果如下:
转账成功后输出的是此次交易的 hash 码。
此时查看账户信息,发现账户余额并没有发生变化。
这是因为当前没有处于挖矿状态,只有处于挖矿的状态才能确认打包交易。但此时我们可以在交易池中看到有一笔待确认的交易。执行一下命令查看交易池信息:
> txpool.status
从返回结果中我们可以看到有一个待确认的交易。
执行如下命令查看待确认交易的详细信息:
> eth.getBlock("pending", true).transactions
返回交易信息如下:
此时我们重新启动挖矿,稍后再查看账户信息如下所示:
可以看到第二个账户多了2个ETH,如果挖矿时间段,此时查看第一个账户,应该比之前少了2个ETH。如果挖矿时间长,则账户余额应该会有较大变化,相比之前会更多。
八、查看区块和交易信息
1、查看区块信息
- 查看区块总数
> eth.blockNumber
- 根据区块编号查看区块信息
> eth.getBlock(1)
2、查看交易信息
查看上面转账交易成功后输出的交易hash,通过该hash我们可以查看交易详细信息
> eth.getTransaction("0x5372d5d4580c5cd2055e13e31d81079ffe64fa151930cc5c70f8c1659d527249
")
返回结果如下:
九、 Geth控制台常用对象及命令
Geth控制台内置了一些用来操作以太坊的Javascript对象,用户可以直接使用这些对象。主要包括:
- eth:操作区块链相关的方法
- net:查看p2p网络状态的方法
- admin:与管理节点相关的方法
- miner:启动&停止挖矿的方法
- personal:管理账户的方法
- txpool:查看交易内存池的方法
- web3:包含了以上对象,还包含一些单位换算的方法
这些对象的常用命令有:
- personal.newAccount():创建账户
- personal.unlockAccount():解锁账户
- eth.accounts:枚举系统中的账户
- eth.getBalance():查看账户余额,返回值的单位是 Wei(Wei 是以太坊中最小单位,类似比特币中的聪,1 ether = 10^18 Wei)
- eth.blockNumber:列出区块总数
- eth.getBlock():根据区块编码获取区块详细信息
- eth.getTransaction():根据交易hash获取交易详细信息
- miner.start():开始挖矿
- miner.stop():停止挖矿
- eth.coinbase:挖矿奖励的账户
- web3.fromWei():Wei 换算成以太币
- web3.toWei():以太币换算成 Wei
- txpool.status:交易池中的状态
- admin.addPeer():连接到其他节点
到这里,在本机搭建以太坊私有链的步骤就全部完成了。后面我会继续介绍在《CentOS下搭建Geth环境》以及《Geth私链的多节点运行》。
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)