以太坊搭建私有链(非常详细!!!)(一)

我的系统:CentOS7 64位

环境需要:Go 1.9以上版本
geth工具

WARN [11-04|09:34:47.411] System clock seems off by -10h15m43.047110838s, which can prevent network connectivity 
WARN [11-04|09:34:47.411] Please enable network time synchronisation in system settings. 

一.环境搭建

1.安装Go

下载源码 https://golang.org/dl/
找到适合自己操作系统的版本,必须1.9版本以上。我安装的是1.9.5
解压到/usr/local下

tar   -zxvf   go1.9.5.linux-amd64.tar.gz   -C /usr/local/

创建软链接

ln -s /usr/local/go/bin/go  /usr/bin/go

测试是否成功

go version
#go version go1.9.5 linux/amd64

2.安装geth工具

下载geth源码

git clone https://github.com/ethereum/go-ethereum.git

解压到/usr/local/下

unzip -d /usr/local/ go-ethereum-master.zip

编译源码

cd /usr/local/go-ethereum
make

成功的话会出现如下:

Done building.
Run "/usr/local/go-ethereum-master/build/bin/geth" to launch geth.

创建软链接 这样我们可以直接用geth命令,而不用输入路径

ln -s /usr/local/go-ethereum-master/build/bin/geth /usr/bin/geth

make过程中 如果出现以下错误:
exec: “gcc”: executable file not found in $PATH

则是没有安装gcc的原因,执行

yum install gcc

二.搭建私有链

1.创建用户

mkdir geth
cd geth

进入geth控制台

geth  --datadir db  --nodiscover console

创建用户

> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0x12844bb3206f10a331557bffb7c8d34ee4ca8b65"
> personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0xa6faa81cad6a3b038d9a51db80cedbe65184c7e2"

查看用户余额

> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
0

给用户创建别名

> yujuan=eth.accounts[0]
"0x12844bb3206f10a331557bffb7c8d34ee4ca8b65"
> hcb=eth.accounts[1]
"0xa6faa81cad6a3b038d9a51db80cedbe65184c7e2"

可以看到在db目录下,有个keystore目录,里面已经存了我们刚刚创建的两个账户。

[root@localhost mychain]# tree
.
├── geth
│   ├── chaindata
│   │   ├── 000001.log
│   │   ├── CURRENT
│   │   ├── LOCK
│   │   ├── LOG
│   │   └── MANIFEST-000000
│   ├── LOCK
│   ├── nodekey
│   ├── nodes
│   │   ├── 000001.log
│   │   ├── CURRENT
│   │   ├── LOCK
│   │   ├── LOG
│   │   └── MANIFEST-000000
│   └── transactions.rlp
├── geth.ipc
└── keystore
    ├── UTC--2018-11-04T16-02-52.181405978Z--12844bb3206f10a331557bffb7c8d34ee4ca8b65
    └── UTC--2018-11-04T16-03-15.055116889Z--a6faa81cad6a3b038d9a51db80cedbe65184c7e2

2.传世区块配置文件

cd mychain
 vim gensis.json

在gensis.json中输入如下内容

{
   "alloc": {
      "0x12844bb3206f10a331557bffb7c8d34ee4ca8b65": {
      "balance": "999000000000000000000"
      }
   },
    "config":{
        "chainId":15,
        "homesteadBlock":0,
        "eip155Block":0,
        "eip158Block":0
    },
    "nonce":"0x0000000000000001",
    "mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
    "difficulty": "0x01",
    "coinbase":"0x0000000000000000000000000000000000000000",
    "timestamp": "0x00",
    "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x777573686f756865",
    "gasLimit":"0xffffffff"
}

注意这里的alloc后的地址要用之前创建的地址

2.初始化

准备好创世区块配置文件后,需要初始化区块链,将上面的传世区块信息写入到区块链中。

始初始化区块

geth --datadir “./mychain/” init ./mychain/gensis.json

–datadir 指定数据存放目录
可能出现如下错误,原因是前面启动私有链时已经创建了默认的创世区块

Fatal: Failed to write genesis block: database already contains an incompatible genesis block

如下删除数据

geth removedb

