mhw0 / libethc

Open-source Ethereum C library
https://mhw0.github.io/libethc/
MIT License
46 stars 8 forks source link

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

Closed mhw0 closed 11 months ago

mhw0 commented 11 months ago

int eth_abi_mpint(struct eth_abi *abi, mpz_t *mpz)

DerXanRam commented 11 months ago

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 11 months ago

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

DerXanRam commented 11 months ago

ok bro. Thanks bro :pray:

mhw0 commented 11 months ago

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

DerXanRam commented 11 months ago

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

Ok..

I'm on it bro πŸ‘

DerXanRam commented 11 months ago

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 11 months ago

Okay, could you open ethc/abi.h and put #include <gmp.h> before #ifdef __cplusplus and test?

DerXanRam commented 11 months ago

ok wait...

DerXanRam commented 11 months ago

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 11 months ago

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

mhw0 commented 11 months ago

To print mpzs, do: gmp_printf("%Zd\n", r1);

DerXanRam commented 11 months ago

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 11 months ago

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

DerXanRam commented 11 months ago

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 11 months ago

No, mpz_t is a pointer itself. Just do: eth_abi_mpint(&abi, r1);

DerXanRam commented 11 months ago

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 11 months ago

Try adding -lgmp to args in tasks.json

DerXanRam commented 11 months ago

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 11 months ago

Yes, becuase printf doesn't know about the mpz_t. To print in hex format, do gmp_printf("%Zx\n", r1)

DerXanRam commented 11 months ago

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.

DerXanRam commented 11 months ago

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 11 months ago

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/

DerXanRam commented 11 months ago

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 :pray:

DerXanRam commented 11 months ago

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 :pray:

mhw0 commented 11 months ago

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 11 months ago

Closing the issue. Added in efd7ee074d40e57f6e7ef9a5b0e5fb1abf0cb638