主页 > 下载imtoken官方网站 > 从比特币脚本引擎到以太坊虚拟机

从比特币脚本引擎到以太坊虚拟机

下载imtoken官方网站 2023-01-17 11:46:23

本系列面向区块链开发者和有其他开发经验的CS同学

面对媒体对区块链相关技术的解读和褒奖,不少人一时间不知所措。 在FOMO(害怕错过)心理的驱使下,投资者和大公司争先恐后地宣布一切都在区块链上。 各种名人坐下来谈论区块链技术的社会、政治、经济甚至哲学意义。 人类对未知事物和他们不了解的事物有一种天生的不安全感。 作为开发者,我认为克服焦虑(以及它带来的投机心理)最好的方法是尽可能提高对底层原理和实现的认识。 知道。

从技术角度来看,无论是比特币、以太坊,还是尚未正式上线的EOS、IPFS,都具有很强的实验性,存在各种局限性,不可避免地影响上层应用的开发。 . 大多数区块链应用还涉及金融、信用等重要领域,因此深入理解底层原理是对区块链开发者的基本要求,而不仅仅是跟着教程10分钟部署一个智能合约,尤其是对于各种早期技术在不成熟的情况,生搬硬套,稍有不慎就会造成很大的损失。

本系列的第一篇文章主要关注以比特币为代表的加密货币架构(Blockchain 1.0)与以以太坊为代表的可编程分布式信用基础设施(Blockchain 2.0)之间的核心差异。 一——是否支持图灵完备语言,我们来看看区块链技术架构的演进。

比特币和以太坊的渊源:对于币圈和链圈的人来说,Vitalik Buterin(1994年出生)是无可争议的大师。 很多人可能不知道,V神作为早期比特币社区的活跃成员,最初提出比特币需要开发一种通用的脚本语言来支持功能丰富的应用程序的开发,但是并没有得到支持比特币开发团队。 于是又重新开始,在2013年推出了以太坊项目,有了今天繁荣的加密代币、收藏游戏、DAO。 接下来我们就来看看V神不满的比特币脚本系统到底是个什么样子?

第一部分:比特币脚本引擎交易

交易在区块链世界中有着非常广泛的含义。 在加密货币的应用中,可以狭义地理解为比特币金额在不同地址之间的转移,即转账。 转账是一种由来已久的行为,但转账技术一直在创新。

理解比特币传输模型尤为重要,因为比特币脚本引擎是建立在该模型之上的。

两种传输方式

1、简化传统中心转账:alice(账户A)转账给bob(账户B)x元,银行需要进行原子操作balance[A]-=x,balance[B]+=x,当然隐式条件就是alice已经完成了账户A的认证。

2、解释比特币交易原理的声明:

网络中的每个节点都维护着一个独立的数据库,记录着每个地址的余额。 如果Alice(地址A的所有者)要转x元给Bob(地址B的所有者),她将在网络中广播“地址A给地址B X个单位”,带上pubkeyA并用privatekeyA签名。 每个节点接收并校验成功后,在各自的数据库中执行原子操作balance[addressA]-=x, balance[addressB]+=x。 (注:实际地址是通过pubkey生成的,这里为了简化省略)。

以上1在现实中占据主流,有成熟的扩张计划,但中心化必然带来成本、平台恶等问题;

2的描述来自b-money,一个匿名的、分布式的电子现金系统(这篇文章很重要,深深影响了中本聪对比特币的设计),但是当时无法实践,因为它非常依赖a同步,一个不受干扰的网络环境,否则很难保持一致性。 而且,这种分布式数据库提交问题(拜占庭问题),现有的共识算法paxos、raft(非拜占庭)包括pbft(拜占庭)的扩展性都无法支持数万比特币的节点数。

比特币交易模型设计

关于比特币交易模型最早来自中本聪的

比特币:一种点对点电子现金系统。 中本聪其实提出了两种链。 大家一直在谈论的区块链(chain of blocks)是一种显式的数据组织方式,另一种隐式的是交易链(chain of transactions)是比特币的价值流转。 链。

比特币是挖矿挖出来的吗_比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的

如图,最早的交易描述模型:

如果 Alice(地址 A 的所有者)要转 x 元给 Bob(地址 B 的所有者),她也需要签署交易并在网络上广播。 不同的是,addressA的余额并不保存在各个节点的数据库中,而是保存在别人转给addressA的未花费交易输出中,即UTXO(未花费交易输出)。 我们查询addressA的余额,实际得到的是所有接收地址为addressA的UTXO数量之和。 广播内容类似于“addressA(combining UTXO1...UTXO3) gives X units to addressB”,带上pubkeyA,用privatekeyA签名。

