Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use address parameter for ERC20 contracts #40

Open
sebnyc opened this issue Oct 22, 2018 · 6 comments
Open

Unable to use address parameter for ERC20 contracts #40

sebnyc opened this issue Oct 22, 2018 · 6 comments

Comments

@sebnyc
Copy link
Contributor

sebnyc commented Oct 22, 2018

Hi,

I'm trying to fetch account balances from ERC20 smart contracts.
To do so, I have the ERC20 standard ABI, so I should just have to call the "balanceOf" function of the contracts.
According to the ABI, the "balanceOf" function has just one input : the account address.

Here is my piece of code with a specific example where $abi_json is a json of the ERC20 ABI:

$contract_address = "0x123ab195dd38b1b40510d467a6a359b201af056f";
$account_address = "0xcc7d71df5e7b6c765448fb7ec79a602d6e3ab4f8";
$abi = new Abi(json_decode($abi_json));
$response=$eth->eth_call(new CallTransaction(new EthD20($contract_address), 
    null, null, null, null, 
    $abi->encodeFunction("balanceOf",[new EthD20($account_address)])), 
    new EthBlockParam());

It turns out that the response value is 0, but it should be positive with this particular provided addresses.

I added logs in the Ethereum::request method and I found out that the "data" field sent is :
0x70a08231cc7d71df5e7b6c765448fb7ec79a602d6e3ab4f8.
The first 8 characters 70a08231 represent the signature of the "BalanceOf" function, and the rest is the address sent as an input, on 40 characters.

But it looks like the Ethereum Node is expecting this address to be padded in a 64 characters string.
I could prove that with the geth js console on my Parity node :

> eth.call({to:"0x123ab195dd38b1b40510d467a6a359b201af056f" , data: "0x70a08231cc7d71df5e7b6c765448fb7ec79a602d6e3ab4f8"});
"0x0000000000000000000000000000000000000000000000000000000000000000"
> eth.call({to:"0x123ab195dd38b1b40510d467a6a359b201af056f" , data: "0x70a08231000000000000000000000000cc7d71df5e7b6c765448fb7ec79a602d6e3ab4f8"});
"0x00000000000000000000000000000000000000000000000000000198a3bd5246"

Am I doing something wrong while preparing the "eth_call" request ? How should I do it so that the address is padded to a 64 characters string in the data field ?

@digitaldonkey
Copy link
Owner

Thanks for submitting. I will have a look after Devcon next week. PRs are welcome too.

@byphper
Copy link

byphper commented Nov 28, 2018

I met the same question

@vsiryxm
Copy link

vsiryxm commented Jan 9, 2019

我遇到了这个问题,返回值为空

@vsiryxm
Copy link

vsiryxm commented Jan 9, 2019

Abi.php中45行在签名后面加24个0即可解决这个问题

@digitaldonkey
Copy link
Owner

Would be really helpful id you stick to English.

@asihud
Copy link

asihud commented May 2, 2019

The encodedFunction does not pad to uint256 (32 bytes) of data.
you can add str_pad on the parameters for 64 hex values (32 bytes) with leading zero.

you can update at Abi.php:

    /**
     * @param $methodName
     * @param $values array
     *
     * @return EthD
     * @throws \InvalidArgumentException
     * @throws \Exception
     */
    public function encodeFunction(string $methodName, array $values)
    {
        $m = $this->getParamDefinition($methodName);
        if (count($m->inputs) !== count($values)) {
            throw new \InvalidArgumentException('Expected ' . count($m->inputs) . ' params but got ' . count($values));
        }

        // [METHOD 4bytes] + [PARAMS]
        $params = $this->getSignature($m);
        foreach ($values as $i => $val) {
            $expectedType = $m->inputs[$i]->type;
            $validAbiType = self::convertByAbi($expectedType, $val);
            $params .= str_pad(EthereumStatic::removeHexPrefix($validAbiType->encodedHexVal()),64,'0',STR_PAD_LEFT);

        }
        return new EthD($params);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants