MonteCarloClub / kanban

Create an issue here!
0 stars 0 forks source link

技术方案:智能合约引擎 #5

Open vangogo opened 2 years ago

vangogo commented 2 years ago

1.需求背景

扩展WASM,设计基于堆栈的预编译字节码智能合约⽅案。实现一个类似于 evm 的智能合约引擎。

2. 需求明细

实现一个类似于 evm 的智能合约引擎,用于实现智能合约的部署、执行、权限等基本生 命周期功能。

2.1 外部调用接口

提供 vm 虚拟机接口用于执行交易,包括 1)vm 结构体:存放合约及相关信息,包括代码字节、输入字节、可用 gas,交易发起者 账户等。 2)vm 函数接口:创建合约函数 create、调用合约函数 call,两个函数接收 vm 结构 体涉 及的合约相关信息参数,返回合约执行返回字节、剩余 gas 量、错误代码。

2.2 内部的合约执行

判断交易类型,如果是部署合约,VM 新建一个合约账户来存储合约地址以及合约编译之后 的代码;否则 VM 解析交易中的交易参数等信息,并调用其执行引擎执行相应的智能合约 字节码;执行引擎完成对智能合约的编译执行,是基于堆栈的预编译字节码智能合约运⾏环 境实现;指令执行完成之后,VM 会判断其是否停机,若停机,判断 VM 的停机状态是否 正常,正常则结束执行,否则进行 Undo 操作,状态回滚到本次交易执行之前。

2.3 对底层链的访问接口

实现智能合约引擎功能需要面向世界状态接口。 1)对世界状态数据库对增删改查操作: 增:新建账户、部署合约 改:nonce 值加一,balance 增减 查:给定账户的 nonce、balance、code 值等 2)获取世界状态快照,依据快照回滚数据状态

3.需求调研

3.1 智能合约的运作(EVM)

Solidity/Vyper语言的智能合约被编译为字节码,使用到的编译器叫做“solc” 字节码由网络读取并处理 字节码是Solidity操作码的二进制形式。从EVM转向eWASM的过程中,编译器是非常重要的一个部分,因为EVM无法理解除了字节码之外的任何语言。 每个操作码在规范中都被赋予了易于理解的名称,并由数字代码表示。例如,数字0X01代表ADD操作码。 solidity是合约的执行语言,solidity被solc编译后,变成类似于汇编的EVM指令。 Interpreter定义了一套完整的指令集。solidity被编译后,生成二进制文件,二进制文件就是EVM指令的集合,交易以二进制的形式发往节点,节点收到后,通过EVMC调用EVM执行这些指令。 在EVM中,用代码模拟实现了这些指令的逻辑。

3.2 WebAssembly

wasm是可以在基于栈的虚拟机上运行的一种二进制指令格式,设计的首要目标是性能,很适合用在区块链项目中。WebAssembly二进制代码(wasm格式)可以转换成一种中间表示,一种可读的AST(抽象语法树,wast格式),这种可读的中间表示方便了编写和调试。对扩展性的改进:wasm支持module import/export功能,可以将扩展部分做成module,在项目中导入。 WebAssembly的优势: 受多个JavaScript引擎和运行时环境的支持,可以在大多数现代浏览器中执行。 Go/Rust/C/C++语言可以直接编译为WASM 能够快速适应所有机器级架构,具备极高性能 附带与大多数现代硬件架构兼容的指令集 在大多数平台上趋近于本地运行速度

4.方案

技术方案主要参考以太坊2.0的EVM,实现基于堆栈的预编译字节码智能合约运⾏环境。

4.1 Ewasm

eWASM = WASM – 非确定性 (浮点) + 计量 + EEI路径 (用以与以太坊交互) ewasm允许以太坊开发者使用其他语言(例如Rust、C++等)开发智能合约并编译为以太坊接受的WebAssembly。 部署wasm合约时,要有一个预编译内置合约(合约名称Sentinel Contract)对合约进行检查,要求合约符合EVM2.0的要求,比如不能包括float类型,不能有限定外的操作。 ewasm合约语义设计(Ewasm Contract Interface - ECI) ECI定义了ewasm合约的结构,通过wasm的module实现,实质上是wasm,可以认为ewasm是wasm的子集 。 合约必须符合wasm二进制格式 合约import module只能import EEI,不能import以太坊之外的module保证了EVM是一个沙盒程序。 提供debug module,但debug模式只能用于开发,在部署的时候需要去掉 每个合约必须提供两个export方法,一个是main,供VM执行调用,一个是memory,供EEI调用,保存结果。 wasm module中的start function需要被disable。 Ethereum Environment Interface (EEI) 定义 EEI定义了wasm程序如何与链进行交互,通过EEI将以太坊API暴露给ewasm,使ewasm可以读写链上信息,意义是wasm指令是low level的,high level功能留给客户端实现。

4.2 evmc (如我们只实现一种,即ewasm,是否不需要用evmc)

EVMC – Ethereum Client-VM Connector API 新版本的以太坊将EVM从节点代码中剥离出来,形成一个独立的模块。EVM与节点的交互,抽象出EVMC接口标准。 通过EVMC,节点可以对接多种虚拟机,而不仅限于传统的基于solidity的虚拟机。 传统的solidity虚拟机,在以太坊中称为interpreter

4.3 代码结构主要参考EVM

image

堆栈和内存数据结构: vm使用stack.go里面的对象Stack来作为虚拟机的堆栈。memory代表了虚拟机里面使 用的内存对象。 stack.go:用1024个big.Int的定长数组来作为堆栈的存储。 memory.go:memory的存储就是byte[]. 还有一个lastGasCost的记录。 jump_table.go:jumptable. 是一个 [256]operation 的数据结构. 每个下标对应了一种指令, 使用operation来存储了指令对应的处理逻辑, gas消耗, 堆栈验证方法, memory使用的大小等功能. 数据结构operation存储了一条指令的所需要的函数。

5.技术难点和疑问

1)接收的数据是否是编译好的字节码,是否是wasm格式?是否只要实现类似Ewasm的虚拟机? 2)不清楚目前项目构建的底层链与以太坊区块链的异同,因此根据以太坊的EVM做对应的适配修改有一定困难 3)不清楚项目的执行流程与各个部分之间的关联,包括智能合约解释器部分在上层应该与哪一部分对接,而下层负责构建底层链的又是哪个部分 4)希望能有详细的文档梳理整个项目的执行流程,包括每个部分之间负责实现的功能,输入的数据,输出的数据,每个部分之间的对接关系等