Giter Site home page Giter Site logo

mhw0 / libethc Goto Github PK

View Code? Open in Web Editor NEW
39.0 5.0 6.0 213 KB

Open-source Ethereum C library

Home Page: https://mhw0.github.io/libethc/

License: MIT License

CMake 3.42% C 89.66% C++ 6.92%
ethereum utils contracts blockchain cryptocurrency eip c abi rlp solidity

libethc's People

Contributors

mhw0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

libethc's Issues

[libsecp256k1] illegal argument: secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)

Hello brother. When i try to get my address from PK using the below code, it returns an error of [libsecp256k1] illegal argument: secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)

the coed is

#include <ethc/account.h>
#include <ethc/hex.h>
#include <ethc/keccak256.h>
#include <iostream>

using namespace std;

void test_eth_account_address_get()
{
    struct eth_account account;
    uint8_t privkey[32] = {0xdc, 0xdf, 0x91, 0xb7, 0xb2, 0x9c, 0x4c, 0x06,
                           0x77, 0x33, 0x1b, 0x65, 0x5c, 0x0c, 0x6c, 0xf4,
                           0xe7, 0x1b, 0x6f, 0x87, 0x19, 0x27, 0x3a, 0x11,
                           0x2e, 0xe6, 0x5b, 0x63, 0x9b, 0x88, 0x8f, 0xfa};
    char out[40];
    eth_account_from_privkey(&account, privkey);
    eth_account_address_get(out, &account);
    cout << out << endl;
}
int main()
{
    test_eth_account_address_get();
}

Strange buffer hex post signature

Hello there,

First off, absolutely amazing project. I am trying to compare the output of the library to something like eth_account for python and Web3. I found this strange offset f842a0 after signing a simple message. The full source code is given in the screenshot below. Notice I am using the private key as was given in the Examples section of the docs.

Screenshot_20231109_072521

The above code, seems to return the following signature:

f842a0
40911813bd523b3dbc83f5eb06d024fb43d09609068842dba37c53527fabc33e
a0
3ec391e743b820de01600842f7b23af1b19786e5778766f7e94798bfe500807a

With input keccak hash being:
85f11dc9d9ca7c444897e464dcc1bf1b936931cba10fe3b7b4e58b516a6851a8

What I find relatively interesting is that doing the exact same operation using eth_account, one yields the following signature;

0x40911813bd523b3dbc83f5eb06d024fb43d09609068842dba37c53527fabc33e
3ec391e743b820de01600842f7b23af1b19786e5778766f7e94798bfe500807a
1c

Notice how there are two intermediate hex strings within the signatures (f842a0 and a0). I am not quite sure where these are originating from.

Other Chain

Hello....me again ๐Ÿ˜…

Does this awesome library make signgniture for other chains like BSC,Polygon,Arbitrum?

Sign Contract

Hello bro. I am trying to sign this contract on Uniswapv2 router 02

function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

and i write thos code....

struct eth_abi abi;
	char *fn = "swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)", 
	*addr = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", *hex;
	char *weth="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
	char *usdt="0xdAC17F958D2ee523a2206206994597C13D831ec7";
	char *myaddress="0xa9d0a7dC416f586491f2fb596731598F937617b5";
	size_t hexlen;

	ok(eth_abi_init(&abi, ETH_ABI_ENCODE));

	ok(eth_abi_call(&abi, &fn, NULL)); 
	ok(eth_abi)
	ok(eth_abi_init(&abi, 0));
	ok(eth_abi_array(&abi, ETH_ABI_ENCODE));
	  ok(eth_abi_address(&abi,&weth));
	  ok(eth_abi_address(&abi,&usdt));
	ok(eth_abi_array_end(&abi));
	/*i try to add string "account" but i don't know how*/
	ok(eth_abi_call_end(&abi));	

	ok(eth_abi_to_hex(&abi, &hex, &hexlen));
	ok(eth_abi_free(&abi));
	printf("encoded abi: %s\n", hex);
	free(hex);

But as u can see the comment found in the code, i have hard time to pass string to the ABI. and also where should i add the contract address?

If u can, can u show me how i sign this contract correctly and to send to the RPC-API eth_sendRawTransaction?plsss

Encode array of tuples

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

Bytes decoder returns additional unexpected chars

Hello brother. i'm trying to decode string data type ABI response using this code

