as-scale-codec is AssemblyScript implementation of Polkadot SCALE Codec. The codec is used as a communication mechanism between Polkadot Hosts and Polkadot Runtimes.
More detailed information about the SCALE codec specification can be found here.
This AssemblyScript implementation of the codec is funded by Web3 Foundation via their Open Grants Program! 🙏

The following table shows the status of the types and their arrays:
| Type | Support | Array Support |
|---|---|---|
Fixed width number | ✅ | ✅ |
Compact Int | ✅ | ✅ |
Big Integer | 🔸 Limited Support | 🔸 Limited Support |
Byte | ✅ | ✅ |
Bool | ✅ | ✅ |
Hash | ✅ | ➖ |
String | ✅ | ✅ |
Map | ✅ | ➖ |
The following table shows the status of the fixed width numbers:
| Тype | 8 | 16 | 32 | 64 | 128 | 256 |
|---|---|---|---|---|---|---|
int | ✅ | ✅ | ✅ | ✅ | ➖ | ➖ |
uint | ✅ | ✅ | ✅ | ✅ | ✅ | ➖ |
- Compact Int - Documentation
You can find more information on AssemblyScript and how to get started with it in the AssemblyScript docs -> https://www.assemblyscript.org/introduction.html
In your AssemblyScript project execute:
npm install as-scale-codec
Once you have the library installed in your AssemblyScript project you can use it in your
assemblyfiles by importing the files fromas-scale-codec.
Detailed examples of the exported by the library types are listed below:
Every type has а toU8a function. It encodes type value into an array of bytes
import{Bool,Byte,ScaleString,Hash,CompactInt}from"as-scale-codec"import{Int8,Int16,Int32,Int64}from"as-scale-codec"import{UInt8,UInt16,UInt32,UInt64,UInt128}from"as-scale-codec"// ScaleMapconstscaleMap=newScaleMap<Int32,Bool>();scaleMap.set(newInt32(1),newBool(false));scaleMap.toU8a()// => [4, 1, 0, 0, 0, 0];// BoolconstscaleBool=newBool(true);scaleBool.toU8a()// => [0x01]// ByteconstscaleByte=newByte(0x01);scaleByte.toU8a()// => [0x01]// StringconstscaleString=newScaleString("a");scaleString.toU8a()// => [0x04, 0x61] // HashconstscaleHash=newHash([0xff,0x00,0xab]);scaleHash.toU8a()// => [0xff, 0x00, 0xab, 0x00, ... 0x00] (32 bytes long)// Compact IntconstscaleCompactInt=newCompactInt(1);scaleCompactInt.toU8a()// => [0x04]// IntconstscaleInt8=newInt8(-1);scaleInt8.toU8a()// => [0xff]constscaleInt16=newInt16(-1);scaleInt16.toU8a()// => [0xff, 0xff]constscaleInt32=newInt32(-1);scaleInt32.toU8a()// => [0xff, 0xff, 0xff, 0xff]constscaleInt64=newInt64(-1);scaleInt64.toU8a()// => [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]// UIntconstscaleUInt8=newUInt8(1);scaleUInt8.toU8a()// => [0x01]constscaleUInt16=newUInt16(1);scaleUInt16.toU8a()// => [0x01, 0x00]constscaleUInt32=newUInt32(1);scaleUInt32.toU8a()// => [0x01, 0x00, 0x00, 0x00]constscaleUInt64=newUInt64(1);scaleUInt64.toU8a()// => [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]constscaleUInt128=newUInt128(u128.fromU64(18446744073709551615));scaleUInt128.toU8a()// => [0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]Every type has a static function fromU8a. It decodes an array of bytes to the desired type
import{ScaleMap,Bool,Byte,ScaleString,Hash,CompactInt}from"as-scale-codec"import{Int8,Int16,Int32,Int64}from"as-scale-codec"import{UInt8,UInt16,UInt32,UInt64,UInt128}from"as-scale-codec"// BoolBool.fromU8a([0x01]);// => new Bool(true)// ByteByte.fromU8a([0x01]);// => new Byte(0x01)// StringByte.fromU8a([0x04,0x61]);// => new ScaleString('a')// HashHash.fromU8a([0xff,0x00,0xab]);// => [0xff, 0x00, 0xab, 0x00, ... 0x00] (32 bytes long)ScaleMap<Int32,Bool>.fromU8a([4,1,0,0,0,0]);// => const scaleMap = new ScaleMap<Int32, Bool>()// => scaleMap.set(new Int32(1), new Bool(false))// Compact IntCompactInt.fromU8a([0x04]);// => new CompactInt(1)// IntInt8.fromU8a([0xff]);// => new Int8(-1)Int16.fromU8a([0xff,0xff]);// => new Int16(-1)Int32.fromU8a([0xff,0xff,0xff,0xff]);// => new Int32(-1)Int64.fromU8a([0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff]);// => new Int64(-1)// UIntUInt8.fromU8a([0x01]);// => new UInt8(1)UInt16.fromU8a([0x01,0x00]);// => new UInt16(1)UInt32.fromU8a([0x01,0x00,0x00,0x00]);// => new UInt32(1)UInt64.fromU8a([0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);// => new UInt64(1)UInt128.fromU8a([0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff]);// => 340282366920938463444927863358058659840Every array has toU8a function. It encodes the array values into an array of SCALE encoded bytes.
import{BoolArray,ByteArray,IntArray,StringArray}from"as-scale-codec"// Bool ArrayconstboolArray=newBoolArray([true,false,true]);boolArray.toU8a();// => [0x0c, 0x01, 0x00, 0x01]// Byte ArrayconstbyteArray=newByteArray([0x01,0x01,0x01]);byteArray.toU8a();// => [0x0c, 0x01, 0x01, 0x01]// Int ArrayconstintArray=newIntArray([16384,2,3,4]);intArray.toU8a()// => [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10]// String ArrayconststringArray=newStringArray(["hello","world"]);stringArray.toU8a()// => [0x08, 0x14, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x14, 0x77, 0x6f, 0x72, 0x6c, 0x64]Every array has a static function fromU8a. It decodes an array of SCALE encoded bytes and creates an array instance of the desired type.
import{BoolArray,ByteArray,IntArray,StringArray}from"as-scale-codec"// Bool ArrayBoolArray.fromU8a([0x0c,0x01,0x00,0x01]);// => new BoolArray([true, false, true])// Byte ArrayByteArray.fromU8a([0x0c,0x01,0x01,0x01])// => new ByteArray([0x01, 0x01, 0x01])// Int ArrayIntArray.fromU8a([0x10,0x02,0x00,0x01,0x00,0x08,0x0c,0x10])// => new IntArray([16384, 2, 3, 4])// String ArrayStringArray.fromU8a([0x08,0x14,0x68,0x65,0x6c,0x6c,0x6f,0x14,0x77,0x6f,0x72,0x6c,0x64])// => new StringArray(["hello", "world"])If you have an array of arbitrary SCALE encoded bytes that you need to decode, BytesReader class is a preferred way to do it:
import{BytesReader}from'as-scale-codec';// Arbitrary SCALE encoded bytesconstbytes: u8[]=[0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,69,0,0,0,110,125,239,2,56,97,115,45,115,99,97,108,101,45,99,111,100,101,99,128,1,10,0,0,0,2,2,1,123,33,3,1,35,34,5,8,22,52,1,0,0,0,1,1,1,56,21,142,13,13,1,0];// Instantiate BytesReader instance with SCALE encoded bytesconstbytesReader=newBytesReader(bytes);// Read Int64bytesReader.readInto<Int64>();// => new Int(-1)// Read UInt32bytesReader.readInto<UInt32>();// => new UInt32(69)// Read CompactIntbytesReader.readInto<CompactInt>();// => new CompactInt(12312411)// Read ScaleStringbytesReader.readInto<ScaleString>();// => new ScaleString("as-scale-codec")// Read HashbytesReader.readInto<Hash>();// => new Hash([128, 1, 10, 0, 0, 0, 2, 2, 1, 123, 33, 3, 1, 35, 34, 5, 8, 22, 52, 1, 0, 0, 0, 1, 1, 1, 56, 21, 142, 13, 13, 1])// Read BoolbytesReader.readInto<Bool>();// => new Bool(false)// If you have single SCALE encoded type, you can use static decodeInto<T>() function of BytesReaderconstuInt64Bytes: u8[]=[1,0,0,0,0,0,0];// Read UInt64BytesReader.decodeInto<UInt64>(uInt64Bytes);// => new UInt64(1)consthashBytes: u8[]=[0xff,0x00,0xab];// Read HashBytesReader.decodeInto<Hash>(hashBytes);// new Hash([0xff, 0x00, 0xab])constmapBytes: u8[]=[2,1,0,1,0,0,0,3,0,3,0,0,0];// Read ScaleMapBytesReader.decodeInto<ScaleMap<UInt16,UInt32>>(mapBytes);// => const scaleMap = new ScaleMap<UInt16, UInt32>();// => scaleMap.set(new UInt16(1), new UInt32(1))// => scaleMap.set(new UInt16(3), new UInt32(3))constcmpBytes: u8[]=[169,2];// Read CompactIntBytesReader.decodeInto<CompactInt>(cmpBytes);// new CompactInt(170)constint8Bytes: u8[]=[0xff];// Read Int8BytesReader.decodeInto<Int8>(int8Bytes);// new Int8(-1)Hash.bytesToHash([0xff,0x00,0xab]);// => [0x00, ... , 0x00, 0xff, 0x00, 0xab] (32 bytes long)Hash.bytesToHash([0xff,0x00, ...,0x00]);// (32 bytes long)// => [0xff, ... , 0x00] (32 bytes long)In order to run the unit tests, one must perform:
npm run testThis repository is licensed under Apache 2.0 license