ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

作者: 陈天(ArcBlock 研发副总裁)

10 月 25 日,刚刚忙完 CyberMiles 超级节点部署的陈天同学,为庆祝专属于程序员的“1024 节”写下了这篇技术学习分享文章,以飨读者。

庆祝 CyberMiles 主网上线,ArcBlock 创始人兼CEO 冒志鸿在美国西雅图郊外的 Lake Quinalt 发来祝贺视频

前两周上线了我们为 Cybermiles 提供的 supernode,因为 Cybermiles 主网使用了 Tendermint,于是上周便研究了一下 Tendermint,边学边写了个 slides 介绍 Tendermint。

Tendermint 是一个脱胎于 PBFT 的 consensus engine,并在此之上构建了一个 Application BlockChain Interface (ABCI),让 blockchain 的开发者可以关注于如何提供服务,以及维系服务的状态,而把如何达成共识,如何管理 mempool,如何进行安全的 p2p 通讯这样的琐事交给 Tendermint 来处理。Tendermint 自身是 golang 撰写的,其 ABCI 接口用 protobuf 实现,并使用 raw TCP 或者 http2 (gRPC) 和 application layer 通讯。

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

周日,闲来无事,想用 tendermint 做点东西。无奈 tendermint 没有提供 elixir 的 ABCI 实现,社区的 erlang 实现又缺失一些东西,且我很不喜欢 erlang 下用 Record 来描述 protobuf 的方式,于是用 Tony 的 protobuf 库,写了个 elixir 的 ABCI 实现,放在 github.com/arcblock/ex_abci 上,并随后实现了 Tendermint 自身提供的 counter example app - 用区块链的不可篡改性来维护一个全网唯一的计数器。

使用 ex_abci,counter app 的核心代码也就几十行,就是实现 info,check_tx,deliver_tx 几个接口即可:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

这样的 app 当 hello world 还可以,用来验证 Tendermint 是否靠谱,本身并不靠谱。Tendermint 还提供了一个 kv store 的 example,也没有 get 到区块链的核心要素,于是我便萌生了搞一个足够简单,最好能在几百行内演示区块链技术的 Simple Chain。那什么算是区块链的核心要素呢,我觉得是这幅图 - Merkle Patricia Tree (MPT):

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

这是以太坊保存其 World State 的核心 - 我相信我的读者们了解 patricia tree (prefix tree, radix tree, 或者叫 trie),有一些区块链知识的读者应该知道 merkle tree,MPT 结合二者,组织出一个自带验证的 persistent data structure(函数式编程语言保存 list / map 的方式),关于 MPT 和以及上图,我们的工程师丁沛灵同学在上次北京 Hackathon 有一个精彩的讲座,感兴趣的同学可以去 youtube arcblock channel 上找:ArcBlock’s Introduction to Blockchain,在 37 分钟附近开始讲 MPT,大约 10 分钟,非常之深入浅出。篇幅有限,我这里就不详细展开。

看不了 youtube ,点这个腾讯视频也是一样的:)

关于 Simple Chain,产品上我是这么考虑的:

  1. 账号系统兼容以太坊

  2. 完整使用 Tendermint 的全部接口,并探索它们的意义

  3. chain 的状态使用 MPT 保存,并将每个 block commit 后的 state root 提交给 Tendermint

  4. chain 能够具有基本的容错 - 比如 tx 执行到一半,crash 了,可以恢复到上一个 block 的 state 继续往下执行

  5. Transaction 使用简化版本的 Ethereum tx,一个 TX 只包含 from, to, nonce, total 和 pub key

  6. MPT 里保存类似 Ethereum 的 account,每个 account 有自己的 balance,nonce 和 num_txs

  7. client RPC 直接整合在 Wallet 模块里,方便演示

