Skip to content

Commit

Permalink
Fixed encoding of (multidimentional) dynamic arrays (#149)
Browse files Browse the repository at this point in the history
* Fixed encoding of (multidimentional) dynamic arrays

* Added reference link
  • Loading branch information
yglukhov authored May 21, 2024
1 parent 3cb2a77 commit 46b4b4c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
6 changes: 5 additions & 1 deletion tests/test_contract_dsl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ contract(TestContract):
proc getBool(): bool
proc setBool(a: bool)
proc setString(a: string)
proc g(a: seq[seq[UInt256]], b: seq[string])

contract(TestContractWithConstructor):
proc init(someArg1, someArg2: UInt256) {.constructor.}
Expand All @@ -47,7 +48,10 @@ suite "Contract DSL":
checkData(c.getBool(), "0x12a7b914")
checkData(c.setBool(true), "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001")
checkData(c.setBool(false), "0x1e26fd330000000000000000000000000000000000000000000000000000000000000000")
checkData(c.setString("hello"), "0x7fcaf6660000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f0000000000")
checkData(c.setString("hello"), "0x7fcaf6660000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000")

# Example taken from https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types
checkData(c.g(@[@[1.u256, 2.u256], @[3.u256]], @["one", "two", "three"]), "0x2289b18c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000036f6e650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000374776f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057468726565000000000000000000000000000000000000000000000000000000")

test "Constructors":
let s = DummySender()
Expand Down
9 changes: 5 additions & 4 deletions web3/encoding.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ func decode*(input: openarray[byte], baseOffset, offset: int, to: var Address):
func encodeDynamic(v: openArray[byte]): seq[byte] =
result = encode(v.len.u256)
result.add(v)
for i in 0 ..< (v.len mod 32):
result.add(0)
let pad = v.len mod 32
if pad != 0:
result.setLen(result.len + 32 - pad)

func encode*(x: DynamicBytes): seq[byte] {.inline.} =
encodeDynamic(distinctBase x)
Expand Down Expand Up @@ -157,9 +158,9 @@ func encode*[T](x: openarray[T]): seq[byte] =
when isDynamicType(T):
result.setLen((1 + x.len) * 32)
for i in 0 ..< x.len:
let offset = result.len
let offset = result.len - 32
result &= encode(x[i])
result[i .. i + 31] = encode(offset.u256)
result[(i + 1) * 32 .. (i + 2) * 32 - 1] = encode(offset.u256)
else:
for i in 0 ..< x.len:
result &= encode(x[i])
Expand Down

0 comments on commit 46b4b4c

Please sign in to comment.