diff --git a/web3/encoding.nim b/web3/encoding.nim index 89e07e9..bc1a20c 100644 --- a/web3/encoding.nim +++ b/web3/encoding.nim @@ -11,6 +11,23 @@ import std/macros, stint, ./eth_api_types, stew/[assign2, byteutils] +macro makeEncodingEthereumFuncs(): untyped = + ## Creates all the encoding funcs needed to properly interact with Ethereum-like chains + result = newStmtList() + for numBits in [256, 128, 64, 32, 16, 8]: + let identUint = newIdentNode("EthereumUint" & $numBits) + + result.add quote do: + func encode*(x: `identUint`): seq[byte] = + ## the Ethereum types are created by makeEthereumType macro in eth_api_types.nim + let numTargetBytes = `numBits` div 8 + let paddingBytes = 32 - numTargetBytes + ## the Ethereum ABI imposes a 32 byte width for every type + let paddingZeros = newSeq[byte](paddingBytes) + paddingZeros & @(stint.toBytesBE(x)) + +makeEncodingEthereumFuncs() + func encode*[bits: static[int]](x: StUint[bits]): seq[byte] = @(x.toBytesBE()) diff --git a/web3/eth_api_types.nim b/web3/eth_api_types.nim index 22e661a..93f2f9f 100644 --- a/web3/eth_api_types.nim +++ b/web3/eth_api_types.nim @@ -10,6 +10,7 @@ {.push raises: [].} import + std/macros, stint, ./primitives @@ -299,6 +300,19 @@ func payload*(args: TransactionArgs): seq[byte] = func isEIP4844*(args: TransactionArgs): bool = args.maxFeePerBlobGas.isSome or args.blobVersionedHashes.isSome +macro makeEthereumTypes(): untyped = + ## This macro creates all the various types of Eth contracts and maps + ## them to the type used for their encoding. + result = newStmtList() + for i in [256, 128, 64, 32, 16, 8]: + let + identUint = newIdentNode("EthereumUint" & $i) + + result.add quote do: + type `identUint`* = StUint[`i`] + +makeEthereumTypes() + # Backwards compatibility type