主页 > imtoken官网下载 > 回声 | 以太坊的设计理念,Part-1

回声 | 以太坊的设计理念,Part-1

imtoken官网下载 2023-06-17 07:18:25

编者按:本译文的第一版于 2010 年出版。本次重印已经过校对。 在此向原译者 Kim 表示感谢。

原文的写作时间不详,但可以作为一个起点来反思以太坊的设计理念以及以太坊过去几年的演进。 既要反思其创新,又要反思其考虑不足。

尽管以太坊的许多概念已经在早期的加密货币(如比特币)上使用和测试了五年,但在以太坊中处理某些协议功能的方式仍然存在许多差异。 此外,以太坊可用于开发全新的经济工具以太坊交易信息获取,因为它具有许多其他系统所没有的功能。 本文将详细描述以太坊的所有潜在优势,以及在构建以太坊协议过程中的一些争议点。 此外,还将指出我们的解决方案和替代解决方案的潜在风险。

原则

以太坊协议的设计遵循以下原则:

Sandwich Complex Model(又译为“复杂性分层模型”):我们认为以太坊的底层协议应该越简单越好,接口设计应该通俗易懂(无论是面向开发者的高层编程语言界面或面向用户的使用界面)。 那些不可避免的复杂部分应该放在中间层。 中间层不是核心共识的一部分,对最终用户是不可见的。 它包括:高级语言编译器、参数序列化和反序列化脚本、存储数据结构模型、leveldb存储接口和网络协议。 当然,区分线并不是绝对明确的,有时需要酌情调整。 自由:不应限制用户使用以太坊协议,也不应试图赞成或不支持某些以太坊合约或交易。 这类似于“网络中立”概念背后的指导原则。 比特币交易协议不遵循这个原则:比特币交易协议不鼓励区块链的“off-labal purpose”(例如,数据存储,元协议)(校对注:off-labal的初衷是使用用于其批准适应症以外的症状的药物,例如使用咳嗽药治疗头痛。这里,它被解释为“非常规使用”); 并且,有时,一些人使用准协议层更改(例如,将 OP_RETURN 字段的长度限制为 40 字节)来攻击以“未经授权”的方式使用区块链的应用程序的倾向)。

以太坊交易信息获取_以太坊在中国交易合法吗_以太坊币交易网站

因此,在以太坊中,我们坚决支持仅使用交易费用来实现大致激励相容的方法——用户在整个网络中消耗的资源越多,需要支付的价格就越高,即使他们自己承担成本(即Pigou)税)。 泛化:以太坊协议的特性和操作码应该最大化低级概念(如基本粒子),以便它们可以随意组合,包括组合今天看起来没用但将来可能有用的东西。 此外,可以通过剥离不需要的功能来提高低级概念的效率。 遵循这一原则的一个例子是我们选择 LOG 操作码作为向 dapp 提供信息的方式,而不是像以前那样记录所有交易和消息。 在早期,“消息(message)”的概念完全是各种概念的集合,其中包括“函数调用(function call)”和“外部观察者感兴趣的事件信息(event)”,两者是完全可分离。 没有特性就是最大的特性:为了遵循泛化的原则,我们拒绝将那些高级用例作为协议的一部分嵌入,即使是经常使用的用例,我们也永远不会这样做。 如果真的想实现这些用例,可以在合约中创建子协议(例如,基于以太坊的子货币、比特币/莱特币/狗狗币侧链等)。 例如,以太坊缺乏类似于比特币的“时间锁定”功能。 但是这个功能可以通过下面的协议来模拟:用户将一个签名的数据包发送给特定的合约进行处理,如果数据包在特定的合约中有效,则执行相应的功能。 不规避风险:如果增加的风险带来可衡量的收益(例如,常见的状态转换、出块时间减少 50 倍、共识效率等),我们愿意承担更高的风险。 这些原则指导着以太坊的发展,但并不是绝对的; 在某些情况下,为了减少开发时间或者不想一下子做太多的改动,也会让我们延迟做某些改动,留待以后的版本去修改。

区块链层协议

本节介绍以太坊区块链层协议的变化,包括区块和交易如何工作,数据如何序列化和存储,以及账户背后的机制。

