以太坊是比特币的全面改进, 以太坊从2014年初次开始众筹,其主要卖点就是”智能合约”.
所以”智能合约” 是主导以太坊设计架构的核心理念, 沿着这个核心理念出发, 我们就很容易厘清整个以太坊的设计脉络.
首先”智能合约”的最终目标是实现去中心化应用(DAPP), 所以决定了底层是构建在传统区块链的基础设施之上,
智能合约与账户类型/账户状态转换
首先 Merkle Tree 的天然属性 就使得在新旧区块之间的只用存储变化了状态子树,而不是重新存储整个结构.
为了防止构造恶意的数据结构, 使用Keccake256散列值做为树的键值, 这一就导致了使用Patricia Tree做为优化的必要性.
于是Secure MPT这个拧巴的数据结构就诞生了
比特币以及其变种, 使用了一种特殊的账户状态转换模型 UTXO unspent transaction outputs. 整个系统的收支状态信息都保存在所有这些UTXO中. 在每一个交易中都会消耗一部分UTXO,然后再产生一些新的UTXO, UTXO 是和用户地址绑定的.
UTXO 带来一个问题, 智能合约需要一个执行的主体.在UTXO模型中, 同一个主体可以拥有多个地址, 对于智能合约而言, 最简单直接的方案还是使用单一账户模型而不是UTXO,尤其是在引入Gas来限制计算工作量之后, 如果智能合约还需要去实时计算(和解锁)多地址的UTXO可用token数量来判断合约是否可以继续执行,就太繁琐低效了. 最终以太坊采用的是合约账户这一单一的执行主体, 同时为了配合合约账户, 外部账户也使用单一的账户记账模式.简化了设计. 因为执行合约时, 同样外部账户需要转账支付Gas以执行合约.
同时还要考虑到节省空间,UTXO本身就非常占用空间, 因为同一个用户可能需要引用多个UTXO, 以太坊加入了智能合约, 那么增加了很多其它的metadata要存储(例如输入数据, log)必须要找到一个节省空间的方案.
单一账户模式需要引入nonce来防止重放攻击, 所以这里也做了防御性的设计.
引入了单一账户模式后, 整个存储状态的数据结构得设计也就自然而然的引入了基于Secure Merkle Patricia Tree的设计.
智能合约要求图灵完备的解决方案.
灵活的智能合约编程语言当然最好是图灵完备的. 但是图灵完备就需要计算每一个指令消耗的计算资源(防止滥用,例如deadloop),于是Gas的设计就应运而生.
考虑到合约间调用等各种复杂场景, 引入了非常多的规则来规范Gas的消耗量计算. (整套规则非常复杂,例如合约suicide 这个场景)
合约执行会在中途失败, 也需要引入各种log以备回滚.
同时这个Gas必须要和token链接起来, 所以Gas还有一个价格, 当然是以ether来计算的.
同时也导致整个块的大小不是固定的, 而是由这个块整体所能包含的Gas数量来决定的.
智能合约执行的虚拟机.
因为智能合约最终的主要一个作用就是根据特定的编写的逻辑,来更改对应的全局存储, 例如余额. 但是同时还是需要许多临时的状态来辅助. (临时状态访问比较快捷)
为了执行智能合约就需要区分全局存储和临时存储. 临时存储的生命周期只限于虚拟机实例开始执行到执行结束. 永久存储以每个账户为划分单位存在于区块链上(storage trie)
要负责进行所有的Gas规则的检查.
要向智能合约编程语言提供所有的全局状态量查询结构.
需要提供特定的密码学计算接口.比如keccak
智能合约的编程语言除了基本的功能以外.
理所当然的,这个编程语言需要是面向合约的.
合约也理所当然的应该有一个创建人和所有人.
合约应该可以接收转账,也可以向其它合约和外部账户转账.
该编程语言需要区分全局存储和临时存储
该编程语言需要一个便捷的对外接口ABI
该编程语言的设计必须是安全的, 合约是可以形式化验证的.
综上所述, 智能合约的概念影响到以太坊所有关键组件的设计, 渗透到了每一个具体的设计之中, 只要抓住这一个核心理念, 提纲携领,顺藤摸瓜, 就会大大加速你对以太坊设计框架的理解.
深入以太坊课程更新结束,大家可以集中两天完成课程。答疑请大家加入《区块极客》知识星球社区,目前已经聚集1500多区块链开发者。
网易报名,请扫码如下二维码:
答疑请扫码加入社区。