成功的话可以看到如下结果

[root@localhost blockchain]# geth --datadir "./mychain/" init ./mychain/gensis.json 
WARN [11-04|11:59:11.370] Sanitizing cache to Go's GC limits       provided=1024 updated=324
INFO [11-04|11:59:11.380] Maximum peer count                       ETH=25 LES=0 total=25
INFO [11-04|11:59:11.383] Allocated cache and file handles         database=/home/blockchain/mychain/geth/chaindata cache=16 handles=16
INFO [11-04|11:59:11.411] Writing custom genesis block 
INFO [11-04|11:59:11.412] Persisted trie from memory database      nodes=1 size=149.00B time=230.093µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-04|11:59:11.412] Successfully wrote genesis state         database=chaindata                               hash=481cfe…9fd026
INFO [11-04|11:59:11.412] Allocated cache and file handles         database=/home/blockchain/mychain/geth/lightchaindata cache=16 handles=16
INFO [11-04|11:59:11.425] Writing custom genesis block 
INFO [11-04|11:59:11.426] Persisted trie from memory database      nodes=1 size=149.00B time=1.090266ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-04|11:59:11.427] Successfully wrote genesis state         database=lightchaindata                               hash=481cfe…9fd026

3.测试基本的操作

1)此时再查看余额,可以看到

> eth.accounts
["0x12844bb3206f10a331557bffb7c8d34ee4ca8b65", "0xa6faa81cad6a3b038d9a51db80cedbe65184c7e2"]
> eth.getBalance(eth.accounts[0])
999000000000000000000

2)转账

> a1=eth.accounts[0]
"0x12844bb3206f10a331557bffb7c8d34ee4ca8b65"
> a2=eth.accounts[1]
"0xa6faa81cad6a3b038d9a51db80cedbe65184c7e2"
我们从账户a1转10个以太币给a2
转账之前需要先对账户a1解锁
> personal.unlockAccount(a1,"123456")
true

转账

> eth.sendTransaction({from:a1, to:a2, value:web3.toWei(10,"ether")})
INFO [11-04|12:28:37.209] Setting new local account                address=0x12844bB3206F10A331557bFfB7c8D34eE4ca8b65
INFO [11-04|12:28:37.210] Submitted transaction                    fullhash=0x21d4e590f240322b2ab16b750f6e7ded187242ecdfb17c49cb5d229649f1bc56 recipient=0xA6fAA81cAD6A3b038D9a51DB80CEDbe65184c7E2
"0x21d4e590f240322b2ab16b750f6e7ded187242ecdfb17c49cb5d229649f1bc56"

交易已经成功执行,最后一排即是交易的hash值
那我们再来看一下两个账户的余额

> eth.getBalance(a1)
999000000000000000000
> eth.getBalance(a2)
0

奇怪,为什么账户的余额根本就没有变呢。那是因为这里没有矿工参与,所以也没有人来将交易打包写入区块。

3)启动节点

    geth --datadir "./mychain" --rpc --rpcaddr=0.0.0.0 --rpcport 8545 --rpccorsdomain "*"  --rpcapi "eth,net,web3,personal,admin,ssh,txpool,debug,miner" --nodiscover --maxpeers 30  --networkid 1981 --mine --minerthreads 1 --etherbase  "0x12844bb3206f10a331557bffb7c8d34ee4ca8b65" console

在这里插入图片描述这样我们就成功运行了一个私有链,再稍过一会儿
就会发现出现了斧头,说明已经开始挖矿了
这个时候我们再来看刚刚转账后的账户余额

> web3.fromWei(eth.getBalance(eth.accounts[0]))
994
> web3.fromWei(eth.getBalance(eth.accounts[1]))
10

web3.fromWei是将Wei转换成ether
因为我们设置的矿工奖励地址是accounts[0],所以这里的账户余额是994,而不是989

4) 交易

通过attach命令,连接一个已经启动的节点,启动JS命令环境

geth --datadir './mychain/' attach ipc:./mychain/geth.ipc 

