帮酷LOGO
  • 显示原文与译文双语对照的内容
文章标签:IMP  
the ethereum VM implemented in JS

  • 源代码名称:ethereumjs-vm
  • 源代码网址:http://www.github.com/ethereumjs/ethereumjs-vm
  • ethereumjs-vm源代码文档
  • ethereumjs-vm源代码下载
  • Git URL:
    git://www.github.com/ethereumjs/ethereumjs-vm.git
  • Git Clone代码到本地:
    git clone http://www.github.com/ethereumjs/ethereumjs-vm
  • Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/ethereumjs/ethereumjs-vm
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
  • 概要

    NPM PackageBuild StatusCoverage StatusGitter freenode上的或者 #ethereumjs

    js-standard-style

    在Javascript中实现ethereum的VM 。

    fork-支持

    这个库只支持当前活跃的Ethereum mainnet fork 规则及其最新版本,一旦出现 HF,旧的fork 规则就会被丢弃。

    当前主要的版本版本支持 Byzantium版本更改。 对于 Spurious Spurious兼容版本的库安装最新的2.2.x 系列。

    安装

    npm install ethereumjs-vm

    用法
    varVM=require('ethereumjs-vm')//create a new VM instancevar vm =newVM()var code ='7f4e616d65526567000000000000000000000000000000000000000000000000003055307f4e616d6552656700000000000000000000000000000000000000000000000000557f436f6e666967000000000000000000000000000000000000000000000000000073661005d2720d855f1d9976f88bb10c1a3398c77f5573661005d2720d855f1d9976f88bb10c1a3398c77f7f436f6e6669670000000000000000000000000000000000000000000000000000553360455560df806100c56000396000f3007f726567697374657200000000000000000000000000000000000000000000000060003514156053576020355415603257005b335415603e5760003354555b6020353360006000a233602035556020353355005b60007f756e72656769737465720000000000000000000000000000000000000000000060003514156082575033545b1560995733335460006000a2600033545560003355005b60007f6b696c6c00000000000000000000000000000000000000000000000000000000600035141560cb575060455433145b1560d25733ff5b6000355460005260206000f3'vm.runCode({
     code:Buffer.from(code, 'hex'), // code needs to be a Buffer gasLimit:Buffer.from('ffffffff', 'hex')
    }, function(err, results){
     console.log('returned: '+results.return.toString('hex'));
    })

    这里还可以找到更多的例子

    浏览器

    若要在浏览器中独立使用,请安装 browserify 并检查 run-transactions-simple示例。 这将给你一个全局变量 EthVM 来使用。 生成的文件将位于 ./examples/run-transactions-simple/build.js

    API

    new VM([opts])

    创建新的虚拟机对象

    • opts
      • stateManager - 状态管理器实例( 实验 - 不稳定的API )
      • state - 状态树的merkle-patricia-tree实例( 如果通过 stateManager,则忽略)
      • blockchain - 用于存储/检索块的区块对象( 如果传递 stateManager 时忽略)
      • activatePrecompiles - 在状态树中为预编译协定创建条目

    VM 方法

    vm.runBlockchain(blockchain, cb)

    进程块并将它们添加到区块区块中。

    vm.runBlock(opts, cb)

    处理运行所有事务的block,并更新挖掘器的帐户。

    • opts.block 要处理的block
    • opts.generate - Boolean,是否生成 stateRoot 。 如果 false runBlock 将根据Trie检查 block的stateRoot
    • 返回包含可能发生的错误或者 null,以及具有以下属性的results 对象的字符串:
      • receipts - 块中交易的收据
      • results - 块中事务的结果的array
    vm.runTx(opts, cb)

    处理事务。

    • opts.tx 一个 Transaction 运行。
    • opts.block - tx 所属的block 。 如果省略,将使用空白 block 。
    • 返回包含可能发生的错误或者 null,以及具有以下属性的results 对象的字符串:
    vm.runCode(opts, cb)

    运行EVM代码

    • opts.code - 作为 Buffer 运行的EVM代码
    • opts.data - 作为 Buffer 输入的输入数据
    • opts.value - 正被发送到 opt.address的以太网中的值。 默认为 0
    • opts.block - blocktx 属于。 如果省略,将使用空白 block 。
    • opts.gasLimit - 作为 Buffer 提供的代码的气体限制
    • opts.account: 执行代码所属的Account 。 如果省略,将使用空账户
    • opts.address - 执行这里代码的帐户的地址。 地址应该是字节的Buffer 。 默认为 0
    • opts.origin - 呼叫来源的地址。 地址应该是 20位的Buffer 。 默认为 0
    • opts.caller - 运行这里代码的地址。 地址应该是 20位的Buffer 。 默认为 0
    • 返回一个包含可能发生的错误或者 nullresults 对象的两个参数,带有以下属性
      • gas - 作为 bignum的剩余气体量
      • gasUsed - 作为 bignum的气体数量用于运行的代码。
      • gasRefund - 包含从存储值中删除的气体数量的bignum
      • selfdestruct - 带有密钥的Object,具有用于平衡传输收件人帐户的selfdestructed和值。
      • logs - 协定发出的日志的Array
      • exception - 0 如果协定遇到异常,则为 1
      • exceptionError - 描述异常的String,如果有的话。
      • return - 包含由协定返回的值的Buffer
    vm.stateManager.generateCanonicalGenesis(cb)

    生成规范的起始状态。

    vm.stateManager.generateGenesis(genesisData, cb)

    生成产生状态。

    • genesisData - 一个密钥是地址和值的Object,它的String 表示初始值的初始分配。
    • cb - 回调
    var genesisData = {
     "51ba59315b3a95761d0863b05ccc7a7f54703d99":"1606938044258990275541962092341162602522202993782792835301376",
     "e4157b34ea9615cfbde6b4fda419828124b70c78":"1606938044258990275541962092341162602522202993782792835301376"}vm.generateGenesis(genesisData, function(){
     console.log('generation done');
    })

    events

    所有事件都是异步eventemmiter的实例。 如果事件处理程序的数量为 2,VM将暂停,直到调用回调

    step

    step 事件被赋予一个 Object 和回调。 Object 具有以下属性。

    • pc - 表示程序计数器的Number
    • opcode - 要运行的下一个操作码
    • gasLeft - 支持gasLeft数量的bignum
    • stack - 包含堆栈的BuffersArray
    • storageTrie - 帐户的存储 trie
    • Account: 拥有代码运行的 Account 插件。
    • address - Account的地址
    • depth - 合同中当前调用的次数
    • memory - 将虚拟机的内存作为 Buffer
    • cache - 帐户缓存。 包含从trie树加载的所有帐户。 它是一个功能红 black 树的实例。
    beforeBlock

    发出即将处理的block 。

    afterBlock

    将处理结果的结果发送到块。

    beforeTx

    发出即将处理的事务。

    afterTx

    发出事务的结果。

    内部结构

    虚拟机在多个级别上处理状态更改。

    • runBlockchain
      • 对于每个 block,runBlock
    • runBlock
      • 对于每个 tx,runTx
      • pay miner
    • runTx
      • 检查发件人余额
      • 检查发件人临时
      • runCall
      • 转移气体电荷
    • runCall
      • 检查点状态
      • 传输值
      • 加载代码
      • runCode
      • 创建创建的合同
      • 还原或者提交检查点
    • runCode
      • 迭代代码
      • 运行操作代码
      • 跟踪气体使用情况
    • OpFns
      • 运行单个操作代码
      • 修改堆栈
      • 修改内存
      • 计算费用

    CREATECALLCALLCODE 调用的opFns返回到 runCall

    测试

    运行测试

    测试可以在 tests 目录中找到,FORK_CONFIG 设置为 tests/tester.jsState测试runners和区块链测试 。 由于边界燃气成本不再受支持,虚拟机测试被禁用。 然后由 ethereumjs测试工具库执行测试,使用正式客户端独立的Ethereum测试工具。

    关于如何使用测试实现eip的更多图片,你可以查看这个 reddit帖子,或者有关与ethereumjs虚拟机开发的核心开发相关的视频介绍。

    正在运行不同的测试类型

    运行所有测试:

    npm test

    运行状态测试:

    node./tests/tester -s

    正在运行区块链测试:

    node./tests/tester -b

    还可以针对 dist 文件夹运行状态测试和链链测试( 默认为: lib ):

    node./tests/tester -b --dist

    状态测试运行的速度比块测试快,因这里通常是开始修复状态测试的好选择。

    正在运行特定测试

    在 file: 中运行所有区块区块测试

    node./tests/tester -b --file='randomStatetest303'

    从特定目录运行测试:

    node./tests/tester -b --dir='bcBlockGasLimitTest'

    运行特定状态测试用例:

    node./tests/tester -s --test='stackOverflow'

    只运行选定的datagas 和/或者 value 值( 请参见测试文档中的属性描述 )的测试用例,由测试 Transaction 部分的array 元素索引提供:

    node tests/tester -s --test='CreateCollisionToEmpty' --data=0 --gas=1 --value=0

    从不在 tests 目录下的指定源文件运行状态测试: node./tests/tester -s --customStateTest='{path_to_file}'

    跳过测试

    有三种类型的跳过列表( 。BROKENPERMANENTSLOW ) 可以在 tests/tester.js 中找到。 默认情况下,忽略所有跳过列表中的测试。

    你可以通过以下方式更改这里行为:

    node tests/tester -s --skip=BROKEN,PERMANENT

    仅跳过 BROKENPERMANENT 测试,并包括 SLOW 测试。 还有 NONE 或者 ALL的关键字用于方便。

    也可以只运行跳过列表中的测试:

    node tests/tester -s --runSkipped=SLOW

    命令行调试

    本地调试

    对于状态测试,你可以使用 --jsontrace 标志输出操作码跟踪信息。

    链区块测试支持 --debug 来验证 postState:

    node./tests/tester -b --debug --test='ZeroValue_SELFDESTRUCT_ToOneStorageKey_OOGRevert_d0g0v0_EIP158'

    all测试版本 repo 中的Blockchain测试版本debugging中的debugging测试版本 can replicated/大多数状态测试复制为链块测试( 在Ethereum测试中),以便调试单个测试用例。

    命令行调试工具

    为了比较 EVM 跟踪,这里是一些设置 pyethereum 以生成状态测试对应跟踪的说明。

    比较区块/状态测试中的点击输出,并生成( 范例) 之间的差异的简明差异:

    curl https://gist.githubusercontent.com/jwasinger/6cef66711b5e0787667ceb3db6bea0dc/raw/0740f03b4ce90d0955d5aba1e0c30ce698c7145a/gistfile1.txt> output-wip-byzantium.txt
    curl https://gist.githubusercontent.com/jwasinger/e7004e82426ff0a7137a88d273f11819/raw/66fbd58722747ebe4f7006cee59bbe22461df8eb/gistfile1.txt> output-master.txt
    python utils/diffTestOutput.py output-wip-byzantium.txt output-master.txt

    一个非常丰富且强大的工具箱是来自的 evmlab插件,用于调试和创建新测试用例或者示例数据。

    许可证

    MPL-2.0



    文章标签:IMP  

    Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语