char *data ="0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000";

		// decoding
		struct eth_abi abi1;
		uint8_t *add;
		eth_abi_from_hex(&abi1, data, -1);
		eth_abi_bytes(&abi1, &add, NULL);
		eth_abi_free(&abi1);
		cout<<add<<endl;

and the out put is USDCPU . the supposed out put is USDC(u can check using this ABI decoder ).The function i called is

function name() external pure returns (string memory);

sometimes the decoder works fine and sometimes not. Here is when the decoder works fine

The data
0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000650415245544f0000000000000000000000000000000000000000000000000000

Decoded result PARETO
supposed result PARETO

RPC responded Insufficient funds even if i have funds

Discussed in #30

Originally posted by DerXanRam September 22, 2023
I'm trying to swap on Binance Smart Chain(which this library also works for it) using 1inch dex. But it says sometimes
"message":"insufficient funds for gas * price + value"
and some times
"message":"INTERNAL_ERROR: insufficient funds"

even if i have fund in my account to do the swap and cover the gas. all my balance is BNB and i'm swaping BNB(0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee) to BUSD(0xe9e7cea3dedca5984780bafc599bd69add087d56).

this are the values used in making the raw tnx

nonce=0x1
gasPrice is 0xd09dc300
GasLimit is 0x42c23
value is 0x2386f26fc10000
ToAddress is 0x1111111254eeb25477b68fb85ed929f73a960582

The ABI data is

0x12aa3caf000000000000000000000000f8a1527325bb62d6d0320eb2312748d590f1ce27000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d56000000000000000000000000f8a1527325bb62d6d0320eb2312748d590f1ce27000000000000000000000000b438d71c1e6e8e53637e1f1dec37c2e635e335fc000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000001cfbbfaad4cc354a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016800000000000000000000000000000000000000000000000000014a00001a4041bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095cd0e30db05120830c9e0295730bbb220bd78346c6499ff37851fbbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00a4a5dcbcdf000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000002c93437fa01c0123ed21e8b862762c887c1195130000000000000000000000001111111254eeb25477b68fb85ed929f73a960582ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008b1ccac8

and this is the raw tnx generated
f9036f0184d09dc30083042c23941111111254eeb25477b68fb85ed929f73a96058280b9030812aa3caf000000000000000000000000f8a1527325bb62d6d0320eb2312748d590f1ce27000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d56000000000000000000000000f8a1527325bb62d6d0320eb2312748d590f1ce27000000000000000000000000b438d71c1e6e8e53637e1f1dec37c2e635e335fc000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000001cfbbfaad4cc354a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016800000000000000000000000000000000000000000000000000014a00001a4041bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095cd0e30db05120830c9e0295730bbb220bd78346c6499ff37851fbbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c00a4a5dcbcdf000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000002c93437fa01c0123ed21e8b862762c887c1195130000000000000000000000001111111254eeb25477b68fb85ed929f73a960582ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008b1ccac88193a0e67028be55afd7e2d967d969b1ca6ad19cc87b9a4157701c12704675fa21d560a06767242acafe600388c1909d0b599417f85937c0c069b9c6dddbf5075d070010

any encoding error ?Please help ๐Ÿ™

rlp: add dynamic integer encoding/decoding functions

It's good to have a function that determines how many bytes it takes to encode the integer instead of manually specifying it. Can be really useful when encoding/decoding non-deterministic recovery id v in the signature.

uint64_t v = 12345;
eth_rlp_uint(&abi, &v); // 12345 occupies 2 bytes (0x3039)

#9 (comment)

cpp: add cpp wrappers

I think it would be cool if we had cpp wrappers for our C functions. Let's say we want to encode some ABI elements:

#include <ethc/ethcxx.h> // maybe just ethc.hh?

int main(void) {
  eth::ABIEncoder abi;

  abi.encodeUint16(0xffac); // or abi.decodeUint16 on decode? and it returns the decoded element?

  std::cout << abi << std::endl; // ABIEncoder supports streams?

  return 0;
}

ABI generated is not correct

Hello bro.... To day i was testing the ABI encoder using this code

char *ABIFunction()
{
	struct eth_abi abi;
	char *fn = "allPairs(uint)", *hex;
	uint64_t num = 2;
	size_t hexlen;
	uint64_t amount_out_min = 0, deadline = 346744838;
	//////////////////
	eth_abi_init(&abi, ETH_ABI_ENCODE);
	eth_abi_call(&abi, &fn, NULL);
	eth_abi_uint64(&abi,&num);
	eth_abi_call_end(&abi);

	ok(eth_abi_to_hex(&abi, &hex, &hexlen));
	ok(eth_abi_free(&abi));
	return hex;
}