成功进入

  [root@localhost blockchain]# geth --datadir './mychain/' attach ipc:./mychain/geth.ipc 
    WARN [11-04|14:01:44.332] Sanitizing cache to Go's GC limits       provided=1024 updated=324
    Welcome to the Geth JavaScript console!
    
    instance: Geth/v1.8.18-unstable/linux-amd64/go1.9.5
    coinbase: 0x12844bb3206f10a331557bffb7c8d34ee4ca8b65
    at block: 1 (Sun, 04 Nov 2018 12:43:43 EST)
     datadir: /home/blockchain/mychain
     modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

现在开始挖矿
可以通过miner.setEtherbase(eth.accounts[0])来设置挖矿奖励地址

> eth.accounts
["0x12844bb3206f10a331557bffb7c8d34ee4ca8b65", "0xa6faa81cad6a3b038d9a51db80cedbe65184c7e2", "0x0cdba6a391a52155042d4709a90fbc9ed3b72f06"]
 > a2=eth.accounts[2]
  "0x0cdba6a391a52155042d4709a90fbc9ed3b72f06"
> a0=eth.accounts[0]
"0x12844bb3206f10a331557bffb7c8d34ee4ca8b65"
> personal.unlockAccount(a0)
Unlock account 0x12844bb3206f10a331557bffb7c8d34ee4ca8b65
Passphrase: 
 true
 > eth.sendTransaction({from:a0,to:a2,value:web3.toWei(20,"ether")})
"0x0d711995130df3809294b5e8f62652a91cd9154188282b10c250fc99a6d06745"

将账户a2设置为挖矿奖励地址

> miner.setEtherbase(a2)
 true
> eth.coinbase
"0x0cdba6a391a52155042d4709a90fbc9ed3b72f06"
> 

现在已经有一个未打包进区块的交易在交易池中。txpool.status返回正在等待打包的交易。pending表示已经提交还未被处理的交易

> txpool.status
{
  pending: 1,
  queued: 0
}

查看pending交易详情

> txpool.inspect.pending
{
  0x12844bB3206F10A331557bFfB7c8D34eE4ca8b65: {
    1: "0x0CDBA6A391a52155042D4709A90fBC9ed3B72F06: 20000000000000000000 wei + 90000 gas × 1000000000 wei"
  }
}

5)挖矿

要使交易被处理,必须要挖矿,
这里启动挖矿,然后等到挖到第一个区块之后就停止挖矿
miner.start(1);admin.sleepBlocks(1);miner.stop();

6)区块

之前交易的hash值0x0d711995130df3809294b5e8f62652a91cd9154188282b10c250fc99a6d06745
得到发起交易时的详情

eth.getTransaction("0x0d711995130df3809294b5e8f62652a91cd9154188282b10c250fc99a6d06745")

下面是交易被打包进区块时详细信息:

eth.getTransactionReceipt("0x0d711995130df3809294b5e8f62652a91cd9154188282b10c250fc99a6d06745")

查看当前区块总数
eth.blockNumber
查询最新区块
eth.getBlock(‘latest’)
返回区块number的信息
eth.getBlock(0)

4远程节点管理

重新开一台机子(当然贫困的我是重开了一个虚拟机)
依照上面配置环境后启动节点。注意gensis.block需要一样。

添加其他节点
可以通过admin.addPeer()方法连接到其他节点,两个节点要想联通,必须保证网络是连接的,并且启动时指定的networkid相同。
通过下面的命令获得另一个节点的ecode信息

> admin.nodeInfo.enode
"enode://c56903836723db6d643a2b9fb13e11ed30e53618606c600f7c0ebab89246d24b381df7ef6f08b19461b423b72d88d62dcbf6aa2989024093b24536633977515a@127.0.0.1:30303?discport=0"

链接节点2:

> admin.addPeer("enode://c56903836723db6d643a2b9fb13e11ed30e53618606c600f7c0ebab89246d24b381df7ef6f08b19461b423b72d88d62dcbf6aa2989024093b24536633977515a@192.168.183.137:30303?discport=0")
true

注意这里需要把ip地址改成节点2的ip地址。
连接成功后,节点二会开始同步节点一的区块,同步完成后,任意一个节点开始挖矿,另一个节点会自动同步区块。
查看已连接到的节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值