写点什么

Substrate 合约书之合约模型

用户头像
Patract
关注
发布于: 2021 年 04 月 15 日
Substrate 合约书之合约模型

前言


「Substrate 合约书」用于介绍 Substrate 中与 Wasm 合约体系相关的一系列知识。本书由 Patract (https://patract.io/)主导编写,由 Aten (https://github.com/atenjin)负责。本书仓库位于 https://github.com/patractlabs/substrate-contracts-book(opens new window),欢迎有志之士一起为本书做出贡献。


本书当前主要以 Pallet-Contracts (即 Wasm 合约)作为主体进行介绍。因此本书内容包含:

  • 运行合约的合约平台(模块)

    Pallet-Contracts

  • 编写合约的语言

    ink!

    Ask!

    Solang

  • 帮助合约开发的工具们

    Redspot

    Europa

    Elara


其中由于 Pallet-EVM(即 EVM/Solidity 体系的合约)在以太坊生态中已有比较丰富的资料,故不会在本合约书中当做重点讲解。而另外的合约体系如 Pallet-Actor,或 Libra 移植合约平台等皆处于比较早期的研究阶段,因此也不会作为本书的重点。

为了让合约开发者更好的理解 Pallet-Contracts 模块与 Wasm 合约的运行方式,本书也会涉及一些 Wasm 的介绍以及区块链合约模型的介绍。

合约模型


在已经具备合约及合约沙盒的概念后,我们就可以开始讨论合约模型的概念了。

合约沙盒只是代表运行合约的环境,而合约是以什么方式运行的,合约和合约是怎么交互的,合约是怎么与链的数据互动的,这些问题就归属于合约模型问题。

换句话说,合约模型就是合约是以什么模型运行在合约沙盒/虚拟机中的

如图所示,合约模型与合约虚拟机本质上是可以解耦的,其中关系只存在合约虚拟机是否能支持上层所需要的合约模型,例如:


1.Bitcoin 的虚拟机就是比特币脚本的栈执行器,由于执行器设计是非图灵完备的 OP_CODE,因此对于上层的合约模型只能支持 Bitcoin 的脚本。


2.Ethereum 跟随 Bitcoin 的灵感,设计了具备图灵完备的 OP_CODE,即 EVM 虚拟机(Ethereum Virtual Machine)。但是 EVM 的 OP_CODE 比较简陋,且只有栈的设计,没有堆的概念。但是 EVM 引入了读写状态的 OP_CODE,因此从虚拟机机制上对合约模型可以支持状态模型。因此 EVM 也被看做一个执行状态转换的状态转换机(如 Gavin Wood 撰写的以太坊黄皮书中所描述的)。


状态模型实际上是比较通用的抽象模型,绝大多数模型都可以用状态模型模拟(如在状态模型中构建 UTXO 模型),因此从理论上来说,只要继续完善 EVM 的 OP_CODE,EVM 的上层同样可以构建出其他合约模型。


3.Libra 认为区块链的核心在于资产的处理,因此提出了 Move 的虚拟机模型(Move Virtual Machine <MVM>)来从虚拟机上限定合约的模型,可以理解为是一种特化逻辑过的 OP_CODE 集合。因此 MVM 的上层只能运行 Move 模型。


通过以上讨论,我们可以认识到合约模型的概念,并且理解到虚拟机对上层合约模型的限制,因此接下来就可以讨论 Wasm 虚拟机可以运行的合约模型以及 Pallet-Contracts 的合约模型构成。

Wasm 虚拟机


Wasm 是一种在基于栈的虚拟机上运行的二进制的指令格式(WebAssembly<abbreviated Wasm)>is a binary instruction format for a stack-based virtual machine, from https://webassembly.org/<opens new window>)。


因此 Wasm 的模型和主流计算机程序的模型结构比较相似。另一方面 Wasm 被设计成为了一种比较通用的形式,且设计了 WASI 并支持了运行环境自由定义 Host Function,因此虽然 Wasm 从浏览器发展而来,但是当前的使用场景已经不限于浏览器,开始在边缘计算,热更新,Serverless 平台等发挥效果。

若以指令的完备性来衡量一个虚拟机的能力,则 EVM 处于半成品的程度,限制多且不够灵活;而 JVM,Wasm 虚拟机则是比较完备的,限制少,功能性强。另一方面指令设计的合理性一定程度也会影响虚拟机的执行效率,同时虚拟机采用的实现方案也会对执行效率产生比较大的影响。


例如 EVM 当前只能以解释器(Interpreter)的形式运行,并且当前的实现过程体(Go, C++等版本)中没有看到针对解释器的优化,执行效率比较底下,而 JVM, Wasm 等虚拟机有采用 JIT 的模式的实现,执行效率相当高甚至逼近本地执行的性能。


注:Pallet-Contracts 当前只能使用 Wasmi(解释器)执行 Wasm 代码,因此合约的执行性能比不上使用 Wasmtime 的 Runtime 的执行性能。


而同时,Wasm 虚拟机相比于 JVM 等虚拟机,十分轻便(LightWeight),快速,可定制性强,且 Host Function 的功能给予了 Wasm 虚拟机与宿主之间交互的通道,因此和其他虚拟机相比,将 Wasm 虚拟机作为区块链合约沙盒与链的功能结合在一起比较容易。


另一方面在笔者看来,Wasm 是处于底层代码与上层代码之间比较好的一个抽象层,且其复杂性与完备性也远超于 EVM,因此比较适合区块链合约领域的需求。


因此 Wasm 虚拟机提供的沙盒环境在满足合约沙盒的前提下还满足以下 2 点要求:


  • 指令完备,功能性丰富,执行效率高

  • 有适合的接口能与宿主(这里指代运行 Wasm 的环境,即链)交互,方便宿主提供需要的功能。

EVM 的合约模型


由于 Ethereum 是存储状态的区块链,因此 EVM 的合约模型理所应当的需要基本读写状态的功能。如果把每次合约运行的过程看做一次程序的启动到执行结束的过程,那么状态数据的变化就对应着这个程序需要持久化数据的变化。


因此对于读写状态,以太坊的 EVM 提供了 SLOAD 和 SSTORE 两个指令。


另一方面以太坊描述一个账户使用了“账户模型”,即将合约和调用合约的用户都看做了一个账户,在这个账户下存在 Balance 等概念,因此 EVM 提供了 CALLER,ORIGIN,CALLVALUE 等等一系列指令来描述这种模型。


同时由于在 EVM 的抽象体系中,认为合约与用户是一致的,因此出现了“合约调用合约”的模型,即 CALL,DELEGATECALL 等指令,由此带来了合约的可组合性,造就了 Ethereum 繁荣的生态。而在 EVM 中,一个合约依托于一个 EVM 进行运行,因此合约调用合约是在一个 EVM 中启动了另一个 EVM 并加载指令进行执行。


当然 EVM 虚拟机设计的初衷就是为了解决比特币脚本的非图灵完备问题,为了解决这个问题并保证停机问题不发生,引入了指令的 Gas 计费模型,因此总结以上可以得到,EVM 的合约模型具备以下特性:


1.处理数据的模型是状态机模型,状态的变更靠外界调用触发(类比于调用了状态变更函数的过程);

2.合约模型中需要链相关的特性;

3.将合约与用户看做一致,允许合约调用合约;

4.引入指令计费模型。

Pallet-Contracts 的合约模型


这里直接下结论:Pallet-Contracts 虽然使用了 Wasm 虚拟机来执行代码,但是其合约模型基本与 EVM 合约模型一致。


也就是说 Pallet-Contracts 的合约模型同样具备以下 4 点特性:

  1. 处理数据的模型是状态机模型;

  2. 合约模型中需要链相关的特性;

  3. 将合约与用户看做一致,允许合约调用合约;

  4. 引入指令计费模型。


并且,在以上 4 种特性的基础上,增加了“存储租赁模型”:


  • Rent 存储租赁计费


在上文已经称述了合约执行的环境和合约模型是可以解耦的,EVM 由于设计的比较早还没有解耦这个层次的概念,因此在指令中 SLOAD,SSTORE 及类似和链相关的指令是与 EVM 其他指令合并一起的。而 Wasm 本来并非为区块链设计,因此一定不存在这些和链环境相关的指令。


因此 Wasm 的 Host Function 即是用来完成这件事情的。链作为 Host 宿主,只需要把他认为合约可能会用到的方法提供给 Wasm 虚拟机,让他导入这些函数对象,在合约的执行过程中即可以使用。因此通过 Host Function,Pallet-Contracts 合约模块就可以具备 1,2,4 功能,并将提供 3 需要的部分功能,同时第 5 点特性(租赁计费)也可以引入。


并且其中第 3 点功能的实现方式也与 EVM 一致,当出现合约调用合约的部分时,通过 Host Function 从 Wasm 回到了 Pallet-Contracts 模块,并启动了一个新的 Wasm 虚拟机去执行被调用的合约。(该部分在以后的文章中会描述)


因此总结而言,Pallet-Contracts 的合约模型具备如下特性:


1.合约模型与 EVM 的合约模型一致,并在此基础上增加了存储计费模型

2.与链交互的实现通过 Wasm 的 Host Function 特性实现

使用 Wasm 虚拟机实现其他合约模型


刚才简要描述了 Pallet-Contracts 是如何在 Wasm 虚拟机上实现合约模型的,由于前文已经解释了虚拟机与合约模型是可以解耦的,因此实际上在 Wasm 虚拟机上同样可以实现其他的合约模型。


例如我们可以考虑将 Move 虚拟机也移植到 Wasm 虚拟机中,其有两种可能的实现方式:


1.类比于将 EVM 的实现体在 Runtime 的 Wasm 环境运行,可以将 MVM 的实现体也编译成 Wasm 的形式(例如命名为 Pallet-MVM),在 Runtime Wasm 中运行。


基于这种实现,Move 依然可以按正常方式编译,并和 Solidity 的编译结果运行于 Pallet-EVM 一致,将 Move 的编译结果运行在例如 Pallet-MVM 的平台上。


2.将 MVM 与所有权,链相关的特性抽象一层,做成和 Pallet-Contracts 的形式,并设计将 Move 语言编译的中间码 IR 编译到 Wasm。


基于这种实现,可以将 Move 编译成为 Wasm,并在 Wasm 虚拟机中运行。

其他合约模型


  • EOS 的合约模型


EOS 的合约模型与 EVM 类似,同时强化了账户模型的概念。因此 EOS 使用 Wasm 的方式也是基于 Wasm 的执行,并通过 Host Function 引入与链相关的功能。


EOS 和 EVM 模型的主要区别在于,EOS 的合约调用合约的过程是以发交易的形态调用,并且 EOS 的资源模型是抵押模型。当前普遍认为正是 EOS 的抵押模型最后导致 EOS 没有走向成功。


  • 异步合约模型


pallet-actor 是 Substrate 尝试实现异步合约模型的一个开端,当前没有什么进展。pallet-actor 的模型打算使用 Wasm 虚拟机作为运行环境,并在此基础上添加异步的功能以提升性能。

当前也有其他少数对异步合约模型的研究,但是皆处于比较初步的阶段。

About Patract 


Patract 为波卡 Wasm 合约生态的平行链和 DApp 开发提供解决方案。我们帮助社区平行链设计和开发链上合约模块和 Runtime 支持,并且为 DApp 开发者提供覆盖开发、测试、调试、部署、监控、数据提供和前端开发等阶段的全栈工具和服务支持。

How to join Patract


1.对于合约开发者,可以访问官网 (https://patract.io),熟悉测试链和工具套件。欢迎加入官方开发群:

Elementhttps://app.element.io/#/room/#PatractLabsDev:matrix.org

Discordhttps://discord.gg/wJ8TnTfjcq

搜索“Patract 开发平台”关注 Patract 微信公众号

 

2.对于将要集成 Wasm 合约功能的平行链项目方,或者使用 Wasm 合约开发的 DApp 项目方,商务合作欢迎联系 santry@patract.io

 

3.对于用户,欢迎加入:

Telegramhttps://t.me/patract

Twitterhttps://twitter.com/PatractLabs

 

4.对于求职者,我们在招聘区块链开发工程师、前端/全栈开发工程师、开发者运营等岗位,可以联系 sean@patract.io

用户头像

Patract

关注

还未添加个人签名 2021.03.12 加入

Patract的使命是加速智能合约行业向Wasm技术栈的转变。

评论

发布
暂无评论
Substrate 合约书之合约模型