以太坊区块链搭建

如何安装

sudo apt-get update

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版本号

wangzhen@wangzhen-VirtualBox:/opt$ geth version

Geth
Version: 1.8.4-stable
Git Commit: 2423ae01e0d2f853512eb2b46954b5ad0754a897
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.10

开始创建以太坊私有链

初始化一个创世区块

初始化创世区块时,要先创建一个genesis.json文件,内容如下:
genesis.json:

{
  "config": {
        "chainId": 10,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x20000",
  "extraData"  : "",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0x0000000000000042",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00",
  "alloc"      : {}
}
参数名 参数描述
mixhash 与nonce配合用于挖矿,由上一个区块的一部分生成的hash。注意他和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 上一个区块的hash值,因为是创世块,所以这个值是0
------ --------
extraData 附加信息,随便填,可以填你的个性信息
------ --------
gasLimit 该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大。
------ --------

接下来,我们使用geth init ./genesis.json --datadir "./chain"命令,来进行创世区块的初始化,当前区块链网络数据存放的位置会保存在chain目录中:

wangzhen@wangzhen-VirtualBox:/opt/born$ geth init ./genesis.json --datadir "./chain"
INFO [04-19|16:16:55] Maximum peer count                       ETH=25 LES=0 total=25
INFO [04-19|16:16:55] Allocated cache and file handles         database=/opt/born/chain/geth/chaindata cache=16 handles=16
INFO [04-19|16:16:55] Writing custom genesis block 
INFO [04-19|16:16:55] Persisted trie from memory database      nodes=0 size=0.00B time=1.845µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [04-19|16:16:55] Successfully wrote genesis state         database=chaindata                      hash=5e1fc7…d790e0
INFO [04-19|16:16:55] Allocated cache and file handles         database=/opt/born/chain/geth/lightchaindata cache=16 handles=16
INFO [04-19|16:16:55] Writing custom genesis block 
INFO [04-19|16:16:55] Persisted trie from memory database      nodes=0 size=0.00B time=3.16µs  gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [04-19|16:16:55] Successfully wrote genesis state         database=lightchaindata                      hash=5e1fc7…d790e0


启用私有链

geth \
  --datadir "./chain" \
  --nodiscover \
  console 2>>eth_output.log

启动后的效果如下:

wangzhen@wangzhen-VirtualBox:/opt/born$ geth \
>   --datadir "./chain" \
>   --nodiscover \
>   console 2>>eth_output.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.4-stable-2423ae01/linux-amd64/go1.10
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

参数名称 参数描述
datadir 设置当前区块链网络数据存放的位置
---- ----
console 启动命令行模式,可以在Geth中执行命令
---- ----
nodiscover 私有链地址,不会被网上看到

在当前目录执行tail -f eth_output.log,可以看到输出日志。

wangzhen@wangzhen-VirtualBox:/opt/born$ tail -f eth_output.log
INFO [04-19|16:18:29] Disk storage enabled for ethash DAGs     dir=/home/wangzhen/.ethash      count=2
INFO [04-19|16:18:29] Initialising Ethereum protocol           versions="[63 62]" network=1
INFO [04-19|16:18:29] Loaded most recent local header          number=0 hash=5e1fc7…d790e0 td=131072
INFO [04-19|16:18:29] Loaded most recent local full block      number=0 hash=5e1fc7…d790e0 td=131072
INFO [04-19|16:18:29] Loaded most recent local fast block      number=0 hash=5e1fc7…d790e0 td=131072
INFO [04-19|16:18:29] Regenerated local transaction journal    transactions=0 accounts=0
INFO [04-19|16:18:29] Starting P2P networking 
INFO [04-19|16:18:29] IPC endpoint opened                      url=/opt/born/chain/geth.ipc
INFO [04-19|16:18:29] Database deduplication successful        deduped=0
INFO [04-19|16:18:29] RLPx listener up                         self="enode://5231f4677b0576292a6d7cd11890218ae2f84336338a4ce7b08e296aa3b9007c8dc728bf26b2e10a3de9afb4d5272ab13e86030a1e7db42474d6577aad174d09@[::]:30303?discport=0"


后面章节中的命令,都是在启动私有链后的Geth javascript console中操作

帐户的添加和查看

查看帐户,可以看到当前帐户是空的


> web3.eth.accounts
[]
> 

创建帐户的方式有两种,第一种创建帐户时直接初始化密码

> web3.personal.newAccount("123456")
"0x25df465d9d9060423ce46137ca25aa5a10fd9a2f"


其中返回的0x25df465d9d9060423ce46137ca25aa5a10fd9a2f是帐户,123456是帐户的密码

第二种方法是先创建账户,然后输入密码


> web3.personal.newAccount()
Passphrase: 
Repeat passphrase: 
"0xd7b8a838f947adb4da47fa7208a2c177cfed6ab3"

这时我们再查看帐户,能够看到刚才创建的两个帐户已经存在了

> web3.eth.accounts
["0x25df465d9d9060423ce46137ca25aa5a10fd9a2f", "0xd7b8a838f947adb4da47fa7208a2c177cfed6ab3"]

开始挖矿和停止挖矿

挖矿执行以下命令:

 miner.start()

执行以后,通过刚才查看日志的方法tail -f eth_output.log,能够看到类似下面的日志,因为只有发送交易才会自动挖矿,所以会显示如下信息。

INFO [04-19|16:30:08] Commit new mining work                   number=1 txs=0 uncles=0 elapsed=175.12µs
INFO [04-19|16:30:16] Generating DAG in progress               epoch=0 percentage=0 elapsed=6.662s
INFO [04-19|16:30:23] Generating DAG in progress               epoch=0 percentage=1 elapsed=12.780s
INFO [04-19|16:30:29] Generating DAG in progress               epoch=0 percentage=2 elapsed=19.418s
INFO [04-19|16:30:35] Generating DAG in progress               epoch=0 percentage=3 elapsed=24.970s


需要在开发环境下,才能进行挖矿,修改上述命令为:

geth   --datadir "./chaindev"   --nodiscover    console 2>>eth_output.log  --dev --dev.period 1

挖矿执行以下命令:

 miner.start()

出现如下信息代表开始挖矿了

INFO [04-19|16:57:28] Successfully sealed new block            number=1 hash=eb3609…3747ef
INFO [04-19|16:57:28] 🔨 mined potential block                  number=1 hash=eb3609…3747ef
INFO [04-19|16:57:28] Commit new mining work                   number=2 txs=0 uncles=0 elapsed=417.68µs

挖矿会默认保存到创建的第一个帐户0x6426ea256ba1d45e966c9aabc0268594093251c4中。
block number=66,说明我们已经创建了66个区块
在以太坊官方的网络上,平均每15秒产生一个区块

停止挖矿执行以下命令:


> miner.stop()
true

停止挖矿后,以太币则不会产生,同样智能合约、转帐等操作也不会起作用。

查看帐户余额

查看帐户余额的方法如下:

> web3.eth.getBalance("0x6426ea256ba1d45e966c9aabc0268594093251c4")
1.15792089237316195423570985008687907853269984665640564039457584007913129639927e+77

以太币最小的单位是wei(18个0)

每次记一长串的地址很麻烦,我们可以通过设置变量来acc0表示帐户1

> acc0 = web3.eth.accounts[0]

"0x6426ea256ba1d45e966c9aabc0268594093251c4"

查看格式化的以太币

web3.fromWei(web3.eth.getBalance(acc0), 'ether')
1.15792089237316195423570985008687907853269984665640564039457584007913129639927e+59

因为geth javascript console是基于javascript的,所以也可以创建js函数,查看所有帐户余额


> function checkAllBalances() {
      var totalBal = 0;
      for (var acctNum in eth.accounts) {
         var acct = eth.accounts[acctNum];
         var acctBal = web3.fromWei(eth.getBalance(acct), "ether");
          totalBal += parseFloat(acctBal);
          console.log("  eth.accounts[" + acctNum + "]: \t" + acct + " \tbalance: " + acctBal + " ether");
      }
      console.log("  Total balance: " + totalBal + " ether");
  };

> checkAllBalances()
  eth.accounts[0]:  0x6426ea256ba1d45e966c9aabc0268594093251c4  balance: 1.15792089237316195423570985008687907853269984665640564039457584007913129639927e+59 ether
  eth.accounts[1]:  0x9e8e4b905e054575a7495a6822545da82f197b13  balance: 0 ether
  Total balance: 1.157920892373162e+59 ether

> 

如果命令较多,可以保存到一个脚本里,使用命令载入脚本:loadScript('/path/script/here.js')

转帐操作

从帐户0x6426ea256ba1d45e966c9aabc0268594093251c4转3个以太币到0x9e8e4b905e054575a7495a6822545da82f197b13,如果不指定单位ether,默认转的是wei。

>web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"ether")})
Error: authentication needed: password or unlock
    at web3.js:3104:20
    at web3.js:6191:15
    at web3.js:5004:36
    at <anonymous>:1:1

