mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-11 21:04:11 +00:00
modexp precompile allow arbitrary input length
This commit is contained in:
parent
408394a2bd
commit
4e58f9d79a
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -217,3 +217,8 @@
|
||||
url = https://github.com/status-im/portal-spec-tests.git
|
||||
ignore = untracked
|
||||
branch = master
|
||||
[submodule "vendor/libtommath"]
|
||||
path = vendor/libtommath
|
||||
url = https://github.com/libtom/libtommath
|
||||
ignore = untracked
|
||||
branch = develop
|
||||
|
@ -78,6 +78,16 @@ proc rangeToPadded*[T: StUint](x: openArray[byte], first, last, size: int): T =
|
||||
allowPadding = true
|
||||
)
|
||||
|
||||
proc rangeToPadded*(x: openArray[byte], first, size: int): seq[byte] =
|
||||
let last = first + size - 1
|
||||
let lo = max(0, first)
|
||||
let hi = min(min(x.high, last), (lo+size)-1)
|
||||
|
||||
result = newSeq[byte](size)
|
||||
if not(lo <= hi):
|
||||
return # 0
|
||||
result[0..hi-lo] = x.toOpenArray(lo, hi)
|
||||
|
||||
# calculates the memory size required for a step
|
||||
func calcMemSize*(offset, length: int): int {.inline.} =
|
||||
if length.isZero: return 0
|
||||
|
218
nimbus/evm/modexp.nim
Normal file
218
nimbus/evm/modexp.nim
Normal file
@ -0,0 +1,218 @@
|
||||
import
|
||||
std/strutils
|
||||
|
||||
from os import DirSep, AltSep
|
||||
|
||||
const
|
||||
vendorPath = currentSourcePath.rsplit({DirSep, AltSep}, 3)[0] & "/vendor"
|
||||
srcPath = vendorPath & "/libtommath"
|
||||
|
||||
{.passc: "-IMP_32BIT"}
|
||||
{.compile: srcPath & "/mp_radix_size.c"}
|
||||
{.compile: srcPath & "/mp_to_radix.c"}
|
||||
{.compile: srcPath & "/mp_init_u64.c"}
|
||||
{.compile: srcPath & "/mp_init_i32.c"}
|
||||
{.compile: srcPath & "/mp_init_multi.c"}
|
||||
{.compile: srcPath & "/mp_init.c"}
|
||||
{.compile: srcPath & "/mp_init_size.c"}
|
||||
{.compile: srcPath & "/mp_init_copy.c"}
|
||||
{.compile: srcPath & "/mp_invmod.c"}
|
||||
{.compile: srcPath & "/mp_abs.c"}
|
||||
{.compile: srcPath & "/mp_set_u64.c"}
|
||||
{.compile: srcPath & "/mp_set_u32.c"}
|
||||
{.compile: srcPath & "/mp_set_i32.c"}
|
||||
{.compile: srcPath & "/mp_get_i32.c"}
|
||||
{.compile: srcPath & "/mp_get_i64.c"}
|
||||
{.compile: srcPath & "/mp_exptmod.c"}
|
||||
{.compile: srcPath & "/mp_clear_multi.c"}
|
||||
{.compile: srcPath & "/mp_clear.c"}
|
||||
{.compile: srcPath & "/mp_montgomery_reduce.c"}
|
||||
{.compile: srcPath & "/mp_clamp.c"}
|
||||
{.compile: srcPath & "/mp_grow.c"}
|
||||
{.compile: srcPath & "/mp_mul.c"}
|
||||
{.compile: srcPath & "/mp_mul_2.c"}
|
||||
{.compile: srcPath & "/mp_mul_2d.c"}
|
||||
{.compile: srcPath & "/mp_mod_2d.c"}
|
||||
{.compile: srcPath & "/mp_log_n.c"}
|
||||
{.compile: srcPath & "/mp_div_2.c"}
|
||||
{.compile: srcPath & "/mp_div_d.c"}
|
||||
{.compile: srcPath & "/mp_add.c"}
|
||||
{.compile: srcPath & "/mp_sub.c"}
|
||||
{.compile: srcPath & "/mp_exch.c"}
|
||||
{.compile: srcPath & "/mp_rshd.c"}
|
||||
{.compile: srcPath & "/mp_lshd.c"}
|
||||
{.compile: srcPath & "/mp_zero.c"}
|
||||
{.compile: srcPath & "/mp_dr_reduce.c"}
|
||||
{.compile: srcPath & "/mp_cmp_mag.c"}
|
||||
{.compile: srcPath & "/mp_cutoffs.c"}
|
||||
{.compile: srcPath & "/mp_reduce.c"}
|
||||
{.compile: srcPath & "/mp_count_bits.c"}
|
||||
{.compile: srcPath & "/mp_montgomery_setup.c"}
|
||||
{.compile: srcPath & "/mp_dr_setup.c"}
|
||||
{.compile: srcPath & "/mp_reduce_2k_setup.c"}
|
||||
{.compile: srcPath & "/mp_reduce_2k_setup_l.c"}
|
||||
{.compile: srcPath & "/mp_reduce_2k.c"}
|
||||
{.compile: srcPath & "/mp_reduce_2k_l.c"}
|
||||
{.compile: srcPath & "/mp_reduce_is_2k_l.c"}
|
||||
{.compile: srcPath & "/mp_reduce_is_2k.c"}
|
||||
{.compile: srcPath & "/mp_reduce_setup.c"}
|
||||
{.compile: srcPath & "/mp_dr_is_modulus.c"}
|
||||
{.compile: srcPath & "/mp_mulmod.c"}
|
||||
{.compile: srcPath & "/mp_set.c"}
|
||||
{.compile: srcPath & "/mp_mod.c"}
|
||||
{.compile: srcPath & "/mp_copy.c"}
|
||||
{.compile: srcPath & "/mp_div.c"}
|
||||
{.compile: srcPath & "/mp_div_2d.c"}
|
||||
{.compile: srcPath & "/mp_mul_d.c"}
|
||||
{.compile: srcPath & "/mp_2expt.c"}
|
||||
{.compile: srcPath & "/mp_cmp.c"}
|
||||
{.compile: srcPath & "/mp_cmp_d.c"}
|
||||
{.compile: srcPath & "/mp_log.c"}
|
||||
{.compile: srcPath & "/mp_sub_d.c"}
|
||||
{.compile: srcPath & "/mp_add_d.c"}
|
||||
{.compile: srcPath & "/mp_cnt_lsb.c"}
|
||||
{.compile: srcPath & "/mp_expt_n.c"}
|
||||
{.compile: srcPath & "/mp_get_mag_u32.c"}
|
||||
{.compile: srcPath & "/mp_get_mag_u64.c"}
|
||||
{.compile: srcPath & "/mp_from_ubin.c"}
|
||||
{.compile: srcPath & "/mp_ubin_size.c"}
|
||||
{.compile: srcPath & "/mp_to_ubin.c"}
|
||||
{.compile: srcPath & "/mp_montgomery_calc_normalization.c"}
|
||||
{.compile: srcPath & "/s_mp_exptmod.c"}
|
||||
{.compile: srcPath & "/s_mp_exptmod_fast.c"}
|
||||
{.compile: srcPath & "/s_mp_zero_digs.c"}
|
||||
{.compile: srcPath & "/s_mp_montgomery_reduce_comba.c"}
|
||||
{.compile: srcPath & "/s_mp_add.c"}
|
||||
{.compile: srcPath & "/s_mp_sub.c"}
|
||||
{.compile: srcPath & "/s_mp_mul.c"}
|
||||
{.compile: srcPath & "/s_mp_mul_comba.c"}
|
||||
{.compile: srcPath & "/s_mp_mul_toom.c"}
|
||||
{.compile: srcPath & "/s_mp_mul_karatsuba.c"}
|
||||
{.compile: srcPath & "/s_mp_mul_balance.c"}
|
||||
{.compile: srcPath & "/s_mp_copy_digs.c"}
|
||||
{.compile: srcPath & "/s_mp_div_3.c"}
|
||||
{.compile: srcPath & "/s_mp_sqr.c"}
|
||||
{.compile: srcPath & "/s_mp_sqr_comba.c"}
|
||||
{.compile: srcPath & "/s_mp_sqr_toom.c"}
|
||||
{.compile: srcPath & "/s_mp_sqr_karatsuba.c"}
|
||||
{.compile: srcPath & "/s_mp_zero_buf.c"}
|
||||
{.compile: srcPath & "/s_mp_radix_map.c"}
|
||||
{.compile: srcPath & "/s_mp_invmod.c"}
|
||||
{.compile: srcPath & "/s_mp_invmod_odd.c"}
|
||||
{.compile: srcPath & "/s_mp_mul_high.c"}
|
||||
{.compile: srcPath & "/s_mp_mul_high_comba.c"}
|
||||
{.compile: srcPath & "/s_mp_div_recursive.c"}
|
||||
{.compile: srcPath & "/s_mp_div_school.c"}
|
||||
{.compile: srcPath & "/s_mp_fp_log_d.c"}
|
||||
{.compile: srcPath & "/s_mp_fp_log.c"}
|
||||
|
||||
{.passc: "-I" & srcPath .}
|
||||
|
||||
type
|
||||
mp_int {.importc: "mp_int",
|
||||
header: "tommath.h", byref.} = object
|
||||
|
||||
mp_digit = uint32
|
||||
|
||||
mp_err {.importc: "mp_err",
|
||||
header: "tommath.h".} = cint
|
||||
|
||||
mp_ord = cint
|
||||
|
||||
{.pragma: mp_abi, importc, cdecl, header: "tommath.h".}
|
||||
|
||||
const
|
||||
MP_OKAY = 0.mp_err
|
||||
|
||||
MP_LT = -1
|
||||
MP_EQ = 0
|
||||
MP_GT = 1
|
||||
|
||||
template getPtr(z: untyped): untyped =
|
||||
when (NimMajor, NimMinor) > (1,6):
|
||||
z.addr
|
||||
else:
|
||||
z.unsafeAddr
|
||||
|
||||
# init a bignum
|
||||
# proc mp_init(a: mp_int): mp_err {.mp_abi.}
|
||||
# proc mp_init_size(a: mp_int, size: cint): mp_err {.mp_abi.}
|
||||
|
||||
# init multiple bignum, 2nd, 3rd, and soon use addr, terminated with nil
|
||||
proc mp_init_multi(mp: mp_int): mp_err {.mp_abi, varargs.}
|
||||
|
||||
# free a bignum
|
||||
proc mp_clear(a: mp_int) {.mp_abi.}
|
||||
|
||||
# clear multiple mp_ints, terminated with nil
|
||||
proc mp_clear_multi(mp: mp_int) {.mp_abi, varargs.}
|
||||
|
||||
# compare against a single digit
|
||||
proc mp_cmp_d(a: mp_int, b: mp_digit): mp_ord {.mp_abi.}
|
||||
|
||||
# conversion from/to big endian bytes
|
||||
proc mp_ubin_size(a: mp_int): csize_t {.mp_abi.}
|
||||
proc mp_from_ubin(a: mp_int, buf: ptr byte, size: csize_t): mp_err {.mp_abi.}
|
||||
proc mp_to_ubin(a: mp_int, buf: ptr byte, maxlen: csize_t, written: var csize_t): mp_err {.mp_abi.}
|
||||
|
||||
# Y = G**X (mod P)
|
||||
proc mp_exptmod(G, X, P, Y: mp_int): mp_err {.mp_abi.}
|
||||
|
||||
proc mp_get_i32(a: mp_int): int32 {.mp_abi.}
|
||||
proc mp_get_u32(a: mp_int): uint32 =
|
||||
cast[uint32](mp_get_i32(a))
|
||||
|
||||
# proc mp_init_u64(a: mp_int, b: uint64): mp_err {.mp_abi.}
|
||||
# proc mp_set_u64(a: mp_int, b: uint64) {.mp_abi.}
|
||||
|
||||
proc mp_to_radix(a: mp_int, str: ptr char, maxlen: csize_t, written: var csize_t, radix: cint): mp_err {.mp_abi.}
|
||||
proc mp_radix_size(a: mp_int, radix: cint, size: var csize_t): mp_err {.mp_abi.}
|
||||
|
||||
proc toString*(a: mp_int): string =
|
||||
var size: csize_t
|
||||
if mp_radix_size(a, 10.cint, size) != MP_OKAY:
|
||||
return
|
||||
if size.int == 0:
|
||||
return
|
||||
result = newString(size.int)
|
||||
if mp_to_radix(a, result[0].getPtr, size, size, 10.cint) != MP_OKAY:
|
||||
return
|
||||
result.setLen(size-1)
|
||||
|
||||
proc modExp*(b, e, m: openArray[byte]): seq[byte] =
|
||||
var
|
||||
base, exp, modulo, res: mp_int
|
||||
|
||||
if mp_init_multi(base, exp.addr, modulo.addr, nil) != MP_OKAY:
|
||||
return
|
||||
|
||||
if m.len > 0:
|
||||
discard mp_from_ubin(modulo, m[0].getPtr, m.len.csize_t)
|
||||
if mp_cmp_d(modulo, 1.mp_digit) <= MP_EQ:
|
||||
# EVM special case 1
|
||||
# If m == 0: EVM returns 0.
|
||||
# If m == 1: we can shortcut that to 0 as well
|
||||
mp_clear(modulo)
|
||||
return @[0.byte]
|
||||
|
||||
if e.len > 0:
|
||||
discard mp_from_ubin(exp, e[0].getPtr, e.len.csize_t)
|
||||
if mp_cmp_d(exp, 0.mp_digit) == MP_EQ:
|
||||
# EVM special case 2
|
||||
# If 0^0: EVM returns 1
|
||||
# For all x != 0, x^0 == 1 as well
|
||||
mp_clear_multi(exp, modulo.addr, nil)
|
||||
return @[1.byte]
|
||||
|
||||
if b.len > 0:
|
||||
discard mp_from_ubin(base, b[0].getPtr, b.len.csize_t)
|
||||
|
||||
if mp_exptmod(base, exp, modulo, res) == MP_OKAY:
|
||||
let size = mp_ubin_size(res)
|
||||
if size.int > 0:
|
||||
var written: csize_t
|
||||
result = newSeq[byte](size.int)
|
||||
discard mp_to_ubin(res, result[0].getPtr, size, written)
|
||||
result.setLen(written)
|
||||
|
||||
mp_clear_multi(base, exp.addr, modulo.addr, res.addr, nil)
|
@ -14,7 +14,8 @@ import
|
||||
./interpreter/[gas_meter, gas_costs, utils/utils_numeric],
|
||||
../errors, eth/[common, keys], chronicles,
|
||||
nimcrypto/[ripemd, sha2, utils], bncurve/[fields, groups],
|
||||
../common/evmforks
|
||||
../common/evmforks,
|
||||
./modexp
|
||||
|
||||
type
|
||||
PrecompileAddresses* = enum
|
||||
@ -162,47 +163,6 @@ proc identity*(computation: Computation) =
|
||||
computation.output = computation.msg.data
|
||||
#trace "Identity precompile", output = computation.output.toHex
|
||||
|
||||
proc modExpInternal(computation: Computation, baseLen, expLen, modLen: int, T: type StUint) =
|
||||
template data: untyped {.dirty.} =
|
||||
computation.msg.data
|
||||
|
||||
let
|
||||
base = data.rangeToPadded[:T](96, 95 + baseLen, baseLen)
|
||||
exp = data.rangeToPadded[:T](96 + baseLen, 95 + baseLen + expLen, expLen)
|
||||
modulo = data.rangeToPadded[:T](96 + baseLen + expLen, 95 + baseLen + expLen + modLen, modLen)
|
||||
|
||||
# TODO: specs mentions that we should return in "M" format
|
||||
# i.e. if Base and exp are uint512 and Modulo an uint256
|
||||
# we should return a 256-bit big-endian byte array
|
||||
|
||||
# Force static evaluation
|
||||
func zero(): array[T.bits div 8, byte] {.compileTime.} = discard
|
||||
func one(): array[T.bits div 8, byte] {.compileTime.} =
|
||||
when cpuEndian == bigEndian:
|
||||
result[0] = 1
|
||||
else:
|
||||
result[^1] = 1
|
||||
|
||||
# Start with EVM special cases
|
||||
let output = if modulo <= 1:
|
||||
# If m == 0: EVM returns 0.
|
||||
# If m == 1: we can shortcut that to 0 as well
|
||||
zero()
|
||||
elif exp.isZero():
|
||||
# If 0^0: EVM returns 1
|
||||
# For all x != 0, x^0 == 1 as well
|
||||
one()
|
||||
else:
|
||||
powmod(base, exp, modulo).toByteArrayBE
|
||||
|
||||
# maximum output len is the same as modLen
|
||||
# if it less than modLen, it will be zero padded at left
|
||||
if output.len >= modLen:
|
||||
computation.output = @(output[^modLen..^1])
|
||||
else:
|
||||
computation.output = newSeq[byte](modLen)
|
||||
computation.output[^output.len..^1] = output[0..^1]
|
||||
|
||||
proc modExpFee(c: Computation, baseLen, expLen, modLen: UInt256, fork: EVMFork): GasInt =
|
||||
template data: untyped {.dirty.} =
|
||||
c.msg.data
|
||||
@ -247,8 +207,6 @@ proc modExpFee(c: Computation, baseLen, expLen, modLen: UInt256, fork: EVMFork):
|
||||
let gasFee = if fork >= FkBerlin: gasCalc(mulComplexityEIP2565, GasQuadDivisorEIP2565)
|
||||
else: gasCalc(mulComplexity, GasQuadDivisor)
|
||||
|
||||
# let gasFee = gasCalc(mulComplexity, GasQuadDivisor)
|
||||
|
||||
if gasFee > high(GasInt).u256:
|
||||
raise newException(OutOfGas, "modExp gas overflow")
|
||||
|
||||
@ -282,21 +240,28 @@ proc modExp*(c: Computation, fork: EVMFork = FkByzantium) =
|
||||
c.output = @[]
|
||||
return
|
||||
|
||||
let maxBytes = max(baseLen, max(expLen, modLen))
|
||||
if maxBytes <= 32:
|
||||
c.modExpInternal(baseLen, expLen, modLen, UInt256)
|
||||
elif maxBytes <= 64:
|
||||
c.modExpInternal(baseLen, expLen, modLen, StUint[512])
|
||||
elif maxBytes <= 128:
|
||||
c.modExpInternal(baseLen, expLen, modLen, StUint[1024])
|
||||
elif maxBytes <= 256:
|
||||
c.modExpInternal(baseLen, expLen, modLen, StUint[2048])
|
||||
elif maxBytes <= 512:
|
||||
c.modExpInternal(baseLen, expLen, modLen, StUint[4096])
|
||||
elif maxBytes <= 1024:
|
||||
c.modExpInternal(baseLen, expLen, modLen, StUint[8192])
|
||||
const maxSize = int32.high.u256
|
||||
if baseL > maxSize or expL > maxSize or modL > maxSize:
|
||||
raise newException(EVMError, "The Nimbus VM doesn't support oversized modExp operand")
|
||||
|
||||
# TODO:
|
||||
# add EVM special case:
|
||||
# - modulo <= 1: return zero
|
||||
# - exp == zero: return one
|
||||
|
||||
let output = modExp(
|
||||
data.rangeToPadded(96, baseLen),
|
||||
data.rangeToPadded(96 + baseLen, expLen),
|
||||
data.rangeToPadded(96 + baseLen + expLen, modLen)
|
||||
)
|
||||
|
||||
# maximum output len is the same as modLen
|
||||
# if it less than modLen, it will be zero padded at left
|
||||
if output.len >= modLen:
|
||||
c.output = @(output[^modLen..^1])
|
||||
else:
|
||||
raise newException(EVMError, "The Nimbus VM doesn't support modular exponentiation with numbers larger than uint8192")
|
||||
c.output = newSeq[byte](modLen)
|
||||
c.output[^output.len..^1] = output[0..^1]
|
||||
|
||||
proc bn256ecAdd*(computation: Computation, fork: EVMFork = FkByzantium) =
|
||||
let gasFee = if fork < FkIstanbul: GasECAdd else: GasECAddIstanbul
|
||||
|
@ -9,7 +9,7 @@
|
||||
# according to those terms.
|
||||
|
||||
import
|
||||
std/[json, os, tables, strutils, options],
|
||||
std/[json, os, tables, strutils, options, times],
|
||||
unittest2,
|
||||
eth/rlp, eth/trie/trie_defs, eth/common/eth_types_rlp,
|
||||
stew/byteutils,
|
||||
@ -421,6 +421,8 @@ proc blockchainJsonMain*(debugMode = false) =
|
||||
when isMainModule:
|
||||
var message: string
|
||||
|
||||
let start = getTime()
|
||||
|
||||
## Processing command line arguments
|
||||
if test_config.processArguments(message) != test_config.Success:
|
||||
echo message
|
||||
@ -431,6 +433,8 @@ when isMainModule:
|
||||
quit(QuitSuccess)
|
||||
|
||||
blockchainJsonMain(true)
|
||||
let elpd = getTime() - start
|
||||
echo "TIME: ", elpd
|
||||
|
||||
# lastBlockHash -> every fixture has it, hash of a block header
|
||||
# genesisRLP -> NOT every fixture has it, rlp bytes of genesis block header
|
||||
|
@ -6,7 +6,7 @@
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
std/[strutils, tables, json, os, sets, options],
|
||||
std/[strutils, tables, json, os, sets, options, times],
|
||||
./test_helpers, ./test_allowed_to_fail,
|
||||
../nimbus/core/executor, test_config,
|
||||
../nimbus/transaction,
|
||||
@ -192,6 +192,8 @@ proc generalStateJsonMain*(debugMode = false) =
|
||||
when isMainModule:
|
||||
var message: string
|
||||
|
||||
let start = getTime()
|
||||
|
||||
## Processing command line arguments
|
||||
if processArguments(message) != Success:
|
||||
echo message
|
||||
@ -202,3 +204,5 @@ when isMainModule:
|
||||
quit(QuitSuccess)
|
||||
|
||||
generalStateJsonMain(true)
|
||||
let elpd = getTime() - start
|
||||
echo "TIME: ", elpd
|
||||
|
53
tools/evmstate/testdata/modexp-big-modulo.json
vendored
Normal file
53
tools/evmstate/testdata/modexp-big-modulo.json
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"FuzzyVM-0005291080bcae6f483e351511f01a9c3cec41b3d9162d661c1300ed62632ba1":{
|
||||
"env":{
|
||||
"currentCoinbase":"b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
|
||||
"currentDifficulty":"0x20000",
|
||||
"currentRandom":"0x0000000000000000000000000000000000000000000000000000000000020000",
|
||||
"currentGasLimit":"0x26e1f476fe1e22",
|
||||
"currentNumber":"0x1",
|
||||
"currentTimestamp":"0x3e8",
|
||||
"previousHash":"0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d",
|
||||
"currentBaseFee":"0x10"
|
||||
},
|
||||
"pre":{
|
||||
"0x000000000000000000000000000000ca1100f022":{
|
||||
"code":"0x6000608055585f4636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430fa3d6000593e5960002080557f0947b9382a3232f23448d43038803258605f434665363846658439306afa0080605f527f6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00607f527f806a0947b9382a3232f23448d43038803258605f434665363846658439306afa609f52600060bf53608060c053606a60c153600960c253604760c35360b960c453603860c553602a60c653603260c753603260c8534636468430",
|
||||
"storage":{},
|
||||
"balance":"0x0",
|
||||
"nonce":"0x0"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b":{
|
||||
"code":"0x",
|
||||
"storage":{},
|
||||
"balance":"0x3fffffffffffffff",
|
||||
"nonce":"0x0"
|
||||
}
|
||||
},
|
||||
"transaction":{
|
||||
"gasPrice":"0x80",
|
||||
"nonce":"0x0",
|
||||
"to":"0x000000000000000000000000000000ca1100f022",
|
||||
"data":[
|
||||
"0x6a0947b9382a3232f23448d43038803258605f434665363846658439306afa00806a0947b9382a3232f23448d43038803258605f434665363846658439306afa00806a0947b9382a3232f23448d43038803258605f434665363846658439306afa00806a"
|
||||
],
|
||||
"gasLimit":["0x1312d00"],
|
||||
"value":["0x6afa0080"],
|
||||
"secretKey":"0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
||||
},
|
||||
"out":"0x",
|
||||
"post":{
|
||||
"Shanghai":[
|
||||
{
|
||||
"hash":"0x6adb86e08a2be12ee2354356cd2aaea54656c42652a650f60940cc65280fa92a",
|
||||
"logs":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"indexes":{
|
||||
"data":0,
|
||||
"gas":0,
|
||||
"value":0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
1
vendor/libtommath
vendored
Submodule
1
vendor/libtommath
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 0df542cb70f621bbeec207be1949832fb1442479
|
Loading…
x
Reference in New Issue
Block a user