Substrate 合约书之合约模型
发布日期:2021-06-28 22:54:49 浏览次数:2 分类:技术文章

本文共 5264 字,大约阅读时间需要 17 分钟。

在这里插入图片描述

前言

「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 )来从虚拟机上限定合约的模型,可以理解为是一种特化逻辑过的 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/)。

因此 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点特性:

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

合约模型中需要链相关的特性;
将合约与用户看做一致,允许合约调用合约;
引入指令计费模型。

并且,在以上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),熟悉测试链和工具套件。欢迎加入官方开发群:

Element(https://app.element.io/#/room/#PatractLabsDev:matrix.org)
Discord(https://discord.gg/wJ8TnTfjcq)
搜索**“Patract开放平台”**关注Patract微信公众号

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

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

Telegram(https://t.me/patract)
Twitter(https://twitter.com/PatractLabs)

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

转载地址:https://blog.csdn.net/Yikuailianxi/article/details/115721706 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:波卡与 Wasm 合约双剑合璧
下一篇:Substrate 合约书之合约综述

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月02日 13时31分51秒