Web3.swift icon indicating copy to clipboard operation
Web3.swift copied to clipboard

Dynamic array's encode/decode issue

Open Crypto-Doby opened this issue 3 years ago • 3 comments

now the dynamic array's encoding logic is to encode every item, then concat the hex string follow the length encoded hex.:

public func abiEncodeDynamic() -> String? {
    // get values
    let values = self.compactMap { value -> String? in
        return value.abiEncode(dynamic: true)
    }
    // number of elements in the array, padded left
    let length = String(values.count, radix: 16).paddingLeft(toLength: 64, withPad: "0")
    // values, joined with no separator
    return length + values.joined()
}

but follw the document: https://docs.soliditylang.org/en/v0.8.13/abi-spec.html#formal-specification-of-the-encoding it seems that the dynamic array's encoded data should have extra bytes between length hex and item's hex, to represent the dynamic item's data location.

for example: I want to encode a dynamic array of 4 datas:

let testArr = [
    Data.init(hex: "0x01"),
    Data.init(hex: "0x02"),
    Data.init(hex: "0x03"),
    Data.init(hex: "0x04")
]

let testData = testArr.abiEncode(dynamic: true)

the testData now is this:

0000000000000000000000000000000000000000000000000000000000000004

0000000000000000000000000000000000000000000000000000000000000001
0100000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000001
0200000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000001
0300000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000001
0400000000000000000000000000000000000000000000000000000000000000

it seems should add the extra bytes like this:

0000000000000000000000000000000000000000000000000000000000000004

0000000000000000000000000000000000000000000000000000000000000080
00000000000000000000000000000000000000000000000000000000000000c0
0000000000000000000000000000000000000000000000000000000000000100
0000000000000000000000000000000000000000000000000000000000000140

0000000000000000000000000000000000000000000000000000000000000001
0100000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000001
0200000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000001
0300000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000001
0400000000000000000000000000000000000000000000000000000000000000

I was trying to send a eth_call with dynamic array's encoded data but got error. after add the extra bytes. the call is success.

is there any wrong usage of me or any missunderstanding?

Crypto-Doby avatar Jun 22 '22 04:06 Crypto-Doby

@Crypto-Doby Can you fix this method and make a PR? Please also include the official test cases from Solidity's docs.

koraykoska avatar Jun 22 '22 15:06 koraykoska

@Crypto-Doby Please check #135

That's just decoding for now. But after making a few tests I will recreate the encoding API as well.

koraykoska avatar Oct 21 '22 13:10 koraykoska

This issue has not been fixed

rkingxbank avatar Nov 20 '23 08:11 rkingxbank