Try it Live
Run RLP examples in the interactive playground
Return Type
decodeArray returns a JavaScript array with decoded elements:
Copy
Ask AI
import { Rlp } from 'tevm'
const encoded = Rlp.encodeArray([
new Uint8Array([1, 2, 3]),
new Uint8Array([4, 5, 6])
])
const arr = Rlp.decodeArray(encoded)
// arr is an array: [Uint8Array([1,2,3]), Uint8Array([4,5,6])]
// Can destructure
const [first, second] = arr
console.log(first) // Uint8Array([1, 2, 3])
console.log(second) // Uint8Array([4, 5, 6])
// Can iterate
for (const item of arr) {
console.log('Item:', item)
}
Usage Patterns
Transaction Decoding
Decode transaction fields:Copy
Ask AI
import { Rlp } from 'tevm'
interface LegacyTx {
nonce: bigint
gasPrice: bigint
gasLimit: bigint
to: Uint8Array
value: bigint
data: Uint8Array
v: bigint
r: Uint8Array
s: Uint8Array
}
function decodeLegacyTx(bytes: Uint8Array): LegacyTx {
const arr = Rlp.decodeArray(bytes)
return {
nonce: bytesToBigint(arr[0]),
gasPrice: bytesToBigint(arr[1]),
gasLimit: bytesToBigint(arr[2]),
to: arr[3],
value: bytesToBigint(arr[4]),
data: arr[5],
v: bytesToBigint(arr[6]),
r: arr[7],
s: arr[8]
}
}
const txBytes = new Uint8Array([...])
const tx = decodeLegacyTx(txBytes)
console.log('Nonce:', tx.nonce)
console.log('To:', tx.to)
Block Header Decoding
Decode block header:Copy
Ask AI
import { Rlp } from 'tevm'
interface BlockHeader {
parentHash: Uint8Array
uncleHash: Uint8Array
coinbase: Uint8Array
stateRoot: Uint8Array
transactionsRoot: Uint8Array
receiptsRoot: Uint8Array
logsBloom: Uint8Array
difficulty: bigint
number: bigint
gasLimit: bigint
gasUsed: bigint
timestamp: bigint
extraData: Uint8Array
}
function decodeBlockHeader(bytes: Uint8Array): BlockHeader {
const [
parentHash,
uncleHash,
coinbase,
stateRoot,
transactionsRoot,
receiptsRoot,
logsBloom,
difficulty,
number,
gasLimit,
gasUsed,
timestamp,
extraData
] = Rlp.decodeArray(bytes)
return {
parentHash,
uncleHash,
coinbase,
stateRoot,
transactionsRoot,
receiptsRoot,
logsBloom,
difficulty: bytesToBigint(difficulty),
number: bytesToBigint(number),
gasLimit: bytesToBigint(gasLimit),
gasUsed: bytesToBigint(gasUsed),
timestamp: bytesToBigint(timestamp),
extraData
}
}
Log Entry Decoding
Decode event logs:Copy
Ask AI
import { Rlp } from 'tevm'
interface Log {
address: Uint8Array
topics: Uint8Array[]
data: Uint8Array
}
function decodeLog(bytes: Uint8Array): Log {
const [address, topics, data] = Rlp.decodeArray(bytes)
return {
address,
topics, // Already an array
data
}
}
const logBytes = new Uint8Array([...])
const log = decodeLog(logBytes)
console.log('Address:', log.address)
console.log('Topics:', log.topics)
Account State Decoding
Decode account state:Copy
Ask AI
import { Rlp } from 'tevm'
interface AccountState {
nonce: bigint
balance: bigint
storageRoot: Uint8Array
codeHash: Uint8Array
}
function decodeAccountState(bytes: Uint8Array): AccountState {
const [nonce, balance, storageRoot, codeHash] = Rlp.decodeArray(bytes)
return {
nonce: bytesToBigint(nonce),
balance: bytesToBigint(balance),
storageRoot,
codeHash
}
}
const accountBytes = new Uint8Array([...])
const account = decodeAccountState(accountBytes)
console.log('Balance:', account.balance)
Merkle Patricia Trie Node
Decode trie nodes:Copy
Ask AI
import { Rlp } from 'tevm'
type TrieNode =
| { type: 'branch'; children: Uint8Array[]; value: Uint8Array }
| { type: 'extension'; path: Uint8Array; child: Uint8Array }
| { type: 'leaf'; path: Uint8Array; value: Uint8Array }
function decodeTrieNode(bytes: Uint8Array): TrieNode {
const arr = Rlp.decodeArray(bytes)
if (arr.length === 17) {
// Branch node: 16 children + value
return {
type: 'branch',
children: arr.slice(0, 16),
value: arr[16]
}
}
if (arr.length === 2) {
// Extension or leaf
const path = arr[0]
const hasTerminator = (path[0] & 0x20) !== 0
if (hasTerminator) {
return {
type: 'leaf',
path,
value: arr[1]
}
} else {
return {
type: 'extension',
path,
child: arr[1]
}
}
}
throw new Error('Invalid trie node')
}
Validation
decodeArray validates RLP encoding:
Copy
Ask AI
import { Rlp } from 'tevm'
// Valid encoding
const valid = new Uint8Array([0xc4, 0x01, 0x02, 0x03])
const arr = Rlp.decodeArray(valid)
// => [Uint8Array([1]), Uint8Array([2]), Uint8Array([3])]
// Invalid encoding throws
const invalid = new Uint8Array([0xc4, 0x01]) // Incomplete
try {
Rlp.decodeArray(invalid)
} catch (error) {
console.error('Invalid RLP:', error)
}
// Not a list throws
const notList = new Uint8Array([0x83, 1, 2, 3]) // Bytes, not list
try {
Rlp.decodeArray(notList)
} catch (error) {
console.error('Expected list:', error)
}
Schema-based Decoding
Define typed decoders:Copy
Ask AI
import { Rlp } from 'tevm'
// Define schema
type Schema<T> = {
encode: (value: T) => Uint8Array
decode: (bytes: Uint8Array) => T
}
// Create schema
function createArraySchema<T>(
itemSchema: Schema<T>
): Schema<T[]> {
return {
encode: (items) => {
const encoded = items.map(item => itemSchema.encode(item))
return Rlp.encodeArray(encoded)
},
decode: (bytes) => {
const arr = Rlp.decodeArray(bytes)
return arr.map(item => itemSchema.decode(item))
}
}
}
// Use schema
const uint256Schema: Schema<bigint> = {
encode: (n) => bigintToBytes(n),
decode: (b) => bytesToBigint(b)
}
const uint256ArraySchema = createArraySchema(uint256Schema)
// Encode
const numbers = [1n, 2n, 3n]
const encoded = uint256ArraySchema.encode(numbers)
// Decode
const decoded = uint256ArraySchema.decode(encoded)
// => [1n, 2n, 3n]
Performance
Direct Array Access
decodeArray returns a plain JavaScript array for efficient access:
Copy
Ask AI
import { Rlp } from 'tevm'
const encoded = Rlp.encodeArray([
new Uint8Array([1]),
new Uint8Array([2]),
new Uint8Array([3])
])
const arr = Rlp.decodeArray(encoded)
// Fast array access
console.log(arr[0]) // O(1)
console.log(arr.length) // O(1)
// Fast iteration
for (const item of arr) {
process(item)
}
vs decode
decodeArray is more convenient than decode for array access:
Copy
Ask AI
import { Rlp } from 'tevm'
const encoded = new Uint8Array([...])
// Using decodeArray (convenient)
const arr = Rlp.decodeArray(encoded)
const first = arr[0]
// Using decode (more verbose)
const decoded = Rlp.decode(encoded)
if (decoded.data.type === 'list') {
const first = decoded.data.value[0]
if (first.type === 'bytes') {
const value = first.value
}
}
Caching
Cache decoded results for repeated access:Copy
Ask AI
import { Rlp } from 'tevm'
class TxCache {
private cache = new Map<string, any[]>()
decode(bytes: Uint8Array): any[] {
const key = Hex.fromBytes(bytes).slice(2)
let cached = this.cache.get(key)
if (!cached) {
cached = Rlp.decodeArray(bytes)
this.cache.set(key, cached)
}
return cached
}
}
See Also
- decode - Decode to RLP data structure
- encodeArray - Encode array
- decodeObject - Decode to object
- Algorithm - RLP specification

