web3p / web3.php

A php interface for interacting with the Ethereum blockchain and ecosystem. Native ABI parsing and smart contract interactions.
MIT License
1.15k stars 540 forks source link

Failed to call smart contract method. #320

Open polym2 opened 1 year ago

polym2 commented 1 year ago

My goal is to create NFT tokens through a smart contract method call. It is not possible to call the smart contract method, instead a "duplicate" of the smart contract itself is created. In addition, for some reason, when creating a copy of the contract, there is also an error: Warning! Error encountered during contract execution [gas uint64 overflow]

Through the metamask, the NFT is created.

Here is my code, what am I missing?

$provider = new HttpProvider(new HttpRequestManager($this->params->get('BNB_SERVER'), 15));

        $web3 = new Web3($provider);
        $contract = new Contract($provider, $this->getAbi());

        // make DATA mintNFT function (?)
        $data = $contract->at($this->params->get('SMART_CONTRACT_ADDRESS'))->getData('mintNFT', $this->params->get('BNB_WALLET'), $tokenUrl);

        // get estimateGas
        $contract->at($this->params->get('SMART_CONTRACT_ADDRESS'))->estimateGas('mintNFT',
            $this->params->get('BNB_WALLET'), $tokenUrl, ['from' => $this->params->get('BNB_WALLET'), 'data' => $data], function ($err, $gas) use (&$gasLimit) {
                if ($err !== null) {
                    echo $err->getMessage();
                    return false;
                } else {
                    $gasLimit = $gas;
                }
            });

        $eth = new Eth($provider);

        // get transactionCount
        $eth->getTransactionCount($this->params->get('BNB_WALLET'), function ($err, $data) {
            $this->countTransactions = gmp_intval($data->value);
            return $this->countTransactions;
        });

        /** @var \phpseclib\Math\BigInteger $gasLimit */
        $transaction = new Transaction([
            'from' => $this->params->get('BNB_WALLET'),
            'to' => $this->params->get('SMART_CONTRACT_ADDRESS'),
            'gas' => sprintf('0x%s', $web3->getUtils()::toHex((int)$gasLimit->value)),
            'gasPrice' => sprintf('0x%s', $web3->getUtils()::toHex(15000000000)),
            'gasLimit' => '0x'.$web3->getUtils()::toHex((int)$gasLimit->value * 2),
            'chainId' => 0x61,
            'nonce' => '0x'.$web3->getUtils()::toHex($this->countTransactions),
            'data' => $data,
        ]);

        $signedTx = $transaction->sign($this->params->get('BNB_PRIVATE_KEY'));

        $eth->batch(true);

        $eth->sendRawTransaction(sprintf('0x%s', $signedTx));

        $eth->getProvider()->execute(function ($err, $data) use ($web3): string {
            if ($err !== null) {
                // do something
            }
            if (isset($data[0])) {
                $this->hexTransaction = '0x' . $web3->getUtils()::toHex($data[0]);
                return $this->hexTransaction;
            }
            return 0;
        });

Here's what happens when I try to create an NFT through a metamask, and here's what happens when I call the code above.

image

image

I'm willing to pay for help if needed.

polym2 commented 1 year ago

The difference was in the "data" parameter. Encoded string from metamask: 0xeacabe140000000000000000000000009e2cdab6be1fdd6e526ac4d037b61e606cf8753e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000047465737400000000000000000000000000000000000000000000000000000000

Substituted this line instead $data = $contract->at($this->params->get('SMART_CONTRACT_ADDRESS'))->getData('mintNFT', $this->params->get('BNB_WALLET'), $tokenUrl);

And the program worked as it should. The NFT is created and transferred to the wallet.

What is wrong with the line: $data = $contract->at($this->params->get('SMART_CONTRACT_ADDRESS'))->getData('mintNFT', $this->params->get('BNB_WALLET'), $tokenUrl); ?

This line produces the following encoded string: 0xeacabe140000000000000000000000009e2cdab6be1fdd6e526ac4d037b61e606cf8753e0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003b68747470733a2f2f6e6674616d612e696f2f39343165363866353335623737373663373834653736373134626430353165332f6e66742f6d6574610000000000

Highlight areas that differ.

Help.