Overview
What is polkadart_scale_codec?
The polkadart_scale_codec package is Polkadart's pure Dart implementation of the SCALE (Simple Concatenated Aggregate Little-Endian) codec. SCALE is the primary encoding format used by Substrate-based blockchains, including Polkadot and Kusama, for efficient binary serialization and deserialization of data.
Think of it as the fundamental layer that enables your Dart application to speak the same language as the blockchain - converting complex data structures into compact binary representations and back.
What is SCALE?
SCALE (Simple Concatenated Aggregate Little-Endian) is a lightweight, efficient encoding format with these characteristics:
- Compact: Minimal overhead and space-efficient encoding
- Deterministic: Same input always produces same output
- Self-describing: Type information is known from context (metadata)
- Little-endian: Consistent byte ordering across platforms
SCALE is specifically designed for blockchain use cases where:
- Storage space is precious
- Network bandwidth is limited
- Deterministic encoding is critical for consensus
Key Features
Complete Type Coverage
Full support for all SCALE primitive and composite types
Input/Output Abstraction
Flexible I/O system supporting bytes, hex, and custom outputs
Compact Encoding
Space-efficient compact integer encoding for optimal storage
Generic Codecs
Support for Option, Result, tuples, arrays, and sequences
Composite Types
Build complex structures from simple codecs
Zero Dependencies
Pure Dart implementation with minimal external dependencies
Core Concepts
The Codec Interface
Every type in SCALE has a corresponding codec that implements the Codec<E> mixin:
mixin Codec<E> {
// Decode from binary input
E decode(Input input);
// Encode to binary output
void encodeTo(E value, Output output);
// Encode to bytes
Uint8List encode(E value);
// Hint about encoded size
int sizeHint(E value);
}
Input and Output
The codec system uses abstracted I/O:
// Create input from various sources
final input1 = Input.fromHex('0x2a');
final input2 = Input.fromBytes([42]);
// Create different output types
final byteOutput = ByteOutput();
final hexOutput = HexOutput();
Available Codecs
Primitive Types
| Type | Description | Dart Type |
|---|---|---|
| bool | Boolean value | bool |
| u8, u16, u32, u64 | Unsigned integers | int |
| u128, u256 | Large unsigned integers | BigInt |
| i8, i16, i32, i64 | Signed integers | int |
| i128, i256 | Large signed integers | BigInt |
| str | UTF-8 string | String |
Compact Types
| Type | Description | Use Case |
|---|---|---|
| Compact | Compact integer encoding | Space-efficient integers |
| CompactBigInt | Compact encoding for BigInt | Large numbers |
Collection Types
| Type | Description | Dart Type |
|---|---|---|
| Array | Fixed-length array | List<T> |
| Sequence | Variable-length vector | List<T> |
| BTreeMap | Sorted map | Map<K, V> |
| Set | Unique collection | Set<T> |
| BitSequence | Bit array | List<bool> |
Generic Types
| Type | Description | Dart Type |
|---|---|---|
| Option | Optional value | T? or Option<T> |
| Result | Result type | Result<T, E> |
| Tuple | Fixed-size tuple | List<dynamic> |
Composite Types
| Type | Description | Dart Type |
|---|---|---|
| Composite | Struct/object | Map<String, dynamic> |
| Enum | Enumeration | MapEntry<String, T> |
Installation
Add polkadart_scale_codec to your pubspec.yaml:
dependencies:
polkadart_scale_codec: ^2.0.0
Quick Start
Here's a simple example encoding and decoding data:
import 'package:polkadart_scale_codec/polkadart_scale_codec.dart';
void main() {
// Encode a simple integer
final output = ByteOutput();
U32Codec.codec.encodeTo(42, output);
final bytes = output.toBytes();
print('Encoded: ${bytes}'); // [42, 0, 0, 0]
// Decode it back
final input = Input.fromBytes(bytes);
final value = U32Codec.codec.decode(input);
print('Decoded: $value'); // 42
// Using hex for readability
final hexOutput = HexOutput();
U32Codec.codec.encodeTo(42, hexOutput);
print('Hex: ${hexOutput.toString()}'); // 0x2a000000
}
Common Use Cases
Encoding Account Balances
// Compact encoding saves space for large numbers
final balance = BigInt.from(1000000000000); // 1 DOT
final output = ByteOutput();
CompactBigIntCodec.codec.encodeTo(balance, output);
Working with Optional Values
// Encoding Some(value)
final codec = OptionCodec(U32Codec.codec);
final output = ByteOutput();
codec.encodeTo(42, output); // [1, 42, 0, 0, 0]
// Encoding None
codec.encodeTo(null, output); // [0]
Complex Structures
// Account info structure
final accountCodec = CompositeCodec({
'nonce': U32Codec.codec,
'consumers': U32Codec.codec,
'providers': U32Codec.codec,
'data': CompositeCodec({
'free': U128Codec.codec,
'reserved': U128Codec.codec,
}),
});
final accountData = {
'nonce': 5,
'consumers': 0,
'providers': 1,
'data': {
'free': BigInt.from(1000000000000),
'reserved': BigInt.zero,
},
};
final encoded = accountCodec.encode(accountData);
Architecture
The package is organized into several modules:
Core Module
- Codec: Base interface for all codecs
- Input/Output: I/O abstraction layer
Primitives Module
- All primitive type codecs (integers, booleans, strings)
- Generic codecs (Option, Result, etc.)
- Collection codecs (Array, Sequence, etc.)
- Composite codecs (Composite, Enum)
Extended Codecs
- Specialized codecs built on top of primitives
- Length-prefixed codec for custom use cases
Utils Module
- Exception types
- Helper functions
- Regular expressions for parsing
Integration with Other Packages
The polkadart_scale_codec package is used throughout the Polkadart ecosystem:
- substrate_metadata: Uses SCALE codecs to decode metadata and chain data
- polkadart: Uses codecs for encoding extrinsics and decoding storage
- polkadart_cli: Generates type-safe codecs from chain metadata
Performance Characteristics
SCALE encoding is designed for performance:
- Zero-copy decoding: Direct buffer access where possible
- Compact representation: Minimal overhead for common values
- Predictable: Size hints allow pre-allocation
- Efficient: Little-endian encoding is native on most platforms
When to Use This Package
You'll use polkadart_scale_codec when:
- Building custom blockchain interactions
- Implementing custom storage queries
- Creating offline transaction signing
- Developing blockchain explorers
- Building indexers or monitoring tools
- Working with raw blockchain data
For most application development, the higher-level polkadart and substrate_metadata packages handle SCALE encoding automatically.
Next Steps
- Primitive Types - Learn about basic SCALE types
- Compact Encoding - Understand compact integer encoding
- Collections - Work with arrays, sequences, and maps
- Generic Types - Use Option, Result, and tuples
- Composite Types - Build complex structures
- Input/Output - Master the I/O system