轻松搭建以太坊私有链

0x00 序言

最近不论是币圈还是技术圈,区块链都这么火热,17 年 9 月 ICO 在国内被取缔,没过几天国内所有数字货币交易所都被叫停,消息一出无数韭菜被迫割肉。谁料币圈在脱离中国市场后一路高歌猛击,比特币为首的数字货币在此之后一路拉升再创新高。而 17 年一开始数字货币的基石——区块链技术更是被捧上天。更有甚者将 18 年称作区块链元年。这是继人工智能之后的又一个被广泛看好的技术。并且区块链的应用落地将比人工智能门槛更低,马太效应已经显现,会有大量资本涌入,也隐藏着很多机会。

0x01 配置创世区块

搭建私有链前需要创建一个 json 配置文件,用于初始化创世区块。这里作者将创建一个名为 genesis.json 的文件。

内容如下:

{
  "config": {
        "chainId": 1000,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x400",
  "extraData"  : "Oh My God!",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0x0000000000000042",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00",
  "alloc": {}
}

配置说明:
config.chainId // 区块链的ID,在 geth 命令中的 --networkid 参数需要与 chainId 的值一致
config.homesteadBlock // Homestead 硬分叉区块高度,不需要关注
config.eip155Block // EIP 155 硬分叉高度,不需要关注
config.eip158Block // EIP 158 硬分叉高度,不需要关注
coinbase // 矿工账号,第一个区块挖出后将给这个矿工账号发送奖励的以太币
difficulty // 难度值,越大越难
extraData // 附加信息随便填
gasLimit // gas 的消耗总量限制,用来限制区块能包含的交易信息总和,因为我们是私有链,所以填最大
nonce // 一个 64 位随机数
mixhash // 与 nonce 配合用于挖矿,由上一个区块的一部分生成的 hash
parentHash // 上一个区块的 hash 值
alloc // 预设账号以及账号的以太币数量,私有链挖矿比较容易可以不配置

好啦~配置项解释完毕可以开始初始化创世区块了!!!

0x02 初始化创世区块

这里需要用到 geth 的 init 命令。

geth --datadir $HOME/privateNet/bootnode init genesis.json                                                     
...
INFO [01-13|20:07:29] Successfully wrote genesis state    database=lightchaindata                                           hash=49c2dd…aff051

参数解释:
--datadir 指定数据存放的目录

0x03 启动私链起始节点(boot node)

geth --datadir $HOME/privateNet/bootnode \
--networkid 1000 \
--identity "bootnode" \
--port 30303 \
--rpc \
--rpcport 8545 \
--rpccorsdomain "*" \
--nodiscover \
--verbosity 4 \
console
...
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.2-stable/darwin-amd64/go1.9.2
 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

>

参数说明:
--networkid 与 genesis.json 中的 chainId 一致
--identity 设置节点ID
--port geth 节点端口 default: 30303
--rpc 启用 rpc 服务 default: 8545
--rpcport rpc 服务端口
--rpccorsdomain 这里配置“*”是允许通过任意域名访问,也可以指定具体的域名如:“http://yourdomain.com
--nodiscover 关闭节点自动发现
--verbosity 日志等级:0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 3)

提示:
在 geth console 模式下可以使用 eth.getBlock(区块号) 查看区块内容

