mirror of https://github.com/status-im/nim-eth.git
implement eip2718: transaction type envelope
also add more test cases for both tx and receipt rlp encoding decoding
This commit is contained in:
parent
8890175b6a
commit
61d5327f55
|
@ -8,11 +8,8 @@ export
|
||||||
|
|
||||||
type
|
type
|
||||||
Hash256* = MDigest[256]
|
Hash256* = MDigest[256]
|
||||||
|
|
||||||
EthTime* = Time
|
EthTime* = Time
|
||||||
|
|
||||||
VMWord* = UInt256
|
VMWord* = UInt256
|
||||||
|
|
||||||
BlockNonce* = array[8, byte]
|
BlockNonce* = array[8, byte]
|
||||||
AccountNonce* = uint64
|
AccountNonce* = uint64
|
||||||
Blob* = seq[byte]
|
Blob* = seq[byte]
|
||||||
|
@ -33,23 +30,61 @@ type
|
||||||
ForkID* = tuple[crc: uint32, nextFork: uint64]
|
ForkID* = tuple[crc: uint32, nextFork: uint64]
|
||||||
# EIP 2364/2124
|
# EIP 2364/2124
|
||||||
|
|
||||||
|
BlockNumber* = UInt256
|
||||||
|
StorageKey* = array[32, byte]
|
||||||
|
|
||||||
|
# beware that although in some cases
|
||||||
|
# chainId have identical value to networkId
|
||||||
|
# they are separate entity
|
||||||
|
ChainId* = distinct uint64
|
||||||
|
|
||||||
Account* = object
|
Account* = object
|
||||||
nonce*: AccountNonce
|
nonce*: AccountNonce
|
||||||
balance*: UInt256
|
balance*: UInt256
|
||||||
storageRoot*: Hash256
|
storageRoot*: Hash256
|
||||||
codeHash*: Hash256
|
codeHash*: Hash256
|
||||||
|
|
||||||
Transaction* = object
|
LegacyTx* = object
|
||||||
accountNonce*: AccountNonce
|
nonce* : AccountNonce
|
||||||
gasPrice*: GasInt
|
gasPrice*: GasInt
|
||||||
gasLimit*: GasInt
|
gasLimit*: GasInt
|
||||||
to* {.rlpCustomSerialization.}: EthAddress
|
to* {.rlpCustomSerialization.}: EthAddress
|
||||||
value* : UInt256
|
value* : UInt256
|
||||||
payload* : Blob
|
payload* : Blob
|
||||||
V*: byte
|
V* : int64
|
||||||
R*, S* : UInt256
|
R*, S* : UInt256
|
||||||
isContractCreation* {.rlpIgnore.}: bool
|
isContractCreation* {.rlpIgnore.}: bool
|
||||||
|
|
||||||
|
AccessPair* = object
|
||||||
|
address* : EthAddress
|
||||||
|
storageKeys*: seq[StorageKey]
|
||||||
|
|
||||||
|
AccessList* = seq[AccessPair]
|
||||||
|
|
||||||
|
AccessListTx* = object
|
||||||
|
chainId* {.rlpCustomSerialization.}: ChainId
|
||||||
|
nonce* : AccountNonce
|
||||||
|
gasPrice* : GasInt
|
||||||
|
gasLimit* : GasInt
|
||||||
|
to* {.rlpCustomSerialization.}: EthAddress
|
||||||
|
value* : UInt256
|
||||||
|
payload* : Blob
|
||||||
|
accessList*: AccessList
|
||||||
|
V* : int64
|
||||||
|
R*, S* : UInt256
|
||||||
|
isContractCreation* {.rlpIgnore.}: bool
|
||||||
|
|
||||||
|
TxType* = enum
|
||||||
|
LegacyTxType
|
||||||
|
AccessListTxType
|
||||||
|
|
||||||
|
Transaction* = object
|
||||||
|
case txType*: TxType
|
||||||
|
of LegacyTxType:
|
||||||
|
legacyTx*: LegacyTx
|
||||||
|
of AccessListTxType:
|
||||||
|
accessListTx*: AccessListTx
|
||||||
|
|
||||||
TransactionStatus* = enum
|
TransactionStatus* = enum
|
||||||
Unknown,
|
Unknown,
|
||||||
Queued,
|
Queued,
|
||||||
|
@ -61,8 +96,6 @@ type
|
||||||
status*: TransactionStatus
|
status*: TransactionStatus
|
||||||
data*: Blob
|
data*: Blob
|
||||||
|
|
||||||
BlockNumber* = UInt256
|
|
||||||
|
|
||||||
BlockHeader* = object
|
BlockHeader* = object
|
||||||
parentHash*: Hash256
|
parentHash*: Hash256
|
||||||
ommersHash*: Hash256
|
ommersHash*: Hash256
|
||||||
|
@ -96,24 +129,33 @@ type
|
||||||
else:
|
else:
|
||||||
status*: bool
|
status*: bool
|
||||||
|
|
||||||
Receipt* = object
|
LegacyReceipt* = object
|
||||||
stateRootOrStatus*: HashOrStatus
|
stateRootOrStatus*: HashOrStatus
|
||||||
cumulativeGasUsed*: GasInt
|
cumulativeGasUsed*: GasInt
|
||||||
bloom*: BloomFilter
|
bloom*: BloomFilter
|
||||||
logs* : seq[Log]
|
logs* : seq[Log]
|
||||||
|
|
||||||
AccessList* = object
|
AccessListReceipt* = object
|
||||||
# XXX: Specify the structure of this
|
status*: bool
|
||||||
|
cumulativeGasUsed*: GasInt
|
||||||
|
bloom* : BloomFilter
|
||||||
|
logs* : seq[Log]
|
||||||
|
|
||||||
ShardTransaction* = object
|
ReceiptType* = enum
|
||||||
chain*: uint
|
LegacyReceiptType
|
||||||
shard*: uint
|
AccessListReceiptType
|
||||||
to*: EthAddress
|
|
||||||
data*: Blob
|
Receipt* = object
|
||||||
gas*: GasInt
|
case receiptType*: ReceiptType
|
||||||
accessList*: AccessList
|
of LegacyReceiptType:
|
||||||
code*: Blob
|
legacyReceipt*: LegacyReceipt
|
||||||
salt*: Hash256
|
of AccessListReceiptType:
|
||||||
|
accessListReceipt*: AccessListReceipt
|
||||||
|
|
||||||
|
EthBlock* = object
|
||||||
|
header*: BlockHeader
|
||||||
|
txs* : seq[Transaction]
|
||||||
|
uncles*: seq[BlockHeader]
|
||||||
|
|
||||||
CollationHeader* = object
|
CollationHeader* = object
|
||||||
shard*: uint
|
shard*: uint
|
||||||
|
@ -232,17 +274,17 @@ proc hashOrStatus*(hash: Hash256): HashOrStatus =
|
||||||
proc hashOrStatus*(status: bool): HashOrStatus =
|
proc hashOrStatus*(status: bool): HashOrStatus =
|
||||||
HashOrStatus(isHash: false, status: status)
|
HashOrStatus(isHash: false, status: status)
|
||||||
|
|
||||||
proc hasStatus*(rec: Receipt): bool {.inline.} =
|
proc hasStatus*(rec: LegacyReceipt): bool {.inline.} =
|
||||||
rec.stateRootOrStatus.isHash == false
|
rec.stateRootOrStatus.isHash == false
|
||||||
|
|
||||||
proc hasStateRoot*(rec: Receipt): bool {.inline.} =
|
proc hasStateRoot*(rec: LegacyReceipt): bool {.inline.} =
|
||||||
rec.stateRootOrStatus.isHash == true
|
rec.stateRootOrStatus.isHash == true
|
||||||
|
|
||||||
proc stateRoot*(rec: Receipt): Hash256 {.inline.} =
|
proc stateRoot*(rec: LegacyReceipt): Hash256 {.inline.} =
|
||||||
doAssert(rec.hasStateRoot)
|
doAssert(rec.hasStateRoot)
|
||||||
rec.stateRootOrStatus.hash
|
rec.stateRootOrStatus.hash
|
||||||
|
|
||||||
proc status*(rec: Receipt): int {.inline.} =
|
proc status*(rec: LegacyReceipt): int {.inline.} =
|
||||||
doAssert(rec.hasStatus)
|
doAssert(rec.hasStatus)
|
||||||
if rec.stateRootOrStatus.status: 1 else: 0
|
if rec.stateRootOrStatus.status: 1 else: 0
|
||||||
|
|
||||||
|
@ -250,7 +292,7 @@ proc status*(rec: Receipt): int {.inline.} =
|
||||||
# Rlp serialization:
|
# Rlp serialization:
|
||||||
#
|
#
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: typedesc[StUint]): T {.inline.} =
|
proc read*(rlp: var Rlp, T: type StUint): T {.inline.} =
|
||||||
if rlp.isBlob:
|
if rlp.isBlob:
|
||||||
let bytes = rlp.toBytes
|
let bytes = rlp.toBytes
|
||||||
if bytes.len > 0:
|
if bytes.len > 0:
|
||||||
|
@ -275,7 +317,7 @@ proc append*(rlpWriter: var RlpWriter, value: StUint) =
|
||||||
else:
|
else:
|
||||||
rlpWriter.append(value.truncate(int))
|
rlpWriter.append(value.truncate(int))
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: typedesc[Stint]): T {.inline.} =
|
proc read*(rlp: var Rlp, T: type Stint): T {.inline.} =
|
||||||
# The Ethereum Yellow Paper defines the RLP serialization only
|
# The Ethereum Yellow Paper defines the RLP serialization only
|
||||||
# for unsigned integers:
|
# for unsigned integers:
|
||||||
{.fatal: "RLP serialization of signed integers is not allowed".}
|
{.fatal: "RLP serialization of signed integers is not allowed".}
|
||||||
|
@ -287,20 +329,53 @@ proc append*(rlpWriter: var RlpWriter, value: Stint) =
|
||||||
{.fatal: "RLP serialization of signed integers is not allowed".}
|
{.fatal: "RLP serialization of signed integers is not allowed".}
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, t: var Transaction, _: type EthAddress): EthAddress {.inline.} =
|
type
|
||||||
|
TxTypes = LegacyTx | AccessListTx
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, t: var TxTypes, _: type EthAddress): EthAddress {.inline.} =
|
||||||
if rlp.blobLen != 0:
|
if rlp.blobLen != 0:
|
||||||
result = rlp.read(EthAddress)
|
result = rlp.read(EthAddress)
|
||||||
else:
|
else:
|
||||||
t.isContractCreation = true
|
t.isContractCreation = true
|
||||||
rlp.skipElem()
|
rlp.skipElem()
|
||||||
|
|
||||||
proc append*(rlpWriter: var RlpWriter, t: Transaction, a: EthAddress) {.inline.} =
|
proc append*(rlpWriter: var RlpWriter, t: TxTypes, a: EthAddress) {.inline.} =
|
||||||
if t.isContractCreation:
|
if t.isContractCreation:
|
||||||
rlpWriter.append("")
|
rlpWriter.append("")
|
||||||
else:
|
else:
|
||||||
rlpWriter.append(a)
|
rlpWriter.append(a)
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: typedesc[HashOrStatus]): T {.inline.} =
|
proc read*(rlp: var Rlp, t: var AccessListTx, _: type ChainId): ChainId {.inline.} =
|
||||||
|
rlp.read(uint64).ChainId
|
||||||
|
|
||||||
|
proc append*(rlpWriter: var RlpWriter, t: AccessListTx, a: ChainId) {.inline.} =
|
||||||
|
rlpWriter.append(a.uint64)
|
||||||
|
|
||||||
|
proc append*(rlpWriter: var RlpWriter, tx: Transaction) =
|
||||||
|
if tx.txType == LegacyTxType:
|
||||||
|
rlpWriter.append(tx.legacyTx)
|
||||||
|
else:
|
||||||
|
var rw = initRlpWriter()
|
||||||
|
rw.append(1)
|
||||||
|
rw.append(tx.accessListTx)
|
||||||
|
rlpWriter.append(rw.finish())
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, T: type Transaction): T =
|
||||||
|
if rlp.isList:
|
||||||
|
result = Transaction(
|
||||||
|
txType: LegacyTxType,
|
||||||
|
legacyTx: rlp.read(LegacyTx)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
let bytes = rlp.read(Blob)
|
||||||
|
var rr = rlpFromBytes(bytes)
|
||||||
|
assert(rr.read(int) == 1)
|
||||||
|
result = Transaction(
|
||||||
|
txType: AccessListTxType,
|
||||||
|
accessListTx: rr.read(AccessListTx)
|
||||||
|
)
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, T: type HashOrStatus): T {.inline.} =
|
||||||
if rlp.isBlob() and (rlp.blobLen() == 32 or rlp.blobLen() == 1):
|
if rlp.isBlob() and (rlp.blobLen() == 32 or rlp.blobLen() == 1):
|
||||||
if rlp.blobLen == 1:
|
if rlp.blobLen == 1:
|
||||||
result = hashOrStatus(rlp.read(uint8) == 1)
|
result = hashOrStatus(rlp.read(uint8) == 1)
|
||||||
|
@ -334,7 +409,31 @@ proc append*(rlpWriter: var RlpWriter, value: HashOrStatus) {.inline.} =
|
||||||
else:
|
else:
|
||||||
rlpWriter.append(if value.status: 1'u8 else: 0'u8)
|
rlpWriter.append(if value.status: 1'u8 else: 0'u8)
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: typedesc[Time]): T {.inline.} =
|
proc append*(rlpWriter: var RlpWriter, rec: Receipt) =
|
||||||
|
if rec.receiptType == LegacyReceiptType:
|
||||||
|
rlpWriter.append(rec.legacyReceipt)
|
||||||
|
else:
|
||||||
|
var rw = initRlpWriter()
|
||||||
|
rw.append(1)
|
||||||
|
rw.append(rec.accessListReceipt)
|
||||||
|
rlpWriter.append(rw.finish())
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, T: type Receipt): T =
|
||||||
|
if rlp.isList:
|
||||||
|
result = Receipt(
|
||||||
|
receiptType: LegacyReceiptType,
|
||||||
|
legacyReceipt: rlp.read(LegacyReceipt)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
let bytes = rlp.read(Blob)
|
||||||
|
var rr = rlpFromBytes(bytes)
|
||||||
|
assert(rr.read(int) == 1)
|
||||||
|
result = Receipt(
|
||||||
|
receiptType: AccessListReceiptType,
|
||||||
|
accessListReceipt: rr.read(AccessListReceipt)
|
||||||
|
)
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, T: type Time): T {.inline.} =
|
||||||
result = fromUnix(rlp.read(int64))
|
result = fromUnix(rlp.read(int64))
|
||||||
|
|
||||||
proc append*(rlpWriter: var RlpWriter, value: HashOrNum) =
|
proc append*(rlpWriter: var RlpWriter, value: HashOrNum) =
|
||||||
|
@ -344,7 +443,7 @@ proc append*(rlpWriter: var RlpWriter, value: HashOrNum) =
|
||||||
else:
|
else:
|
||||||
rlpWriter.append(value.number)
|
rlpWriter.append(value.number)
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, T: typedesc[HashOrNum]): T =
|
proc read*(rlp: var Rlp, T: type HashOrNum): T =
|
||||||
if rlp.blobLen == 32:
|
if rlp.blobLen == 32:
|
||||||
result = HashOrNum(isHash: true, hash: rlp.read(Hash256))
|
result = HashOrNum(isHash: true, hash: rlp.read(Hash256))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -2,8 +2,8 @@ import
|
||||||
nimcrypto/keccak,
|
nimcrypto/keccak,
|
||||||
".."/[common, rlp, keys]
|
".."/[common, rlp, keys]
|
||||||
|
|
||||||
proc initTransaction*(nonce: AccountNonce, gasPrice, gasLimit: GasInt, to: EthAddress,
|
proc initLegacyTx*(nonce: AccountNonce, gasPrice, gasLimit: GasInt, to: EthAddress,
|
||||||
value: UInt256, payload: Blob, V: byte, R, S: UInt256, isContractCreation = false): Transaction =
|
value: UInt256, payload: Blob, V: uint64, R, S: UInt256, isContractCreation = false): LegacyTx =
|
||||||
result.accountNonce = nonce
|
result.accountNonce = nonce
|
||||||
result.gasPrice = gasPrice
|
result.gasPrice = gasPrice
|
||||||
result.gasLimit = gasLimit
|
result.gasLimit = gasLimit
|
||||||
|
@ -40,7 +40,7 @@ proc append(rlpWriter: var RlpWriter, t: TransHashObj, a: EthAddress) {.inline.}
|
||||||
const
|
const
|
||||||
EIP155_CHAIN_ID_OFFSET* = 35
|
EIP155_CHAIN_ID_OFFSET* = 35
|
||||||
|
|
||||||
func rlpEncode*(transaction: Transaction): auto =
|
func rlpEncode*(transaction: LegacyTx): auto =
|
||||||
# Encode transaction without signature
|
# Encode transaction without signature
|
||||||
return rlp.encode(TransHashObj(
|
return rlp.encode(TransHashObj(
|
||||||
accountNonce: transaction.accountNonce,
|
accountNonce: transaction.accountNonce,
|
||||||
|
@ -52,7 +52,7 @@ func rlpEncode*(transaction: Transaction): auto =
|
||||||
mIsContractCreation: transaction.isContractCreation
|
mIsContractCreation: transaction.isContractCreation
|
||||||
))
|
))
|
||||||
|
|
||||||
func rlpEncodeEIP155*(tx: Transaction): auto =
|
func rlpEncodeEIP155*(tx: LegacyTx): auto =
|
||||||
let V = (tx.V.int - EIP155_CHAIN_ID_OFFSET) div 2
|
let V = (tx.V.int - EIP155_CHAIN_ID_OFFSET) div 2
|
||||||
# Encode transaction without signature
|
# Encode transaction without signature
|
||||||
return rlp.encode(Transaction(
|
return rlp.encode(Transaction(
|
||||||
|
@ -63,11 +63,11 @@ func rlpEncodeEIP155*(tx: Transaction): auto =
|
||||||
value: tx.value,
|
value: tx.value,
|
||||||
payload: tx.payload,
|
payload: tx.payload,
|
||||||
isContractCreation: tx.isContractCreation,
|
isContractCreation: tx.isContractCreation,
|
||||||
V: V.byte,
|
V: V.uint64,
|
||||||
R: 0.u256,
|
R: 0.u256,
|
||||||
S: 0.u256
|
S: 0.u256
|
||||||
))
|
))
|
||||||
|
|
||||||
func txHashNoSignature*(tx: Transaction): Hash256 =
|
func txHashNoSignature*(tx: LegacyTx): Hash256 =
|
||||||
# Hash transaction without signature
|
# Hash transaction without signature
|
||||||
return keccak256.digest(if tx.V.int >= EIP155_CHAIN_ID_OFFSET: tx.rlpEncodeEIP155 else: tx.rlpEncode)
|
return keccak256.digest(if tx.V.int >= EIP155_CHAIN_ID_OFFSET: tx.rlpEncodeEIP155 else: tx.rlpEncode)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"rlp": "f90263f901f5a0151b04645af991f513d5e11f8ed62e12b73f080af9c7a6a3d98fd6b1503f23faa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0968408b8a2f170bc78230cc2fac3881120a93f7392cf26b609566d8648abfd79a0e8137f2b67ac4680d8103f8b1cd7c05c49f56e4df464b0a79253679f38df9ab4a07f53535270d749f41b9d783aa1abcfceb73cc2a16ecde789cd3bc97a42fbda2ab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018347e7c48262740a80a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f868f866800a8301e24194000000000000000000000000000000000000aaaa808086f2ded8deec88a0e7545c5664e63873d7aeb4bb5f92152c3366a9095c9140e5f8453af0998194bea04d24143ac9bc97c0aa07a7074c12ab60484d83d3b447b1e5e6ba5cbf421675bfc0",
|
||||||
|
"json": {
|
||||||
|
"header": {
|
||||||
|
"parentHash": "0x151b04645af991f513d5e11f8ed62e12b73f080af9c7a6a3d98fd6b1503f23fa",
|
||||||
|
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||||
|
"miner": "0x0100000000000000000000000000000000000000",
|
||||||
|
"stateRoot": "0x968408b8a2f170bc78230cc2fac3881120a93f7392cf26b609566d8648abfd79",
|
||||||
|
"transactionsRoot": "0xe8137f2b67ac4680d8103f8b1cd7c05c49f56e4df464b0a79253679f38df9ab4",
|
||||||
|
"receiptsRoot": "0x7f53535270d749f41b9d783aa1abcfceb73cc2a16ecde789cd3bc97a42fbda2a",
|
||||||
|
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"number": "0x1",
|
||||||
|
"gasLimit": "0x47e7c4",
|
||||||
|
"gasUsed": "0x6274",
|
||||||
|
"timestamp": "0xa",
|
||||||
|
"extraData": "0x",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"nonce": "0x0000000000000000",
|
||||||
|
"hash": "0x9aa9cdb2afc4ebf893c32b67dedf1dea4291673bf4e80d3227a4e7f8d0feaf68"
|
||||||
|
},
|
||||||
|
"transactions": [
|
||||||
|
{
|
||||||
|
"type": "0x0",
|
||||||
|
"chainId": null,
|
||||||
|
"nonce": "0x0",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": null,
|
||||||
|
"v": "0xf2ded8deec88",
|
||||||
|
"r": "0xe7545c5664e63873d7aeb4bb5f92152c3366a9095c9140e5f8453af0998194be",
|
||||||
|
"s": "0x4d24143ac9bc97c0aa07a7074c12ab60484d83d3b447b1e5e6ba5cbf421675bf",
|
||||||
|
"hash": "0x7e122173adcc02b9a3c94da426f65c7d46e724e8e3fdb16be73d5e0405e280b6"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"uncles": null,
|
||||||
|
"receipts": null
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
"rlp": "f9032df901f5a09aa9cdb2afc4ebf893c32b67dedf1dea4291673bf4e80d3227a4e7f8d0feaf68a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0fb70f6c0512e7979903607bba8a4f1b18c2dd1060a8eff1b777a2182d05af524a0dfcad019a36acdf0f3fac6b3db02bf1d70012a0bd3eadabea87b856be9a6f1cca0a7a57ba954834e69b55d9115305f14f7faff9beb83443f7bb5526585848c6aefb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000028347e7c482dd201480a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f90131b8c701f8c486796f6c6f7632010a8301e24194000000000000000000000000000000000000aaaa8080f85bf859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000001a0a9efa6b5fd3c2f210c4ec7232058d8dd30c93a456b4f6074429fb09bbd73eb4fa070632eff8bf0933381917c9161a98494e34fc7b836ee150445cae9ab151d267bf866020a8301e24194000000000000000000000000000000000000aaaa808086f2ded8deec88a055a39da3ce02c75e976ad84f608771080811a5ef322c6b6536c362f716c60985a018ab5df4198436eacd0e991f59bdeb8da9a75c678067db6b1a4d07881555c7a8c0",
|
||||||
|
"json": {
|
||||||
|
"header": {
|
||||||
|
"parentHash": "0x9aa9cdb2afc4ebf893c32b67dedf1dea4291673bf4e80d3227a4e7f8d0feaf68",
|
||||||
|
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||||
|
"miner": "0x0100000000000000000000000000000000000000",
|
||||||
|
"stateRoot": "0xfb70f6c0512e7979903607bba8a4f1b18c2dd1060a8eff1b777a2182d05af524",
|
||||||
|
"transactionsRoot": "0xdfcad019a36acdf0f3fac6b3db02bf1d70012a0bd3eadabea87b856be9a6f1cc",
|
||||||
|
"receiptsRoot": "0xa7a57ba954834e69b55d9115305f14f7faff9beb83443f7bb5526585848c6aef",
|
||||||
|
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"number": "0x2",
|
||||||
|
"gasLimit": "0x47e7c4",
|
||||||
|
"gasUsed": "0xdd20",
|
||||||
|
"timestamp": "0x14",
|
||||||
|
"extraData": "0x",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"nonce": "0x0000000000000000",
|
||||||
|
"hash": "0xe1807e7366284bc72d34c8f02318f81c6598454dbff4c6cdd71e872cd8d5748c"
|
||||||
|
},
|
||||||
|
"transactions": [
|
||||||
|
{
|
||||||
|
"type": "0x1",
|
||||||
|
"chainId": "0x796f6c6f7632",
|
||||||
|
"nonce": "0x1",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": [
|
||||||
|
{
|
||||||
|
"address": "0x0000000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"v": "0x1",
|
||||||
|
"r": "0xa9efa6b5fd3c2f210c4ec7232058d8dd30c93a456b4f6074429fb09bbd73eb4f",
|
||||||
|
"s": "0x70632eff8bf0933381917c9161a98494e34fc7b836ee150445cae9ab151d267b",
|
||||||
|
"hash": "0x1916413ac8d1d5ee4eda786e5fe29509a109910f800894e0e18eb84abb7564cb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "0x0",
|
||||||
|
"chainId": null,
|
||||||
|
"nonce": "0x2",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": null,
|
||||||
|
"v": "0xf2ded8deec88",
|
||||||
|
"r": "0x55a39da3ce02c75e976ad84f608771080811a5ef322c6b6536c362f716c60985",
|
||||||
|
"s": "0x18ab5df4198436eacd0e991f59bdeb8da9a75c678067db6b1a4d07881555c7a8",
|
||||||
|
"hash": "0x54c6cfb51cbbe2c562e17a0d6ee1324f1b50013a9b9d47589cedcf0ec4ac342a"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"uncles": null,
|
||||||
|
"receipts": null
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
{
|
||||||
|
"rlp": "f904b1f901f6a0e1807e7366284bc72d34c8f02318f81c6598454dbff4c6cdd71e872cd8d5748ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a025e5b4b7668760c0aa01d44c061d77e24b53f6d247d3e1d85a91e23646c1d679a0be53a36dd90786b4cd30fb0f3677ad3ce5f804a5615872a7b0512b6be82639a2a076946d9f034a6657c6832a6ad4df3ef0ddf3fa9f3f8be98ea64880fb23bd23e3b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000038347e7c48301883c1e80a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f902b4b9012301f9011f86796f6c6f7632030a8301e24194000000000000000000000000000000000000aaaa8080f8b6f859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000f859940100000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a0010000000000000000000000000000000000000000000000000000000000000001a0635c44b8110989ef84c77de11a377f19cbd84660559ed76b37ba0f7fdee1fb40a012e1576d168301614720c68f1a9e9d5ed20e23622dab6c3587b11177155d59f4b9012301f9011f86796f6c6f7632040a8301e24194000000000000000000000000000000000000aaaa8080f8b6f859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000f859940100000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a0010000000000000000000000000000000000000000000000000000000000000001a00380e446bf3992ee1df44b8177a11e948dc52cc3faa8eae059a52b7183126c0fa05206f0f35648d3b8f23092d4d7bdccb926967d840a269cf65b706a8a359b9029f866050a8301e24194000000000000000000000000000000000000aaaa808086f2ded8deec87a0ea5de382dbf422aa1bd156547a2bc3a9357d745a68cdc9203b14812307068567a0388f7425b873ae204d43d91f4997ca41d2af6759be49538b174a06f67d5741b5c0",
|
||||||
|
"json": {
|
||||||
|
"header": {
|
||||||
|
"parentHash": "0xe1807e7366284bc72d34c8f02318f81c6598454dbff4c6cdd71e872cd8d5748c",
|
||||||
|
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||||
|
"miner": "0x0100000000000000000000000000000000000000",
|
||||||
|
"stateRoot": "0x25e5b4b7668760c0aa01d44c061d77e24b53f6d247d3e1d85a91e23646c1d679",
|
||||||
|
"transactionsRoot": "0xbe53a36dd90786b4cd30fb0f3677ad3ce5f804a5615872a7b0512b6be82639a2",
|
||||||
|
"receiptsRoot": "0x76946d9f034a6657c6832a6ad4df3ef0ddf3fa9f3f8be98ea64880fb23bd23e3",
|
||||||
|
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"number": "0x3",
|
||||||
|
"gasLimit": "0x47e7c4",
|
||||||
|
"gasUsed": "0x1883c",
|
||||||
|
"timestamp": "0x1e",
|
||||||
|
"extraData": "0x",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"nonce": "0x0000000000000000",
|
||||||
|
"hash": "0x1615129d2aa7b437cd40e3aa1a5794af9e40b07b9b017014e4123cefeef785ce"
|
||||||
|
},
|
||||||
|
"transactions": [
|
||||||
|
{
|
||||||
|
"type": "0x1",
|
||||||
|
"chainId": "0x796f6c6f7632",
|
||||||
|
"nonce": "0x3",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": [
|
||||||
|
{
|
||||||
|
"address": "0x0000000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0100000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0100000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"v": "0x1",
|
||||||
|
"r": "0x635c44b8110989ef84c77de11a377f19cbd84660559ed76b37ba0f7fdee1fb40",
|
||||||
|
"s": "0x12e1576d168301614720c68f1a9e9d5ed20e23622dab6c3587b11177155d59f4",
|
||||||
|
"hash": "0x54471f503901f2c2fe392e43df0377a11f9a1cd9cde0ec5c68c89eac1723e02a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "0x1",
|
||||||
|
"chainId": "0x796f6c6f7632",
|
||||||
|
"nonce": "0x4",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": [
|
||||||
|
{
|
||||||
|
"address": "0x0000000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0100000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0100000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"v": "0x1",
|
||||||
|
"r": "0x380e446bf3992ee1df44b8177a11e948dc52cc3faa8eae059a52b7183126c0f",
|
||||||
|
"s": "0x5206f0f35648d3b8f23092d4d7bdccb926967d840a269cf65b706a8a359b9029",
|
||||||
|
"hash": "0xe3a1354e84d22ebbca0c55751937b075083f0f0e3a47c65fc7249d86f872f268"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "0x0",
|
||||||
|
"chainId": null,
|
||||||
|
"nonce": "0x5",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": null,
|
||||||
|
"v": "0xf2ded8deec87",
|
||||||
|
"r": "0xea5de382dbf422aa1bd156547a2bc3a9357d745a68cdc9203b14812307068567",
|
||||||
|
"s": "0x388f7425b873ae204d43d91f4997ca41d2af6759be49538b174a06f67d5741b5",
|
||||||
|
"hash": "0x44b1e9999ac02a3b0daf1391be16bb00a262079706418697094bab5f37b522d7"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"uncles": null,
|
||||||
|
"receipts": null
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
{
|
||||||
|
"rlp": "f906ebf901f6a01615129d2aa7b437cd40e3aa1a5794af9e40b07b9b017014e4123cefeef785cea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0e2c895d53740e942c84623e1612189e72eea9e767b150cc0d8802b490f2574b2a060b6fa13cd50ea3732f59eb726368639dea2006ab4b67dc5730ea27b0cd75732a058ac726e0fc55cd550539c38baf3f6023615e2657ceedccc21ce7edd6516bc31b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000048347e7c4830263c82880a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f904eeb9017f01f9017b86796f6c6f7632060a8301e24194000000000000000000000000000000000000aaaa8080f90111f859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000f859940100000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00100000000000000000000000000000000000000000000000000000000000000f859940200000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a0020000000000000000000000000000000000000000000000000000000000000001a0587b3fd59a84469be7c918ae73047141027d27c47cc63f3cf13c6161bf92efaaa0453d3cd2dffd1f048a58fb1046917327f5e95cc8aedc47f82d41bffebfe31bbdb9017f01f9017b86796f6c6f7632070a8301e24194000000000000000000000000000000000000aaaa8080f90111f859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000f859940100000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00100000000000000000000000000000000000000000000000000000000000000f859940200000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a0020000000000000000000000000000000000000000000000000000000000000080a0b1944f4797bf4da4d041a66be9c41c317b40d158894103ccd50de5e4ca174b4aa079d6834c013b40d0039ca6755cecc72938461e5b8cd8d3619ddcdfb15c15b866b9017f01f9017b86796f6c6f7632080a8301e24194000000000000000000000000000000000000aaaa8080f90111f859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000f859940100000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a00100000000000000000000000000000000000000000000000000000000000000f859940200000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000000a0020000000000000000000000000000000000000000000000000000000000000001a0793cd38309611e0117269275243fc3761fe233dc371918e450b547c70132c033a07276d4b20788938ca0ff7e4e921aec7739103dc73d3b953f47947ef194720757f866090a8301e24194000000000000000000000000000000000000aaaa808086f2ded8deec88a0a6528544064aef10d166e16d3968ae83aa29161beb57f2756dfd1151682adbe7a0507fe2d475ffab209e718345a3ad9fb20fee6e15a8c4980df3ed8ff0a714367ac0",
|
||||||
|
"json": {
|
||||||
|
"header": {
|
||||||
|
"parentHash": "0x1615129d2aa7b437cd40e3aa1a5794af9e40b07b9b017014e4123cefeef785ce",
|
||||||
|
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||||
|
"miner": "0x0100000000000000000000000000000000000000",
|
||||||
|
"stateRoot": "0xe2c895d53740e942c84623e1612189e72eea9e767b150cc0d8802b490f2574b2",
|
||||||
|
"transactionsRoot": "0x60b6fa13cd50ea3732f59eb726368639dea2006ab4b67dc5730ea27b0cd75732",
|
||||||
|
"receiptsRoot": "0x58ac726e0fc55cd550539c38baf3f6023615e2657ceedccc21ce7edd6516bc31",
|
||||||
|
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"number": "0x4",
|
||||||
|
"gasLimit": "0x47e7c4",
|
||||||
|
"gasUsed": "0x263c8",
|
||||||
|
"timestamp": "0x28",
|
||||||
|
"extraData": "0x",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"nonce": "0x0000000000000000",
|
||||||
|
"hash": "0xc6340ac0a1b76cae78479a4bc6211031550719fa9b58ae42d773dce7ff7409ce"
|
||||||
|
},
|
||||||
|
"transactions": [
|
||||||
|
{
|
||||||
|
"type": "0x1",
|
||||||
|
"chainId": "0x796f6c6f7632",
|
||||||
|
"nonce": "0x6",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": [
|
||||||
|
{
|
||||||
|
"address": "0x0000000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0100000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0100000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0200000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0200000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"v": "0x1",
|
||||||
|
"r": "0x587b3fd59a84469be7c918ae73047141027d27c47cc63f3cf13c6161bf92efaa",
|
||||||
|
"s": "0x453d3cd2dffd1f048a58fb1046917327f5e95cc8aedc47f82d41bffebfe31bbd",
|
||||||
|
"hash": "0xbc9b06b5d31e6e257a3c25048e935ba433c68fdd5fa5d0ddd726d5ab7356aafd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "0x1",
|
||||||
|
"chainId": "0x796f6c6f7632",
|
||||||
|
"nonce": "0x7",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": [
|
||||||
|
{
|
||||||
|
"address": "0x0000000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0100000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0100000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0200000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0200000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"v": "0x0",
|
||||||
|
"r": "0xb1944f4797bf4da4d041a66be9c41c317b40d158894103ccd50de5e4ca174b4a",
|
||||||
|
"s": "0x79d6834c013b40d0039ca6755cecc72938461e5b8cd8d3619ddcdfb15c15b866",
|
||||||
|
"hash": "0x474ec2766068f9e9d0548aca3769ca406fdde21ba87c254d9230c18be35fe99a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "0x1",
|
||||||
|
"chainId": "0x796f6c6f7632",
|
||||||
|
"nonce": "0x8",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": [
|
||||||
|
{
|
||||||
|
"address": "0x0000000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0100000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0100000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x0200000000000000000000000000000000000000",
|
||||||
|
"storageKeys": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"0x0200000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"v": "0x1",
|
||||||
|
"r": "0x793cd38309611e0117269275243fc3761fe233dc371918e450b547c70132c033",
|
||||||
|
"s": "0x7276d4b20788938ca0ff7e4e921aec7739103dc73d3b953f47947ef194720757",
|
||||||
|
"hash": "0xe46963eb63cd75a120990ca597532020bc2dcefc4588025c0d50901681a7aae9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "0x0",
|
||||||
|
"chainId": null,
|
||||||
|
"nonce": "0x9",
|
||||||
|
"gasPrice": "0xa",
|
||||||
|
"gas": "0x1e241",
|
||||||
|
"to": "0x000000000000000000000000000000000000aaaa",
|
||||||
|
"value": "0x0",
|
||||||
|
"input": "0x",
|
||||||
|
"accessList": null,
|
||||||
|
"v": "0xf2ded8deec88",
|
||||||
|
"r": "0xa6528544064aef10d166e16d3968ae83aa29161beb57f2756dfd1151682adbe7",
|
||||||
|
"s": "0x507fe2d475ffab209e718345a3ad9fb20fee6e15a8c4980df3ed8ff0a714367a",
|
||||||
|
"hash": "0x61fc16fea6b57d81f269e733cdd15d994bbc10dc6e9b0acbedbe32e6fe70a06c"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"uncles": null,
|
||||||
|
"receipts": null
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"chainId": 133519467574834,
|
||||||
|
"homesteadBlock": 0,
|
||||||
|
"daoForkSupport": true,
|
||||||
|
"eip150Block": 0,
|
||||||
|
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"eip155Block": 0,
|
||||||
|
"eip158Block": 0,
|
||||||
|
"byzantiumBlock": 0,
|
||||||
|
"constantinopleBlock": 0,
|
||||||
|
"petersburgBlock": 0,
|
||||||
|
"istanbulBlock": 0,
|
||||||
|
"yoloV2Block": 0,
|
||||||
|
"clique": {
|
||||||
|
"period": 15,
|
||||||
|
"epoch": 30000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nonce": "0x0",
|
||||||
|
"timestamp": "0x0",
|
||||||
|
"extraData": "0x",
|
||||||
|
"gasLimit": "0x0",
|
||||||
|
"difficulty": null,
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"coinbase": "0x0000000000000000000000000000000000000000",
|
||||||
|
"alloc": {
|
||||||
|
"000000000000000000000000000000000000aaaa": {
|
||||||
|
"code": "0x58585454",
|
||||||
|
"balance": "0x0"
|
||||||
|
},
|
||||||
|
"71562b71999873db5b286df957af199ec94617f7": {
|
||||||
|
"balance": "0x3b9aca00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": "0x0",
|
||||||
|
"gasUsed": "0x0",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ proc q(s: string): string = "\"" & s & "\""
|
||||||
proc i(s: string): string = s.replace(" ").replace("\n")
|
proc i(s: string): string = s.replace(" ").replace("\n")
|
||||||
proc inspectMatch(r: Rlp, s: string): bool = r.inspect.i == s.i
|
proc inspectMatch(r: Rlp, s: string): bool = r.inspect.i == s.i
|
||||||
|
|
||||||
|
proc suite() =
|
||||||
|
suite "test api usage":
|
||||||
test "empty bytes are not a proper RLP":
|
test "empty bytes are not a proper RLP":
|
||||||
var rlp = rlpFromBytes seq[byte](@[])
|
var rlp = rlpFromBytes seq[byte](@[])
|
||||||
|
|
||||||
|
@ -211,3 +213,5 @@ test "invalid enum":
|
||||||
rlp.skipElem()
|
rlp.skipElem()
|
||||||
expect RlpTypeMismatch:
|
expect RlpTypeMismatch:
|
||||||
discard rlp.read(MyEnum)
|
discard rlp.read(MyEnum)
|
||||||
|
|
||||||
|
suite()
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import
|
import
|
||||||
std/unittest,
|
std/[unittest, os, json],
|
||||||
|
stew/byteutils,
|
||||||
../../eth/[common, rlp]
|
../../eth/[common, rlp]
|
||||||
|
|
||||||
proc `==`(a, b: HashOrStatus): bool =
|
proc `==`(a, b: HashOrStatus): bool =
|
||||||
|
@ -12,29 +13,92 @@ proc `==`(a, b: HashOrStatus): bool =
|
||||||
else:
|
else:
|
||||||
result = result and a.status == b.status
|
result = result and a.status == b.status
|
||||||
|
|
||||||
|
func `==`(a, b: ChainId): bool =
|
||||||
|
a.uint64 == b.uint64
|
||||||
|
|
||||||
|
func `==`(a, b: Transaction): bool =
|
||||||
|
if a.txType != b.txType:
|
||||||
|
return false
|
||||||
|
if a.txType == LegacyTxType:
|
||||||
|
return a.legacyTx == b.legacyTx
|
||||||
|
else:
|
||||||
|
return a.accessListTx == b.accessListTx
|
||||||
|
|
||||||
|
func `==`(a, b: Receipt): bool =
|
||||||
|
if a.receiptType != b.receiptType:
|
||||||
|
return false
|
||||||
|
if a.receiptType == LegacyReceiptType:
|
||||||
|
return a.legacyReceipt == b.legacyReceipt
|
||||||
|
else:
|
||||||
|
return a.accessListReceipt == b.accessListReceipt
|
||||||
|
|
||||||
|
proc loadFile(x: int) =
|
||||||
|
let fileName = "tests" / "rlp" / "eip2718" / "acl_block_" & $x & ".json"
|
||||||
|
test fileName:
|
||||||
|
let n = json.parseFile(fileName)
|
||||||
|
let data = n["rlp"].getStr()
|
||||||
|
var bytes = hexToSeqByte(data)
|
||||||
|
var blk = rlp.decode(bytes, EthBlock)
|
||||||
|
|
||||||
|
let rlpbytes = rlp.encode(blk)
|
||||||
|
var blk2 = rlp.decode(rlpbytes, EthBlock)
|
||||||
|
check blk == blk2
|
||||||
|
check bytes == rlpbytes
|
||||||
|
|
||||||
|
proc suite1() =
|
||||||
suite "rlp encoding":
|
suite "rlp encoding":
|
||||||
|
|
||||||
test "receipt roundtrip":
|
test "receipt roundtrip":
|
||||||
var a, b, c, d: Receipt
|
let a = Receipt(
|
||||||
|
receiptType: LegacyReceiptType,
|
||||||
|
legacyReceipt: LegacyReceipt(
|
||||||
|
stateRootOrStatus: hashOrStatus(true),
|
||||||
|
cumulativeGasUsed: 51000
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
var hash = rlpHash(a)
|
let hash = rlpHash(a)
|
||||||
a.stateRootOrStatus = hashOrStatus(hash)
|
let b = Receipt(
|
||||||
a.cumulativeGasUsed = 21000
|
receiptType: LegacyReceiptType,
|
||||||
a.logs = @[]
|
legacyReceipt: LegacyReceipt(
|
||||||
|
stateRootOrStatus: hashOrStatus(hash),
|
||||||
|
cumulativeGasUsed: 21000
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
b.stateRootOrStatus = hashOrStatus(true)
|
let abytes = rlp.encode(a)
|
||||||
b.cumulativeGasUsed = 52000
|
let bbytes = rlp.encode(b)
|
||||||
b.logs = @[]
|
let aa = rlp.decode(abytes, Receipt)
|
||||||
|
let bb = rlp.decode(bbytes, Receipt)
|
||||||
|
check aa == a
|
||||||
|
check bb == b
|
||||||
|
|
||||||
var x = rlp.encode(a)
|
test "access list receipt":
|
||||||
var y = rlp.encode(b)
|
let a = Receipt(
|
||||||
|
receiptType: AccessListReceiptType,
|
||||||
|
accessListReceipt: AccessListReceipt(
|
||||||
|
status: true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
c = x.decode(Receipt)
|
let b = Receipt(
|
||||||
d = y.decode(Receipt)
|
receiptType: AccessListReceiptType,
|
||||||
check c == a
|
accessListReceipt: AccessListReceipt(
|
||||||
check d == b
|
status: false,
|
||||||
|
cumulativeGasUsed: 21000
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
check c.hasStateRoot
|
let abytes = rlp.encode(a)
|
||||||
check c.stateRoot == hash
|
let bbytes = rlp.encode(b)
|
||||||
check d.hasStatus
|
let aa = rlp.decode(abytes, Receipt)
|
||||||
check d.status == 1
|
let bb = rlp.decode(bbytes, Receipt)
|
||||||
|
check aa == a
|
||||||
|
check bb == b
|
||||||
|
|
||||||
|
proc suite2() =
|
||||||
|
suite "eip 2718 transaction":
|
||||||
|
for i in 0..<10:
|
||||||
|
loadFile(i)
|
||||||
|
|
||||||
|
suite1()
|
||||||
|
suite2()
|
|
@ -43,6 +43,8 @@ proc read*(rlp: var Rlp, holder: var CustomSerialized, T: type Foo): Foo =
|
||||||
result.y = newString(rlp.read(int))
|
result.y = newString(rlp.read(int))
|
||||||
holder.ignored = rlp.read(int) * 2
|
holder.ignored = rlp.read(int) * 2
|
||||||
|
|
||||||
|
proc suite() =
|
||||||
|
suite "object serialization":
|
||||||
test "encoding and decoding an object":
|
test "encoding and decoding an object":
|
||||||
var originalBar = Bar(b: "abracadabra",
|
var originalBar = Bar(b: "abracadabra",
|
||||||
f: Foo(x: 5'u64, y: "hocus pocus", z: @[100, 200, 300]))
|
f: Foo(x: 5'u64, y: "hocus pocus", z: @[100, 200, 300]))
|
||||||
|
@ -81,3 +83,5 @@ test "RLP fields count":
|
||||||
Bar.rlpFieldsCount == 2
|
Bar.rlpFieldsCount == 2
|
||||||
Foo.rlpFieldsCount == 3
|
Foo.rlpFieldsCount == 3
|
||||||
Transaction.rlpFieldsCount == 3
|
Transaction.rlpFieldsCount == 3
|
||||||
|
|
||||||
|
suite()
|
||||||
|
|
Loading…
Reference in New Issue