Skip to content

Repository files navigation

AssemblyScript SCALE Codec

LicenseTestsnpm versionGitHub release (latest by date)

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! 🙏 WEB3 Badge

Supported types

The following table shows the status of the types and their arrays:

TypeSupportArray 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:

Тype8163264128256
int
uint

Special Types

Getting Started

You can find more information on AssemblyScript and how to get started with it in the AssemblyScript docs -> https://www.assemblyscript.org/introduction.html

  1. In your AssemblyScript project execute:

    npm install as-scale-codec
  2. Once you have the library installed in your AssemblyScript project you can use it in your assembly files by importing the files from as-scale-codec.

Detailed examples of the exported by the library types are listed below:

Types

Encoding

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]

Decoding

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]);// => 340282366920938463444927863358058659840

Arrays

Encoding

Every 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]

Decoding

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"])

BytesReader

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)

Miscellaneous

Convert bytes to hash

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)

Tests

In order to run the unit tests, one must perform:

npm run test

License

This repository is licensed under Apache 2.0 license

About

AssemblyScript implementation of the SCALE codec used in the Parity Substrate framework.

Resources

Stars

20 stars

Watchers

4 watching

Forks

Releases

Used by

Contributors

Languages