web3p / ethereum-tx

Ethereum transaction library in PHP.
https://www.web3p.xyz/ethereumtx.html
MIT License
182 stars 60 forks source link

sending token from smart contract to wallet #47

Closed Razorholt closed 2 years ago

Razorholt commented 2 years ago

Hello! I created a simple smart contract that I deployed on the bsc testnet. Now, I would like to send XRP tokens from that smart contract to a wallet.

This doesn't work:

// PARAMETERS
$prov = 'https://speedy-nodes-nyc.moralis.io/42d9f6cacd16ccd009e8960a/bsc/testnet';
//$prov = 'https://data-seed-prebsc-1-s1.binance.org:8545/';
$web3 = new Web3(new HttpProvider(new HttpRequestManager($prov)));
$tokenAddress = "0xa83575490d7df4e2f47b7d38ef351a2722ca45b9"; // XRP token
$senderAccount = "0xF2935F3448Ce4e777D514d522Ea32342496eF694"; // Smart Contract
$senderOwner = "0x5f1c07282957E8hsfghsfgha53d2Eb86E6DEE3"; // Account 5 (Owner)
$destAccount = "0xA995b19209sdhfsgh943F332eE044B";
$senderPK = "4193617b3a8bf422965f0sfhsdghfghsfgheb0dc2300102629b75ee";
$abi = file_get_contents(__DIR__ . '/resources/ERC20AbiMarketingPool.json');
$contract = new Contract($prov, $abi);
$eth = $contract->eth;
$secondsToWaitForReceipt = 60;
$factorToMultiplyGasEstimate = 600;
$chainId = 97; // Testnet
$amount = 0.11;
$amountInWholeNumber = intval($amount) * (10 ** 18);

// XRP BALANCE
$contract->at($tokenAddress)->call('balanceOf', $senderAccount, [
    'from' => $senderAccount
], function ($err, $results) use ($contract) {
    if ($err !== null) {
        echo $err->getMessage() . "<br>";
    }
    if (isset($results)) {
        foreach ($results as &$result) {
            $bn = Utils::toBn($result);
            echo 'XRP Balance: ' . $bn->toString()/1000000000000000000 . "<br><br>";
        }
    }
});

// TRANSFER XRP TO WALLET
$rawTransactionData = '0x' . $contract->at($tokenAddress)->getData('transfer', $senderAccount, $amountInWholeNumber);
$transactionCount = null;
$eth->getTransactionCount($senderOwner, function ($err, $transactionCountResult) use(&$transactionCount) {
    if($err) { 
        echo 'getTransactionCount error: ' . $err->getMessage() . "<br>"; 
    } else {
        $transactionCount = $transactionCountResult;
    }
});
echo "\$transactionCount=$transactionCount" . "<br>";

$transactionParams = [
    'nonce' => "0x" . dechex($transactionCount->toString()),
    'from' => $senderAccount,
    'to' =>  $destAccount,
    'gasPrice' =>  hexdec(dechex(20000000000)),
    'value' => '0x0',
    'data' => $rawTransactionData
];

$estimatedGas = null;
$eth->estimateGas($transactionParams, function ($err, $gas) use (&$estimatedGas) {
    if ($err) {
        echo 'estimateGas error: ' . $err->getMessage() . "<br>"; 
    } else {
        $estimatedGas = $gas;
    }
});
echo "\$estimatedGas=$estimatedGas" . "<br>";

$gasPriceMultiplied = hexdec(dechex($estimatedGas->toString())) * $factorToMultiplyGasEstimate;
echo "\$gasPriceMultiplied=$gasPriceMultiplied" . "<br>";
$transactionParams['gas'] = '0x' . dechex($gasPriceMultiplied);
$transactionParams['chainId'] = $chainId;
$tx = new Transaction($transactionParams);
$signedTx = '0x' . $tx->sign($senderPK);

$txHash = null;
$eth->sendRawTransaction($signedTx, function ($err, $txResult) use (&$txHash) {
    if($err) { 
        echo 'transaction error: ' . $err->getMessage() . "<br>"; 
    } else {
        $txHash = $txResult;
    }
});
echo "\$txHash=$txHash" . "<br>";

The transaction goes through but it sends 0 BNB (instead of 0.11 XRPs) from the senderOwner (instead of the smart contract) to the destination wallet (that one is good).

Thanks for your help!

sc0Vu commented 2 years ago

Hi @Razorholt The to address should be the smart contract address. Hope it helps.

Razorholt commented 2 years ago

Hi @Razorholt The to address should be the smart contract address. Hope it helps.

Thanks @sc0Vu for your reply. However, when I try your solution the estimateGas function returns 'execution reverted'.

Razorholt commented 2 years ago

I searched for 3 days. Not a single example on the web or just an explanation on how to send a token from a smart contract to a wallet. So frustrating, man.

carlosalbertocruz commented 2 years ago

Apparently not even the owner of the project knows how to solve this or understands what's going on. lol

sc0Vu commented 2 years ago

I've created example repo: https://github.com/web3p/examples

Razorholt commented 2 years ago

I've created example repo: https://github.com/web3p/examples

Dude, this is FANTASTIC!!! Exactly what I needed today. Thank you so much!! Now, a few questions on the swap example (if you don't mind):

  1. On line 17, the number 1700000000 is the default gasPrice, correct?
  2. Are you using an API to get the gas price in real time or you just update your script as it varies?
  3. How do you set slippage?

Thank you again! -Dan

EDIT: Oh wait, 1700000000 must be the timestamp...