当直接执行此方法时会抛出异常,显示帐号被锁

执行开发者模式,创建的默认账户,不会报这个错误
如果报相关错误,执行以下语句

> web3.personal.unlockAccount(acc0,"123456")
true

转账完成的正确显示为:

web3.eth.sendTransaction({from:acc0,to:acc1,value:web3.toWei(3,"ether")})
"0x1c59a753ecd2efd7e916912df7bd8ae2973379df23024de9a3cee6ceb242b611"

但此时查看时会发现接收账户依旧为原来数值。此时需要执行挖矿命令,才会把转账真正完成。

> checkAllBalances()
  eth.accounts[0]:  0x6426ea256ba1d45e966c9aabc0268594093251c4  balance: 1.15792089237316195423570985008687907853269984665640564039457584007913129639927e+59 ether
  eth.accounts[1]:  0x9e8e4b905e054575a7495a6822545da82f197b13  balance: 0 ether
  Total balance: 1.157920892373162e+59 ether
undefined
> miner.start()
null
> checkAllBalances()
  eth.accounts[0]:  0x6426ea256ba1d45e966c9aabc0268594093251c4  balance: 1.15792089237316195423570985008687907853269984665640564039451584007913129639927e+59 ether
  eth.accounts[1]:  0x9e8e4b905e054575a7495a6822545da82f197b13  balance: 6 ether
  Total balance: 1.157920892373162e+59 ether
