学习笔记之以太坊
以太坊:下一代的智能合约和去中心化应用程序平台
A Next-Generation Smart Contract and Decentralized Application Platform
智能合约(Smart Contract)
智能合约指的是一种基于计算机技术实现的,可以免除人工干预而自动执行、自动校验、自动基于外部指令给出回应的具有交互性或者互操作性的合约;其本质是一种计算机程序。是基于某些公开的、众所周知的规则,能够根据用户的指令和实际业务数据的状态给出可预期的回应的这样一种应用程序。
特性:这个过程是“无需信任(trustless)”的。也就是合约双方不需要相互认识乃至相互信任,而是基于一种不可篡改、不可抵赖、不可逆转的自动化的技术方案保证了整个过程的可信性,同时不需要任何第三方的介入。
智能合约可以理解为一种会经过“技术公证”的状态存储和状态转换(也就是程序执行),以此来确保这个过程“无需信任”。
去中心化应用程序(Decentralized Application)
将数据保存到“基于点对点网络的时间戳服务器(即区块链)”这样的,并不是由中心化的公司或组织控制的服务中,并且由这样的“去中心化”服务来提供具体的业务数据计算能力的一种应用程序。“去中心化应用程序”也可以简单地理解为是基于智能合约进行状态追踪和计算的一种应用程序。
以太坊的开创意义在于:它借鉴了由比特币系统创造出来的“通过工作量证明算法达成共识的、基于点对点网络的时间戳服务器”(也就是所谓的“区块链”),构建出了一种可以执行“通用目的”计算任务的基础设施,将“区块链”的可编程性提升到了一个新的高度;创造出了真正的“智能合约”平台。
区块链范式(blockchain paradigm):Apply(S, tx) = S',其中的 Apply 即“状态转换函数”。
从技术层面讲,我们可以把类似于比特币这样的、通过分布式共识进行“技术公证”的公共账本系统(也就是所谓的“区块链”)抽象地理解为一个“状态转换系统(state transition system)”。这种系统会维持一个“全局的状态”(我们用 S 来表示),然后通过系统中发生的“交易”(我们用 tx 来表示)来进行相应的状态转换以达到一个“新的全局状态”(我们用 S' 来表示)。
这是一个通用的范式,它适用于比特币,也适用于以太坊,并且同样适用于其他类似于比特币和以太坊这样的基于“区块链”的分布式共识账本系统。而不同的区块链系统的差别就在于如何表示系统中的状态以及如何定义状态转换函数(也就是交易)。
UTXO (Unspent Transaction Output)
比特币中的交易都是由若干输入(Input)和若干输出(Output)组成的。按照协议约定,一个输入必定是某个历史交易的某个输出的引用,通过在输入中包含特定的“解锁脚本(unlocking script)”来对历史交易的输出中指定的“锁定脚本(locking script)”进行解锁,以此来“消耗/使用(spend)”相应的输出。那些未被任何“输入”引用过的“输出”就是 UTXO。
比特币系统其实就是一个对当前系统中所有可用的 UTXO 的状态记录,它通过一个具体交易来对当前可用的若干 UTXO 进行合并和拆分来生成新的 UTXO,并将系统状态转换为新的 UTXO 集合;同时,这个过程是在一个点对点网络中进行“全网公证”的。
“区块链”,其实就是一个通过交易来触发状态变动,并以区块为单位来记录状态变动的状态转换系统。
以太坊的账户模型:
用“地址(address)”来作为账户的全局唯一标识
逻辑上分为两种:EOA(External Owned Account,即由外部用户基于椭圆曲线数字签名的私钥控制的账户)和 Contract Account(即合约账户)。
不过从基础数据上看,这两种账户是一样的,它们的区别仅在于账户是否与合约代码相关联:如果一个账户没有关联代码,它就是 EOA;否则它就是合约账户。
对于自定义状态机来讲,需要持久化保存的应该是自定义状态数据和用来修改状态数据的可执行代码,这其实就是所谓的“合约状态”和“合约代码”。
基于账户模型,以太坊使用了一个全局的数据结构来保存所有的合约状态和合约代码。因为合约是可以由用户自定义的,所以保存这些数据的数据结构必须是可以进行高效的动态查找、增删和修改的,并且是可以进行简单验证的。以太坊中就使用了一种叫做 Merkle Patricia Tree(简称 MPT)的数据结构来实现这一点。
MPT:任意叶节点数据的变动都会导致根节点哈希的变动,所以根节点哈希可以用来标识树中所有数据的某个特定的版本。
基于这个原理,就可以在点对点网络的参与者之间通过由各个客户端分别维护的一个全局 MPT 的根节点哈希来验证所有自定义状态数据、账户余额和代码数据的版本一致性。这个全局的 MPT 也就是以太坊的“状态树(state tree)”,它相当于比特币系统中所有可用 UTXO 的全集。
以太坊的持久化数据存储方案:以太坊中的每个合约账户都可以在“存储”中使用若干“存储单元(storage slot)”:每个合约的代码中可以自定义若干状态数据,每个状态数据对应一个或多个“存储单元”;这些存储单元都可以通过简单的寻址算法进行存取操作。
以太坊中的状态转换:
图中演示了以太坊中的一个由交易引发的状态转换:在初始状态 State 中,14c5f8ba、bb75a980、892bf92f 和 4096ad65 代表了 4 个账户地址,其中 14c5f8ba 和 4096ad65 是 EOA,bb75a980 和 892bf92f 则为合约账户(因为有关联代码)。然后图中所示的交易,其逻辑意义也很简单,即从 14c5f8ba 向 bb75a980 发送 10 以太币,并附加了一些额外的数据 Data,这个 Data 数据的意思是将目标合约的第 2 个“存储单元”的数值设定为“CHARLIE”。这个交易的执行会产生一个新的状态 State',其中 14c5f8ba 地址的余额减少了 10 以太币,bb75a980 地址的余额增加了 10 以太币,并且 bb75a980 地址的第 2 个“存储单元”的数值变为了“CHARLIE”。
以太坊中的可执行代码:
在交易的 data 字段中附加一种特殊的“可执行代码”来完成任意的计算任务,这种“可执行代码”是在一个虚拟的执行环境中运行的。
与比特币脚本系统的执行环境类似,以太坊的这种虚拟执行环境也是基于“栈(stack)”的;
但以太坊的虚拟执行环境还提供了可以供应用程序在运行时使用的临时存储空间“内存(memory)”和刚刚介绍过的永久存储机制“存储(storage)”。这就使以太坊的虚拟执行环境有了更强的计算能力,更像是一种“虚拟的计算机”,这个虚拟的执行环境就是大名鼎鼎的“以太坊虚拟机(Ethereum Virtual Machine,简称 EVM)”,EVM 也是以太坊被称为“世界计算机(World Computer)”的由来,它也是以太坊与比特币相比在技术层面的最大创新。
EVM 字节码:在 EVM 中运行的“可执行代码”。
以太坊的高级开发语言 Solidity 就可以编译为 EVM 字节码,然后在 EVM 中运行。
综上所述,以太坊其实就是“区块链”+“以太坊虚拟机”。