ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

EVM、Wasm虚拟机原理和设计思路

2021-07-02 13:57:29  阅读:928  来源: 互联网

标签:EVM 虚拟机 +---------------+ Wasm 合约 字节


EVM和WASM(EOS虚拟机)基本原理

EVM是以太坊图灵完备的虚拟机(Ethereum Virtual Machine), 简称EVM

  • 由程序翻译指令并执行
  • EVM出于所谓运算速度和效率方面考虑,采用了非主流的256bit整数
  • 不支持浮点数
  • 缺乏标准库支持,例如字符串拼接、切割、查找等等都需要开发者自己实现
  • 给合约打补丁或是部分升级合约代码在EVM中是完全不可能的

比特币的程序非常简单,由解锁脚本和锁定脚本构成。以太坊有智能合约,有图灵完备的虚拟机EVM,但是指令也相对简单,且自成一套。这两种程序本质上都是脚本程序,即由程序翻译指令并执行,而不是由本地机器CPU读取指令并执行,效率不高。但选择解释性语言有它的合理性,就是他的高度兼容性,它对智能合约的执行设备(矿机)没有限制。

WASM是EOS的智能合约标准Web Assembly,简称WASM

  • 可以由解释器执行,也可以编译成机器码后执行
  • 一种中间代码(字节码),所有其他语言编写的程序(C \ C++ \ Rust \ Golang \ java 等)都可以编程成wasm字节码的程序
  • Wasm 是分布式系统开发的基础,智能合约将能够用可以被编译成 wasm 的任何语言进行开发。
  • 智能合约可升级

WASM

它是谷歌、苹果、微软三大竞争公司同时支持的一种中间代码(字节码), 是浏览器都支持的一种代码。

WASM

基于EOS.IO的区块链使用Web Assembly(WASM)执行开发者提供的应用代码。WASM是一个已崭露头角的web标准,受到Google, Microsoft, Apple及其他大公司的广泛支持。目前为止,最成熟的用于构建应用及WASM代码编译的工具链是clang/LLVM及其C/C++编译器。希望C++ 将成为开发高性能及安全智能合约的最佳语言

LLVM的命名最早来源于底层语言虚拟机(Low Level Virtual Machine)的缩写。它是一个用于建立编译器的基础框架,以C++编写。创建此工程的目的是对于任意的编程语言,利用该基础框架,构建一个包括编译时、链接时、执行时等的语言执行器。目前官方的LLVM只支持处理C/C++,Objective-C三种语言,当然也有一些非官方的扩展,使其支持ActionScript、Ada、D语言、Fortran、GLSL、Haskell、Java bytecode、Objective-C、Python、Ruby、Rust、Scala以及C#。

以太坊支持WASM吗?

  • Parity 以太坊客户端在 Wasmi 解释器中运行 Wasm 字节码,以保证 Wasm 代码能够访问区块链并与区块链进行交互
  • 可以在 Kovan 测试网(PoA算法,Parity专用,Rust 语言)上测试 Wasm;在该测试网上,EVM 智能合约以及 Wasm 智能合约可以共存甚至互动

EWASM

eWASM将允许以太坊开发人员能够使用多种编程语言来编写代码——而不仅仅目前所使用的以太坊专用的语言Solidity——据说eWASM还会带来大量的性能增强。

Ewasm (Web Assembly for Ethereum) 并不是一个智能合约语言,而是一个编译器目标,它将允许以太坊程序员用其他语言编程(如Rust,C ++,也许某一天是智能合约特定语言,如 Simplicity),并编译成以太坊风格的 WebAssembly。Ewasm 是 WebAssembly 的一个更安全的子集,它是 Web 平台相对较新的低级编译目标。方便的是,wasm(以及 ewasm)模块可以在任何 JavaScript 项目中使用。对于大多数区块链代码,通常超过 75% 的代码根本不在智能合约中 — 它在 JavaScript 中必须与智能合约进行通信。Ewasm 和 JavaScript 共享绑定和模块支持的共同基础。

 实现思路

Cosmos-SDK实现的Ethereum 的智能合约链,底层提供了EVM、Wasm两种虚拟机来运行智能合约。开发者可以使用传统的Solidity语言编写合约、或其它可以编译为WebAssembly高级语言(如:Rust/C++/AssemblyScript)编写合约,将编译后的合约字节码上传至 Chain上运行;并且两种类型的字节码合约之间可以互相进行调用。

基于上述这种开发理念,引申出一个问题:如何在Wasm上实现实现Ethereum . 对此初步提供了三种方案:

  1. 将Solidity合约编译为Wasm字节码

    • 使用类似于SOLL的方案,将Solidity合约编译为等价的WebAssembly字节码,底层提供Wasm虚拟机来运行合约。
  2. 在Wasm上提供系统合约,来运行Solidity字节码的合约

    • 在Wasm虚拟机上构建EVM字节码器,来运行编译后的Solidity字节码。
  3. 提供两种虚拟机的实现,不同的字节码合约在不同的虚拟机上运行

    • 使用两种虚拟机,分别运行EVM字节码合约和WebAseembly字节码合约,同时在Wasm虚拟机上通过Host函数,提供Ethereum 的实现,以便做到两种虚拟机合约之间的互相调用。

