| Crates.io | ccnext-abi-encoding |
| lib.rs | ccnext-abi-encoding |
| version | 99.99.102 |
| created_at | 2025-04-09 01:01:03.405049+00 |
| updated_at | 2025-12-02 09:08:36.263382+00 |
| description | ABI encoding library intended for use with the ccnext project. |
| homepage | |
| repository | |
| max_upload_size | |
| id | 1626167 |
| size | 178,374 |
A Rust library for encoding Ethereum transactions and receipts into ABI format, specifically designed for the CCNext project. This library provides efficient encoding that respects Solidity's stack limitations through a sophisticated chunking mechanism.
The CCNext ABI encoding library transforms Ethereum transactions and their corresponding receipts into a standardized ABI-encoded format. The primary innovation of this library is its chunked encoding approach, which is specifically designed to work around Solidity's stack depth limitations.
Solidity has a strict stack depth limit of 1024 slots. When dealing with complex Ethereum transactions (especially Type 3 and Type 4 transactions), encoding all transaction data as a single large tuple can easily exceed this limit, causing smart contract calls to fail with stack overflow errors.
Consider a Type 3 (EIP-4844) transaction with:
Encoding all this data in one tuple could require 1500+ stack slots, exceeding Solidity's limit.
Our chunking strategy divides transaction data into logical, smaller chunks that can be processed independently:
// Instead of one massive tuple:
// (nonce, gasLimit, from, to, value, input, accessList, blobHashes, ..., logs, receipts)
// We use multiple smaller chunks:
// Chunk 1: Common fields (nonce, gasLimit, from, to, value, input)
// Chunk 2: Transaction-specific fields (gasPrice, accessList, signatures)
// Chunk 3: Receipt data (status, gasUsed, logs, blooms)
// Chunk 4: Additional data for complex transaction types
This approach ensures that:
The library supports all current Ethereum transaction types with optimized chunking:
| Type | Description | Chunks | Key Features |
|---|---|---|---|
| Type 0 | Legacy transactions | 3 | Basic transaction data, gas price, signatures |
| Type 1 | EIP-2930 (Access Lists) | 3 | Adds access list encoding |
| Type 2 | EIP-1559 (Dynamic Fees) | 3 | Max fee per gas, priority fees |
| Type 3 | EIP-4844 (Blob transactions) | 4 | Blob versioned hashes, blob gas |
| Type 4 | EIP-7702 (Account Abstraction) | 4 | Authorization lists, delegation |
(
nonce: uint64,
gasLimit: uint64,
from: address,
isToNull: bool, // true for contract creation
to: address,
value: uint256,
input: bytes // transaction data
)
Varies by transaction type, but includes signatures, gas pricing, and type-specific data.
Additional authorization lists, blob data, or other complex structures.
(
status: uint8, // success/failure
gasUsed: uint64,
logs: Log[], // event logs
logsBloom: bytes // bloom filter
)
use ccnext_abi_encoding::{abi_encode, EncodingVersion};
use alloy::rpc::types::{Transaction, TransactionReceipt};
// Encode a transaction and receipt
let result = abi_encode(transaction, receipt, EncodingVersion::V1)?;
// Get the encoded bytes
let encoded_bytes = result.abi();
// Verify the encoding version
assert_eq!(result.version(), EncodingVersion::V1);
The final encoded output follows this structure:
(
transactionType: uint8, // 0, 1, 2, 3, or 4
chunks: bytes[] // Array of ABI-encoded chunks
)
Each chunk in the array is independently ABI-encoded, allowing for:
The chunking strategy ensures that no single operation exceeds ~800 stack items, leaving a safety margin below Solidity's 1024 limit. This is achieved by:
The encoding is completely deterministic:
Smart contracts can efficiently process the chunked encoding:
function processTransaction(bytes memory encodedData) external {
(uint8 txType, bytes[] memory chunks) = abi.decode(encodedData, (uint8, bytes[]));
// Process each chunk individually - no stack overflow!
for (uint i = 0; i < chunks.length; i++) {
processChunk(txType, i, chunks[i]);
}
}