undefined
> miner.stop()
true

这里看到转账了6个币,是因为我执行了两次:)

添加节点

首先要知道自己的节点信息,在Geth命令行界面下输入命令,注意大小写

admin.nodeInfo

显示结果为:

> admin.nodeInfo
{
  enode: "enode://5231f4677b0576292a6d7cd11890218ae2f84336338a4ce7b08e296aa3b9007c8dc728bf26b2e10a3de9afb4d5272ab13e86030a1e7db42474d6577aad174d09@[::]:30303?discport=0",
  id: "5231f4677b0576292a6d7cd11890218ae2f84336338a4ce7b08e296aa3b9007c8dc728bf26b2e10a3de9afb4d5272ab13e86030a1e7db42474d6577aad174d09",
  ip: "::",
  listenAddr: "[::]:30303",
  name: "Geth/v1.8.4-stable-2423ae01/linux-amd64/go1.10",
  ports: {
    discovery: 0,
    listener: 30303
  },
  protocols: {
    eth: {
      config: {
        chainId: 10,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0
      },
      difficulty: 131072,
      genesis: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
      head: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
      network: 1
    }
  }
}

其中

 enode: "enode://5231f4677b0576292a6d7cd11890218ae2f84336338a4ce7b08e296aa3b9007c8dc728bf26b2e10a3de9afb4d5272ab13e86030a1e7db42474d6577aad174d09@[::]:30303?discport=0"
 

就是自己节点的信息,注意要把“0.0.0.0“换成你自己的IP。将这个信息发送给其他节点,在其他节点的命令行中输入:

admin.addPeer("enode://5231f4677b0576292a6d7cd11890218ae2f84336338a4ce7b08e296aa3b9007c8dc728bf26b2e10a3de9afb4d5272ab13e86030a1e7db42474d6577aad174d09@192.168.1.121:30303?discport=0")

如果添加成功,输入admin.peers会显示出新添加的节点。

> admin.peers
[{
    caps: ["eth/63"],
    id: "5231f4677b0576292a6d7cd11890218ae2f84336338a4ce7b08e296aa3b9007c8dc728bf26b2e10a3de9afb4d5272ab13e86030a1e7db42474d6577aad174d09",
    name: "Geth/v1.8.4-stable-2423ae01/linux-amd64/go1.10",
    network: {
      inbound: false,
      localAddress: "192.168.1.112:42702",
      remoteAddress: "192.168.1.121:30303",
      static: true,
      trusted: false
    },
    protocols: {
      eth: {
        difficulty: 131072,
        head: "0x5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0",
        version: 63
      }
    }
}]
> 

发送交易

解锁账户

> personal.unlockAccount(eth.accounts[0])


Unlock account 0x20869f8cb579e7712f60167d3d153d3f038960c9
Passphrase: 
true

发送交易

> eth.sendTransaction({from: "0x20869f8cb579e7712f60167d3d153d3f038960c9", to: "0x25df465d9d9060423ce46137ca25aa5a10fd9a2f", gas:31000, 'gasPrice': web3.toWei(300, 'gwei'), "value": "1"})
"0xe4ecfa81d367d2906e87a0f45b5bb90a0424f58bbd74d896ef217f3d5f132533"

此时交易已经提交到区块链,返回了交易的hash,但还未被处理,要使交易被处理,必须要挖矿。

交易成功后再对方账户上收到

> web3.fromWei(web3.eth.getBalance(eth.accounts[0]))
5.006300000000000001

参考资料

使用 Go-Ethereum 1.7.2搭建以太坊私有链
以太坊执行miner.start返回null终极解决方案
Geth官方安装指南
以太坊私链demo,实现第一笔交易
以太坊中的账户、交易、Gas和区块Gas Limit

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容