mhw0/libethc

abi: add functions to encode/decode non-standard types like `uint128` etc.

mhw0 opened this issue Β· 26 comments

mhw0 commented

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 ?

mhw0 commented

As soon as I have free time. It's not hard to implement.

ok bro. Thanks bro πŸ™

mhw0 commented

Hi @DerXanRam. Can you pull the dev branch and test the eth_abi_mpint? efd7ee0

Hi @DerXanRam. Can you pull the dev branch and test the eth_abi_mpint?

Ok..

I'm on it bro πŸ‘

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
}]
mhw0 commented

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);

mhw0 commented

You have to initialize r1 and r2 first (mpz_init(r1) etc).

mhw0 commented

To print mpzs, 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* ?

mhw0 commented

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
}]
mhw0 commented

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
mhw0 commented

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
mhw0 commented

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 the mpz_t. To print in hex format, do gmp_printf("%Zx\n", r1)

so how to store the data to char* or int for further processing from this data type?

mhw0 commented

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 the mpz_t. To print in hex format, do gmp_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 πŸ™

mhw0 commented

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);
mhw0 commented

Closing the issue. Added in efd7ee0