4 个版本

0.11.0 2019年5月7日
0.11.0-beta.32019年4月29日
0.11.0-beta.22019年4月28日
0.11.0-beta.02019年4月24日

#17 in #pre-compiled

Apache-2.0 和可能 GPL-3.0

28KB
308 代码行数,不包括注释

网络无关性 SputnikVM 补丁

此软件包提供 DynamicPatch API 的重导出,以及一组覆盖 ETH Constantinople 的预编译合约

EVM 配置有两种主要方法

以下提供两种方法的示例

动态补丁 API

DynamicPatch API 对于多网络客户端(如多 geth)最有用,在这些客户端中,按功能而不是分叉配置 EVM 是首选。

示例

use evm::{SeqTransactionVM, ValidTransaction, TransactionAction, HeaderParams};
use evm_network::{DynamicPatch, DynamicAccountPatch, PRECOMPILEDS};
use bigint::{Gas, U256, Address};
use std::rc::Rc;

fn main() {
  let transaction = ValidTransaction {
     caller: Some(Address::default()),
     gas_price: Gas::zero(),
     gas_limit: Gas::max_value(),
     action: TransactionAction::Create,
     value: U256::zero(),
     input: Rc::new(Vec::new()),
     nonce: U256::zero()
  };

  // Block Header
  let header = HeaderParams {
     beneficiary: Address::default(),
     timestamp: 0,
     number: U256::zero(),
     difficulty: U256::zero(),
     gas_limit: Gas::zero()
  };

  // Account Patch for ETC MainNet
  let account_patch = DynamicAccountPatch {
     initial_nonce: U256::zero(),
     initial_create_nonce: U256::zero(),
     empty_considered_exists: true,
     allow_partial_change: true
  };

  // Patch for Constantinople hardfork
  let patch = DynamicPatch {
     account_patch,
     code_deposit_limit: None,
     callstack_limit: 1024,
     gas_extcode: Gas::from(700_usize),
     gas_balance: Gas::from(400_usize),
     gas_sload: Gas::from(200_usize),
     gas_suicide: Gas::from(5000_usize),
     gas_suicide_new_account: Gas::from(25000_usize),
     gas_call: Gas::from(700_usize),
     gas_expbyte: Gas::from(50_usize),
     gas_transaction_create: Gas::from(32000_usize),
     force_code_deposit: false,
     has_delegate_call: true,
     has_static_call: true,
     has_revert: true,
     has_return_data: true,
     has_bitwise_shift: true,
     has_extcodehash: true,
     has_create2: true,
     has_reduced_sstore_gas_metering: true,
     err_on_call_with_more_gas: false,
     call_create_l64_after_gas: true,
     memory_limit: usize::max_value(),
     // Enable all eight precompiled contracts by their addresses
     enabled_precompileds: (0x1..=0x8).into_iter().map(Address::from).collect(),
     precompileds: &PRECOMPILEDS
  };

  SeqTransactionVM::new(
      &patch,
      transaction,
      header
  );
}

补丁 API

如果您只需要单个网络或单个功能集,请直接使用 Patch 特性,它允许创建自定义功能集,而无需 DynamicPatch 的小额开销。

示例

use evm::{SeqTransactionVM, ValidTransaction, TransactionAction, HeaderParams, Precompiled};
use evm_network::{AccountPatch, Patch, PRECOMPILEDS};
use bigint::{Gas, U256, Address};
use std::rc::Rc;

struct MainnetAccountPatch;
impl AccountPatch for MainnetAccountPatch {
   fn initial_nonce(&self) -> U256 { U256::zero() }
   fn initial_create_nonce(&self) -> U256 { U256::zero() }
   fn empty_considered_exists(&self) -> bool { true }
}

static MAINNET_ACCOUNT_PATCH: MainnetAccountPatch = MainnetAccountPatch;

struct ConstantinoplePatch;
impl Patch for ConstantinoplePatch {
   type Account = MainnetAccountPatch;
   fn account_patch(&self) -> &'static Self::Account { &MAINNET_ACCOUNT_PATCH }
   fn code_deposit_limit(&self) -> Option<usize> { None }
   fn callstack_limit(&self) -> usize { 1024 }
   fn gas_extcode(&self) -> Gas { Gas::from(700usize) }
   fn gas_balance(&self) -> Gas { Gas::from(400usize) }
   fn gas_sload(&self) -> Gas { Gas::from(200usize) }
   fn gas_suicide(&self) -> Gas { Gas::from(5000usize) }
   fn gas_suicide_new_account(&self) -> Gas { Gas::from(25000usize) }
   fn gas_call(&self) -> Gas { Gas::from(700usize) }
   fn gas_expbyte(&self) -> Gas { Gas::from(50usize) }
   fn gas_transaction_create(&self) -> Gas { Gas::from(32000usize) }
   fn force_code_deposit(&self) -> bool { false }
   fn has_delegate_call(&self) -> bool { true }
   fn has_static_call(&self) -> bool { true }
   fn has_revert(&self) -> bool { true }
   fn has_return_data(&self) -> bool { true }
   fn has_bitwise_shift(&self) -> bool { true }
   fn has_create2(&self) -> bool { true }
   fn has_extcodehash(&self) -> bool { true }
   fn has_reduced_sstore_gas_metering(&self) -> bool { true }
   fn err_on_call_with_more_gas(&self) -> bool { false }
   fn call_create_l64_after_gas(&self) -> bool { true }
   fn memory_limit(&self) -> usize { usize::max_value() }
   fn is_precompiled_contract_enabled(&self, address: &Address) -> bool {
       match address.low_u64() {
           0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 | 0x7 | 0x8 => true,
           _ => false,
       }
   }
   fn precompileds(&self) -> &'static [(Address, Option<&'static [u8]>, &'static Precompiled)] {
       &PRECOMPILEDS
   }
}


fn main() {
  let transaction = ValidTransaction {
     caller: Some(Address::default()),
     gas_price: Gas::zero(),
     gas_limit: Gas::max_value(),
     action: TransactionAction::Create,
     value: U256::zero(),
     input: Rc::new(Vec::new()),
     nonce: U256::zero()
  };

  // Block Header
  let header = HeaderParams {
     beneficiary: Address::default(),
     timestamp: 0,
     number: U256::zero(),
     difficulty: U256::zero(),
     gas_limit: Gas::zero()
  };

  let patch = ConstantinoplePatch;

  SeqTransactionVM::new(
      &patch,
      transaction,
      header
  );
}

依赖关系

~6MB
~53K SLoC