Accounts, not UTXO1 比特币及其众多变体将用户的余额信息存储在 UTXO 结构中,系统的整个状态由一系列“未花费的输出”组成(你可以将这些“未花费的输出”想象成币)(校对笔记:一个更好的比喻可能是“支票”。)。 每个 UTXO 都有一个所有者和它自己的值属性。 一笔交易在消费若干个UTXO的同时,会产生若干个新的UTXO; 且交易受以下有效性要求约束: 1. 每个引用的输入必须有效且未使用; 2.交易的签名必须与每个输入的所有者签名相匹配; 3. 输入的总值必须等于或大于输出的总值。 因此,在比特币系统中,一个用户的“余额”是该用户的私钥可以有效签名的所有UTXO的总和。 下图展示了比特币系统中的交易输入输出过程:

以太坊交易信息获取_以太坊币交易网站_以太坊在中国交易合法吗

以太坊在中国交易合法吗_以太坊交易信息获取_以太坊币交易网站

- 比特币使用的三式簿记 -

不过,以太坊放弃了UTXO方案,转而采用更简单的方法:利用状态(state)的概念来存储一系列账户,每个账户都有自己的余额,以及以太坊特有的数据(代码和内存)。 如果交易发起人的账户余额足以支付交易费用,则交易有效,相应的金额将从发起人的账户中扣除并记入接收账户。 在某些情况下,如果接收账户中有需要执行的代码,交易会触发代码的执行,那么账户的内部内存可能会发生变化,甚至可能会创建额外的消息发送到其他账户,导致新的交易发生。 虽然以太坊没有采用 UTXO 的概念,但是 UTXO 有一些优点: 隐私保护程度更高:如果用户每次交易都使用新地址,则很难关联账户。 这适用于对安全性要求高的货币系统,但不适用于任何dapp。 因为dapps通常需要跟踪用户复杂的绑定状态,dapps的状态不能像货币体系中的状态那样简单划分。 潜在的可扩展性:理论上,UTXO更适合某些类型的可扩展性方案(scalability paradigm),因为只有持有者需要有默克尔证明才能证明他们的货币所有权,即使所有的人(包括TA自己)都忘记了这个数据,而且这个人真的受到了伤害,其他人没有受到影响。

在以太坊账户体系中,如果每个人都丢失了Merkle树对应一个账户的部分,那么这个账户将无法处理任何能影响到它的消息,包括发送给它的消息,它也无法处理它。 但是,UTXO并不是唯一可以扩展的,还有不依赖UTXO扩展的方法(这里不做扩展,译者注)。 账户的好处如下: 节省大量空间:如果一个账户有 5 个 UTXO,从 UTXO 模式转换为账户模式,所需空间将从 300 字节减少到 30 字节。 具体计算如下:300 = (20+32+8) * 5(20为地址字节数,32为TX id字节数,8为面额占用字节数); 30 = 20 + 8 + 2(20为地址字节,8为账户余额值字节,2为nonce 2字节); 但实际节省的并不多,因为账户需要存储在帕特里夏树中。 此外,以太坊中的交易比比特币小(以太坊为 100 字节,比特币为 200-250 字节),因为每笔交易只需要生成一个引用、一个签名和一个输出。 互换性更强:UTXO结构没有区块链层的概念,所以无论从技术上还是法律上,建立红名单/黑名单,根据这些“有效输出”的来源来区分,都不太实用。

简单性:以太坊编码更简单、更容易理解,尤其是当涉及到复杂的脚本时。 虽然任何去中心化应用程序都可以(勉强地)使用 UTXO 实现,但这种方法本质上是授权脚本限制给定 UTXO 可以输出的 UTXO 的类型及其使用条件(例如,它需要包含 Merkle 树证明以帮助脚本的相应的应用程序更改状态根)。 因此,UTXO 的实现要比以太坊使用账户的方式复杂得多。 轻客户端:轻客户端可以通过指定方向扫描状态树,随时访问与账户相关的所有数据。 在UTXO范式中,每笔交易都需要使用不同的引用,这对于使用上述UTXO根状态传播机制的长时间运行的dapp应用来说无疑是沉重的负担。 我们相信账户的好处远远超过其他选择,特别是对于我们想要支持的可以包含任意状态和代码的 dapp。 此外,本着“没有特色就是最大特色”的指导原则,我们相信如果用户真的很在意隐私,他们可以通过合约中的签名数据包协议构建一个加密的“mixer and coinjoin”混淆支付路径。 账户方式的一个弱点是,为了防止重放攻击(replay attacks,即重复执行同一笔交易),每笔交易都必须有一个“nonce”(序号)。