> eth.getBlock(0)
{
  difficulty: 16,
  extraData: "0x01010101",
  gasLimit: 3141592,
  gasUsed: 0,
  hash: "0xdd97c4469e8bf4054b7c756c1d620ee21d41e5ade129adfbb5ddce3937d6f66e",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x0000000000000000000000000000000000000000",
  mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 508,
  stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  timestamp: 0,
  totalDifficulty: 16,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

创世都搞定了接下来的事就更简单了~

0x04 创建新账号

在 geth console 模式下实际是一个 JavaScript 运行环境,有点类似 Node.js 的命令行模式。可以使用一些预设的对象方法执行一些操作。personal 对象下的 newAccount 方法可以创建新的账号,该方法返回一个账号地址。

personal.newAccount("yourPassphrase")
"0xe6a8faf90ddc1ec0c335d0a83f660c5de9ec12d1"

0x05 挖矿

挖矿赚取以太比奖励,由于创世区块中难度值设置的很低因此不会很难挖。

miner.start()

挖矿同时可以用 geth attach 命令打开另一个终端查看账户余额

geth attach $HOME/privateNet/bootnode/geth.ipc
...
> eth.getBalance(eth.accounts[0])

0x06 创建新节点

都说区块链是去中心化的账本那么可以满足于单机挖矿?说干就干接下来创建一个新节点并将太接入我们的主节点。这里需要注意以下几点:

  • 新节点的 networkid 要与 boot node 一致
  • 需要与 boot node 使用同一个创世区块
  • 如果多个节点都在一台机器上注意端口区分,避免端口冲突
    • --port 30304
    • --rpcport 9545
geth --datadir $HOME/privateNet/node2 init genesis.json
geth --datadir $HOME/privateNet/node2 \
--fast \
--cache 512 \
--port 30304 \
--networkid 1000 \
--identity "node2" \
--rpc \
--rpcport 9545 \
--rpccorsdomain "*" \
--nodiscover \
--verbosity 4 \
console

接来下需要建立节点间的联系

这里有三种方式:

  1. 使用 admin.addPeer() 命令手动添加 bootnode
    在 boot node 上获取 enode 信息:
admin.nodeInfo.enode
"enode://xxx"

将 boot node 的 enode 信息写入 node2

admin.addPeer("enode://xxx");

geth console 中显示

DEBUG[01-13|22:54:35] Ethereum peer connected                  id=b0ac9d91125e7a1b conn=inbound name=Geth/node2/v1.7.2-stable/darwin-amd64/go1.9.2

使用 admin.peers 命令可以看到两个节点之间已经取得联系

# boot node
> admin.peers
[{
    caps: ["eth/63"],
    id: "b0ac9d91125e7a1bebff6d473cd3a9bcf41243060e52f97c3744053c060f24c9e2c36cc181e589d46ede5559509c7dd2c8528d9d039ee5cc900e0700f56c27e7",
    name: "Geth/node2/v1.7.2-stable/darwin-amd64/go1.9.2",
    network: {
      localAddress: "[::1]:30303",
      remoteAddress: "[::1]:64087"
    },
    protocols: {
      eth: {
        difficulty: 245728379,
        head: "0x65ae6da1d42ab4ea75bc468e47912cc61cd3a51b5d406482904c7d0c51785548",
        version: 63
      }
    }
}]
# node2
> admin.peers
[{
    caps: ["eth/62", "eth/63"],
    id: "8cc33dabb8f5fa2033cf646549e6988418439c8756d96e62f418ebb57ecd0cc2cfbf7ceab4450d262331d8d4fe68358200030e6a16988f2ebe393bf6214380fe",
    name: "Geth/bootnode/v1.7.2-stable/darwin-amd64/go1.9.2",
    network: {
      localAddress: "[::1]:64087",
      remoteAddress: "[::1]:30303"
    },
    protocols: {
      eth: {
        difficulty: 245728379,
        head: "0x65ae6da1d42ab4ea75bc468e47912cc61cd3a51b5d406482904c7d0c51785548",
        version: 63
      }
    }
}]
  1. 使用 static-nodes.json 文件
    除了在 geth console 下使用 admin.addPeer() 也可在 --datadir 指定的目录中添加 static-nodes.json 文件让节点取得联系
[
    "enode://xxx" // boot node 地址
]
  1. 使用命令行 --bootnodes 参数指定 enode

0x07 节点间服务自发现

// 假设有 node2,node3 都加入 bootnode,验证node2 node3 之间能否自动服务发现

参考列表

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

推荐阅读更多精彩内容