Comment on page
Signing Raw Transactions
The closest real world example of a raw transaction — probably a bank cheque
💸
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.
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.
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.const ethers = require('ethers');
async function main() {
// rest of code goes here
}
main();
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.const ethers = require('ethers');
async function main() {
// defining the wallet private key
let privatekey = 'CE75F1A875F2DB7FB064F5DBD302B0C77FFEAA18CC4C314167A5111A04F79AFA';
let wallet = new ethers.Wallet(privatekey);
// print the wallet address
console.log('Using wallet address ' + wallet.address);
}
main();
A transactions is made up of several parameters that have to be defined, for this example we'll be making a simple ETH transfer.
If you are following this article on a testnet, feel free to get some testnet Ether
to fund your address.

Parameter | Description |
---|---|
to | the address to send Ether to |
value | the amount of Ether to send |
gasLimit | |
maxPriorityFeePerGas | |
maxFeePerGas | |
nonce | |
type | set to 0x2 , to denote EIP-1559 type transactions |
chainId |
The sample code to send
1 Ether
to address 0xEeee7341f206302f2216e39D715B96D8C6901A1C
on the Arbiscan testnet will be as follows.const ethers = require('ethers');
async function main() {
let privatekey = 'CE75F1A875F2DB7FB064F5DBD302B0C77FFEAA18CC4C314167A5111A04F79AFA';
let wallet = new ethers.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: 421613
};
}
main();
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.
const ethers = require('ethers');
async function main() {
let privatekey = 'CE75F1A875F2DB7FB064F5DBD302B0C77FFEAA18CC4C314167A5111A04F79AFA';
let wallet = new ethers.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: 421613
};
// sign and serialize the transaction
let rawTransaction = await wallet.signTransaction(transaction).then(ethers.utils.serializeTransaction(transaction));
// print the raw transaction hash
console.log('Raw txhash string ' + rawTransaction);
}
main();
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 Arbiscan!
You can run this code using the command
node transaction.js
const ethers = require('ethers');
async function main() {
let privatekey = 'CE75F1A875F2DB7FB064F5DBD302B0C77FFEAA18CC4C314167A5111A04F79AFA';
let wallet = new ethers.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: 421613
};
let rawTransaction = await wallet.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-goerli.arbiscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=${rawTransaction}&apikey=YourApiKeyToken`);
let response = await gethProxy.json();
// print the API response
console.log(response);
}
main();
The full sample code for this tutorial is on Github, feel free to fork and extend the functionality of it !
🤖
Last modified 1yr ago