Closed dkamm closed 7 months ago
Is there a way to encode an array of tuples? Would like to do the following in ethc but didn't seem like it was supported
from eth_abi.abi import encode print(encode(("(uint64,uint64)[]",),([(1,2),(3,4)],)).hex())
Hello brother. If you are asking encoding of ABI that contains array, You can do like this
for Instance, when u decode a data for uniswap's getAmountsOut
method, u can code like this
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ethc/abi.h>
#include <ethc/unit.h>
#include <ethc/hex.h>
#include <string.h>
using namespace std;
#define ok(ethcop) assert(ethcop >= 0)
int main()
{
string function = "getAmountsOut(uint256,address[])"; // method name
string pathA = "0x55d398326f99059ff775485246999027b3197955", pathB = "0xe9e7cea3dedca5984780bafc599bd69add087d56";
uint64_t amt = 10000000000;
char *path0, *path1, *fn, *hex;
path0 = strdup(pathA.c_str());
path1 = strdup(pathB.c_str());
fn = strdup(function.c_str());
struct eth_abi abi;
uint64_t arraySize = 2;
size_t hexlen;
eth_abi_init(&abi, ETH_ABI_ENCODE);
eth_abi_call(&abi, &fn, NULL);
eth_abi_uint64(&abi, &amt);
eth_abi_array(&abi, &arraySize); // array begin
eth_abi_address(&abi, &path0);
eth_abi_address(&abi, &path1);
eth_abi_array_end(&abi); // array end
eth_abi_call_end(&abi);
ok(eth_abi_to_hex(&abi, &hex, &hexlen));
ok(eth_abi_free(&abi));
cout << "0x" << hex << endl;
}
for more, u can refer the Documentation or the test folder
Hello @dkamm I think tuples are encoded & decoded as arrays. If the signature is (uint64,uint64)[]
and you want to encode [(1,2),(3,4)]
, this should be valid:
eth_abi_array(&ab, &size);
eth_abi_array(&abi, &size);
// encode 1 and 2
eth_abi_array_end(&abi);
eth_abi_array(&abi, &size);
// encode 3 and 4
eth_abi_array_end(&abi);
eth_abi_array_end(&abi);
Please, let me know if this works. Thanks.
@mhw0 @DerXanRam thanks for the quick response! I actually tried that and a got different result than my python script
Python result
000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
Using nested array
#include <stdio.h>
#include <stdlib.h>
#include <ethc/abi.h>
#include <ethc/hex.h>
int main(void) {
struct eth_abi abi;
uint64_t a = 1, b = 2, c = 3, d = 4;
eth_abi_init(&abi, ETH_ABI_ENCODE);
eth_abi_array(&abi, NULL);
eth_abi_array(&abi, NULL);
eth_abi_uint64(&abi, &a);
eth_abi_uint64(&abi, &b);
eth_abi_array_end(&abi);
eth_abi_array(&abi, NULL);
eth_abi_uint64(&abi, &c);
eth_abi_uint64(&abi, &d);
eth_abi_array_end(&abi);
eth_abi_array_end(&abi);
char *hex;
size_t hexlen;
eth_abi_to_hex(&abi, &hex, &hexlen);
printf("%s\n", hex);
eth_abi_free(&abi);
free(hex);
return 0;
}
Result
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
Also tried this
#include <stdio.h>
#include <stdlib.h>
#include <ethc/abi.h>
#include <ethc/hex.h>
int main(void) {
struct eth_abi abi;
char* fn = "(uint64,uint64)";
uint64_t a = 1, b = 2, c = 3, d = 4;
eth_abi_init(&abi, ETH_ABI_ENCODE);
eth_abi_array(&abi, NULL);
eth_abi_call(&abi, &fn, NULL);
eth_abi_uint64(&abi, &a);
eth_abi_uint64(&abi, &b);
eth_abi_call_end(&abi);
eth_abi_call(&abi, &fn, NULL);
eth_abi_uint64(&abi, &c);
eth_abi_uint64(&abi, &d);
eth_abi_call_end(&abi);
eth_abi_array_end(&abi);
char *hex;
size_t hexlen;
eth_abi_to_hex(&abi, &hex, &hexlen);
printf("%s\n", hex);
eth_abi_free(&abi);
free(hex);
return 0;
}
Result
000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000040a111f3f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020a111f3f00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
@mhw0 @DerXanRam thanks for the quick response! I actually tried that and a got different result than my python script
Python result
000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
Using nested array
#include <stdio.h> #include <stdlib.h> #include <ethc/abi.h> #include <ethc/hex.h> int main(void) { struct eth_abi abi; uint64_t a = 1, b = 2, c = 3, d = 4; eth_abi_init(&abi, ETH_ABI_ENCODE); eth_abi_array(&abi, NULL); eth_abi_array(&abi, NULL); eth_abi_uint64(&abi, &a); eth_abi_uint64(&abi, &b); eth_abi_array_end(&abi); eth_abi_array(&abi, NULL); eth_abi_uint64(&abi, &c); eth_abi_uint64(&abi, &d); eth_abi_array_end(&abi); eth_abi_array_end(&abi); char *hex; size_t hexlen; eth_abi_to_hex(&abi, &hex, &hexlen); printf("%s\n", hex); eth_abi_free(&abi); free(hex); return 0; }
Result
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
Also tried this
#include <stdio.h> #include <stdlib.h> #include <ethc/abi.h> #include <ethc/hex.h> int main(void) { struct eth_abi abi; char* fn = "(uint64,uint64)"; uint64_t a = 1, b = 2, c = 3, d = 4; eth_abi_init(&abi, ETH_ABI_ENCODE); eth_abi_array(&abi, NULL); eth_abi_call(&abi, &fn, NULL); eth_abi_uint64(&abi, &a); eth_abi_uint64(&abi, &b); eth_abi_call_end(&abi); eth_abi_call(&abi, &fn, NULL); eth_abi_uint64(&abi, &c); eth_abi_uint64(&abi, &d); eth_abi_call_end(&abi); eth_abi_array_end(&abi); char *hex; size_t hexlen; eth_abi_to_hex(&abi, &hex, &hexlen); printf("%s\n", hex); eth_abi_free(&abi); free(hex); return 0; }
Result
000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000040a111f3f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020a111f3f00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004
Do u tried @mhw0 solution ? I think that's the correct solution .
@DerXanRam Yes, the first code block is his solution, although I didn't set the len
field because it's ignored during encoding.
Okay, I think the library can't encode tuples. I'll open an issue. Thanks!
Is there a way to encode an array of tuples? Would like to do the following in ethc but didn't seem like it was supported