The generated hex is

0xe9e0f23f0000000000000000000000000000000000000000000000000000000000000002

when i send this to eth_call RPC, the generated RPC response is

{"error":{"code":-32000,"message":"execution reverted"},"id":0,"jsonrpc":"2.0"}

But when i use https://abi.hashex.org/ to generate the ABI, the ABI hex is

0x1e3dd18b0000000000000000000000000000000000000000000000000000000000000002

and when i send it to The RPC, the same way i sent the above ABI data, The RPC response is

{"id":0,"jsonrpc":"2.0","result":"0x00000000000000000000000012ede161c702d1494612d19f05992f43aa6a26fb"}

which is success. As u can see the ABI generated by the code and by the website, The difference is found only in the first 10 digits. Can u look at it please? Thanks ๐Ÿ™

leading zero bytes

Hello bro. how u doing...... after converting my real private key to bytes and sign a real transaction there are two problems. The first one is, as u mentioned in the previous issue, u suggest me to use this website to make ABI. But when i compare the result of ABI generated by the code and by the website, they differ slightly with the same input...see below

By the website
0x7ff36ab500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000a9d0a7dc416f586491f2fb596731598f937617b50000000000000000000000000000000000000000000000000000000014aae8060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
By the code
0xfda71c7f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000a9d0a7dc416f586491f2fb596731598f937617b50000000000000000000000000000000000000000000000000000000014aae8060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7

See the first 10 digits ... they differ at that point, the rest is the same.
After this i generated raw transaction using the code below,my address(no balance), the address's real private key and the ABI generated by the website. the code is

char *SignTransaction()
{
	char *abi_result="0x7ff36ab500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000a9d0a7dc416f586491f2fb596731598f937617b50000000000000000000000000000000000000000000000000000000014aae8060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7";// = ABIFunction();

	struct eth_rlp rlp0, rlp1;
	struct eth_ecdsa_signature sign;
	  
	uint8_t privkey[] ={0x80, 0x3e, 0x53, 0x83, 0x51, 0x93, 0xdd, 0x6e, 
	                    0xad, 0x61, 0xa2, 0x5a, 0x74, 0x5f, 0xa6, 0x35, 
						0x86, 0xb4, 0xb2, 0xdd, 0x7b, 0x6a, 0xbe, 0x4a, 
						0x06, 0xfa, 0x7f, 0x33, 0xc1, 0x1a, 0xed, 0x81}; //real private key of the account 0xa9d0a7dC416f586491f2fb596731598F937617b5
	//ok(eth_hex_to_bytes(&privkey,keys,64));
	
	uint8_t nonce = 0x00, zero = 0x00, keccak[32], *rlp0bytes, *r, *s;
	char *gasprice = "0x04a817c800", *gaslimit = "0x5208", *value = "0x00";
	char *toaddr = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", *txn;
	uint16_t chainid = 0x1, v;
	size_t rlp0len, rlp1len, siglen = 32;

	ok(eth_rlp_init(&rlp0, ETH_RLP_ENCODE));
	ok(eth_rlp_array(&rlp0));
	ok(eth_rlp_uint8(&rlp0, &nonce));
	ok(eth_rlp_hex(&rlp0, &gasprice, NULL));
	ok(eth_rlp_hex(&rlp0, &gaslimit, NULL));
	ok(eth_rlp_address(&rlp0, &toaddr));
	ok(eth_rlp_hex(&rlp0, &value, NULL));
	ok(eth_rlp_hex(&rlp0, &abi_result, NULL));
	ok(eth_rlp_uint16(&rlp0, &chainid));
	ok(eth_rlp_uint8(&rlp0, &zero)); //   0x,
	ok(eth_rlp_uint8(&rlp0, &zero)); //   0x,
	ok(eth_rlp_array_end(&rlp0));	 // ]

	ok(eth_rlp_to_bytes(&rlp0bytes, &rlp0len, &rlp0));
	ok(eth_rlp_free(&rlp0));

	// compute the keccak hash of the encoded rlp elements
	ok(eth_keccak256(keccak, rlp0bytes, rlp0len));
	free(rlp0bytes);

	// sign the transaction
	ok(eth_ecdsa_sign(&sign, privkey, keccak));

	// calculate v
	v = sign.recid + chainid * 2 + 35;
	r = sign.r;
	s = sign.s;

	ok(eth_rlp_init(&rlp1, ETH_RLP_ENCODE));
	ok(eth_rlp_array(&rlp1));
	ok(eth_rlp_uint8(&rlp1, &nonce));
	ok(eth_rlp_hex(&rlp1, &gasprice, NULL));
	ok(eth_rlp_hex(&rlp1, &gaslimit, NULL));
	ok(eth_rlp_address(&rlp1, &toaddr));
	ok(eth_rlp_hex(&rlp1, &value, NULL));
	ok(eth_rlp_hex(&rlp1, &abi_result, NULL)); // replaced
	ok(eth_rlp_uint16(&rlp1, &v));
	ok(eth_rlp_bytes(&rlp1, &r, &siglen));
	ok(eth_rlp_bytes(&rlp1, &s, &siglen));
	ok(eth_rlp_array_end(&rlp1));

	// FIX3: this actually returns the output length
	ok(eth_rlp_to_hex(&txn, &rlp1) > 0);
	ok(eth_rlp_free(&rlp1));
	return txn;
}

