Some ways we can utilize raw transactions include signing a transaction offline on a secure machine and then broadcasting it separately or to send a transaction at a later point of time.
1. Setting up a Node.js project
In a new folder, initiate a new Node.js project with the command npm init -y to accept all default project parameters.
A package.json file will be created for you, which contains all your packages and project information.
2. Integrating Ethers.js
We'll need to integrate a helpful JavaScript library known as Ethers.js that will help with interacting with the Ethereum blockchain.
We can do so using the command npm i ethers from a terminal within this project, which will add ethers as a dependency.
We'll then create a new file named transaction.js where we'll write the rest of the code in JavaScript and import ethers at the top of the file.
constethers=require('ethers');asyncfunctionmain() {// rest of code goes here}main();
3. Creating a wallet
One of the useful classes that Ethers.js provides is a Wallet, which represents a regular Ethereum address that you can use to store and send Ether.
We can initiate a new Wallet by specifying a private key which we can generate or grab one from an existing wallet like MetaMask.****
constethers=require('ethers');asyncfunctionmain() {// defining the wallet private keylet privatekey ='CE75F1A875F2DB7FB064F5DBD302B0C77FFEAA18CC4C314167A5111A04F79AFA';let wallet =newethers.Wallet(privatekey);// print the wallet addressconsole.log('Using wallet address '+wallet.address);}main();
4. Crafting the transaction
A transactions is made up of several parameters that have to be defined, for this example we'll be making a simple ETH transfer.
The sample code to send 1 Ether to address 0xEeee7341f206302f2216e39D715B96D8C6901A1C on the Ropsteh testnet will be as follows.
After detailing the contents of the transaction, we'll need to sign it — using the wallet's private key we created in Step 3 to prove we are allowed to spend funds in the wallet address.
With the transaction signed, we have just one more step to serialize, or simply converting our transaction into a hexadecimal format.
constethers=require('ethers');asyncfunctionmain() {let privatekey ='CE75F1A875F2DB7FB064F5DBD302B0C77FFEAA18CC4C314167A5111A04F79AFA';let wallet =newethers.Wallet(privatekey);console.log('Using wallet address '+wallet.address);let transaction = { to:'0xa238b6008Bc2FBd9E386A5d4784511980cE504Cd', value:ethers.utils.parseEther('1'), gasLimit:'21000', maxPriorityFeePerGas:ethers.utils.parseUnits('5','gwei'), maxFeePerGas:ethers.utils.parseUnits('20','gwei'), nonce:1, type:2, chainId:3 };// sign and serialize the transaction let rawTransaction =awaitwallet.signTransaction(transaction).then(ethers.utils.serializeTransaction(transaction));// print the raw transaction hashconsole.log('Raw txhash string '+ rawTransaction);}main();
6. Send via API
With the signed raw transaction, we can now pass it to the "eth_sendRawTransaction" endpoint to be broadcasted to the Ethereum network.
A successfully broadcasted transaction will return a transaction hash, which you can use the "eth_getTransactionbyHash" endpoint or look it up on Optimism Etherscan!
You can run this code using the command node transaction.js
constethers=require('ethers');constfetch=require('node-fetch');asyncfunctionmain() {let privatekey ='CE75F1A875F2DB7FB064F5DBD302B0C77FFEAA18CC4C314167A5111A04F79AFA';let wallet =newethers.Wallet(privatekey);console.log('Using wallet address '+wallet.address);let transaction = { to:'0xa238b6008Bc2FBd9E386A5d4784511980cE504Cd', value:ethers.utils.parseEther('1'), gasLimit:'21000', maxPriorityFeePerGas:ethers.utils.parseUnits('5','gwei'), maxFeePerGas:ethers.utils.parseUnits('20','gwei'), nonce:1, type:2, chainId:3 };let rawTransaction =awaitwallet.signTransaction(transaction).then(ethers.utils.serializeTransaction(transaction));console.log('Raw txhash string '+ rawTransaction);// pass the raw transaction hash to the "eth_sendRawTransaction" endpoint let gethProxy = await fetch(`https://api-ropsten.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=${rawTransaction}&apikey=YourApiKeyToken`);
let response =awaitgethProxy.json(); // print the API responseconsole.log(response);}main();