1.1.0 • Published 7 months ago
@bcoders.gr/abi-codec v1.1.0
High-Performance ABI Codec
A blazing-fast Node.js module for encoding/decoding Ethereum ABI data compatible with Geth. Optimized for maximum performance with zero-copy Buffer operations.
Features
- ✅ Function encoding/decoding - All Solidity types supported
- ✅ Event log decoding - Individual logs and full receipts
- ✅ Receipt processing - Decode all matching logs from transaction receipts
- ✅ Maximum performance - Direct Buffer operations, minimal hex conversions
- ✅ Geth compatibility - 100% compatible with Ethereum node outputs
- ✅ Minimal dependencies - Only ethers.js utils for keccak256
Installation
npm installQuick Start
const { ABICodec } = require('./index');
// Your contract ABI
const contractABI = [
{
"type": "function",
"name": "transfer",
"inputs": [
{"name": "to", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"outputs": [{"name": "success", "type": "bool"}]
},
{
"type": "event",
"name": "Transfer",
"inputs": [
{"name": "from", "type": "address", "indexed": true},
{"name": "to", "type": "address", "indexed": true},
{"name": "value", "type": "uint256", "indexed": false}
]
}
];
const codec = new ABICodec(contractABI);API Reference
Function Encoding/Decoding
// Encode function call
const calldata = codec.encodeFunction('transfer', [
'0x742d35Cc6634C0532925a3b8D8e9eED89B7A6de6',
BigInt('1000000000000000000')
]);
// Decode function call
const params = codec.decodeFunction('transfer', calldata);
// Returns: ['0x742d35Cc6634C0532925a3b8D8e9eED89B7A6de6', 1000000000000000000n]
// Decode function result
const result = codec.decodeFunctionResult('transfer', '0x0000...0001');
// Returns: [true]Event Log Decoding
// Decode single event log
const decodedLog = codec.decodeLog(logData, topics, 'Transfer');
// Returns: { name: 'Transfer', args: { from: '0x...', to: '0x...', value: 1000n } }
// Decode all logs from a transaction receipt
const decodedLogs = codec.decodeReceiptLogs(receipt);
// Returns: Array of decoded logs that match ABI events
// Decode multiple receipts at once
const allLogs = codec.decodeMultipleReceipts([receipt1, receipt2, receipt3]);
// Filter logs by event name
const transferLogs = codec.filterLogsByEvent(decodedLogs, 'Transfer');Utility Functions
// Get function selector (4-byte signature)
const selector = codec.getFunctionSelector('transfer');
// Returns: '0xa9059cbb'
// Get event selector (32-byte topic hash)
const eventTopic = codec.getEventSelector('Transfer');
// Returns: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
// Get all event topics this codec can decode
const knownTopics = codec.getKnownEventTopics();
// Returns: ['0xddf252...', '0x8c5be1...', ...]Supported Types
| Solidity Type | Supported | Notes |
|---|---|---|
uint8 to uint256 | ✅ | Including uint (defaults to uint256) |
int8 to int256 | ✅ | Including int (defaults to int256) |
bool | ✅ | |
address | ✅ | |
bytes1 to bytes32 | ✅ | Fixed-size byte arrays |
bytes | ✅ | Dynamic byte arrays |
string | ✅ | UTF-8 encoded |
uint256[] | ✅ | Dynamic arrays |
uint256[5] | ✅ | Fixed-size arrays |
tuple | 🔄 | Coming soon (structs) |
Performance
Benchmarked on typical hardware:
- 10,000 function encodings: ~96ms (0.0096ms per encoding)
- 1,000 receipt decodings: ~12ms (0.012ms per receipt)
- Zero-copy operations where possible for maximum speed
Real-World Usage
Processing Transaction Receipts
// Process multiple transaction receipts
function processTransactions(receipts, codec) {
const results = {
totalLogs: 0,
decodedLogs: 0,
events: {}
};
for (const receipt of receipts) {
results.totalLogs += receipt.logs?.length || 0;
const decoded = codec.decodeReceiptLogs(receipt);
results.decodedLogs += decoded.length;
// Count events by type
decoded.forEach(log => {
results.events[log.name] = (results.events[log.name] || 0) + 1;
});
}
return results;
}
const stats = processTransactions(receipts, codec);
console.log(\`Decoded \${stats.decodedLogs}/\${stats.totalLogs} logs\`);Event Filtering and Analysis
// Get all Transfer events from multiple receipts
const allLogs = codec.decodeMultipleReceipts(receipts);
const transfers = codec.filterLogsByEvent(allLogs, 'Transfer');
// Analyze transfer patterns
const transferAnalysis = transfers.map(log => ({
from: log.args.from,
to: log.args.to,
amount: log.args.value,
blockNumber: log.blockNumber,
txHash: log.transactionHash
}));Error Handling
The codec throws descriptive errors for invalid inputs:
try {
const result = codec.encodeFunction('unknownFunction', []);
} catch (error) {
console.error('Function not found:', error.message);
}
try {
const result = codec.decodeReceiptLogs(invalidReceipt);
} catch (error) {
console.error('Invalid receipt format:', error.message);
}Testing
Run the test suite:
# Basic functionality tests
node test/basic.test.js
# Receipt decoding tests
node test/receipt.test.js
# Usage examples
node example.js
node receipt-example.jsLicense
MIT
Contributing
This module is optimized for performance. When contributing:
- Maintain zero-copy Buffer operations where possible
- Avoid unnecessary hex string conversions
- Pre-compile and cache expensive operations
- Add performance benchmarks for new features
Built for maximum performance with Ethereum/Geth compatibility in mind. 🚀