Reputation: 250
I am using ethereumjs-tx (^2.1.2) to sign the transaction using this code:
const Tx = require('ethereumjs-tx').Transaction
const argv = require('minimist')(process.argv.slice(2));
const privateKey = Buffer.from('mykey');
var rawTx = {
chainId: 0x89,
nonce: argv.nonce,
gasPrice: '0x174876E800',
gasLimit: '0x186A0',
to: '0x666CBED29287F0dee02a1A925F432f07CFbFECD5',
value: '0x0',
data: argv.data
}
const tx = new Tx(rawTx)
tx.sign(privateKey)
const serializedTx = tx.serialize()
console.log(serializedTx.toString('hex'))
The transaction is calling Transfer function of a token's smart contract (here as "to" parameter) on Polygon and the result is a signed transaction that I send to Infura using the PHP code below:
//gettxcount() works properly
$nonce = "0x" . dechex(hexdec(json_decode(gettxcount())->result) + 1);
echo "nonce: " . $nonce . "\n";
//Transfer function ABI, plus the parameters sent
$txdata = "0xa9059cbb000000000000000000000000".
substr($address, 2).
str_pad(base_convert(number_format($amount * 10**18, 0, "", ""), 10, 16), 64, '0', STR_PAD_LEFT);
echo "txdata: " . $txdata . "\n";
$RLP = "0x" . exec("node signer/signTransaction.js --nonce=$nonce --data=$txdata");
echo "RLP: " . $RLP . "\n";
$curld = curl_init();
curl_setopt_array($curld, [
CURLOPT_URL => "https://polygon-mainnet.infura.io/v3/$API_KEY",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'id' => 1,
'jsonrpc' => '2.0',
'method' => 'eth_sendRawTransaction',
'params' => [
$RLP
]
]),
CURLOPT_HTTPHEADER => [
"accept: application/json",
"content-type: application/json"
],
]);
$output = curl_exec($curld);
curl_close($curld);
return $output;
and the result I get is always: {"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"invalid sender"}}
P.S: I am sure that the privatekey is right
Update: after changing the JS code to the following using a JS sample code from Infura I faced the error countryBlocked
, probably due to me connecting to the server from Iran, (It's really disappointing to see the entities claiming to be advocating for cryptocurrencies and it's core value which is financial freedom openly censor transactions and act in favor of entities advocating economical sanctions)
The correct and working JS code to sign the transaction:
const { Web3 } = require("web3");
const argv = require('minimist')(process.argv.slice(2));
async function main() {
// Configuring the connection to the Polygon node
const web3 = new Web3(
new Web3.providers.HttpProvider(
`https://polygon-mainnet.core.chainstack.com/APIKEY`, //Fill in the API KEY
),
);
// Creating a signing account from a private key
const privateKey = Buffer.from('PRIVATE_KEY', 'hex'); //Fill in the PRIVATE KEY
const signer = web3.eth.accounts.privateKeyToAccount(
privateKey,
);
web3.eth.accounts.wallet.add(signer);
// Creating the transaction object
const tx = {
gasPrice: '0x174876E800', //Manually set gasPrice
from: signer.address,
to: "SMART CONTRACT", //Fill in the smart contract address
value: "0x0",
data: argv.data,
};
// Assigning the right amount of gas
tx.gas = await web3.eth.estimateGas(tx);
console.log(tx.gas);
// Sending the transaction to the network
const receipt = await web3.eth
.sendTransaction(tx)
.once("transactionHash", (txhash) => {
console.log(`Mining transaction ...`);
console.log(`Transaction hash: ${txhash}`);
});
// The transaction is now on chain!
console.log(`Mined in block ${receipt.blockNumber}`);
}
main();
Notes: the sample code from Infura didn't include gasPrice in it's tx object and this lead to a replacement transaction underpriced
error, I added a hardcoded gasPrice and now it's working.
Upvotes: 1
Views: 112