Here's an example of how to sign the transaction and get the signed transaction:
import { randomBytes } from 'crypto';
import { ecsign, keccak256 } from 'ethereumjs-util';
import { encode } from 'rlp';
// Randomly generated 32 byte private key
const privateKey = randomBytes(32);
const transaction = {
nonce: '0x1e7',
gasPrice: '0x2e90edd000',
gasLimit: '0x30d40',
to: '0xbd064928cdd4fd67fb99917c880e6560978d7ca1',
value: '0xde0b6b3a7640000',
data: '0x',
chainId: 1
};
const params = [transaction.nonce, transaction.gasPrice, transaction.gasLimit, transaction.to, transaction.value, transaction.data];
// Raw transaction as Buffer
const rawTransaction = encode(params);
const hash = keccak256(rawTransaction);
// Signature of the hash of the raw transaction
const { v, r, s } = ecsign(hash, privateKey, transaction.chainId);
// RLP encoded signed transaction as Buffer
const signedTransaction = encode([...params, v, r, s]);
console.log(signedTransaction.toString('hex'));
Note the extra chainId
property of transaction
, this is required to get the correct value for v
. If we assume our signature is the one mentioned in the example transaction, the signed transaction looks like this:
f86f8201e7852e90edd00083030d4094bd064928cdd4fd67fb99917c880e6560978d7ca1880de0b6b3a76400008025a07e833413ead52b8c538001b12ab5a85bac88db0b34b61251bb0fc81573ca093fa049634f1e439e3760265888434a2f9782928362412030db1429458ddc9dcee995
This is the full transaction that can be broadcast to the network. You can verify this through MyCrypto's broadcast tool for example.