Transfer funds between accounts in a transaction
You can get started with the Developer Quickstart to rapidly generate local blockchain networks.
This tutorial shows you how to transfer funds (ETH) between accounts in a transaction.
Prerequisites
Use eth_sendSignedTransaction
The simplest way to transfer funds between externally-owned accounts is using eth_sendSignedTransaction
. This example uses eth_sendSignedTransaction
and one of the test accounts to transfer funds to a newly created account.
The private key is publicly displayed, which means the account is not secure.
Before making the transaction, check the balances of both accounts to verify the funds transfer after the transaction.
const web3 = new Web3(host);
// Pre-seeded account with 90000 ETH
const privateKeyA =
"0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3";
const accountA = web3.eth.accounts.privateKeyToAccount(privateKeyA);
var accountABalance = web3.utils.fromWei(
await web3.eth.getBalance(accountA.address),
);
console.log("Account A has balance of: " + accountABalance);
// Create a new account to transfer ETH to
var accountB = web3.eth.accounts.create();
var accountBBalance = web3.utils.fromWei(
await web3.eth.getBalance(accountB.address),
);
console.log("Account B has balance of: " + accountBBalance);
Use the test account address (Account A) for the from
parameter, the recipient account address (Account B) for the to
parameter, and the amount of ETH to transfer between accounts for the value
parameter. Sign the transaction with Account A's private key and send it using eth_sendSignedTransaction
.
// Send some ETH from A to B
const rawTxOptions = {
nonce: web3.utils.numberToHex(
await web3.eth.getTransactionCount(accountA.address),
),
from: accountA.address,
to: accountB.address,
value: "0x100", // Amount of ETH to transfer
gasPrice: "0x0", // ETH per unit of gas
gasLimit: "0x24A22", // Max number of gas units the tx is allowed to use
};
console.log("Creating transaction...");
const tx = new Tx(rawTxOptions);
console.log("Signing transaction...");
tx.sign(Buffer.from(accountA.privateKey.substring(2), "hex"));
console.log("Sending transaction...");
var serializedTx = tx.serialize();
const pTx = await web3.eth.sendSignedTransaction(
"0x" + serializedTx.toString("hex").toString("hex"),
);
console.log("tx transactionHash: " + pTx.transactionHash);
Once it completes, you can see the updated balances.
// After the transaction, there should be some ETH transferred
var accountABalance = await getAccountBalance(host, accountA);
console.log("Account A has an updated balance of: " + accountABalance);
var accountBBalance = await getAccountBalance(host, accountB);
console.log("Account B has an updatedbalance of: " + accountBBalance);
}
A full example can be found in the Developer Quickstart.
Use eth_sendTransaction
An alternative to using eth_sendSignedTransaction
is eth_sendTransaction
. However, Hyperledger Besu does not support the eth_sendTransaction
API call and keeps account management separate for stronger security. Instead, Besu uses EthSigner to make the eth_sendTransaction
API call.
An example can be found in the Developer Quickstart where the RPC node is paired with EthSigner. Refer to the EthSigner documentation configuration details.
Use eth_sendTransaction
similarly to using eth_sendSignedTransaction
(without the signing step which is done by EthSigner):
const web3 = new Web3(host);
// Pre-seeded account with 90000 ETH
const privateKeyA = "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3";
const accountA = web3.eth.accounts.privateKeyToAccount(privateKeyA);
var accountABalance = web3.utils.fromWei(await web3.eth.getBalance(accountA.address));
console.log("Account A has balance of: " + accountABalance);
// Create a new account to transfer ETH to
var accountB = web3.eth.accounts.create();
var accountBBalance = web3.utils.fromWei(await web3.eth.getBalance(accountB.address));
console.log("Account B has balance of: " + accountBBalance);
// Send some ETH from A to B
const txOptions = {
from: accountA.address,
to: accountB.address,
value: "0x100", // Amount of ETH to transfer
gasPrice: "0x0", // ETH per unit of gas
gasLimit: "0x24A22" // Max number of gas units the tx is allowed to use
};
console.log("Creating transaction...");
const pTx = await web3.eth.sendTransaction(txOptions);
console.log("tx transactionHash: " + pTx.transactionHash);
// After the transaction, there should be some ETH transferred
var accountABalance = await getAccountBalance(host, accountA);
console.log("Account A has an updated balance of: " + accountABalance);
var accountBBalance = await getAccountBalance(host, accountB);
console.log("Account B has an updatedbalance of: " + accountBBalance);
}