Try it Live Run Transaction examples in the interactive playground
Conceptual Guide - For API reference and method documentation, see Transaction API .
Ethereum transactions are cryptographically signed messages that initiate state transitions on the Ethereum blockchain. This guide teaches transaction fundamentals using Tevm.
What Are Transactions?
Transactions are the only way to modify Ethereum state. Every state change (ETH transfer, contract deployment, function call) requires a transaction.
Key properties:
Atomic - Either fully executes or fully reverts
Cryptographically signed - Proves sender authorization via ECDSA signature
Immutable - Once mined, cannot be altered
Ordered - Executed sequentially per account (nonce ordering)
Transaction Types
Ethereum supports 5 transaction types, each adding new capabilities:
Legacy (Type 0)
Original transaction format from Ethereum genesis (2015).
import * as Transaction from 'tevm/Transaction' ;
import * as Address from 'tevm/Address' ;
const legacy : Transaction . Legacy = {
type: Transaction . Type . Legacy ,
nonce: 0 n ,
gasPrice: 20_000_000_000 n , // 20 gwei fixed price
gasLimit: 21_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n , // 1 ETH
data: new Uint8Array (),
v: 27 n , // Signature v (pre-EIP-155: 27 or 28)
r: Bytes32 (), // Signature r component
s: Bytes32 (), // Signature s component
};
// Serialize to bytes for broadcasting
const serialized = Transaction . serialize ( legacy );
// Compute transaction hash
const txHash = Transaction . hash ( legacy );
Characteristics:
Fixed gasPrice - No automatic fee market
v encodes chain ID (EIP-155) - Prevents replay attacks across chains
Simple structure - 9 fields total
Still widely supported
EIP-2930 (Type 1)
Access list transactions introduced in Berlin hard fork (2021).
import * as Transaction from 'tevm/Transaction' ;
import * as Address from 'tevm/Address' ;
const eip2930 : Transaction . EIP2930 = {
type: Transaction . Type . EIP2930 ,
chainId: 1 n , // Explicit chain ID
nonce: 0 n ,
gasPrice: 20_000_000_000 n ,
gasLimit: 30_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 0 n ,
data: new Uint8Array (),
accessList: [
{
address: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
storageKeys: [
Bytes32 (), // Storage slot to access
],
},
],
yParity: 0 , // Signature parity (0 or 1, replaces v)
r: Bytes32 (),
s: Bytes32 (),
};
const serialized = Transaction . serialize ( eip2930 );
Access Lists:
Pre-declare which addresses and storage slots will be accessed. Reduces gas costs for declared access (2100 gas → 100 gas for warm access).
Why use EIP-2930?
Gas savings on repeated storage access
Explicit contract interaction declaration
Foundation for later transaction types
EIP-1559 (Type 2)
Dynamic fee market transactions from London hard fork (2021).
import * as Transaction from 'tevm/Transaction' ;
import * as Address from 'tevm/Address' ;
const eip1559 : Transaction . EIP1559 = {
type: Transaction . Type . EIP1559 ,
chainId: 1 n ,
nonce: 0 n ,
maxPriorityFeePerGas: 2_000_000_000 n , // 2 gwei tip to miner
maxFeePerGas: 30_000_000_000 n , // 30 gwei max willing to pay
gasLimit: 21_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n ,
data: new Uint8Array (),
accessList: [],
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
};
// Calculate effective gas price given current base fee
const baseFee = 20_000_000_000 n ; // 20 gwei from block
const effectiveGasPrice = Transaction . EIP1559 . getEffectiveGasPrice (
eip1559 ,
baseFee
);
console . log ( effectiveGasPrice );
// 22_000_000_000n (base 20 + priority 2)
const serialized = Transaction . serialize ( eip1559 );
Fee Mechanics:
effectiveGasPrice = min(
baseFee + maxPriorityFeePerGas,
maxFeePerGas
)
totalCost = gasLimit * effectiveGasPrice + value
refund = (maxFeePerGas - effectiveGasPrice) * gasUsed
Base Fee:
Set by protocol, adjusts block-to-block based on block fullness
Burns to Ethereum (deflationary mechanism)
Target: 50% block utilization
Priority Fee:
Tip to miner/validator
Incentivizes transaction inclusion
Goes to block proposer
Benefits:
Predictable fees - Base fee visible before transaction
No overpayment - Refund if actual < max
ETH burn - Reduces supply
EIP-4844 (Type 3)
Blob transactions for L2 data availability from Dencun hard fork (2024).
import * as Transaction from 'tevm/Transaction' ;
import * as Address from 'tevm/Address' ;
import * as Hash from 'tevm/Hash' ;
const eip4844 : Transaction . EIP4844 = {
type: Transaction . Type . EIP4844 ,
chainId: 1 n ,
nonce: 0 n ,
maxPriorityFeePerGas: 1_000_000_000 n ,
maxFeePerGas: 20_000_000_000 n ,
gasLimit: 100_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ), // Must be contract
value: 0 n ,
data: new Uint8Array (),
accessList: [],
maxFeePerBlobGas: 1_000_000_000 n , // Max willing to pay per blob gas
blobVersionedHashes: [
Hash ( '0x01...' ), // KZG commitment hash for blob 1
Hash ( '0x01...' ), // KZG commitment hash for blob 2
],
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
};
// Calculate blob gas cost
const blobBaseFee = 1 n ; // From block header
const blobGasCost = Transaction . EIP4844 . getBlobGasCost ( eip4844 , blobBaseFee );
console . log ( blobGasCost );
// blobCount * blobBaseFee * 131_072
const serialized = Transaction . serialize ( eip4844 );
Blob Details:
Size : 128 KB per blob (131,072 bytes)
Maximum : 6 blobs per transaction
Pricing : Separate from execution gas, adapts to blob demand
Availability : Data pruned after ~18 days (not permanent storage)
Use case : L2 rollups post batch data cheaply
Total Cost:
executionCost = gasLimit * effectiveGasPrice
blobCost = blobCount * blobBaseFee * 131_072
totalCost = executionCost + blobCost + value
Why blob transactions?
10-100x cheaper than CALLDATA for L2s
Scales Ethereum data availability
Does not compete with execution gas market
EIP-7702 (Type 4)
EOA delegation transactions from Pectra hard fork (2024).
import * as Transaction from 'tevm/Transaction' ;
import * as Address from 'tevm/Address' ;
import * as Authorization from 'tevm/Authorization' ;
const eip7702 : Transaction . EIP7702 = {
type: Transaction . Type . EIP7702 ,
chainId: 1 n ,
nonce: 0 n ,
maxPriorityFeePerGas: 1_000_000_000 n ,
maxFeePerGas: 20_000_000_000 n ,
gasLimit: 100_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 0 n ,
data: new Uint8Array (),
accessList: [],
authorizationList: [
{
chainId: 1 n ,
address: Address ( '0x...' ), // Contract to delegate to
nonce: 0 n , // EOA nonce at time of signing
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
},
],
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
};
const serialized = Transaction . serialize ( eip7702 );
Authorization List:
Each authorization temporarily delegates an EOA’s code to a contract:
EOA signs authorization to execute contract logic
Transaction sender can trigger delegated logic
EOA retains control (can revoke by incrementing nonce)
Enables account abstraction without migrating funds
Use cases:
Batched transactions from EOA
Sponsored transactions (gasless for user)
Social recovery
Multi-sig from EOA
Transaction Lifecycle
┌────────────────────────────────────────────────────────────┐
│ 1. CONSTRUCTION │
│ Create transaction object with all required fields │
├────────────────────────────────────────────────────────────┤
│ 2. SIGNING HASH │
│ Compute keccak256 hash of transaction fields │
│ (excludes signature fields: v/r/s or yParity/r/s) │
├────────────────────────────────────────────────────────────┤
│ 3. SIGNING │
│ Sign hash with private key using secp256k1 ECDSA │
│ Produces r, s, v (or yParity) signature components │
├────────────────────────────────────────────────────────────┤
│ 4. SERIALIZATION │
│ RLP encode transaction + signature → bytes │
│ For typed txs (1-4): [type_byte] + RLP(fields) │
├────────────────────────────────────────────────────────────┤
│ 5. BROADCASTING │
│ Send serialized bytes via eth_sendRawTransaction │
│ Transaction enters mempool │
├────────────────────────────────────────────────────────────┤
│ 6. MINING/VALIDATION │
│ Block proposer includes transaction in block │
│ EVM executes transaction, updates state │
├────────────────────────────────────────────────────────────┤
│ 7. CONFIRMATION │
│ Block finalized, transaction immutable │
│ Can verify sender via signature recovery │
└────────────────────────────────────────────────────────────┘
Complete Example: Send ETH
import * as Transaction from 'tevm/Transaction' ;
import * as Address from 'tevm/Address' ;
import * as Secp256k1 from 'tevm/Secp256k1' ;
// 1. CONSTRUCT - Create unsigned transaction
const tx : Transaction . EIP1559 = {
type: Transaction . Type . EIP1559 ,
chainId: 1 n ,
nonce: 5 n , // Sender's transaction count
maxPriorityFeePerGas: 2_000_000_000 n , // 2 gwei
maxFeePerGas: 30_000_000_000 n , // 30 gwei
gasLimit: 21_000 n , // Standard ETH transfer
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n , // 1 ETH
data: new Uint8Array (),
accessList: [],
yParity: 0 , // Placeholder, will be overwritten
r: Bytes32 (), // Placeholder
s: Bytes32 (), // Placeholder
};
// 2. SIGNING HASH - Compute what gets signed
const signingHash = Transaction . getSigningHash ( tx );
console . log ( signingHash );
// Uint8Array(32) - keccak256 hash
// 3. SIGNING - Sign with private key
const privateKey = Bytes32 (); // Your private key
const signature = Secp256k1 . sign ( signingHash , privateKey );
// Update transaction with signature
const signedTx : Transaction . EIP1559 = {
... tx ,
yParity: signature . recovery ,
r: signature . r ,
s: signature . s ,
};
// 4. SERIALIZATION - Encode to bytes
const serialized = Transaction . serialize ( signedTx );
console . log ( serialized );
// Uint8Array - Ready for broadcasting
// 5. BROADCASTING - Send via JSON-RPC (example)
// await provider.send('eth_sendRawTransaction', [toHex(serialized)])
// 7. VERIFICATION - Recover sender from signature
const sender = Transaction . getSender ( signedTx );
console . log ( sender );
// AddressType - Matches signing key's address
Signing Hash Computation
The signing hash is what gets signed by the sender’s private key. It proves the transaction came from that sender.
import * as Transaction from 'tevm/Transaction' ;
import * as Rlp from 'tevm/Rlp' ;
import * as Keccak256 from 'tevm/Keccak256' ;
const tx : Transaction . EIP1559 = {
type: Transaction . Type . EIP1559 ,
chainId: 1 n ,
nonce: 0 n ,
maxPriorityFeePerGas: 2_000_000_000 n ,
maxFeePerGas: 30_000_000_000 n ,
gasLimit: 21_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n ,
data: new Uint8Array (),
accessList: [],
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
};
// What gets signed (excludes signature fields)
const payload = Rlp . encode ([
tx . chainId ,
tx . nonce ,
tx . maxPriorityFeePerGas ,
tx . maxFeePerGas ,
tx . gasLimit ,
tx . to ?? new Uint8Array (),
tx . value ,
tx . data ,
tx . accessList ,
]);
// For typed transactions, prepend type byte
const signingData = new Uint8Array ([ 0x02 , ... payload ]);
// Hash to produce signing hash
const signingHash = Keccak256 . hash ( signingData );
// Equivalent to
const signingHashDirect = Transaction . getSigningHash ( tx );
import * as Transaction from 'tevm/Transaction' ;
import * as Rlp from 'tevm/Rlp' ;
import * as Keccak256 from 'tevm/Keccak256' ;
const tx : Transaction . Legacy = {
type: Transaction . Type . Legacy ,
nonce: 0 n ,
gasPrice: 20_000_000_000 n ,
gasLimit: 21_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n ,
data: new Uint8Array (),
v: 27 n ,
r: Bytes32 (),
s: Bytes32 (),
};
// Extract chain ID from v (EIP-155)
const chainId = ( tx . v - 35 n ) / 2 n ; // If v >= 35
// Signing payload includes chain ID for replay protection
const payload = Rlp . encode ([
tx . nonce ,
tx . gasPrice ,
tx . gasLimit ,
tx . to ?? new Uint8Array (),
tx . value ,
tx . data ,
chainId ,
0 ,
0 ,
]);
const signingHash = Keccak256 . hash ( payload );
// Equivalent to
const signingHashDirect = Transaction . getSigningHash ( tx );
The signing hash does not include the signature fields. This prevents circular dependencies - you need the hash to compute the signature.
Gas Mechanics
Gas is the unit of computational work on Ethereum. Every operation (opcode) costs gas.
Gas Limit
Maximum gas you’re willing to consume for the transaction.
// Simple ETH transfer
gasLimit : 21_000 n // Intrinsic gas for transaction
// Contract interaction (estimate required)
gasLimit : 100_000 n // More complex operations
// Too low: Transaction reverts, you still pay gas
// Too high: Unused gas refunded, but max fee reserved upfront
Gas Price (Legacy)
const legacy : Transaction . Legacy = {
gasPrice: 20_000_000_000 n , // 20 gwei per gas
gasLimit: 21_000 n ,
// ...
};
// Total cost reserved upfront
const maxCost = legacy . gasPrice * legacy . gasLimit ;
// 420_000_000_000_000n (0.00042 ETH)
// If transaction uses all gas
const actualCost = legacy . gasPrice * 21_000 n ;
// 420_000_000_000_000n
// No refund mechanism for overestimation
Max Fee Per Gas (EIP-1559)
const eip1559 : Transaction . EIP1559 = {
maxPriorityFeePerGas: 2_000_000_000 n , // 2 gwei tip
maxFeePerGas: 30_000_000_000 n , // 30 gwei max
gasLimit: 21_000 n ,
// ...
};
// Current block's base fee
const baseFee = 20_000_000_000 n ; // 20 gwei
// Effective gas price
const effectiveGasPrice = Math . min (
baseFee + eip1559 . maxPriorityFeePerGas , // 22 gwei
eip1559 . maxFeePerGas // 30 gwei
);
// 22_000_000_000n
// Max cost reserved upfront
const maxCost = eip1559 . maxFeePerGas * eip1559 . gasLimit ;
// 630_000_000_000_000n (0.00063 ETH)
// Actual cost if transaction uses 21,000 gas
const actualCost = effectiveGasPrice * 21_000 n ;
// 462_000_000_000_000n (0.000462 ETH)
// Refund
const refund = maxCost - actualCost ;
// 168_000_000_000_000n (0.000168 ETH)
Base Fee Adjustment
Base fee adjusts block-to-block based on congestion:
Target gas per block: 15M gas
Max gas per block: 30M gas
If block uses > 15M gas:
nextBaseFee = baseFee * 1.125 (12.5% increase)
If block uses < 15M gas:
nextBaseFee = baseFee * 0.875 (12.5% decrease)
This creates automatic fee market adjustment without user intervention.
Blob Gas (EIP-4844)
Separate gas market for blob data:
const eip4844 : Transaction . EIP4844 = {
maxFeePerGas: 30_000_000_000 n , // Execution gas
maxFeePerBlobGas: 1_000_000_000 n , // Blob gas
gasLimit: 100_000 n ,
blobVersionedHashes: [ hash1 , hash2 ], // 2 blobs
// ...
};
// Blob gas per blob: 131,072 (fixed)
const blobGasPerBlob = 131_072 ;
// Current blob base fee
const blobBaseFee = 1 n ;
// Blob cost
const blobCost = 2 * blobGasPerBlob * blobBaseFee ;
// 262_144n
// Execution cost (same as EIP-1559)
const executionCost = effectiveGasPrice * gasUsed ;
// Total transaction cost
const totalCost = executionCost + blobCost + value ;
Blob base fee adjusts independently from execution base fee based on blob usage:
Target: 3 blobs per block
Max: 6 blobs per block
Same 12.5% adjustment algorithm
Transaction Validation
Transactions must satisfy multiple validation rules:
import * as Transaction from 'tevm/Transaction' ;
const tx : Transaction . EIP1559 = {
type: Transaction . Type . EIP1559 ,
chainId: 1 n ,
nonce: 0 n ,
maxPriorityFeePerGas: 2_000_000_000 n ,
maxFeePerGas: 30_000_000_000 n ,
gasLimit: 21_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n ,
data: new Uint8Array (),
accessList: [],
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
};
// Import typed errors
import { TransactionError , InvalidSignatureError } from 'tevm/errors' ;
// 1. Check transaction is signed
const isSigned = Transaction . isSigned ( tx );
if ( ! isSigned ) {
throw new TransactionError ( 'Transaction not signed' , {
code: 'TRANSACTION_NOT_SIGNED'
});
}
// 2. Verify signature is valid
const isValid = Transaction . verifySignature ( tx );
if ( ! isValid ) {
throw new InvalidSignatureError ( 'Invalid signature' , {
context: { tx }
});
}
// 3. Recover sender address
const sender = Transaction . getSender ( tx );
console . log ( sender );
// AddressType
// 4. Validate field constraints
// - maxPriorityFeePerGas <= maxFeePerGas
// - gasLimit >= intrinsic gas (21,000 for basic transfer)
// - nonce matches sender's current nonce
// - sender has sufficient balance for maxCost
Intrinsic Gas
Minimum gas required before execution:
// Base transaction cost
const baseCost = 21_000 n ;
// Data cost (per byte)
const zeroByteCost = 4 n ;
const nonZeroByteCost = 16 n ;
// Access list cost
const accessListAddressCost = 2_400 n ;
const accessListStorageKeyCost = 1_900 n ;
// Example calculation
function intrinsicGas ( tx : Transaction . EIP1559 ) : bigint {
let gas = baseCost ;
// Data cost
for ( const byte of tx . data ) {
gas += byte === 0 ? zeroByteCost : nonZeroByteCost ;
}
// Access list cost
for ( const entry of tx . accessList ) {
gas += accessListAddressCost ;
gas += BigInt ( entry . storageKeys . length ) * accessListStorageKeyCost ;
}
return gas ;
}
Detecting Transaction Type
import * as Transaction from 'tevm/Transaction' ;
// From serialized bytes
const serialized = new Uint8Array ([ 0x02 , /* ... */ ]);
// Detect type from first byte
const type = Transaction . detectType ( serialized );
console . log ( type );
// 2 (EIP-1559)
// Deserialize to typed transaction
const tx = Transaction . deserialize ( serialized );
// Check type with type guard
if ( tx . type === Transaction . Type . EIP1559 ) {
// TypeScript knows this is EIP1559 transaction
console . log ( tx . maxPriorityFeePerGas );
}
Type Detection Rules
If first byte < 0xc0:
- Type byte determines transaction type
- 0x00 = Legacy
- 0x01 = EIP-2930
- 0x02 = EIP-1559
- 0x03 = EIP-4844
- 0x04 = EIP-7702
If first byte >= 0xc0:
- Legacy transaction (RLP list marker)
- No type byte prefix
Working With Signatures
Sign Transaction
import * as Transaction from 'tevm/Transaction' ;
import * as Secp256k1 from 'tevm/Secp256k1' ;
// Unsigned transaction
const unsigned : Transaction . EIP1559 = {
type: Transaction . Type . EIP1559 ,
chainId: 1 n ,
nonce: 0 n ,
maxPriorityFeePerGas: 2_000_000_000 n ,
maxFeePerGas: 30_000_000_000 n ,
gasLimit: 21_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n ,
data: new Uint8Array (),
accessList: [],
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
};
// Get signing hash
const hash = Transaction . getSigningHash ( unsigned );
// Sign with private key
const privateKey = Bytes32 (); // Your private key
const signature = Secp256k1 . sign ( hash , privateKey );
// Create signed transaction
const signed : Transaction . EIP1559 = {
... unsigned ,
yParity: signature . recovery ,
r: signature . r ,
s: signature . s ,
};
Verify Signature
import * as Transaction from 'tevm/Transaction' ;
// Verify signature is valid
const isValid = Transaction . verifySignature ( signed );
console . log ( isValid ); // true
// Recover sender address
const sender = Transaction . getSender ( signed );
console . log ( sender );
// AddressType matching private key
Assert Signed
import * as Transaction from 'tevm/Transaction' ;
import { TransactionError } from 'tevm/errors' ;
// Check if transaction is signed
if ( ! Transaction . isSigned ( tx )) {
throw new TransactionError ( 'Transaction not signed' , {
code: 'TRANSACTION_NOT_SIGNED'
});
}
// Or use assertion (throws if not signed)
Transaction . assertSigned ( tx );
// Now safe to call getSender
const sender = Transaction . getSender ( tx );
Comparing Transaction Types
Use Cases
Gas Costs
Limitations
Type Best For Legacy Compatibility with old tools, simple transfers EIP-2930 Gas savings on known storage access patterns EIP-1559 Modern applications, predictable fees EIP-4844 L2 rollup data posting, batch submissions EIP-7702 Account abstraction, sponsored transactions
Type Gas Price Additional Costs Legacy Fixed gasPrice None EIP-2930 Fixed gasPrice Access list (2400 + 1900n per storage key) EIP-1559 maxFee + priorityFeeAccess list (optional) EIP-4844 maxFee + priorityFeeBlob gas (131,072 per blob) EIP-7702 maxFee + priorityFeeAuthorization signatures
Type Limitations Legacy No access lists, fixed gas pricing EIP-2930 Still uses fixed gas price EIP-1559 None (standard) EIP-4844 Cannot deploy contracts (to must be address) EIP-7702 EOA delegation complexity
RLP Serialization
Transactions use Recursive Length Prefix (RLP) encoding:
import * as Transaction from 'tevm/Transaction' ;
import * as Hex from 'tevm/Hex' ;
const tx : Transaction . EIP1559 = {
type: Transaction . Type . EIP1559 ,
chainId: 1 n ,
nonce: 0 n ,
maxPriorityFeePerGas: 2_000_000_000 n ,
maxFeePerGas: 30_000_000_000 n ,
gasLimit: 21_000 n ,
to: Address ( '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2' ),
value: 1_000_000_000_000_000_000 n ,
data: new Uint8Array (),
accessList: [],
yParity: 0 ,
r: Bytes32 (),
s: Bytes32 (),
};
// Serialize to bytes
const serialized = Transaction . serialize ( tx );
console . log ( Hex ( serialized ));
// "0x02f8..."
// Deserialize back to transaction
const deserialized = Transaction . deserialize ( serialized );
console . log ( deserialized . type === tx . type ); // true
Typed Transactions
Legacy
Serialized = [type_byte] + RLP(transaction_fields)
Example (EIP-1559):
0x02 + RLP([
chainId,
nonce,
maxPriorityFeePerGas,
maxFeePerGas,
gasLimit,
to,
value,
data,
accessList,
yParity,
r,
s
])
Serialized = RLP([
nonce,
gasPrice,
gasLimit,
to,
value,
data,
v,
r,
s
])
No type byte prefix
Resources
Next Steps