Tendermint: 什么是 ABCI (应用区块链接口)

区块链应用接口(Application BlockChain Interface,ABCI)允许应用的拜占庭容错复制可以由任意一种编程语言编写。

Motivation

至今为止,所有的区块链“栈”(比如,比特币)都有着大一统的设计。这就是说,每个区块链栈都是一个单一的程序,这个程序处理了去中心化账本的所有事务。它还包括了 P2P 连接,交易的“内存池”广播,在最新块上的共识,账户余额,图灵完备的合约,用户级别的许可权等。

在计算机科学中,使用大一统的架构,是一个典型的错误实践。这会使得代码重用变得困难,而且如果真的去这么做时,会导致代码库分支的维护变得十分复杂。尤其当代码设计并非模块化时,会产生难以维护的“意大利面条式代码”。

大一统设计的另一个问题是,它限制了区块链栈的语言。比如在以太坊中,它支持一个图灵完备的字节码虚拟机,它限制你必须使用可以编译为那种类型字节码的语言。目前,它所支持的语言是 Serpent 和 Solidity。

相反,我们的方式是从特定区块链应用的应用状态细节中,将共识引擎和 P2P 层分离开来。我们通过将应用细节抽象为一个借口来实现这一点,这个接口被实现为一个 socket 协议。

所以,我们就有了一个接口,应用区块链接口(ABCI),和它的主要实现,Tendermint Socket Protocol (TSP, 或 Teaspoon)。

Intro to ABCI

Tendermint Core (“共识引擎”)通过一个满足 ABCI 标准的 socket 协议与应用进行交流。

举个大家比较熟悉的例子,比特币。比特币是一个加密货币区块链,其中的每个节点维护了一个完全经过审计的 UTXO 数据库。如果有人想要在 ABCI 之上创建一个类似比特币的系统,Tendermint Core 将会负责:

  • 在节点间共享区块和交易
  • 建立交易(区块链)的标准/不可变顺序

而应用将会负责:

  • 维护 UTXO 数据库
  • 验证交易的加密签名
  • 阻止花费尚未存在的交易
  • 允许客户端查询 UTXO 数据库

Tendermint 能够通过在应用过程和共识过程之间,提供一个非常简单的 API (也就是 ABCI)来分解区块链设计。

ABCI 包含了 3 个主要的消息类型,它们由 core 发送至应用。应用会对消息产生相应的回复。

消息的详细说明在这里:ABCI 消息类型。

DeliverTx 消息是应用的主要部分。链中的每笔交易都通过这个消息进行传送。应用需要基于当前状态,应用协议,和交易的加密证书上,去验证接收到 DeliverTx 消息的每笔交易,。一个经过验证的交易然后需要去更新应用状态 – 比如通过将绑定一个值到键值存储,或者通过更新 UTXO 数据库。

CheckTx 消息类似于 DeliverTx,但是它仅用于验证交易。Tendermint Core 的内存池首先通过 CheckTx 检验一笔交易的有效性,并且只将有效交易中继到其他节点。比如,一个应用可能会检查在交易中不断增长的序列号,如果序列号过时,CheckTx 就会返回一个错误。又或者,他们可能使用一个基于容量的系统,该系统需要对每笔交易重新更新容量。

Commit 消息用于计算当前应用状态的一个加密保证(cryptographic commitment),这个加密保证会被放到下一个区块头。这有一些比较方便的属性。现在,更新状态时的不一致性会被认为是区块链的分支,分支会捕获所有的编程错误。这同样也简化了保障轻节点客户端安全的开发,因为 Merkel-hash 证明可以通过在区块哈希上的检查得到验证,区块链哈希由一个 quorum 签署。

一个应用可能有多个 ABCI socket 连接。Tendermint Core 给应用创建了三个 ABCI 连接:一个用于内存池广播时的交易验证,一个用于运行提交区块时的共识引擎,还有一个用于查询应用状态。

很显然,在创建区块链时,应用的设计者需要非常小心地设计他们的消息处理,这个架构提供一个范例。下图阐释了通过 ABCI 的消息流:

Tendermint: 什么是 ABCI (应用区块链接口)_第1张图片

A Note on Determinism

区块链交易处理的逻辑必须是确定性的。如果应用逻辑不确定,就无法在 Tendermint Core 复制节点间达成共识。

在以太坊上的 Solidity 是用于区块链应用一个非常好的语言选择,除了一些其他因素,它还是一个完全确定性的编程语言。但是,通过使用现有的一些语言,比如 Java,C++,Python 和 Go 也是可以创建确定性应用的。对通过避免非确定性来源创建确定性程序,游戏程序员和区块链开发者都已经很熟悉了,比如:

  • 随机数生成器(没有确定性的种子)
  • 线程上的竞争条件(或者避免多线程)
  • 系统时钟
  • 未初始化的内存(在像 C 或者 C++ 这样的不安全语言)
  • 浮点数算法
  • 随机的语言特性(比如 Go 语言的 map 迭代)

尽管程序员可以通过加倍小心来避免非确定性,但是给每个语言创建一个特殊的语法检查器或静态分析器,用它们来检查确定性也是有可能的。在未来,我们可能会与合作者一起创造出这样的工具。

本文译自:What is ABCI?

你可能感兴趣的:(Bitcoin,区块链技术研究)