交易在网络中得到确认后,Bob 将多出一笔可用的 UTXO。 如果他要花这笔钱,他需要证明他拥有地址B对应的privatekeyB,然后Bob也用私钥签名。 这样,交易就变成了签名链。

比特币是挖矿挖出来的吗_比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的

显然这里存在三个问题:

1、如果任何一笔交易的输入都需要上一笔交易的输出,那么比特币最初是从哪里来的?

所以在比特币交易中,有一个交易叫做coinbase,也就是大家熟知的挖矿奖励。 比特币是通过挖矿算法生成的,输入来自系统奖励。 其实它还会检查coinbase是否“成熟”,即区块是否已经足够确认。 在比特币中,如果最后没有被列入最长链,就会作为孤块被丢弃,奖励失效。

2.判断一笔交易输出是否为UTXO,是否需要追溯整个区块链?

不会,因为交易是按照默克尔树结构组织的,这就决定了从整个区块链数据库中查询一个交易的效率会非常低。 UTXO 专门存储在 leveldb 数据库 chainstate 中并缓存在内存中。 每当一个新的区块产生时,UTXOs 集合就会更新; 当一个节点进行链重构时,该过程将被回滚。 这里需要注意的是,UTXOs集合并不是待确认交易池(TxMemPool),而是所有待确认交易的输入源; 理论上可以通过 --reindex 从整个区块链重建 UTXO。

3、Alice的账户余额来自4个UTXO,分别是0.05、0.2、0.2、0.3。 现在她需要将 0.6 转给 Bob。 我应该怎么办?

比特币是挖矿挖出来的吗_比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的

理论上,Alice 可以转移 3 次,但实际上是非常不明智的。 它需要更多的费用和糟糕的体验,因此交易输入可以包括多个 UTXO。 关于如何选择UTXO的组合,有专门的分析; 多个input的总和不一定正好等于转账金额Output1,需要找零退款(Output2),当然还会有手续费(Output3),所以交易会包含多个Output。 当然,对于用户来说,只需要设置转账地址、金额和手续费,UTXO和零钱的结合是透明的。

注:以太坊放弃了 UTXOs 模型,采用了类似于 bmoney 的账户范式。 具体原因在以太坊虚拟机的设计介绍之后再分析。

做了这么多铺垫,终于可以进入比特币的脚本设计了。

脚本操作码

比特币交易由一组脚本引擎(Script)处理。 这是 bitcoin-core 源代码 interpreter.cpp 中的注释:

/*** Script is a stack machine (like Forth) that evaluates a predicate* returning a bool indicating valid or not.  There are no loops.*/

Script 是一种类似 Forth 的、基于堆栈的、无状态的、非图灵完备的语言。

操作码分为常量、过程控制、栈操作、算术操作、位操作、密码操作、保留字等,还包括3条内部使用的伪指令。 以下是将出现在以下脚本中的一些说明。 所有说明请参考官方文档和源代码。

支付到公钥哈希 (P2PKH)

上面Alice转发给Bob的例子就是一个典型的P2PKH。 中本聪在论文中只给出了一个交易模型,我们来看一个更具体的实现。

比特币挖矿是浪费资源吗_比特币是挖矿挖出来的吗_挖矿奖励的比特币是哪里来的

如上图,在Alice转账给Bob之前,Bob需要提供自己的收款地址,但实际的P2PKH使用的是Public Key Hash。 这里简单补充一下密钥生成过程,如下图所示,私钥单向生成公钥,公钥通过OP_HASH160命令生成160位的PKH(公钥哈希)。 PKH 可以转换为用户更易读的地址,但编码、验证过程等是双向的。 所以提供地址等同于提供PKH。

比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的_比特币是挖矿挖出来的吗

在下图中,Alice 转给 Bob 的钱通过 Pubkey Script 锁定在 TX1 Output 中。 如果 Bob 试图花这笔钱,他需要解锁 PubkeyScript,并通过证明他是 TX1 输出中公钥哈希的私钥所有者来提供签名脚本。

比特币是挖矿挖出来的吗_挖矿奖励的比特币是哪里来的_比特币挖矿是浪费资源吗

下面是两个脚本。

锁定脚本:
scriptPubKey: OP_DUP OP_HASH160  OP_EQUALVERIFY OP_CHECKSIG
解锁脚本:
scriptSig:  

上面包含的数是要压入栈的数,push指令是默认的。 实际执行时会连接scriptSig和scriptPubkey,脚本会从左到右运行。

