The eth_getTransactionCount
method returns the number of transactions sent from a specified address, which is also known as the "nonce". This value is crucial for creating new transactions, as each transaction from an account must use a nonce value exactly one higher than the previous transaction.
This method returns the current nonce value for an address, which represents the number of transactions sent from that address.
The address to check for transaction count
Block number in hex format or block tag
The number of transactions sent from the address (hexadecimal)
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x4b9" // 1209 in decimal
}
The blockNumber
parameter accepts several special values:
latest
: Current state after all pending transactions are executedpending
: Current state plus pending transactions in the mempoolearliest
: Genesis block statesafe
: Latest block considered safe by networkfinalized
: Latest block that has achieved finalityUsing pending
is especially important for nonce management when sending multiple transactions in sequence.
// Example: Create and sign multiple transactions in sequence
async function sendTransactionBatch(privateKey, toAddress, values) {
const wallet = new ethers.Wallet(privateKey, provider);
const fromAddress = wallet.address;
// Get the current nonce
const nonce = await provider.send('eth_getTransactionCount', [fromAddress, 'pending']);
const currentNonce = parseInt(nonce, 16);
console.log(`Starting nonce: ${currentNonce}`);
// Create and send multiple transactions
const txPromises = values.map((value, index) => {
const txNonce = currentNonce + index;
console.log(`Preparing transaction with nonce ${txNonce}`);
const tx = {
from: fromAddress,
to: toAddress,
value: ethers.utils.parseEther(value.toString()),
nonce: txNonce,
gasLimit: 21000,
gasPrice: ethers.utils.parseUnits('50', 'gwei'),
};
return wallet.sendTransaction(tx);
});
return Promise.all(txPromises);
}
// Usage
const recipientAddress = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
const valueArray = [0.01, 0.02, 0.03]; // ETH values to send
sendTransactionBatch(privateKey, recipientAddress, valueArray)
.then((results) => console.log(`Sent ${results.length} transactions`))
.catch((error) => console.error('Transaction failed:', error));
// Example: Analyzing and fixing nonce gaps
async function analyzeNonceGaps(address) {
// Get confirmed nonce
const confirmedNonceHex = await provider.send('eth_getTransactionCount', [address, 'latest']);
// Get pending nonce (including transactions in mempool)
const pendingNonceHex = await provider.send('eth_getTransactionCount', [address, 'pending']);
const confirmedNonce = parseInt(confirmedNonceHex, 16);
const pendingNonce = parseInt(pendingNonceHex, 16);
console.log(`Address: ${address}`);
console.log(`Confirmed nonce: ${confirmedNonce}`);
console.log(`Pending nonce: ${pendingNonce}`);
if (pendingNonce > confirmedNonce) {
console.log(`There are ${pendingNonce - confirmedNonce} pending transactions`);
// Get pending transactions to analyze
// Note: This would normally require a specialized RPC method or service
// as standard Ethereum nodes don't provide a way to list pending transactions for an address
}
return {
address,
confirmedNonce,
pendingNonce,
pendingCount: pendingNonce - confirmedNonce,
};
}
// Example: Resolving stuck transactions by replacing with higher gas price
async function replaceStuckTransaction(wallet, originalNonce, newGasPrice) {
// Create a "replacement" transaction with same nonce but higher gas price
const tx = {
from: wallet.address,
to: wallet.address, // Send to self
value: 0, // Zero value (just paying gas)
nonce: originalNonce,
gasLimit: 21000,
gasPrice: newGasPrice, // Must be at least 10% higher than original
};
// Sign and send the replacement transaction
return wallet.sendTransaction(tx);
}
// Example: Analyze account activity over time
async function analyzeAccountActivity(address, startBlock, endBlock, interval = 1000) {
const result = [];
// Process in chunks to avoid overwhelming the node
for (let blockNum = startBlock; blockNum <= endBlock; blockNum += interval) {
const blockHex = `0x${blockNum.toString(16)}`;
const count = await provider.send('eth_getTransactionCount', [address, blockHex]);
result.push({
blockNumber: blockNum,
nonce: parseInt(count, 16),
});
}
// Calculate activity in each interval
for (let i = 1; i < result.length; i++) {
const txCount = result[i].nonce - result[i - 1].nonce;
result[i].newTransactions = txCount;
const blockSpan = result[i].blockNumber - result[i - 1].blockNumber;
result[i].txPerBlock = txCount / blockSpan;
}
return result;
}
pending
tag is crucial when creating multiple transactions in sequence