因此,每个账户都必须有一个实时更新的nonce值以太坊交易信息获取,每笔新的交易都会将账户的nonce值加1作为自己的nonce(并在交易处理后用这个值更新账户的nonce值)(校对注:在账户模式,如果交易没有附加这个消耗性标识符,则交易可以重复处理,这样收款账户就可以一遍又一遍地收账,不需要支付任何费用,而发送账户就会被吸干;以太坊账户的 nonce 在处理发起的交易时递增,这解决了这个问题)。 这意味着即使不再使用的帐户也无法从帐户状态中删除。 这个问题的一个简单解决方案是让交易包含一个块号,使它们在一段时间后无法恢复,并且每隔一段时间重置随机数。 如果要删除状态下的账户(比如很久没有使用的账户),必须先把它们“ping”出来,全盘扫描区块链协议的开销非常大。 我们在1.0上没有实现这个机制,1.1及以上版本可能会用到这个机制。 校对注:这是以太坊未来将面临的“状态爆炸”问题的技术原因:必须完整保存所有状态数据,不能合理删除账户。 作为一个区块链协议,以太坊的节点不仅要对交易(交易)的顺序达成共识,还要对全局状态达成共识(表现形式是状态根需要包含在区块中header。因此,要删除状态,也需要全网的共识,否则会陷入分裂。校对注意:这种使用nonce来标记账户交易顺序的方式,也使得用户的交易必须执行依次执行。如果一笔交易无法处理,后续使用 nonce 的交易也将无法处理。“加速”已发送交易的链上进度,请参见 。

以太坊币交易网站_以太坊在中国交易合法吗_以太坊交易信息获取

Merkle Patricia tree (MPT) Merkle Patricia 树/trie,由 Alan Reiner 构想并在 Ripple 协议中实现,是以太坊的主要数据结构。 它用于存储所有帐户状态,以及每个块中的交易和收据数据。 MPT 是 Merkle 树和 Patricia 树的组合。 这两种树组合而成的结构具有以下性质:任意一组键值对对应的根哈希值是唯一的,你想说谎某棵树中某个键值对的存在肯定会被发现(除非攻击者拥有大约 2^128 的计算能力)。 添加、删除和更改键值对的时间复杂度是对数的。 MPT 为我们提供了一个高效、易于更新的“指纹”,代表了整个状态树。 关于 MPT 的更详细描述: 。 MPT 的具体设计决策如下: 节点有两种类型:KV 节点和离散节点。 KV节点的存在提高了效率,因为如果树在某个区域是稀疏的,KV节点可以作为压缩树高的“捷径”(更多细节请阅读MPT的详细描述)。 离散节点是十六进制的,而不是二进制的:这使得查找更有效率,我们现在意识到这种选择并不理想,因为十六进制树的查找效率可以通过批量存储节点来模拟二进制。 然而,MPT 树结构的实现非常容易出错,最终至少会导致状态根不匹配,因此我们决定将更改搁置到 1.1。

不区分空值和非成员:这样做是为了简化逻辑,以太坊中未启用的账户的值(余额)默认为0,空字符串也用0表示。但是,应该强调的是,这牺牲了一些通用性,因此不是最优的。 终止节点和非终止节点的区别:从技术上讲,没有必要去标识一个节点“是否是终止节点”,因为以太坊中所有的树都是用来存储定长(即密钥长度)数据的,但是为了有序为了增加通用性,我们仍然会加上这个标志,希望以太坊的MPT的实现可以被其他加密货币照原样采用。 在“安全树”(状态树和账户存储树)中使用SHA3(k)作为key:使用SHA3(k),你要生成很多账户(账户最多可以让状态树达到64级!)并重复call SLOAD 和 SSTORE 操作码使 DoS 攻击变得更加困难。 请注意,这也使得枚举树变得更加困难; 如果您希望您的客户端能够枚举,最简单的方法是维护一个数据库映射 sha3(k) -> k。 校对注:这里的意思是,如果用k作为Merkle树的key来存储数据,它的分布可能会很稀疏,攻击者可以很容易地规划出需要深树路径存储的账户,并对这些账户进行攻击重复调用状态访问操作会导致网络中的节点过载。 然而,散列函数的结果是随机分布的。 使用sha3(k)作为key可以让key分布更均匀,树高也会更短)。

此功能也有优点和缺点。 一方面,这意味着 DoS 攻击将变得更加困难。 另一方面,也使得一个区块中交易的状态树访问路径很少重叠。 因此,每次搜索都是最坏情况下的复杂度。 此外,这也使得 MPT 不适合实现“无状态”(区块本身携带验证所需的数据,验证者不需要拥有全局状态),因为状态访问的路径不重叠,并且证据的空间效率也是最坏的情况。当然也可以说Merkle树证据本身的空间效率不够高