验证过程:
  OP_DUP OP_HASH160  OP_EQUALVERIFY OP_CHECKSIG

栈上的情况如下两图所示。 有汇编基础的同学会熟悉堆栈计算机模型的工作原理。

比特币是挖矿挖出来的吗_挖矿奖励的比特币是哪里来的_比特币挖矿是浪费资源吗

比特币挖矿是浪费资源吗_比特币是挖矿挖出来的吗_挖矿奖励的比特币是哪里来的

世代奖励矿工

奖励矿工可以看作是一个简化的P2PKH,不同的是交易的输入来自coinbase而不是UTXO。

支付脚本哈希 (P2SH)

P2PKH的设计比较简单,收件人Bob直接提供收件地址。 在实际的价值流通过程中,会涉及到很多条件。 为了满足更复杂的功能,BIP12提出增加OP_EVAL指令(在编程语言设计中,eval意味着该语言具有元编程能力),随后BIP16提出了更完善的交易标准P2SH。

收款人Bob需要先设计一个RedeemScript——取款脚本,然后生成脚本的Hash提供给Alice。

比特币是挖矿挖出来的吗_比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的

如果 Bob 想要花费 UTXO,他需要提供他的签名和 RedeemScript。 验证成功后,会执行RedeemScript中的内容,满足条件后解锁成功。

比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的_比特币是挖矿挖出来的吗

下面的redeemScript是结合具体场景设计的。 后面会结合智能合约的应用给出相应的例子。

锁定脚本:
Pubkey script: OP_HASH160  OP_EQUAL
解锁脚本:
Signature script:  [sig] [sig...] 

在一次P2SH交易中,由于Bob提供了一个脚本的Hash,Alice实际上并不知道交易的细节,交易的具体内容需要Bob设计。 这就是所谓的“将提供赎回交易条件的责任从资金发送者转移到赎回者。他们允许发送者为任意交易提供资金,无论多么复杂,使用 20 字节哈希” . 这在设计上并非没有争议,但在比特币的技术框架下,却是一条以最小的改动支持更多特性的路径。

比特币智能合约

虽然说到智能合约,人们更多的会想到以太坊。 但如前所述,技术发展是一条连续的道路。 早在 1997 年,Nick Szabó 在其开创性论文 Formalizing and Securing Relationships on Public Networks 中提出了智能合约的概念。 比特币的脚本系统支持开发有限的智能合约,主要是通过P2SH交易。

MultiSig 多重签名

BIP11 提出 M-of-N 多重签名交易。 一笔交易的解锁条件是指定的N个公钥中的M个签名认证(M6->4->6->15->6->7->value,value是指向“Snoopy”的hash)。这样做的好处哈希表的方法是不会有冲突;但是如果不做优化,查询步骤会过长。

改进

为了提高效率,以太坊专门设计了树上的节点数据类型。包括以下四种类型的节点

挖矿奖励的比特币是哪里来的_比特币挖矿是浪费资源吗_比特币是挖矿挖出来的吗

如图所示,是一个简化的状态树(后面会详细解释状态树,这里不碍示意图),右上角是\的映射。 前缀项的作用是辅助编码,可以忽略。 4个账户的地址按照MPT组织。 所有扩展节点只是为了优化,可以用多个分支节点代替。

MPT的使用需要一个后端数据库(以太坊中使用levelDB)来维护各个节点之间的连接关系。 该数据库称为状态数据库。 使用 MPT 的好处包括: (1) 该结构的根节点是加密的,依赖于所有内部数据,其哈希可用于安全验证。 这是merkle树的本质,但是merkle树不存储数据块本身的区别在于MPT树节点存储地址数据,这是Patricia树(2)允许任何先前状态(在根哈希已知的情况下)通过简单地改变根哈希值来改变。 记起。

状态

状态树的概念在上面讲解MPT的时候已经介绍过了。 以太坊中世界状态的概念通过 MPT 映射存储去中心化交易系统记录的任何状态。 这对应区块链范式中的S,是以太坊设计的一个核心概念。

比特币挖矿是浪费资源吗_比特币是挖矿挖出来的吗_挖矿奖励的比特币是哪里来的

如图所示,一个简化块中有三个根哈希,对应三个MPT。 其中,state root是state tree的root hash,是到账户数据(Account,序列化存储在levelDB中)的地址(160bit)。 每个有效的交易都会导致状态改变。 比如图中简单的显示了Account175的余额从27变成了45,其他大部分账户都没有交易。 那么block175224只需要在Account175的相关分支上创建数据,其他分支不需要复制! 当然,以太坊主网上新区块包含的交易数量从几十到几百不等,因此涉及的修改会更多。 有关此结构的性能的讨论,请参阅本文。 查询最新账户状态的入口应该是最新确认区块的状态树。

以太坊的账户模型需要特别介绍一下。

帐户

比特币采用UTXO模型计算余额,不能满足记录任何状态的需要。 以太坊设计了 Account 模型,它将存储:

[随机数、余额、storageRoot、codeHash]

其中nonce为交易计数器,balance为余额信息,storageRoot对应另外一个MPT,通过它可以在数据库中调取合约的变量信息,codeHash为代码哈希值,创建后不可更改.

比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的_比特币是挖矿挖出来的吗

有两种类型的帐户

贸易

在 UTXO 模型下,一笔交易本质上是(通过签名数据)输入的解锁和输出的锁定。 在Account模型下挖矿奖励的比特币是哪里来的,交易分为两种:

两种类型的交易都包括以下字段:

[nonce,gasPrice,gasLimit,to,value,[v,r,s]]

合约创建还需要:

挖矿奖励的比特币是哪里来的_比特币是挖矿挖出来的吗_比特币挖矿是浪费资源吗

合约账户地址由sender和nonce共同决定,因此任意两次合约部署成功获得的地址是不同的。 从上图可以看出,代码和状态存储是分开的。 实际上,编译后的字节码会存放在一个虚拟ROM中,无法修改。

消息调用还需要:

比特币挖矿是浪费资源吗_挖矿奖励的比特币是哪里来的_比特币是挖矿挖出来的吗

消息调用会修改账户状态,可能是EOA账户,也可能是合约账户。

交易可以由外部账户或合约发起。 例如,区块 5228886 包含 170 笔交易和 7 笔内部合约交易。

堵塞

以太坊的区块增加了更多的数据项,比比特币复杂很多,但其实本质上并没有太大区别。 比如加入叔叔链hash优化激励,就是支持挖矿协议; 区块本身也会有很多有效性验证和序列化。 这些内容超出了本文的范围,不会深入讨论。

挖矿奖励的比特币是哪里来的_比特币是挖矿挖出来的吗_比特币挖矿是浪费资源吗

上图右半部分可以看出以太坊区块是如何组织数据的,可以看到MPT树的大量使用; 左半部分涉及EVM,这将是下一个重点。

执行模式

EVM恰恰是一个准图灵机,可以在语法上进行任意操作挖矿奖励的比特币是哪里来的,但是为了防止网络滥用,避免图灵完备带来的安全问题,以太坊中的所有操作都在经济上受到限制,也就是gas机制,分为三种情况:

下图展示了EVM执行的内部流程。 指令是从 EVM 代码中获取的。 所有操作都在堆栈上执行。 内存作为临时变量存储,存储的是账户状态。 执行受限于 gas 可用性。

比特币挖矿是浪费资源吗_比特币是挖矿挖出来的吗_挖矿奖励的比特币是哪里来的

现在结合EVM,我们来看看前面介绍的交易的执行细节。 按照区块链范式的定义,T是以太坊的状态转移函数,也是以太坊最复杂的部分。 所有交易在执行前都需要经过内部有效性验证:

下图展示了消息调用的流程。 每笔交易都可能形成一个深度调用栈,交易被不同的合约调用。 调用通过CALL指令传递,参数和返回值通过内存传递。

挖矿奖励的比特币是哪里来的_比特币挖矿是浪费资源吗_比特币是挖矿挖出来的吗

错误处理

EVM 在合约执行期间可能会出现几种类型的错误:

EVM的错误处理有一个简单的原则,叫做revert-state-and-consume-all-gas,即状态恢复到交易执行前的checkpoint,但是消耗的gas不会返还。 虚拟机将所有错误都视为代码错误,不进行具体的错误处理。

EVM分析工具

EVM分析工具请参考Ethereum Virtual Machine (EVM) Awesome List

类 EVM 图灵完备虚拟机 (WIP)

完整的EVM规范非常复杂,但具备一定的编译基础和简化模型的能力,实现类EVM虚拟机是一个挑战。 我会在有时间时发布我自己的实现。 有兴趣的同学可以自行尝试。

参考

1.下一代智能合约和去中心化应用平台

2. 以太坊:一种安全的去中心化广义交易账本

3. 设计原理

4. Stack Exchange:以太坊区块架构

5. 去以太坊

6.evm图解

7. 深入以太坊虚拟机