基于技术实现难度、运行性能等方面的考虑,采用了第三种方案。下面将详细介绍该方案的实现思路

Wasm虚拟机实现Ethereum 

在Wasm虚拟机中运行合约时,除了虚拟机自身之外,还需要依赖一些外部Host函数的支持,通过在Host中,提供EEI实现,以便在Wasm虚拟机中提供 Ethereum 

Chain提供了便于合约导入的SDK,以便在用高级语言(Rust/AssemblyScript/)写Wasm合约时,可以调用这些外部Host函数;将合约编译为Wasm字节码时,SDK中声明的所有export函数,都将由Chain客户端提供实现。

示例如下:

在smart-sdk-as项目中,提供了as项目使用的sdk.

// cesi.ts
export declare function getCallDataSize(): u32
export declare function callDataCopy(bufOut: Uint8Array, offset: u32, length: u32): void
export declare function getCodeSize(): u32

// lib_contract.ts
export namespace contract {
    export function getCodeSize(): u32 {
    return cesi.getCodeSize();
  }
  ....
}

// index_test.ts
export function testCoreAPI(): void {
    var codeSize = contract.getCodeSize(); 
}  

在smart chain链的客户端中,实现了这些Host函数

//export cesiGetCallDataSize
func cesiGetCallDataSize(context unsafe.Pointer) int32 {
    return convertContext(context).getCallDataSize()
}
//export cesiCallDataCopy
func cesiCallDataCopy(context unsafe.Pointer, resultOffset int32, dataOffset, length int32) {
    convertContext(context).callDataCopy(resultOffset, dataOffset, length)
}
//export cesiGetCodeSize
func cesiGetCodeSize(context unsafe.Pointer) int32 {
    return convertContext(context).getCodeSize()
}

将用高级语言(Rust/AssemblyScript)编写的Wasm合约编译为字节码(WebAssembly ByteCode),上传至链,创建Wasm虚拟机后,进行运行,并由Host函数提供EEI语义的支持.


 +--------------+               +---------------+               +---------------+
 |              |   create VM   |               |       run     |               |
 |  Wasm        | ------------> |      VM       | ------------->|   host func   |
 |  ByteCode    |               |               |               |               | 
 +--------------+               +---------------+               +---------------+

EVM虚拟机集成

在chain中,使用了[ethereum/evmone]作为以太坊虚拟机的实现,该项目内部实现了以太坊的所有指令;同时,提供了一个接口HostContext,负责与区块链进行数据交互;在smart chain 客户端中通过实现该接口,为evm虚拟机提供数据支持;

通过调用evmc提供的接口,从evmone的动态库中创建evm虚拟机;然后通过虚拟机提供的接口Execute,传入合约code,用户输入等一系列参数信息,运行合约。

 +--------------+               +---------------+               +---------------+
 |              |   params      | contract code |       run     |               |
 |  Load EMV    | ------------> |     input     | ------------->|  HostContext  |
 |              |               |     ...       |               |               | 
 +--------------+               +---------------+               +---------------+

虚拟机间的兼容

为了使smart chain在执行合约时,不用关注虚拟机的实现细节,增加了中间层,来兼容两种虚拟机的创建、执行;

  1. 在合约的元信息中增加标识,来表明合约字节码类型;
  2. 依据标识来创建指定类型的虚拟机;
  3. 通过引入中间层接口ContractExecutor,来屏蔽smart chain 在链上执行合约时,对两种虚拟机实现细节的关注.
  4. 在虚拟机执行时,通过使用ABI编码后的参数,来做到虚拟机之间的互相调用

type ContractInfo struct {
        ContractType uint8
}

func CreateVM(cfg Config) (ContractExecutor, error) {
    switch cfg.Flag {
    case EVM:
      return evm.NewVmEvmc()
    case Wasm:
      return wasm.NewWasmer(cfg.Ctx, cfg.Keeper, cfg.ContractAddr, cfg.Code, cfg.CodeHash, cfg.Ims)
    }
    return nil, types.ErrVMUnsupported
}

type ContractExecutor interface {
    Execute(ctx interface{}, rev evm.Revision,
      kind evm.CallKind, static bool, depth int, gas int64,
      destination sdk.AccAddress, sender sdk.AccAddress, input []byte, value int64,
      code []byte, create2Salt []byte) (output []byte, gasLeft int64, err error)
}

 +--------------+               +---------------+               +---------------+
 |              |  create vm    |               |    run        |               |
 |  Contract    | ------------> |   Contract    | ------------->|    Execute    |
 |  Info        |               |   Executor    |               |               | 
 +--------------+               +---------------+               +---------------+

总结

至此,我们完整介绍了方案三(提供两种虚拟机)的实现思路;通过在链上支持两种虚拟机,来使以太坊APP的开发者可以几乎无成本的进行生态迁移。



 

标签:EVM,虚拟机,+---------------+,Wasm,合约,字节
来源: https://blog.csdn.net/shangsongwww/article/details/92794878

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有