and the RPC response is

{
    "error": "rlp: non-canonical integer (leading zero bytes) for *big.Int, decoding into (*types.Transaction)(types.LegacyTx).V"
}

which seems formatting issue. i try to look on the internet about the problem and i found this forum answer. They say this happens because S have leading zero byte. I try to work around in the libethc, But I couldn't fix it. Can u check it please?

ABI parameters decoding for arrays data types are not working properly

Hello bro. I was working arround decoding data in the transaction to parameters(see this discussion) ... the decoding process works when parameters are not array. but when they are array eth_abi_array(&abi,&arrlen); is not returning correct array size .. take a look the data, code and the output

data
0xd06ca61f00000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000055d398326f99059ff775485246999027b319795500000000000000000000000055d398326f99059ff775485246999027b3197955

code

void abiDecoder(string data)
	{
		char *input = strdup(data.c_str());
        char *fn="quote(uint256,address[])";
		mpz_t num;
		mpz_init(num);
		uint64_t arrlen;

		// decoding
		struct eth_abi abi;

		eth_abi_from_hex(&abi,input,data.length());
		eth_abi_call(&abi, &fn, NULL);
		eth_abi_mpint(&abi,num);
		eth_abi_array(&abi,&arrlen);
		char *add[arrlen];
		for(uint64_t i=0;i<arrlen;i++)
		    eth_abi_address(&abi,&add[i]);
		eth_abi_array_end(&abi);
 		eth_abi_call_end(&abi);
		ok(eth_abi_free(&abi));
        cout<<"arr len is "<<arrlen<<endl;
		//char *final = (char *)bytes;
		cout << "decoded " <<add[0] << endl;
	}

output

arr len is 0
decoded ๏ฟฝ[UUU

and if i set the array size manually, decoded result misses offset and results incorrect form. This is the output when i set the array size to 2 manually

arr len is 2
decoded 0000000055d398326f99059ff775485246999027

The problem is not only in address array, it also exists in other data types.

The data is encoded correctly and u can check it using this website and using this uniswapv2 abi contract

the function is
quote(uint256,address[])

and the value inside the data are

uint256=10000
address[]=[0x55d398326f99059ff775485246999027b3197955,0x55d398326f99059ff775485246999027b3197955]

Compile error

when i try to compile example "ERC20 balanceOf call" from the documentation it throughs this error

/usr/bin/ld: /home/biruk/Documents/eth/main.c:69: undefined reference to `eth_rlp_free'
collect2: error: ld returned 1 exit status

Build finished with error(s).

 *  The terminal process terminated with exit code: -1.  

I running ubuntu OS and all dependecies are installed correctly. I use Vscode as an IDE and the compiler(gcc) configuration "tasks.json" is :-

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: gcc build active file",
            "command": "/usr/bin/gcc",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "Task generated by Debugger."
        },
        {
            "type": "cppbuild",
            "label": "C/C++: gcc-11 build active file",
            "command": "/usr/bin/gcc-11",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build",
            "detail": "Task generated by Debugger."
        }
    ],
    "version": "2.0.0"
}

Please help

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.