第36讲 | 搭建你的迷你区块链(实践篇)
下载APP
关闭
渠道合作
推荐作者
第36讲 | 搭建你的迷你区块链(实践篇)
2018-06-15 陈浩 来自北京
《深入浅出区块链》
课程介绍
讲述:黄洲君
时长02:31大小3.47M
上一篇文章中,我们介绍了实现一个迷你区块链的大致思路。今天,我们将通过代码编写,以及简单的功能测试,来完成我们的迷你区块链 Tinychain。
除了正常的测试案例之外,我们还可以构造一些极端测试案例,来观察 Tinychain 的分叉合并,挖矿难度调整等情况。
代码编写
通过前文的分析,我们已经了解到了实践一个迷你区块链的大致思路。接下来,我将从顶层到底层来搭建区块链。
代码编写 1 Server
从链的顶层设计来看,我们需要一个入口,那么我们就从入口开始:我需要先为整个服务做一些基础设置,最后再来 Server.run()。
所以,我们的代码大概是这样子的。
我们首先生成一个 node 实例,然后被 Server装载进去,最后设置好 Server 启动。
这个 Server 主要有两个功用,第一是向本地用户服务,也就是接受命令行,接受本地 RPC 调用;第二是接受外部网络传送进来是的新交易,和新的区块。所以 Server 是整个节点的入口。
代码编写 2 node
那么这里的 node 其实就是区块链的 node,里面包含了区块链的基本设置,这些一般都是硬编码在代码中的,例如一般区块链都有个“魔法数”,实际上就是区块链 ID,这个 ID 会被放在所有消息的开头,如果区块链 ID 不匹配,则抛弃接收到的消息。
这里的区块链 ID 我们设置在这里。
代码中所展示的 id_ 就是区块链 ID,在 Tinychain 的案例中,我也是硬编码的。
在一个 node 当中,至少要包含 network、blockchain、miner 三个模块。
network 也就是 P2P 网络类,blockchain 是区块链的核心类,miner 是共识模块下的核心类,三者被聚合到 node 中。
同时,node 也会提供一些 blockchain 和 miner 的接口,方便 Server 层调用。
代码编写 3 blockchain
一个 blockchain 实例,应当包含下面的内容。
genesisblock 就是创世区块,这个是预先生成好的。genesis_block 的信息也是被硬编码在代码中,我在 Tinychain 的例子为了方便测试,每个 genesis_block 都是可以自行生成的。
chaindatabase chain 是相对于 memorypool 而言的,chain就是已经经过确认,并且在本地持久化存储的区块数据(由于时间有限,Tinychain 的案例中还未实现持久化存储,可以后续升级替换)。
memory_pool 是指还未经过确认,暂时驻留在内存中的交易池,交易池中的交易会在挖矿时,被导入到新的区块中。
这里的 pool 就是交易池。
key_pair_database 是指专门存储用户的私钥的数据库,同时提供私钥管理。
同时 blockchain 也负责统一对外提供上述功能的接口。
除了上述接口之外,blockchain 还负责当发现自己处于较短的分叉链上时,自动合并到最长链。
代码编写 4 network
在 network 中,可用的地址簿代表了可用的其他对等节点,至少是连接过成功一次的。
地址簿会随着网络的变化进行更新,实时状态的地址簿是驻留在内存中的,当节点关闭是,会被刷到持久化存储中。
channels 代表了已经激活的连接,这些连接可以被 broadcast 接口使用,当本地节点产生新的区块和交易时,会调起这些 channels。
当 P2P 网络产生了新的事件时,会通过 process 接口处理新到达的交易和区块,这一事件会传导给 blockchain 模块。
代码编写 5 consensus
consensus 的含义为共识,共识会在两种情况下产生,第一是对本地生产的交易进行验证,第二是外来的区块和交易进行验证。
无论是哪种情况,他们遵循的验证规则是一样的。validate_tx 和 validate_block 分别承担了这样的功能。
除了验证区块之外,还涉及到提供基础挖矿设施。我们知道挖矿分为两种,一种叫做 solo 挖矿,另外一种叫做联合挖矿。其实无论哪种挖矿类型,都必须用到 miner 类。
miner 类展示了在 solo 挖矿情况下,支持开始挖矿以及计算自己的 coinbase 的过程。
实际 pow_once 的挖矿代码如下,pow_once 被 start 调用,start 里面是一个死循环,死循环里面包了 pow_once 函数。
上面的代码从一开始到 for 循环之前,都可以提取出来,做成叫做 getblocktemplate 的接口,getblocktemplate 是一种 JSON-RPC 调用。
通过这个调用,就可以把挖矿的状态信息分享给其他矿机,矿机拿到 blocktemplate 以后直接进行 nonce 部分暴力搜索即可。
代码编写 6 database
database 是偏底层的接口,主要的功能有两个,第一是提供区块和私钥的持久化存储,第二是提供交易和区块的查询接口。
上文 blockchain 中的 blockchain_database 和 keypair_database 都是从 database 派生过来的。
代码编写 7 commands
commands 提供了开发者命令行交互接口。
首先得有一个可识别的命令列表,接着是执行接口,例如命令行发起生成新 key_pair 的过程,执行 getnewkey 命令。
先被 command 解析,接着执行 exec,执行的时候需要用到 node 对象。
实际上 command 类比较繁琐,因为一个功能复杂的钱包,维护的命令和种类可能多达几十种。
同时命令又可以被 JSON-RPC 调用,所以一般命令行客户端本身就是一个轻量级的 http-client。
代码编写 8 基础类
基础类是实际生成公私钥对、构建交易 tx 的基本单元类,构建区块的基本单元类。
首次运行
我们编写完基础类和基本结构的代码之后,就可以运行试一试。
编译成功是这样子的。
我们可以看到有 Tinychain 和 Cli-tinychain。
Tnychain 就是我们的核心程序,cli-tinychain 就是我们的命令行客户端。
实际上我在 Server 里还嵌入了一个可视化的 Websocket 界面。
只需要在 Tinychain 可执行文件同目录底下创建 webroot 文件夹,将 etc 底下的 index 放入 webroot 下,接着打开浏览器 127.0.0.1:8000 就可以看到了。
实际上这个页面我想做成区块的监视页面,只是还没改造完成,目前支持发送命令。
我们开始首次运行 Tinychain。
运行后,等 node 和 server 全部 started,就可以开始操作命令行了。
也可以通过日志进行监视,但是需要在代码处详细打桩,这次我偷懒了,没有好好打,所以不多,直接查看同目录下 debug.log 和 error.log 即可。
首次挖矿
我们通过./tinychain 启动之后,开始第一次挖矿。
刚开始挖矿会比较快,随着难度提升,会趋向于稳定到 10 秒种左右一个块,如果长时间不出块,难度会自动降下来。曾经元界的代码在难度调整上有缺陷,遭受了严重的“难度坠落”攻击。
我们可以通过这个位置观察难度调整的情况。
第一笔交易
我们保持挖矿,接下来发送一笔交易。我们先通过 getnewkey 命令获得一个新公私钥对以及对应的地址。
接着发送第一笔交易。
探测到接下来被打包到区块中。
分叉与合并
区块链分叉是数据全网不一致的表现,通常是矿工节点行为不一致导致的,常见的有网络分区和协议不兼容,如果同时产生,那么必然会出现两条比较长的分叉链。
在现实情况中,分叉 1 个是最常见的,2 个已经非常罕见了,3 个以上基本是网络分区造成的。
如果我们要在 Tinychain 中实践网络分区和分叉,我们需要构建局域网多节点私链环境,可以通过 docker 来试验。
通过本文,你可以看到即使是搭建一个迷你区块链,它的工作量也是巨大的,其中不仅仅只是组合几个基础组件那么简单,还要涉及各个模块的设计和交互等详细的工作。
由于在短时间内全部搭建以及实现 Tinychain 所有功能是不可行的,在这里,我只为你提供了一些实践的思路。
目前 Tinychain 缺失了 P2P 网络实现、RSA 公私钥对集成、共识模块的交易和区块的验证等内容,我会在后续逐渐完善,你也可以跟我一起补充。
总结
好了,通过今天的代码实践,我们实现了迷你区块链 Tinychain,并且,通过运行与测试 Tinychain,我们了解到了一个最简单区块链的运行原理,希望通过今天的文章,可以帮你加深对区块链技术的理解。
区块链技术只是作为基础设施,服务于广大的开发者和业务需求。目前区块链的发展远远不止 Tinychain 中所展现的样子,我们还需要去考虑区块链 2.0 智能合约,如何设计 Token 经济等一些问题。
随着区块链的发展和应用规模,区块链安全问题也日益突出,所以今天的问题是,如果要攻击 Tinychain,可以采取什么手段呢?你可以给我留言,我们一起讨论。
感谢你的收听,我们下次再见。
分享给需要的人,Ta购买本课程,你将得18元
生成海报并分享
赞 3
提建议
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
上一篇
第35讲 | 搭建你的迷你区块链(设计篇 )
下一篇
尾声篇 | 授人以鱼,不如授人以渔
精选留言(7)
- huangshaoyan2018-06-16老师,对应的代码可以放到您的github上吗
作者回复: 你好,已经投放哦。github.com/betachen/tinychain
3 - 许成浩2018-06-29老师,可以推荐几本区块链相关的书籍好吗?1
- 峪五2022-08-16 来自浙江做事要有始有终呀. 后面都没实现完呢.
- 杨家荣2020-02-07极客时间第二期 21天打卡行动 33/21 <<深入浅出区块链35,36>>搭建你的迷你区块链 今日所学: 1,搭建包含功能: 提供 P2P 节点发现和同步区块的功能; 提供创建公私钥对的功能; 提供发送交易的功能; 提供交易查询的功能; 提供余额查询的功能; 提供挖矿的功能,在任意地址上都可以发起单机挖矿; 提供基础日志,方便跟踪监视。 2,区块头的设计, 3,地址设计, 4,内存池 5,哈希计算, 6,哈希计算, 7,开发环境搭建, 8,测试环境搭建 代码 1,代码编写 1 Server, 2,代码编写 2 node, 3,代码编写 3 blockchain, 4,代码编写 4 network, 5,代码编写 5 consensus, 6,代码编写 6 database, 7,代码编写 7 commands, 8,代码编写 8 基础类,展开
- 栐哥2020-01-10谢谢,请问区块链的APP是用什么开发语言做的呢?是用node.js吗?是用什么IDE开发的呢?我去下载安装
- Eric2018-12-13陈老师,p2p network类,例子里是不是还没实现好?
- 肖水平2018-06-20老师,代码在mac上编译不通过