web3p / web3.php

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

token transfer between wallets #305

Open amonit opened 1 year ago

amonit commented 1 year ago

I am trying to send a token from one address to another.

It generates a transaction hash, however, the same transaction is not visible in blockchain explorer.

<?php

use Web3\Web3;
use Web3\Providers\HttpProvider;
use Web3\RequestManagers\HttpRequestManager;
use Web3\Utils;
use Web3\Contract;
use Web3p\EthereumTx\Transaction;

function gwei_to_wei($amount)
{
    return bcmul($amount, '1000000000');
}

function wei_to_eth($amount)
{
    return bcdiv(strval($amount), '1000000000000000000', 18);
}

function getNonce($eth, $account) {
    $nonce = 0;
    $eth->getTransactionCount($account, function ($err, $count) use (&$nonce) {
        if ($err !== null) {
            throw $err;
        }
        $nonce = $count;
    });
    return $nonce;
}

function decimal_notation($float)
{
    $parts = explode('E', $float);
    if (count($parts) === 2) {
        $exp = abs(end($parts)) + strlen($parts[0]);
        $decimal = number_format($float, $exp);
        return rtrim($decimal, '.0');
    } else {
        return $float;
    }
}

function bc_number_format($number, $precision)
{
    return bcdiv(decimal_notation($number), 1, $precision);
}

$_CONFIG = require '../inc/config.php';
require '../lib/autoload.php';

$payment_wallet = address;

$web3 = new Web3(new HttpProvider(new HttpRequestManager("https://mainnet-rpc.gaurascan.com", 5)));

$eth = $web3->eth;

$eth->getBalance($payment_wallet, function ($err, $balance) use (&$wallet_balance) {
        if ($err !== null) {
            echo 'Error: ' . $err->getMessage();
            return;
        }
        $wallet_balance = floatval(wei_to_eth($balance));
    });

echo "Wallet Balance: ";
echo $wallet_balance;
echo '<br>';
echo bc_number_format(floatval($wallet_balance), 10);

$abi = '[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"string","name":"symbol","internalType":"string"},{"type":"uint256","name":"totalSupply","internalType":"uint256"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"_owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burn","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]';
$contract = new Contract($web3->provider, $abi);

$acc = address;

$contract = $contract->at("0xE4821faf6E65Bf091119E33dF694033F4C6d173D");

$contract->call('balanceOf', $acc, function ($err, $result) {
    if ($err !== null) {
        throw $err;
    }
    if ($result) {
        echo '<br>Token balance Hex: ' . $result[0]->toHex() . PHP_EOL;
        echo '<br>Token balance Raw: ' . $result[0] . PHP_EOL;
        echo '<br>Token balance : ' . floatval(wei_to_eth($result[0])) . PHP_EOL;
    }
});

$sourceAddress = address;
$sourceAddressKey = private_key;
$gas_wei = gwei_to_wei(2);
$gas_limit = 21000;

$destinationAddress = destination_address;
$amountInWholeNumber = 100;
$contractAddress = "0x32b8376f42af40C58Cfbb7B69908EC66EcE07d7D";

// method 2
$contract = $contract->at($contractAddress);
$estimatedGas = '0x200b20';

$contract->at($contractAddress)->estimateGas('transfer', $destinationAddress, 10, [
    'from' => $sourceAddress,
], function ($err, $result) use (&$estimatedGas) {
    if ($err !== null) {
        throw $err;
    }
    $estimatedGas = '0x' . $result->toHex();
});
echo '<br>Estimated Gas:' . $estimatedGas . '<br>';

$nonce = getNonce($eth, $sourceAddress);

$data = $contract->getData('transfer', $destinationAddress, 10);
$nonce = $nonce->add(Utils::toBn(2));
$transaction = new Transaction([
    'nonce' => '0x' . $nonce->toHex(),
    'from' => $sourceAddress,
    'to' => $contractAddress,
    'gas' => $estimatedGas,
    'gasPrice' => '0x' . Utils::toWei('2', 'gwei')->toHex(),
    'data' => '0x' . $data,
    'chainId' => strval(61115)
]);
$transaction->sign($sourceAddressKey);
$txHash = '';
$eth->sendRawTransaction('0x' . $transaction->serialize(), function ($err, $transaction) use ($eth, $destinationAddress, $sourceAddress, &$txHash) {
    if ($err !== null) {
        echo 'Error: ' . $err->getMessage();
        return;
    }
    echo 'Tx hash: ' . $transaction . PHP_EOL;
    $txHash = $transaction;
});

?>

The code returns a transaction hash, however, the token never move between addresses

Schiocco commented 1 year ago

Can you send the transaction hash?