add helpers for processing receipts to `libnimbus_lc.a` (#5360)

Similar to the existing helpers for processing transactions,
extend `libnimbus_lc.a` with support for processing receipts as well.
This commit is contained in:
Etan Kissling 2023-08-28 17:56:40 +02:00 committed by GitHub
parent d0e935e446
commit 09020ebd2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1179 additions and 47 deletions

View File

@ -870,14 +870,14 @@ const ETHRoot *ETHExecutionPayloadHeaderGetReceiptsRoot(
const ETHExecutionPayloadHeader *execution);
/**
* Execution logs bloom.
* Execution logs Bloom.
*/
typedef struct {
uint8_t bytes[256];
} ETHLogsBloom;
/**
* Obtains the logs bloom of a given execution payload header.
* Obtains the logs Bloom of a given execution payload header.
*
* - The returned value is allocated in the given execution payload header.
* It must neither be released nor written to, and the execution payload
@ -885,7 +885,7 @@ typedef struct {
*
* @param execution Execution payload header.
*
* @return Execution logs bloom.
* @return Execution logs Bloom.
*/
ETH_RESULT_USE_CHECK
const ETHLogsBloom *ETHExecutionPayloadHeaderGetLogsBloom(
@ -957,27 +957,15 @@ int ETHExecutionPayloadHeaderGetTimestamp(
* It must neither be released nor written to, and the execution payload
* header must not be released while the returned value is in use.
*
* - Use `ETHExecutionPayloadHeaderGetNumExtraDataBytes`
* to obtain the length of the buffer.
*
* @param execution Execution payload header.
* @param[out] numBytes Length of buffer.
*
* @return Buffer with execution block extra data.
*/
ETH_RESULT_USE_CHECK
const void *ETHExecutionPayloadHeaderGetExtraDataBytes(
const ETHExecutionPayloadHeader *execution);
/**
* Obtains the extra data buffer's length of a given execution payload header.
*
* @param execution Execution payload header.
*
* @return Length of execution block extra data.
*/
ETH_RESULT_USE_CHECK
int ETHExecutionPayloadHeaderGetNumExtraDataBytes(
const ETHExecutionPayloadHeader *execution);
const ETHExecutionPayloadHeader *execution,
int *numBytes);
/**
* UInt256 (little-endian)
@ -1500,6 +1488,283 @@ const void *ETHTransactionGetBytes(
const ETHTransaction *transaction,
int *numBytes);
/**
* Receipt sequence.
*/
typedef struct ETHReceipts ETHReceipts;
/**
* Verifies that JSON receipts data is valid and that it matches
* the given `receiptsRoot`.
*
* - The JSON-RPC `eth_getTransactionReceipt` may be used to obtain
* receipts data for a given transaction hash. For verification, it is
* necessary to obtain the receipt for _all_ transactions within a block.
* Pass a JSON array containing _all_ receipt's `result` as `receiptsJson`.
* The receipts need to be in the same order as the `transactions`.
*
* - The receipt sequence must be destroyed with `ETHReceiptsDestroy`
* once no longer needed, to release memory.
*
* @param receiptsRoot Execution receipts root.
* @param receiptsJson Buffer with JSON receipts list. NULL-terminated.
* @param transactions Transaction sequence.
*
* @return Pointer to an initialized receipt sequence - If successful.
* @return `NULL` - If the given `receiptsJson` is malformed or incompatible.
*
* @see https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt
*/
ETH_RESULT_USE_CHECK
ETHReceipts *ETHReceiptsCreateFromJson(
const ETHRoot *receiptsRoot,
const char *receiptsJson,
const ETHTransactions *transactions);
/**
* Destroys a receipt sequence.
*
* - The receipt sequence must no longer be used after destruction.
*
* @param receipts Receipt sequence.
*/
void ETHReceiptsDestroy(ETHReceipts *receipts);
/**
* Indicates the total number of receipts in a receipt sequence.
*
* - Individual receipts may be investigated using `ETHReceiptsGet`.
*
* @param receipts Receipt sequence.
*
* @return Number of available receipts.
*/
ETH_RESULT_USE_CHECK
int ETHReceiptsGetCount(const ETHReceipts *receipts);
/**
* Receipt.
*/
typedef struct ETHReceipt ETHReceipt;
/**
* Obtains an individual receipt by sequential index
* in a receipt sequence.
*
* - The returned value is allocated in the given receipt sequence.
* It must neither be released nor written to, and the receipt
* sequence must not be released while the returned value is in use.
*
* @param receipts Receipt sequence.
* @param receiptIndex Sequential receipt index.
*
* @return Receipt.
*/
ETH_RESULT_USE_CHECK
const ETHReceipt *ETHReceiptsGet(
const ETHReceipts *receipts,
int receiptIndex);
/**
* Indicates whether or not a receipt has a status code.
*
* @param receipt Receipt.
*
* @return Whether or not the receipt has a status code.
*
* @see https://eips.ethereum.org/EIPS/eip-658
*/
ETH_RESULT_USE_CHECK
bool ETHReceiptHasStatus(const ETHReceipt *receipt);
/**
* Obtains the intermediate post-state root of a receipt with no status code.
*
* - If the receipt has a status code, this function returns a zero hash.
*
* - The returned value is allocated in the given receipt.
* It must neither be released nor written to, and the receipt
* must not be released while the returned value is in use.
*
* @param receipt Receipt.
*
* @return Intermediate post-state root.
*/
ETH_RESULT_USE_CHECK
const ETHRoot *ETHReceiptGetRoot(const ETHReceipt *receipt);
/**
* Obtains the status code of a receipt with a status code.
*
* - If the receipt has no status code, this function returns true.
*
* @param receipt Receipt.
*
* @return Status code.
*
* @see https://eips.ethereum.org/EIPS/eip-658
*/
ETH_RESULT_USE_CHECK
bool ETHReceiptGetStatus(const ETHReceipt *receipt);
/**
* Obtains the gas used of a receipt.
*
* - The returned value is allocated in the given receipt.
* It must neither be released nor written to, and the receipt
* must not be released while the returned value is in use.
*
* @param receipt Receipt.
*
* @return Gas used.
*/
ETH_RESULT_USE_CHECK
const uint64_t *ETHReceiptGetGasUsed(const ETHReceipt *receipt);
/**
* Obtains the logs Bloom of a receipt.
*
* - The returned value is allocated in the given receipt.
* It must neither be released nor written to, and the receipt
* must not be released while the returned value is in use.
*
* @param receipt Receipt.
*
* @return Logs Bloom.
*/
ETH_RESULT_USE_CHECK
const ETHLogsBloom *ETHReceiptGetLogsBloom(const ETHReceipt *receipt);
/**
* Log sequence.
*/
typedef struct ETHLogs ETHLogs;
/**
* Obtains the logs of a receipt.
*
* - The returned value is allocated in the given receipt.
* It must neither be released nor written to, and the receipt
* must not be released while the returned value is in use.
*
* @param receipt Receipt.
*
* @return Log sequence.
*/
ETH_RESULT_USE_CHECK
const ETHLogs *ETHReceiptGetLogs(const ETHReceipt *receipt);
/**
* Indicates the total number of logs in a log sequence.
*
* - Individual logs may be investigated using `ETHLogsGet`.
*
* @param logs Log sequence.
*
* @return Number of available logs.
*/
ETH_RESULT_USE_CHECK
int ETHLogsGetCount(const ETHLogs *logs);
/**
* Log.
*/
typedef struct ETHLog ETHLog;
/**
* Obtains an individual log by sequential index in a log sequence.
*
* - The returned value is allocated in the given log sequence.
* It must neither be released nor written to, and the log sequence
* must not be released while the returned value is in use.
*
* @param logs Log sequence.
* @param logIndex Sequential log index.
*
* @return Log.
*/
ETH_RESULT_USE_CHECK
const ETHLog *ETHLogsGet(
const ETHLogs *logs,
int logIndex);
/**
* Obtains the address of a log.
*
* - The returned value is allocated in the given log.
* It must neither be released nor written to, and the log
* must not be released while the returned value is in use.
*
* @param log Log.
*
* @return Address.
*/
ETH_RESULT_USE_CHECK
const ETHExecutionAddress *ETHLogGetAddress(const ETHLog *log);
/**
* Indicates the total number of topics in a log.
*
* - Individual topics may be investigated using `ETHLogGetTopic`.
*
* @param log Log.
*
* @return Number of available topics.
*/
ETH_RESULT_USE_CHECK
int ETHLogGetNumTopics(const ETHLog *log);
/**
* Obtains an individual topic by sequential index in a log.
*
* - The returned value is allocated in the given log.
* It must neither be released nor written to, and the log
* must not be released while the returned value is in use.
*
* @param log Log.
* @param topicIndex Sequential topic index.
*
* @return Topic.
*/
ETH_RESULT_USE_CHECK
const ETHRoot *ETHLogGetTopic(
const ETHLog *log,
int topicIndex);
/**
* Obtains the data of a log.
*
* - The returned value is allocated in the given log.
* It must neither be released nor written to, and the log
* must not be released while the returned value is in use.
*
* @param log Log.
* @param[out] numBytes Length of buffer.
*
* @return Buffer with data.
*/
ETH_RESULT_USE_CHECK
const void *ETHLogGetDataBytes(
const ETHLog *log,
int *numBytes);
/**
* Obtains the raw byte representation of a receipt.
*
* - The returned value is allocated in the given receipt.
* It must neither be released nor written to, and the receipt
* must not be released while the returned value is in use.
*
* @param receipt Receipt.
* @param[out] numBytes Length of buffer.
*
* @return Buffer with raw receipt data.
*/
ETH_RESULT_USE_CHECK
const void *ETHReceiptGetBytes(
const ETHReceipt *receipt,
int *numBytes);
#if __has_feature(nullability)
#pragma clang assume_nonnull end
#endif

View File

@ -1038,7 +1038,7 @@ func ETHExecutionPayloadHeaderGetReceiptsRoot(
func ETHExecutionPayloadHeaderGetLogsBloom(
execution: ptr ExecutionPayloadHeader): ptr BloomLogs {.exported.} =
## Obtains the logs bloom of a given execution payload header.
## Obtains the logs Bloom of a given execution payload header.
##
## * The returned value is allocated in the given execution payload header.
## It must neither be released nor written to, and the execution payload
@ -1048,7 +1048,7 @@ func ETHExecutionPayloadHeaderGetLogsBloom(
## * `execution` - Execution payload header.
##
## Returns:
## * Execution logs bloom.
## * Execution logs Bloom.
addr execution[].logs_bloom
func ETHExecutionPayloadHeaderGetPrevRandao(
@ -1111,35 +1111,27 @@ func ETHExecutionPayloadHeaderGetTimestamp(
execution[].timestamp.cint
func ETHExecutionPayloadHeaderGetExtraDataBytes(
execution: ptr ExecutionPayloadHeader
): ptr UncheckedArray[byte] {.exported.} =
execution: ptr ExecutionPayloadHeader,
numBytes #[out]#: ptr cint): ptr UncheckedArray[byte] {.exported.} =
## Obtains the extra data buffer of a given execution payload header.
##
## * The returned value is allocated in the given execution payload header.
## It must neither be released nor written to, and the execution payload
## header must not be released while the returned value is in use.
##
## * Use `ETHExecutionPayloadHeaderGetNumExtraDataBytes`
## to obtain the length of the buffer.
##
## Parameters:
## * `execution` - Execution payload header.
## * `numBytes` [out] - Length of buffer.
##
## Returns:
## * Buffer with execution block extra data.
numBytes[] = execution[].extra_data.len.cint
if execution[].extra_data.len == 0:
# https://github.com/nim-lang/Nim/issues/22389
const defaultExtraData: cstring = ""
return cast[ptr UncheckedArray[byte]](defaultExtraData)
cast[ptr UncheckedArray[byte]](addr execution[].extra_data[0])
func ETHExecutionPayloadHeaderGetNumExtraDataBytes(
execution: ptr ExecutionPayloadHeader): cint {.exported.} =
## Obtains the extra data buffer's length of a given execution payload header.
##
## Parameters:
## * `execution` - Execution payload header.
##
## Returns:
## * Length of execution block extra data.
execution[].extra_data.len.cint
func ETHExecutionPayloadHeaderGetBaseFeePerGas(
execution: ptr ExecutionPayloadHeader): ptr UInt256 {.exported.} =
## Obtains the base fee per gas of a given execution payload header.
@ -1974,3 +1966,428 @@ func ETHTransactionGetBytes(
const defaultBytes: cstring = ""
return cast[ptr UncheckedArray[byte]](defaultBytes)
cast[ptr UncheckedArray[byte]](addr distinctBase(transaction[].bytes)[0])
type
ETHLog = object
address: ExecutionAddress
topics: seq[Eth2Digest]
data: seq[byte]
ReceiptStatusType {.pure.} = enum
Root,
Status # EIP-658
ETHReceipt = object
statusType: ReceiptStatusType
root: Eth2Digest
status: bool
gasUsed: uint64
logsBloom: BloomLogs
logs: seq[ETHLog]
bytes: seq[byte]
proc ETHReceiptsCreateFromJson(
receiptsRoot: ptr Eth2Digest,
receiptsJson: cstring,
transactions: ptr seq[ETHTransaction]): ptr seq[ETHReceipt] {.exported.} =
## Verifies that JSON receipts data is valid and that it matches
## the given `receiptsRoot`.
##
## * The JSON-RPC `eth_getTransactionReceipt` may be used to obtain
## receipts data for a given transaction hash. For verification, it is
## necessary to obtain the receipt for _all_ transactions within a block.
## Pass a JSON array containing _all_ receipt's `result` as `receiptsJson`.
## The receipts need to be in the same order as the `transactions`.
##
## * The receipt sequence must be destroyed with `ETHReceiptsDestroy`
## once no longer needed, to release memory.
##
## Parameters:
## * `receiptsRoot` - Execution receipts root.
## * `receiptsJson` - Buffer with JSON receipts list. NULL-terminated.
## * `transactions` - Transaction sequence.
##
## Returns:
## * Pointer to an initialized receipt sequence - If successful.
## * `NULL` - If the given `receiptsJson` is malformed or incompatible.
##
## See:
## * https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt
let node =
try:
parseJson($receiptsJson)
except Exception:
return nil
var datas: seq[ReceiptObject]
try:
fromJson(node, argName = "", datas)
except KeyError, ValueError:
return nil
if datas.len != ETHTransactionsGetCount(transactions):
return nil
var
recs = newSeqOfCap[ETHReceipt](datas.len)
cumulativeGasUsed = 0'u64
logIndex = uint64.high
for i, data in datas:
# Sanity check
if distinctBase(data.transactionIndex) != i.uint64:
return nil
# Check fork consistency
static: doAssert totalSerializedFields(ReceiptObject) == 15,
"Only update this number once code is adjusted to check new fields!"
static: doAssert totalSerializedFields(LogObject) == 9,
"Only update this number once code is adjusted to check new fields!"
let txType =
case data.`type`.get(0.Quantity):
of 0.Quantity:
TxLegacy
of 1.Quantity:
TxEip2930
of 2.Quantity:
TxEip1559
of 3.Quantity:
TxEip4844
else:
return nil
if data.root.isNone and data.status.isNone or
data.root.isSome and data.status.isSome:
return nil
if data.status.isSome and distinctBase(data.status.get) > 1:
return nil
if distinctBase(data.cumulativeGasUsed) !=
cumulativeGasUsed + distinctBase(data.gasUsed):
return nil
cumulativeGasUsed = distinctBase(data.cumulativeGasUsed)
for log in data.logs:
if log.removed:
return nil
if distinctBase(log.logIndex) != logIndex + 1:
return nil
logIndex = distinctBase(log.logIndex)
if log.transactionIndex != data.transactionIndex:
return nil
if log.transactionHash != data.transactionHash:
return nil
if log.blockHash != data.blockHash:
return nil
if log.blockNumber != data.blockNumber:
return nil
if log.data.len mod 32 != 0:
return nil
if log.topics.len > 4:
return nil
# Construct receipt
static:
doAssert sizeof(int64) == sizeof(data.cumulativeGasUsed)
if distinctBase(data.cumulativeGasUsed) > int64.high.uint64:
return nil
let
rec = ExecutionReceipt(
receiptType: txType,
isHash: data.root.isSome,
status: distinctBase(data.status.get(1.Quantity)) != 0'u64,
hash:
if data.root.isSome:
ExecutionHash256(data: distinctBase(data.root.get))
else:
default(ExecutionHash256),
cumulativeGasUsed: distinctBase(data.cumulativeGasUsed).GasInt,
bloom: distinctBase(data.logsBloom),
logs: data.logs.mapIt(Log(
address: distinctBase(it.address),
topics: it.topics.mapIt(distinctBase(it)),
data: it.data)))
rlpBytes =
try:
rlp.encode(rec)
except RlpError:
raiseAssert "Unreachable"
recs.add ETHReceipt(
statusType:
if rec.isHash:
ReceiptStatusType.Root
else:
ReceiptStatusType.Status,
root: rec.hash,
status: rec.status,
gasUsed: distinctBase(data.gasUsed), # Validated during sanity checks.
logsBloom: BloomLogs(data: rec.bloom),
logs: rec.logs.mapIt(ETHLog(
address: ExecutionAddress(data: it.address),
topics: it.topics.mapIt(Eth2Digest(data: it)),
data: it.data)),
bytes: rlpBytes)
var tr = initHexaryTrie(newMemoryDB())
for i, rec in recs:
try:
tr.put(rlp.encode(i), rec.bytes)
except RlpError:
raiseAssert "Unreachable"
if tr.rootHash() != receiptsRoot[]:
return nil
let receipts = seq[ETHReceipt].new()
receipts[] = recs
receipts.toUnmanagedPtr()
proc ETHReceiptsDestroy(
receipts: ptr seq[ETHReceipt]) {.exported.} =
## Destroys a receipt sequence.
##
## * The receipt sequence must no longer be used after destruction.
##
## Parameters:
## * `receipts` - Receipt sequence.
receipts.destroy()
func ETHReceiptsGetCount(
receipts: ptr seq[ETHReceipt]): cint {.exported.} =
## Indicates the total number of receipts in a receipt sequence.
##
## * Individual receipts may be investigated using `ETHReceiptsGet`.
##
## Parameters:
## * `receipts` - Receipt sequence.
##
## Returns:
## * Number of available receipts.
receipts[].len.cint
func ETHReceiptsGet(
receipts: ptr seq[ETHReceipt],
receiptIndex: cint): ptr ETHReceipt {.exported.} =
## Obtains an individual receipt by sequential index
## in a receipt sequence.
##
## * The returned value is allocated in the given receipt sequence.
## It must neither be released nor written to, and the receipt
## sequence must not be released while the returned value is in use.
##
## Parameters:
## * `receipts` - Receipt sequence.
## * `receiptIndex` - Sequential receipt index.
##
## Returns:
## * Receipt.
addr receipts[][receiptIndex.int]
func ETHReceiptHasStatus(
receipt: ptr ETHReceipt): bool {.exported.} =
## Indicates whether or not a receipt has a status code.
##
## Parameters:
## * `receipt` - Receipt.
##
## Returns:
## * Whether or not the receipt has a status code.
##
## See:
## * https://eips.ethereum.org/EIPS/eip-658
case receipt[].statusType
of ReceiptStatusType.Root:
false
of ReceiptStatusType.Status:
true
func ETHReceiptGetRoot(
receipt: ptr ETHReceipt): ptr Eth2Digest {.exported.} =
## Obtains the intermediate post-state root of a receipt with no status code.
##
## * If the receipt has a status code, this function returns a zero hash.
##
## * The returned value is allocated in the given receipt.
## It must neither be released nor written to, and the receipt
## must not be released while the returned value is in use.
##
## Parameters:
## * `receipt` - Receipt.
##
## Returns:
## * Intermediate post-state root.
addr receipt[].root
func ETHReceiptGetStatus(
receipt: ptr ETHReceipt): bool {.exported.} =
## Obtains the status code of a receipt with a status code.
##
## * If the receipt has no status code, this function returns true.
##
## Parameters:
## * `receipt` - Receipt.
##
## Returns:
## * Status code.
##
## See:
## * https://eips.ethereum.org/EIPS/eip-658
receipt[].status
func ETHReceiptGetGasUsed(
receipt: ptr ETHReceipt): ptr uint64 {.exported.} =
## Obtains the gas used of a receipt.
##
## * The returned value is allocated in the given receipt.
## It must neither be released nor written to, and the receipt
## must not be released while the returned value is in use.
##
## Parameters:
## * `receipt` - Receipt.
##
## Returns:
## * Gas used.
addr receipt[].gasUsed
func ETHReceiptGetLogsBloom(
receipt: ptr ETHReceipt): ptr BloomLogs {.exported.} =
## Obtains the logs Bloom of a receipt.
##
## * The returned value is allocated in the given receipt.
## It must neither be released nor written to, and the receipt
## must not be released while the returned value is in use.
##
## Parameters:
## * `receipt` - Receipt.
##
## Returns:
## * Logs Bloom.
addr receipt[].logsBloom
func ETHReceiptGetLogs(
receipt: ptr ETHReceipt): ptr seq[ETHLog] {.exported.} =
## Obtains the logs of a receipt.
##
## * The returned value is allocated in the given receipt.
## It must neither be released nor written to, and the receipt
## must not be released while the returned value is in use.
##
## Parameters:
## * `receipt` - Receipt.
##
## Returns:
## * Log sequence.
addr receipt[].logs
func ETHLogsGetCount(
logs: ptr seq[ETHLog]): cint {.exported.} =
## Indicates the total number of logs in a log sequence.
##
## * Individual logs may be investigated using `ETHLogsGet`.
##
## Parameters:
## * `logs` - Log sequence.
##
## Returns:
## * Number of available logs.
logs[].len.cint
func ETHLogsGet(
logs: ptr seq[ETHLog],
logIndex: cint): ptr ETHLog {.exported.} =
## Obtains an individual log by sequential index in a log sequence.
##
## * The returned value is allocated in the given log sequence.
## It must neither be released nor written to, and the log sequence
## must not be released while the returned value is in use.
##
## Parameters:
## * `logs` - Log sequence.
## * `logIndex` - Sequential log index.
##
## Returns:
## * Log.
addr logs[][logIndex.int]
func ETHLogGetAddress(
log: ptr ETHLog): ptr ExecutionAddress {.exported.} =
## Obtains the address of a log.
##
## * The returned value is allocated in the given log.
## It must neither be released nor written to, and the log
## must not be released while the returned value is in use.
##
## Parameters:
## * `log` - Log.
##
## Returns:
## * Address.
addr log[].address
func ETHLogGetNumTopics(
log: ptr ETHLog): cint {.exported.} =
## Indicates the total number of topics in a log.
##
## * Individual topics may be investigated using `ETHLogGetTopic`.
##
## Parameters:
## * `log` - Log.
##
## Returns:
## * Number of available topics.
log[].topics.len.cint
func ETHLogGetTopic(
log: ptr ETHLog,
topicIndex: cint): ptr Eth2Digest {.exported.} =
## Obtains an individual topic by sequential index in a log.
##
## * The returned value is allocated in the given log.
## It must neither be released nor written to, and the log
## must not be released while the returned value is in use.
##
## Parameters:
## * `log` - Log.
## * `topicIndex` - Sequential topic index.
##
## Returns:
## * Topic.
addr log[].topics[topicIndex.int]
func ETHLogGetDataBytes(
log: ptr ETHLog,
numBytes #[out]#: ptr cint): ptr UncheckedArray[byte] {.exported.} =
## Obtains the data of a log.
##
## * The returned value is allocated in the given log.
## It must neither be released nor written to, and the log
## must not be released while the returned value is in use.
##
## Parameters:
## * `log` - Log.
## * `numBytes` [out] - Length of buffer.
##
## Returns:
## * Buffer with data.
numBytes[] = log[].data.len.cint
if log[].data.len == 0:
# https://github.com/nim-lang/Nim/issues/22389
const defaultData: cstring = ""
return cast[ptr UncheckedArray[byte]](defaultData)
cast[ptr UncheckedArray[byte]](addr log[].data[0])
func ETHReceiptGetBytes(
receipt: ptr ETHReceipt,
numBytes #[out]#: ptr cint): ptr UncheckedArray[byte] {.exported.} =
## Obtains the raw byte representation of a receipt.
##
## * The returned value is allocated in the given receipt.
## It must neither be released nor written to, and the receipt
## must not be released while the returned value is in use.
##
## Parameters:
## * `receipt` - Receipt.
## * `numBytes` [out] - Length of buffer.
##
## Returns:
## * Buffer with raw receipt data.
numBytes[] = distinctBase(receipt[].bytes).len.cint
if distinctBase(receipt[].bytes).len == 0:
# https://github.com/nim-lang/Nim/issues/22389
const defaultBytes: cstring = ""
return cast[ptr UncheckedArray[byte]](defaultBytes)
cast[ptr UncheckedArray[byte]](addr distinctBase(receipt[].bytes)[0])

View File

@ -0,0 +1,360 @@
[
{
"blockHash": "0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd",
"blockNumber": "0xb443",
"contractAddress": null,
"cumulativeGasUsed": "0x5208",
"effectiveGasPrice": "0x2d79883d2000",
"from": "0xa1e4380a3b1f749673e270229993ee55f35663b4",
"gasUsed": "0x5208",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"root": "0x96a8e009d2b88b1483e6941e6812e32263b05683fac202abc622a3e31aed1957",
"to": "0x5df9b87991262f6ba471f09758cde1c0fc1de734",
"transactionHash": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",
"transactionIndex": "0x0",
"type": "0x0"
},
{
"blockHash": "0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e",
"blockNumber": "0xf4240",
"contractAddress": null,
"cumulativeGasUsed": "0xa410",
"effectiveGasPrice": "0xdf8475800",
"from": "0x32be343b94f860124dc4fee278fdcbd38c102d88",
"gasUsed": "0x5208",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0xdf190dc7190dfba737d7777a163445b7fff16133",
"transactionHash": "0xe9e91f1ee4b56c0df2e9f06c2b8c27c6076195a88a7b8537ba8313d80e6f124e",
"transactionIndex": "0x1",
"type": "0x0"
},
{
"blockHash": "0xe380e7cf640a646ef901b6a5db4d3076fdcad5ac2a922ca098f639d2b762df4f",
"blockNumber": "0x10fa02b",
"contractAddress": null,
"cumulativeGasUsed": "0x1a93e",
"effectiveGasPrice": "0x9839089a0",
"from": "0xbe49bd130e126a917ddb5fabf7cdeb6dd9887f40",
"gasUsed": "0x1052e",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0x84654be796dad370032391d5479f8f1fd9ddd14e",
"transactionHash": "0xdc81918bf78322ce017c592e81c855f40bb96bd82da9779167de1de109962be6",
"transactionIndex": "0x2",
"type": "0x0"
},
{
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"blockNumber": "0xc35000",
"contractAddress": null,
"cumulativeGasUsed": "0x64f13",
"effectiveGasPrice": "0x0",
"from": "0x1fd34033240c95aabf73e186a94b9576c6dab81b",
"gasUsed": "0x4a5d5",
"logs": [
{
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x00000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"0x0000000000000000000000003765521db364ee269e9540970fd21e5a3e825699"
],
"data": "0x00000000000000000000000000000000000000000000000034b819a76c9101dd",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x0",
"removed": false
},
{
"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000006a9850e46518231b23e50467c975fa94026be5d5",
"0x00000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f5640"
],
"data": "0x00000000000000000000000000000000000000000000000000000001dac7be33",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x1",
"removed": false
},
{
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000003765521db364ee269e9540970fd21e5a3e825699",
"0x000000000000000000000000f1f85b2c54a2bd284b1cf4141d64fd171bd85539"
],
"data": "0x00000000000000000000000000000000000000000000000034a2e5498f6f66f8",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x2",
"removed": false
},
{
"address": "0x57ab1ec28d129707052df4df418d58a2d46d5f51",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000f1f85b2c54a2bd284b1cf4141d64fd171bd85539",
"0x0000000000000000000000006a9850e46518231b23e50467c975fa94026be5d5"
],
"data": "0x0000000000000000000000000000000000000000000001ade409ce94c21807e0",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x3",
"removed": false
},
{
"address": "0xf1f85b2c54a2bd284b1cf4141d64fd171bd85539",
"topics": [
"0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"
],
"data": "0x0000000000000000000000000000000000000000000444ae3b74db3b9d4e6c6800000000000000000000000000000000000000000000008597e1b00a2ca3cb8b",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x4",
"removed": false
},
{
"address": "0xf1f85b2c54a2bd284b1cf4141d64fd171bd85539",
"topics": [
"0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822",
"0x0000000000000000000000003765521db364ee269e9540970fd21e5a3e825699",
"0x0000000000000000000000006a9850e46518231b23e50467c975fa94026be5d5"
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034a2e5498f6f66f80000000000000000000000000000000000000000000001ade409ce94c21807e00000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x5",
"removed": false
},
{
"address": "0x6a9850e46518231b23e50467c975fa94026be5d5",
"topics": [
"0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67",
"0x0000000000000000000000003765521db364ee269e9540970fd21e5a3e825699",
"0x00000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f5640"
],
"data": "0x0000000000000000000000000000000000000000000001ade409ce94c21807e0fffffffffffffffffffffffffffffffffffffffffffffffffffffffe253841cd0000000000000000000000000000000000000000000010d1979907b2b7b44fb8000000000000000000000000000000000000000000000020160626e11f50affdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc8cd",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x6",
"removed": false
},
{
"address": "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"topics": [
"0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67",
"0x0000000000000000000000003765521db364ee269e9540970fd21e5a3e825699",
"0x0000000000000000000000003765521db364ee269e9540970fd21e5a3e825699"
],
"data": "0x00000000000000000000000000000000000000000000000000000001dac7be33ffffffffffffffffffffffffffffffffffffffffffffffffcb47e658936efe23000000000000000000000000000000000000555373cbb17fb17a13909e0f3a3b00000000000000000000000000000000000000000000000066d5e9eea910e5ef0000000000000000000000000000000000000000000000000000000000030ca3",
"blockNumber": "0xc35000",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"blockHash": "0x802f1f5a7575098ce5e716cfc6817e24d6944fde8e32eb95dbc178931b11baea",
"logIndex": "0x7",
"removed": false
}
],
"logsBloom": "0x0020000001000000000020008000000000000000000000000000000004000000000000000000000000000800000800000a0000000800200000000000400000000000080000100008080000080010002000000000000000000000010000000000000000000000000000000000000000000000000000000000000000100008000000000000000000000000000000000000000000000100000800000040000000000000000000002010000000000000000000000000000000000020000000080000000000020000000000000000000000000008000000000010000000000000000000002800000004000000100000000000000000000420008000000a0000000000",
"status": "0x1",
"to": "0x3765521db364ee269e9540970fd21e5a3e825699",
"transactionHash": "0x8135b5403ea5528341d661cdadd8eb67983909fc1644b0a133de708b13e10937",
"transactionIndex": "0x3",
"type": "0x1"
},
{
"blockHash": "0xe380e7cf640a646ef901b6a5db4d3076fdcad5ac2a922ca098f639d2b762df4f",
"blockNumber": "0x10fa02b",
"contractAddress": null,
"cumulativeGasUsed": "0x7ff02",
"effectiveGasPrice": "0x64a2d5a95",
"from": "0xae2fc483527b8ef99eb5d9b44875f005ba1fae13",
"gasUsed": "0x1afef",
"logs": [
{
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000006b75d8af000000e20b7a7ddf000ba900b4009a80",
"0x000000000000000000000000397217ae1de4a6e543858b0191c9213aadbcc4ed"
],
"data": "0x00000000000000000000000000000000000000000000000003e168d700000000",
"blockNumber": "0x10fa02b",
"transactionHash": "0xba363483b992ef59342094ab98b8523ed6c055b5788e6726140d2badf27bf6d6",
"transactionIndex": "0x4",
"blockHash": "0xe380e7cf640a646ef901b6a5db4d3076fdcad5ac2a922ca098f639d2b762df4f",
"logIndex": "0x8",
"removed": false
},
{
"address": "0x4ecfc56672c7630b84dac9c1f7407579715de155",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000397217ae1de4a6e543858b0191c9213aadbcc4ed",
"0x0000000000000000000000004ecfc56672c7630b84dac9c1f7407579715de155"
],
"data": "0x0000000000000000000000000000000000000000000001df1858999999999999",
"blockNumber": "0x10fa02b",
"transactionHash": "0xba363483b992ef59342094ab98b8523ed6c055b5788e6726140d2badf27bf6d6",
"transactionIndex": "0x4",
"blockHash": "0xe380e7cf640a646ef901b6a5db4d3076fdcad5ac2a922ca098f639d2b762df4f",
"logIndex": "0x9",
"removed": false
},
{
"address": "0x4ecfc56672c7630b84dac9c1f7407579715de155",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000397217ae1de4a6e543858b0191c9213aadbcc4ed",
"0x0000000000000000000000006b75d8af000000e20b7a7ddf000ba900b4009a80"
],
"data": "0x00000000000000000000000000000000000000000000238ece93666666666667",
"blockNumber": "0x10fa02b",
"transactionHash": "0xba363483b992ef59342094ab98b8523ed6c055b5788e6726140d2badf27bf6d6",
"transactionIndex": "0x4",
"blockHash": "0xe380e7cf640a646ef901b6a5db4d3076fdcad5ac2a922ca098f639d2b762df4f",
"logIndex": "0xa",
"removed": false
},
{
"address": "0x397217ae1de4a6e543858b0191c9213aadbcc4ed",
"topics": [
"0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"
],
"data": "0x0000000000000000000000000000000000000000000ad652dd7967ecf01d441000000000000000000000000000000000000000000000000122a5b6292417bf7a",
"blockNumber": "0x10fa02b",
"transactionHash": "0xba363483b992ef59342094ab98b8523ed6c055b5788e6726140d2badf27bf6d6",
"transactionIndex": "0x4",
"blockHash": "0xe380e7cf640a646ef901b6a5db4d3076fdcad5ac2a922ca098f639d2b762df4f",
"logIndex": "0xb",
"removed": false
},
{
"address": "0x397217ae1de4a6e543858b0191c9213aadbcc4ed",
"topics": [
"0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822",
"0x0000000000000000000000006b75d8af000000e20b7a7ddf000ba900b4009a80",
"0x0000000000000000000000006b75d8af000000e20b7a7ddf000ba900b4009a80"
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e168d70000000000000000000000000000000000000000000000000000256de6ec0000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockNumber": "0x10fa02b",
"transactionHash": "0xba363483b992ef59342094ab98b8523ed6c055b5788e6726140d2badf27bf6d6",
"transactionIndex": "0x4",
"blockHash": "0xe380e7cf640a646ef901b6a5db4d3076fdcad5ac2a922ca098f639d2b762df4f",
"logIndex": "0xc",
"removed": false
}
],
"logsBloom": "0x00200000000000000000000080000000000000000000004000000000400000000000008000000020001000000000040002000000084000000000000000000000000000000000000000000008000000200000000040000000000000000000000000000200000000000000000000000000000000000000000080000010000000000000800000000000000000000000000000000000000000080000004000000000000000000000000000000000000000000000000000100000000000000000400000000002000000000000000000000000000004000000001000001000000000000000200000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0x6b75d8af000000e20b7a7ddf000ba900b4009a80",
"transactionHash": "0xba363483b992ef59342094ab98b8523ed6c055b5788e6726140d2badf27bf6d6",
"transactionIndex": "0x4",
"type": "0x2"
},
{
"type": "0x2",
"transactionHash": "0xa3b805acacb25da412a44bd9612a73464292fc684a400ab54f0a9626f7d9c3f2",
"transactionIndex": "0x5",
"blockHash": "0x421e594f79995d1aba3c62c80c678a1f6d4d70a6c49c9d721a5ad1ef802f79b3",
"blockNumber": "0x10fd2c3",
"from": "0x979db18107552faa36a52480a1dbb65ed3f51d70",
"to": null,
"cumulativeGasUsed": "0x16fa7c",
"gasUsed": "0xefb7a",
"contractAddress": "0x451445a9adb7e4c8ab4a266755626c136e093a4e",
"logs": [
{
"removed": false,
"logIndex": "0xd",
"transactionIndex": "0x5",
"transactionHash": "0xa3b805acacb25da412a44bd9612a73464292fc684a400ab54f0a9626f7d9c3f2",
"blockHash": "0x421e594f79995d1aba3c62c80c678a1f6d4d70a6c49c9d721a5ad1ef802f79b3",
"blockNumber": "0x10fd2c3",
"address": "0x451445a9adb7e4c8ab4a266755626c136e093a4e",
"data": "0x",
"topics": [
"0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b",
"0x0000000000000000000000007e22fcb742572515d1c3fef972ec066c995820ef"
]
},
{
"removed": false,
"logIndex": "0xe",
"transactionIndex": "0x5",
"transactionHash": "0xa3b805acacb25da412a44bd9612a73464292fc684a400ab54f0a9626f7d9c3f2",
"blockHash": "0x421e594f79995d1aba3c62c80c678a1f6d4d70a6c49c9d721a5ad1ef802f79b3",
"blockNumber": "0x10fd2c3",
"address": "0x451445a9adb7e4c8ab4a266755626c136e093a4e",
"data": "0x",
"topics": [
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x000000000000000000000000979db18107552faa36a52480a1dbb65ed3f51d70"
]
},
{
"removed": false,
"logIndex": "0xf",
"transactionIndex": "0x5",
"transactionHash": "0xa3b805acacb25da412a44bd9612a73464292fc684a400ab54f0a9626f7d9c3f2",
"blockHash": "0x421e594f79995d1aba3c62c80c678a1f6d4d70a6c49c9d721a5ad1ef802f79b3",
"blockNumber": "0x10fd2c3",
"address": "0x451445a9adb7e4c8ab4a266755626c136e093a4e",
"data": "0x0000000000000000000000000000000000000000000000000000000064c7eb930000000000000000000000000000000000000000000000000000000064d2bde30000000000000000000000000000000000000000000000000000000064c7e277",
"topics": [
"0x23f6ad8232d75562dd1c6b37dfc895af6bfc1ecd0fb3b88722c6a5e6b4dc9a20"
]
},
{
"removed": false,
"logIndex": "0x10",
"transactionIndex": "0x5",
"transactionHash": "0xa3b805acacb25da412a44bd9612a73464292fc684a400ab54f0a9626f7d9c3f2",
"blockHash": "0x421e594f79995d1aba3c62c80c678a1f6d4d70a6c49c9d721a5ad1ef802f79b3",
"blockNumber": "0x10fd2c3",
"address": "0x451445a9adb7e4c8ab4a266755626c136e093a4e",
"data": "0x0000000000000000000000000000000000000000000000000000000000000001",
"topics": [
"0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"
]
},
{
"removed": false,
"logIndex": "0x11",
"transactionIndex": "0x5",
"transactionHash": "0xa3b805acacb25da412a44bd9612a73464292fc684a400ab54f0a9626f7d9c3f2",
"blockHash": "0x421e594f79995d1aba3c62c80c678a1f6d4d70a6c49c9d721a5ad1ef802f79b3",
"blockNumber": "0x10fd2c3",
"address": "0x451445a9adb7e4c8ab4a266755626c136e093a4e",
"data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d89f6892a2b58d50e0e8f51a961b12a25ce3f757",
"topics": [
"0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"
]
}
],
"logsBloom": "0x0000000000000000000000000000000040000000000000000080000001000000000000000000000000000000000000000000000200004000000000000201000000000000000000000000000000000200000100000000000000000000000000000000000002000000000000000000080004000080000000000000000000000040000000000000000000000004000000000000000000008000000000040080000000000000000000000000000000040000000000000000000000000000000000000000002020000000000000000004000a000000000400000000000000000020000000000000000000000000000000000000000000000000000000000000020000",
"status": "0x1",
"effectiveGasPrice": "0xa00a0c2f8"
}
]

File diff suppressed because one or more lines are too long

View File

@ -238,8 +238,9 @@ static void visualizeHeader(const ETHLightClientHeader *header, const ETHConsens
int executionTimestamp = ETHExecutionPayloadHeaderGetTimestamp(execution);
printf(" - timestamp: %d\n", executionTimestamp);
const void *executionExtraDataBytes = ETHExecutionPayloadHeaderGetExtraDataBytes(execution);
int numExecutionExtraDataBytes = ETHExecutionPayloadHeaderGetNumExtraDataBytes(execution);
int numExecutionExtraDataBytes;
const void *executionExtraDataBytes =
ETHExecutionPayloadHeaderGetExtraDataBytes(execution, &numExecutionExtraDataBytes);
printf(" - extra_data: ");
printHexString(executionExtraDataBytes, numExecutionExtraDataBytes);
printf("\n");
@ -391,10 +392,10 @@ int main(void)
ETHExecutionBlockHeaderDestroy(executionBlockHeader);
ETHRoot sampleTransactionsRoot = {{
0x4e, 0x90, 0xdc, 0x06, 0xca, 0xd6, 0xa7, 0xc0,
0x57, 0xd2, 0xd7, 0x7f, 0x8f, 0x77, 0xd1, 0x45,
0xb4, 0x6f, 0xf3, 0xad, 0x9c, 0xa7, 0xe1, 0xef,
0x57, 0x11, 0x5f, 0xa8, 0xbf, 0xad, 0xfe, 0xe1,
0x73, 0x36, 0x36, 0xe8, 0x0e, 0x47, 0x60, 0x09,
0xd1, 0xc8, 0x9f, 0x81, 0xaa, 0x64, 0xe1, 0xfd,
0xf7, 0xff, 0x36, 0xd6, 0x04, 0x6e, 0x95, 0x6c,
0x39, 0xed, 0xcd, 0x6c, 0x95, 0x2d, 0xce, 0xc2,
}};
void *sampleTransactionsJson = readEntireFile(
__DIR__ "/test_files/transactions.json", /* numBytes: */ NULL);
@ -403,10 +404,26 @@ int main(void)
check(transactions);
free(sampleTransactionsJson);
ETHRoot sampleReceiptsRoot = {{
0x51, 0x4d, 0xdf, 0xd7, 0xf8, 0x33, 0xfb, 0x2a,
0x4f, 0x60, 0xed, 0x49, 0xdf, 0xc7, 0x9c, 0x07,
0xb6, 0x9c, 0x37, 0xef, 0xd1, 0xa5, 0x97, 0xca,
0x42, 0x76, 0x23, 0xff, 0xa1, 0x79, 0x49, 0xae,
}};
void *sampleReceiptsJson = readEntireFile(
__DIR__ "/test_files/receipts.json", /* numBytes: */ NULL);
ETHReceipts *receipts =
ETHReceiptsCreateFromJson(&sampleReceiptsRoot, sampleReceiptsJson, transactions);
check(receipts);
free(sampleReceiptsJson);
int numTransactions = ETHTransactionsGetCount(transactions);
int numReceipts = ETHReceiptsGetCount(receipts);
check(numTransactions == numReceipts);
printf("\nSample transactions:\n");
for (int transactionIndex = 0; transactionIndex < numTransactions; transactionIndex++) {
const ETHTransaction *transaction = ETHTransactionsGet(transactions, transactionIndex);
const ETHReceipt *receipt = ETHReceiptsGet(receipts, transactionIndex);
const ETHRoot *transactionHash = ETHTransactionGetHash(transaction);
printf("- ");
@ -506,8 +523,63 @@ int main(void)
printf(" - bytes: ");
printHexString(transactionBytes, numTransactionBytes);
printf("\n");
printf(" - receipt:\n");
bool receiptHasStatus = ETHReceiptHasStatus(receipt);
if (!receiptHasStatus) {
const ETHRoot *receiptRoot = ETHReceiptGetRoot(receipt);
printf(" - root: ");
printHexString(receiptRoot, sizeof *receiptRoot);
printf("\n");
} else {
bool receiptStatus = ETHReceiptGetStatus(receipt);
printf(" - status: %d\n", receiptStatus);
}
const uint64_t *receiptGasUsed = ETHReceiptGetGasUsed(receipt);
printf(" - gas_used: %" PRIu64 "\n", *receiptGasUsed);
const ETHLogsBloom *receiptLogsBloom = ETHReceiptGetLogsBloom(receipt);
printf(" - logs_bloom: ");
printHexString(receiptLogsBloom, sizeof *receiptLogsBloom);
printf("\n");
const ETHLogs *receiptLogs = ETHReceiptGetLogs(receipt);
printf(" - logs:\n");
int numLogs = ETHLogsGetCount(receiptLogs);
for (int logIndex = 0; logIndex < numLogs; logIndex++) {
const ETHLog *log = ETHLogsGet(receiptLogs, logIndex);
const ETHExecutionAddress *logAddress = ETHLogGetAddress(log);
printf(" - address: ");
printHexString(logAddress, sizeof *logAddress);
printf("\n");
printf(" - topics:\n");
int numTopics = ETHLogGetNumTopics(log);
for (int topicIndex = 0; topicIndex < numTopics; topicIndex++) {
const ETHRoot *topic = ETHLogGetTopic(log, topicIndex);
printf(" - ");
printHexString(topic, sizeof *topic);
printf("\n");
}
int numLogDataBytes;
const void *logDataBytes = ETHLogGetDataBytes(log, &numLogDataBytes);
printf(" - data: ");
printHexString(logDataBytes, numLogDataBytes);
printf("\n");
}
int numReceiptBytes;
const void *receiptBytes = ETHReceiptGetBytes(receipt, &numReceiptBytes);
printf(" - bytes: ");
printHexString(receiptBytes, numReceiptBytes);
printf("\n");
}
ETHReceiptsDestroy(receipts);
ETHTransactionsDestroy(transactions);
return 0;

View File

@ -33,6 +33,7 @@ func toEther*(gwei: Gwei): Ether =
type
ExecutionHash256* = eth_types.Hash256
ExecutionTransaction* = eth_types.Transaction
ExecutionReceipt* = eth_types.Receipt
ExecutionWithdrawal = eth_types.Withdrawal
ExecutionBlockHeader* = eth_types.BlockHeader