diff --git a/web3/encoding.nim b/web3/encoding.nim index b619091..6572326 100644 --- a/web3/encoding.nim +++ b/web3/encoding.nim @@ -11,12 +11,25 @@ import std/macros, stint, ./eth_api_types, stew/[assign2, byteutils] -func encode*(x: EthereumUint32): seq[byte] = - let numTargetBytes = 32 div 8 - let paddingBytes = 32 - numTargetBytes - ## the Ethereum ABI imposes a 32 byte width for every type - let paddingZeros = newSeq[byte](paddingBytes) - paddingZeros & @(x.toByteArrayBE()) +macro makeEncodingEthereumFuncs(): untyped = + ## Creates all the encoding funcs needed to properly interact with Ethereum-like chains + result = newStmtList() + for i in [256, 128, 64, 32, 16, 8]: + let + identUint = newIdentNode("EthereumUint" & $i) + identInt = newIdentNode("EthereumInt" & $i) + + for ident in [`identUint`, `identInt`]: + result.add quote do: + func encode*(x: `ident`): seq[byte] = + ## the Ethereum types are created by makeEthereumType macro in eth_api_types.nim + let numTargetBytes = `i` div 8 + let paddingBytes = 32 - numTargetBytes + ## the Ethereum ABI imposes a 32 byte width for every type + let paddingZeros = newSeq[byte](paddingBytes) + paddingZeros & @(x.toBytesBE()) + +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 1c83c83..fd1eb70 100644 --- a/web3/eth_api_types.nim +++ b/web3/eth_api_types.nim @@ -300,36 +300,21 @@ func payload*(args: TransactionArgs): seq[byte] = func isEIP4844*(args: TransactionArgs): bool = args.maxFeePerBlobGas.isSome or args.blobVersionedHashes.isSome -macro makeEthereumTypeEnum(): untyped = - ## This macro creates all the various types of Solidity contracts and maps - ## them to the type used for their encoding. It also creates an enum to - ## identify these types in the contract signatures, along with encoder - ## functions used in the generated procedures. +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() - var lastpow2: int - for i in countdown(256, 8, 8): + for i in [256, 128, 64, 32, 16, 8]: let identUint = newIdentNode("EthereumUint" & $i) identInt = newIdentNode("EthereumInt" & $i) - if ceil(log2(i.float)) == floor(log2(i.float)): - lastpow2 = i result.add quote do: type - `identUint`* = StUint[`lastpow2`] - `identInt`* = StInt[`lastpow2`] - - let - identUint = ident("EthereumUint") - identInt = ident("EthereumInt") - identBool = ident("EthereumBool") - result.add quote do: - type - `identUint`* = UInt256 - `identInt`* = Int256 - `identBool`* = distinct Int256 - -makeEthereumTypeEnum() + `identUint`* = StUint[`i`] + `identInt`* = StInt[`i`] + +makeEthereumTypes() # Backwards compatibility