RLPRLP (recursive length prefix):递归长度前缀。 RLP 编码是以太坊中主要的序列化格式,无处不在:区块、交易、账户状态和网络协议消息。 详见RLP​​官方描述:RLP旨在成为一种高度简化的序列化格式,其唯一目的是存储嵌套的字节数组3。 与现有的protobuf、BSON等解决方案不同,RLP没有定义任何指定的数据类型,如Boolean(布尔值)、float(浮点数)、double或integer(整数)。 它只是以嵌套数组的形式存储结构,数组的含义由协议来决定。 RLP 也不明确支持地图集合。 半官方的建议是使用 [[k1, v1], [k2, v2], ...] 的嵌套数组来表示键值对集合,k1, k2 ... 按照字符串的标准排序。 和RLP功能相同的一个方案是protobuf或者BSON,都是一直在用的算法。 然而,在以太坊中,我们更喜欢使用 RLP,因为:(1)它易于实现; (2) 绝对保证字节一致性。 许多语言没有键值对集合的显式排序,浮点格式有许多特殊情况,可能导致相同数据的不同编码和不同哈希值。 通过在内部开发协议,我们可以确保在设计时考虑到这些目标(这是一个通用原则,也适用于代码的其他部分,例如虚拟机)。 BitTorrent 使用的编码方法 bencode 可能是 RLP 的替代方法。 但它采用十进制编码方式,略逊于二进制RLP。

压缩算法 网络协议和数据库都使用自定义压缩算法来存储数据。 该算法可以描述为:对0使用长度编码4,同时保留其他值(除某些特殊情况如sha3(' ')),例如如下:

以太坊在中国交易合法吗_以太坊交易信息获取_以太坊币交易网站

>>> compress('horse')'horse'>>> compress('donkey dragon 1231231243')'donkey dragon 1231231243'>>> compress('\xf8\xaf\xf8\xab\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe{b\xd5\xcd\x8d\x87\x97')'\xf8\xaf\xf8\xab\xa0\xfe\x9e\xbe{b\xd5\xcd\x8d\x87\x97'>>> compress("\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p")‘\xfe\x01'

在压缩算法出现之前,以太坊协议中很多地方都有一些特例。 例如,sha3经常被重新定义为sha3(' ')=' ',这样就节省了64个字节,而无需在帐户中存储代码。 然而,最近,所有这些导致以太坊数据结构臃肿的特殊情况都被删除了,取而代之的是,数据保存功能被添加到区块链协议之外的层中,即添加到网络协议中,并添加到其插入用户数据库实现中。 这增加了模块化能力,简化了共识层,并且使得压缩算法的持续更新部署相对简单(例如,可以通过网络协议的版本号来区分和部署)。

树(trie)的使用提示:要理解这部分知识,读者需要了解布隆过滤器5的原理。介绍可以看到:以太坊区块链中的每个区块头都包含指向三棵树的指针:状态树、交易树和收据树。 交易收据是一个RLP编码的数据结构:

[ medstate, gas_used, logbloom, logs ]

在:

以太坊币交易网站_以太坊在中国交易合法吗_以太坊交易信息获取

区块头中还有一个布隆过滤器,它是区块中所有交易的布隆过滤器进行或操作(OR)的结果。 这种结构使得以太坊协议对轻客户端极其友好。 注:UTXO:unspent transaction outputs,字面意思:unspent transaction outputs,即未被任何交易引用为输入的交易输出。 它是比特币协议中用于存储价值(所有权)信息的数据结构。 —— 校对笔记 Nonce,Number used once 或 Number once 的缩写,在密码学中,Nonce 是只使用一次的任意或不重复的随机值,加密技术中的初始向量和加密哈希函数都起到了一定的作用。作用 在各种认证协议的通信应用中起着重要作用,保证认证信息不被重复使用,以对抗重放攻击(Replay Attack)。 ——译者注 嵌套数组:创建一个数组,用其他数组填充。 比如阵宠:

var cats : String[] = ["Cat","Beansprout", "Pumpkin", "Max"];
var dogs : String[] = ["Dog","Oly","Sib"];
var pets : String = [cats, dogs];

——译者注 游程编码(run-length-encoding):一种统计编码。 主要技术是检测重复的位或字符序列,并用它们出现的次数替换它们。 (百度百科) - 译者注 Bloom filter:由Howard Bloom于1970年提出的一种二进制向量数据结构,具有良好的空间和时间效率,用于检测一个元素是否是集合的成员。 (百度百科)-译者注

(未完)

(本文链接较多,可点击左下方“阅读原文”从EthFans网站获取)

原文链接: