mirror of
https://github.com/logos-storage/nim-contract-abi.git
synced 2026-01-08 08:33:12 +00:00
Decode sequences and arrays
This commit is contained in:
parent
767c4ab588
commit
0f4c4d1465
@ -1,6 +1,7 @@
|
||||
import pkg/stint
|
||||
import pkg/stew/endians2
|
||||
import pkg/upraises
|
||||
import ./encoding
|
||||
|
||||
push: {.upraises:[].}
|
||||
|
||||
@ -93,6 +94,20 @@ func finish*(decoder: var AbiDecoder) =
|
||||
doAssert decoder.index == decoder.bytes.len, "unread trailing bytes found"
|
||||
doAssert decoder.index mod 32 == 0, "encoding variant broken"
|
||||
|
||||
func read*[T](decoder: var AbiDecoder, _: type seq[T]): seq[T] =
|
||||
let len = decoder.read(uint64)
|
||||
decoder.startTuple(dynamic=true)
|
||||
for _ in 0..<len:
|
||||
result.add(decoder.read(T))
|
||||
decoder.finishTuple()
|
||||
|
||||
func read*[I,T](decoder: var AbiDecoder, _: type array[I,T]): array[I,T] =
|
||||
const dynamic = AbiEncoder.isDynamic(T)
|
||||
decoder.startTuple(dynamic)
|
||||
for i in 0..<result.len:
|
||||
result[i] = decoder.read(T)
|
||||
decoder.finishTuple()
|
||||
|
||||
func decode*(_: type AbiDecoder, bytes: seq[byte], T: type): T =
|
||||
var decoder = AbiDecoder.init(bytes)
|
||||
result = decoder.read(T)
|
||||
|
||||
@ -128,3 +128,11 @@ func encode*[T](_: type AbiEncoder, value: T): seq[byte] =
|
||||
var encoder = AbiEncoder.init()
|
||||
encoder.write(value)
|
||||
encoder.finish()
|
||||
|
||||
proc isDynamic*(_: type AbiEncoder, T: type): bool {.compileTime.} =
|
||||
var encoder = AbiEncoder.init()
|
||||
encoder.encode(T.default)
|
||||
encoder.stack[^1].dynamic
|
||||
|
||||
proc isStatic*(_: type AbiEncoder, T: type): bool {.compileTime.} =
|
||||
not AbiEncoder.isDynamic(T)
|
||||
|
||||
@ -186,3 +186,12 @@ suite "ABI decoding":
|
||||
decoder.finishTuple()
|
||||
decoder.finish()
|
||||
|
||||
test "decodes sequences":
|
||||
checkDecode(@[seq[byte].example, seq[byte].example])
|
||||
|
||||
test "decodes arrays with static elements":
|
||||
checkDecode([array[32, byte].example, array[32, byte].example])
|
||||
|
||||
test "decodes arrays with dynamic elements":
|
||||
checkDecode([seq[byte].example, seq[byte].example])
|
||||
|
||||
|
||||
@ -171,5 +171,11 @@ suite "ABI encoding":
|
||||
test "encodes strings as UTF-8 byte sequence":
|
||||
check AbiEncoder.encode("hello!☺") == AbiEncoder.encode("hello!☺".toBytes)
|
||||
|
||||
test "can determine whether types are dynamic or static":
|
||||
check static AbiEncoder.isStatic(uint8)
|
||||
check static AbiEncoder.isDynamic(seq[byte])
|
||||
check static AbiEncoder.isStatic(array[2, array[2, byte]])
|
||||
check static AbiEncoder.isDynamic(array[2, seq[byte]])
|
||||
|
||||
# https://medium.com/b2expand/abi-encoding-explanation-4f470927092d
|
||||
# https://docs.soliditylang.org/en/v0.8.1/abi-spec.html#formal-specification-of-the-encoding
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user