Python SCALE Codec Library
The `scalecodec` library is a Python implementation of the Substrate-specific Simple Concatenated Aggregate Little-Endian (SCALE) codec. It provides functionality for encoding and decoding data types used in Substrate-based blockchains, such as Polkadot and Kusama. The library is actively maintained, with frequent updates, and is currently at version 1.2.12, with a major version 2.0.0a (alpha) in development.
Warnings
- breaking Version 2.0.0a (alpha) introduces a 'new from the ground up object based implementation' which fundamentally changes how types are handled and instantiated. This is a significant breaking change from v1.x's string-based type parsing.
- gotcha The SCALE codec is not self-describing; it requires prior knowledge of the data's type definition for correct decoding. Attempting to decode data without the correct type context (e.g., from blockchain metadata) will lead to incorrect or failed decoding.
- gotcha When decoding a byte array, the `decode()` method by default expects the entire byte stream to be consumed. If you are decoding a partial stream or a byte array with trailing data, this will raise an error.
- gotcha For composite types (structures), the SCALE codec ignores field names; only the order of fields matters for encoding and decoding. Re-encoding data that was decoded with an assumed order into a different field order will result in a different (and likely incorrect) byte array.
Install
-
pip install scalecodec
Imports
- ScaleBytes
from scalecodec.base import ScaleBytes
- RuntimeConfiguration
from scalecodec.type_registry import RuntimeConfiguration
- MetadataVersioned
from scalecodec.metadata import MetadataVersioned
Quickstart
from scalecodec.base import ScaleBytes
from scalecodec.type_registry import RuntimeConfiguration
# Initialize a runtime configuration (required for decoding types based on metadata)
# For simple types, a basic config can be used.
# For complex types, load a specific chain's metadata using load_type_registry()
runtime_config = RuntimeConfiguration()
# Example: Encode a Compact integer
compact_int_value = 100000000000000
compact_encoder = runtime_config.create_scale_object("Compact<u128>")
encoded_data = compact_encoder.encode(compact_int_value)
print(f"Encoded {compact_int_value} (Compact<u128>): {encoded_data.to_hex()}")
# Example: Decode a Compact integer
encoded_hex_value = "0x0b00407a10f35a" # The SCALE encoding for 100,000,000,000,000
compact_decoder = runtime_config.create_scale_object("Compact<u128>")
decoded_value = compact_decoder.decode(ScaleBytes(encoded_hex_value))
print(f"Decoded {encoded_hex_value} (Compact<u128>): {decoded_value}")