Polkadart Logo
SCALE Codec

Overview

Comprehensive guide to the polkadart_scale_codec package - SCALE codec implementation for encoding and decoding blockchain data

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

TypeDescriptionDart Type
boolBoolean valuebool
u8, u16, u32, u64Unsigned integersint
u128, u256Large unsigned integersBigInt
i8, i16, i32, i64Signed integersint
i128, i256Large signed integersBigInt
strUTF-8 stringString

Compact Types

TypeDescriptionUse Case
CompactCompact integer encodingSpace-efficient integers
CompactBigIntCompact encoding for BigIntLarge numbers

Collection Types

TypeDescriptionDart Type
ArrayFixed-length arrayList<T>
SequenceVariable-length vectorList<T>
BTreeMapSorted mapMap<K, V>
SetUnique collectionSet<T>
BitSequenceBit arrayList<bool>

Generic Types

TypeDescriptionDart Type
OptionOptional valueT? or Option<T>
ResultResult typeResult<T, E>
TupleFixed-size tupleList<dynamic>

Composite Types

TypeDescriptionDart Type
CompositeStruct/objectMap<String, dynamic>
EnumEnumerationMapEntry<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