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.
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 ofu32
) where possible to reduce gas costs.