Skip to main content

BinaryWriter and BinaryReader Usage

This document details the usage of the BytesWriter and BytesReader classes for encoding and decoding binary data efficiently in blockchain smart contracts.

Why Use BinaryWriter and BinaryReader?

Efficient data serialization and deserialization are critical for blockchain applications to minimize gas costs and ensure compatibility with decentralized protocols. BytesWriter and BytesReader provide robust tools for:

  • Encoding data: Serialize primitive and complex data types into a binary format.
  • Decoding data: Read and parse binary data back into usable types.

Importing BinaryWriter and BinaryReader

To use these utilities, include the necessary imports:

import { BytesWriter, BytesReader } from "@btc-vision/btc-runtime/runtime";
import { u128, u256 } from "as-bignum/assembly";

BytesWriter: Writing Data

The BytesWriter class allows you to serialize various data types into a binary format.

Key Methods

  • writeU8(value: u8): void
    Writes an unsigned 8-bit integer.

  • writeU256(value: u256): void
    Writes a 256-bit unsigned integer.

  • writeString(value: string): void
    Writes a string, character by character.

  • writeBytes(value: Uint8Array): void
    Writes a raw byte array.

Usage Example

import { BytesWriter } from "@btc-vision/btc-runtime/runtime";
import { u256 } from "as-bignum/assembly";

const writer = new BytesWriter(64);
writer.writeU8(255); // Write a single byte
writer.writeString("Hello, blockchain!"); // Write a string
writer.writeU256(new u256(123456)); // Write a 256-bit integer

const encodedData = writer.getBuffer();
console.log(encodedData.toString()); // Encoded byte array

BytesReader: Reading Data

The BytesReader class is used to deserialize binary data into usable types.

Key Methods

  • readU8(): u8
    Reads an unsigned 8-bit integer.

  • readU256(): u256
    Reads a 256-bit unsigned integer.

  • readString(length: u16): string
    Reads a string of a specified length.

  • readBytes(length: u32): Uint8Array
    Reads a raw byte array.

Usage Example

import { BytesReader } from "@btc-vision/btc-runtime/runtime";
import { u256 } from "as-bignum/assembly";

const encodedData: Uint8Array = new Uint8Array(6); // 6 is the length in bytes of the encoded data
encodedData.set([255, 72, 101, 108, 108, 111]); // 255, 72, 101, 108, 108, 111

const reader = new BytesReader(encodedData);

const byte = reader.readU8(); // Read first byte (255)
const str = reader.readString(5); // Read next 5 bytes as a string ("Hello")
console.log(`Byte: ${byte}, String: ${str}`);

Combining BytesWriter and BytesReader

These classes work seamlessly together for encoding and decoding structured data.

Example

import { BytesWriter, BytesReader } from "@btc-vision/btc-runtime/runtime";
import { u256 } from "as-bignum/assembly";

// Writing data
const writer = new BytesWriter(64);
writer.writeU8(100);
writer.writeU256(new u256(500));
const encoded = writer.getBuffer();

// Reading data
const reader = new BytesReader(encoded);
const byte = reader.readU8(); // Read 100
const bigNumber = reader.readU256(); // Read 500

console.log(`Byte: ${byte}, Big Number: ${bigNumber.toString()}`);

Best Practices

  • Always ensure your buffer is large enough to hold all data.
  • Validate inputs and catch errors (e.g., out-of-bounds reads) to prevent runtime issues.
  • Use compact representations (e.g., u8 instead of u32) where possible to reduce gas costs.