花了两天的功夫,一个粗糙的,未经过多节点测试的版本终于实现了,源码见:ex_abci/examples/simple_chain。我们谈谈其主要对外接口:

  1. Wallet.new: 生成离线账号

  2. Wallet.declare: 每个 Wallet 第一次可以让系统给自己打 10000 个 token,这个主要方便测试

  3. Wallet.transfer:一个账户给另一个账户打钱。两方的 address 对应的 account 会在 chain 的 MPT 里更新,每个 block commit 之后,MPT root,也就是 app state 会写入 block header。

  4. Wallet.info / Wallet.chain_info:访问 account 的信息 / chain 的信息

下面是运行时的整个过程。

初始化:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

Wallet 状态:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

转账:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

Tendermint block:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

转账结束后的状态:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

这个 Simple Chain 主要使用到的技术:

  1. Tendermint 和 ex_abci,这是自然

  2. Elixir 下的 MPT 实现:merkle_patricia_tree

  3. Tony 的 protobuf 实现。我们在 MPT 里存储 account,其 value 也是用 protobuf 定义的

  4. keccakf1600:ethereum 的 sha3 的实现,用来产生 account address 和各种需要 hash 的场合(注意,我们这里并没有使用 double hash)

  5. libsecp256k1:ECDSA 的实现,主要用来生成 wallet,以及 transaction 的 sign 和 verify

目前代码量在 400 行内,基本上一目了然,用来理解 Tendermint 和区块链技术的基本逻辑再好不过。感兴趣的读者可以安装 tendermint,下载 github.com/arcblock/ex_abci 尝试。

本来这篇文章想赶在 1024 节前发的 - 昨晚(24日)我处理 crash recovery 没有处理好,今早开车穿越 90 号高速上的迷雾时,突然有了思路,所以文章发晚了。对这些技术感兴趣的同学,可以在 https://hack.arcblock.io/learning/(点击“阅读原文”)上面报名我们未来的 Tech Talk,以及关注 arcblock 的 youtube channel 获取我们之前的知识分享。

祝大家 1024 节快乐!

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

ArcBlock 区块链技术培训系列讲座

今天(10月30日)起正式登陆掘金(juejin.im/events)

ArcBlock Technical Learning Series 第六期

CQRS & Commanded

明天,10 月 31 日下周三上午 8 时 (美国太平洋时间 30 日下午 5 时),由 ArcBlock 软件工程师 周蕾 授课——

在常用的架构中,通常是通过数据访问层来修改或者查询数据,一般修改和查询使用的是相同的实体。在一些业务逻辑简单的系统中可能没有什么问题,但是随着系统逻辑变得复杂,这种设计就会出现一些性能问题。

CQRS全称是:Command Query Responsibility Segregation,即命令查询职责分离。该模式从业务上分离修改和查询的行为。从而使得逻辑更加清晰,便于对不同部分进行针对性的优化。

本期讲座跟你聊一聊——基于CQRS和Commanded库,来做Elixir程序开发。

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

主 讲

周 蕾

ArcBlock 软件工程师

●  美国东北大学毕业

●  信息系统计算机专业硕士

●  区块链热爱者

●  编程语言:Elixir JavaScript Python

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

报名听课,登录官网注册:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

https://hack.arcblock.io/learning/

或登陆掘金注册:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

https://juejin.im/events/all

或扫描二维码注册:

ArcBlock 博客 | 如何用不到 400 行的代码写出一条主链?

ArcBlock 课堂 ① | Intro to GraphQL and Absinthe

ArcBlock 课堂 ② | Intro to Ethereum Smart Contract

ArcBlock 课堂 ③ | Intro to AWS Data Pipeline Services

ArcBlock 课堂 ④ | Intro to AWS Athena

ArcBlock 课堂 ⑤ | What is AWS Kinesis

ArcBlock 课堂 ⑥ | 多步验证那些事 (全程视频 + 文字)

ArcBlock 课堂预告 | 是的,我们将开放大部分技术讲座

相关文章:

  • 2022-12-23
  • 2021-12-23
  • 2021-06-30
  • 2021-10-02
  • 2021-06-17
  • 2021-12-23
  • 2022-01-16
猜你喜欢
  • 2021-08-16
  • 2022-03-04
  • 2021-11-29
  • 2021-12-03
  • 2022-12-23
  • 2021-09-13
相关资源
相似解决方案