Skip to content

Commit

Permalink
creating a more generic and simplified solution as per Etan comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivansete-status committed Jan 23, 2025
1 parent 9de5a8c commit eb25271
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 29 deletions.
25 changes: 19 additions & 6 deletions web3/encoding.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
31 changes: 8 additions & 23 deletions web3/eth_api_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit eb25271

Please sign in to comment.