From 763a758b0a0b47b1d4c04de79a8fd12b9e83e3b8 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Tue, 23 Feb 2021 10:23:42 +0100 Subject: [PATCH] Fix ABI encoding of Ethereum Addresses They should be encoded as if they were UInt160, which means they should be left-padded with zeroes, instead of right-padded. --- nitro/abi.nim | 4 ++++ nitro/types.nim | 7 ++++++- tests/nitro/examples.nim | 3 +++ tests/nitro/testAbi.nim | 5 +++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/nitro/abi.nim b/nitro/abi.nim index f64b0e0..2242b10 100644 --- a/nitro/abi.nim +++ b/nitro/abi.nim @@ -1,5 +1,6 @@ import pkg/stew/endians2 import pkg/stint +import ./types type Abi* = object @@ -61,6 +62,9 @@ proc write*(writer: var AbiWriter, bytes: seq[byte]) = else: writer.writeLater(bytes) +proc write*(writer: var AbiWriter, address: EthAddress) = + writer.padleft(address.toArray) + proc startTuple*(writer: var AbiWriter) = writer.tuples.add(Tuple()) diff --git a/nitro/types.nim b/nitro/types.nim index c61d505..1bae2d7 100644 --- a/nitro/types.nim +++ b/nitro/types.nim @@ -5,4 +5,9 @@ export stint type UInt48* = range[0'u64..2'u64^48-1] - EthAddress* = array[20, byte] + EthAddress* = distinct array[20, byte] + +proc toArray*(address: EthAddress): array[20, byte] = + array[20, byte](address) + +proc `==`*(a, b: EthAddress): bool {.borrow.} diff --git a/tests/nitro/examples.nim b/tests/nitro/examples.nim index 3127957..3becd48 100644 --- a/tests/nitro/examples.nim +++ b/tests/nitro/examples.nim @@ -24,6 +24,9 @@ proc example*(_: type UInt256): UInt256 = proc example*(_: type UInt128): UInt128 = UInt128.fromBytes(array[16, byte].example) +proc example*(_: type EthAddress): EthAddress = + EthAddress(array[20, byte].example) + proc example*(_: type Channel): Channel = Channel( nonce: UInt48.example, diff --git a/tests/nitro/testAbi.nim b/tests/nitro/testAbi.nim index 483500a..2da686c 100644 --- a/tests/nitro/testAbi.nim +++ b/tests/nitro/testAbi.nim @@ -1,5 +1,6 @@ import std/unittest import pkg/nitro/abi +import pkg/nitro/types import pkg/stint import ./examples @@ -61,6 +62,10 @@ suite "ABI encoding": let bytes33len = Abi.encode(bytes33.len.uint64) check Abi.encode(bytes33) == bytes33len & bytes33 & 31.zeroes + test "encodes ethereum addresses": + let address = EthAddress.example + check Abi.encode(address) == 12.zeroes & @(address.toArray) + test "encodes tuples": let a = true let b = @[1'u8, 2'u8, 3'u8]