abi: add functions to encode/decode non-standard types like `uint128` etc.
mhw0 opened this issue Β· 26 comments
int eth_abi_mpint(struct eth_abi *abi, mpz_t *mpz)
int eth_abi_mpint(struct eth_abi *abi, mpz_t *mpz)
int eth_rlp_mpint(struct eth_rlp *rlp, mpz_t *mpz)
can u tell me when we will see this feature implmented ?
As soon as I have free time. It's not hard to implement.
ok bro. Thanks bro π
Hi @DerXanRam. Can you pull the dev branch and test the eth_abi_mpint
? efd7ee0
This the code i am testing with it
void decoder(char *data)
{
struct eth_abi abi;
MP_INT r1, r2;
uint32_t timee;
int a;
// initialize abi struct from encoded abi
eth_abi_from_hex(&abi, data, -1);
// decoding happens here
eth_abi_mpint(&abi,&r1);
eth_abi_mpint(&abi,&r2);
eth_abi_uint32(&abi, &timee);
// free the abi struct
eth_abi_free(&abi);
printf("decoded address: %d\n", r1);
printf("decoded address: %d\n", r2);
printf("decoded address: %d\n", timee);
}
and it throughs this error
[{
"resource": "/usr/include/x86_64-linux-gnu/gmp.h",
"owner": "cpptools",
"severity": 8,
"message": "conflicting declaration of C function βstd::ostream& operator<<(std::ostream&, mpq_srcptr)β",
"source": "gcc",
"startLineNumber": 2286,
"startColumn": 33,
"endLineNumber": 2286,
"endColumn": 33
},{
"resource": "/usr/include/x86_64-linux-gnu/gmp.h",
"owner": "cpptools",
"severity": 8,
"message": "conflicting declaration of C function βstd::ostream& operator<<(std::ostream&, mpf_srcptr)β",
"source": "gcc",
"startLineNumber": 2287,
"startColumn": 33,
"endLineNumber": 2287,
"endColumn": 33
},{
"resource": "/usr/include/x86_64-linux-gnu/gmp.h",
"owner": "cpptools",
"severity": 8,
"message": "conflicting declaration of C function βstd::istream& operator>>(std::istream&, mpq_ptr)β",
"source": "gcc",
"startLineNumber": 2289,
"startColumn": 33,
"endLineNumber": 2289,
"endColumn": 33
},{
"resource": "/usr/include/x86_64-linux-gnu/gmp.h",
"owner": "cpptools",
"severity": 8,
"message": "conflicting declaration of C function βstd::istream& operator>>(std::istream&, mpf_ptr)β",
"source": "gcc",
"startLineNumber": 2290,
"startColumn": 33,
"endLineNumber": 2290,
"endColumn": 33
}]
Okay, could you open ethc/abi.h
and put #include <gmp.h>
before #ifdef __cplusplus
and test?
ok wait...
The previous erros are gone now. But it runs and throws this error
realloc(): invalid pointer
in file abi.c at this line 663
mpz_import(mpz, 32, 1, sizeof(uint8_t), 0, 0, bytes);
You have to initialize r1
and r2
first (mpz_init(r1)
etc).
To print mpz
s, do: gmp_printf("%Zd\n", r1);
this is the code
void decoder(char *data)
{
struct eth_abi abi;
MP_INT r1, r2;
mpz_init(r1);
mpz_init(r2);
uint32_t timee;
int a;
// initialize abi struct from encoded abi
eth_abi_from_hex(&abi, data, -1);
// decoding happens here
eth_abi_mpint(&abi,&r1);
eth_abi_mpint(&abi,&r2);
eth_abi_uint32(&abi, &timee);
// free the abi struct
eth_abi_free(&abi);
printf("decoded address: %d\n", r1);
printf("decoded address: %d\n", r2);
printf("decoded address: %d\n", timee);
}
and it throws this error
[{
"resource": "/home/biruk/Documents/eth/arb+tbot/uniswap.h",
"owner": "C/C++: IntelliSense",
"code": "413",
"severity": 8,
"message": "no suitable conversion function from \"MP_INT\" to \"mpz_ptr\" exists",
"source": "C/C++",
"startLineNumber": 219,
"startColumn": 12,
"endLineNumber": 219,
"endColumn": 14
}]
gmp_printf("%Zd\n", r1);
and is this the only way to print it...what about passing to char* ?
Try replacing MP_INT
with mpz_t
and is this the only way to print it...what about passing to char* ?
gmp_printf
is compatible with printf
, so, just works: gmp_printf("%Zd %s\n", r1, "test");
and now this functions parameters are not compatible with mpz_t
eth_abi_mpint(&abi,&r1);
eth_abi_mpint(&abi,&r2);
the error is
[{
"resource": "/home/biruk/Documents/eth/arb+tbot/uniswap.h",
"owner": "C/C++: IntelliSense",
"code": "167",
"severity": 8,
"message": "argument of type \"mpz_t *\" is incompatible with parameter of type \"__mpz_struct *\"",
"source": "C/C++",
"startLineNumber": 226,
"startColumn": 22,
"endLineNumber": 226,
"endColumn": 22
},{
"resource": "/home/biruk/Documents/eth/arb+tbot/uniswap.h",
"owner": "cpptools",
"severity": 8,
"message": "cannot convert β__mpz_struct (*)[1]β to β__mpz_struct*β",
"source": "gcc",
"startLineNumber": 226,
"startColumn": 36,
"endLineNumber": 226,
"endColumn": 36
},{
"resource": "/home/biruk/Documents/eth/arb+tbot/uniswap.h",
"owner": "C/C++: IntelliSense",
"code": "167",
"severity": 8,
"message": "argument of type \"mpz_t *\" is incompatible with parameter of type \"__mpz_struct *\"",
"source": "C/C++",
"startLineNumber": 227,
"startColumn": 22,
"endLineNumber": 227,
"endColumn": 22
},{
"resource": "/home/biruk/Documents/eth/arb+tbot/uniswap.h",
"owner": "cpptools",
"severity": 8,
"message": "cannot convert β__mpz_struct (*)[1]β to β__mpz_struct*β",
"source": "gcc",
"startLineNumber": 227,
"startColumn": 36,
"endLineNumber": 227,
"endColumn": 36
}]
No, mpz_t
is a pointer itself. Just do: eth_abi_mpint(&abi, r1);
it throws runtim error
/usr/bin/ld: /tmp/ccBXKWZ4.o: undefined reference to symbol '__gmpz_init'
/usr/bin/ld: /lib/x86_64-linux-gnu/libgmp.so.10: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Try adding -lgmp
to args
in tasks.json
it runned succsussfuly and using printf
it gives false decode result and using gmp_printf
correct result.
using printf
decoded address: -10256
decoded address: -10240
decoded address: 1690645691
using gmp_printf
6729450845017214267
6777196
decoded address: 1690645691
Yes, becuase printf
doesn't know about the mpz_t
. To print in hex format, do gmp_printf("%Zx\n", r1)
also i have a question. Can we encode uint256 data types using this new raw data type.... because if i want to send this data back to the RPC function i need a container that holds all of the digits.
Yes, becuase
printf
doesn't know about thempz_t
. To print in hex format, dogmp_printf("%Zx\n", r1)
so how to store the data to char* or int for further processing from this data type?
also i have a question. Can we encode uint256 data types using this new raw data type.... because if i want to send this data back to the RPC function i need a container that holds all of the digits.
Easy:
struct eth_abi abi;
mpz_t mpz;
// 0xfff or 123 or load from uint64 etc..
mpz_init_set_str(mpz, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0);
eth_abi_init(&abi, ETH_ABI_ENCODE);
eth_abi_mpint(&abi, mpz);
// ...
Here's the gmp manual:
https://gmplib.org/manual/
also i have a question. Can we encode uint256 data types using this new raw data type.... because if i want to send this data back to the RPC function i need a container that holds all of the digits.
Easy:
struct eth_abi abi; mpz_t mpz; // 0xfff or 123 or load from uint64 etc.. mpz_init_set_str(mpz, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0); eth_abi_init(&abi, ETH_ABI_ENCODE); eth_abi_mpint(&abi, mpz); // ...Here's the gmp manual: https://gmplib.org/manual/
ok thanks bro π
Yes, becuase
printf
doesn't know about thempz_t
. To print in hex format, dogmp_printf("%Zx\n", r1)
so how to store the data to char* from this data type?
i was trying.... i try to access the struct members and see it. but i lost...... i think i need some hand pls π
i was trying.... i try to access the struct members and see it. but i lost...... i think i need some hand pls π
Do you want to export mpz_t
to char*
? It should be like this:
char *str;
gmp_asprintf(&str, "%Zd", r1);
printf("str: %s\n", str);
free(str);