starcoin-framework

Module 0x1::BCS

Utility for converting a Move value to its binary representation in BCS (Diem Canonical Serialization). BCS is the binary encoding for Move resources and other non-module values published on-chain.

use 0x1::Errors;
use 0x1::Option;

Constants

const ERR_INPUT_NOT_LARGE_ENOUGH: u64 = 201;

const ERR_INVALID_ULEB128_NUMBER_UNEXPECTED_ZERO_DIGIT: u64 = 207;

const ERR_OVERFLOW_PARSING_ULEB128_ENCODED_UINT32: u64 = 206;

const ERR_UNEXPECTED_BOOL_VALUE: u64 = 205;

const INTEGER32_MAX_VALUE: u64 = 2147483647;

Function to_bytes

Return the binary representation of v in BCS (Starcoin Canonical Serialization) format

public fun to_bytes<MoveValue>(v: &MoveValue): vector<u8>
Implementation
native public fun to_bytes<MoveValue>(v: &MoveValue): vector<u8>;

Function to_address

Return the address of key bytes

public fun to_address(key_bytes: vector<u8>): address
Implementation
native public fun to_address(key_bytes: vector<u8>): address;

Function deserialize_option_bytes_vector

public fun deserialize_option_bytes_vector(input: &vector<u8>, offset: u64): (vector<Option::Option<vector<u8>>>, u64)
Implementation
public fun deserialize_option_bytes_vector(input: &vector<u8>, offset: u64): (vector<Option::Option<vector<u8>>>, u64) {
    let (len, new_offset) = deserialize_len(input, offset);
    let i = 0;
    let vec = Vector::empty<Option::Option<vector<u8>>>();
    while (i < len) {
        let (opt_bs, o) = deserialize_option_bytes(input, new_offset);
        Vector::push_back(&mut vec, opt_bs);
        new_offset = o;
        i = i + 1;
    };
    (vec, new_offset)
}
Specification
pragma verify = false;

Function deserialize_bytes_vector

public fun deserialize_bytes_vector(input: &vector<u8>, offset: u64): (vector<vector<u8>>, u64)
Implementation
public fun deserialize_bytes_vector(input: &vector<u8>, offset: u64): (vector<vector<u8>>, u64) {
    let (len, new_offset) = deserialize_len(input, offset);
    let i = 0;
    let vec = Vector::empty<vector<u8>>();
    while (i < len) {
        let (opt_bs, o) = deserialize_bytes(input, new_offset);
        Vector::push_back(&mut vec, opt_bs);
        new_offset = o;
        i = i + 1;
    };
    (vec, new_offset)
}
Specification
pragma verify = false;

Function deserialize_u64_vector

public fun deserialize_u64_vector(input: &vector<u8>, offset: u64): (vector<u64>, u64)
Implementation
public fun deserialize_u64_vector(input: &vector<u8>, offset: u64): (vector<u64>, u64) {
    let (len, new_offset) = deserialize_len(input, offset);
    let i = 0;
    let vec = Vector::empty<u64>();
    while (i < len) {
        let (opt_bs, o) = deserialize_u64(input, new_offset);
        Vector::push_back(&mut vec, opt_bs);
        new_offset = o;
        i = i + 1;
    };
    (vec, new_offset)
}
Specification
pragma verify = false;

Function deserialize_u128_vector

public fun deserialize_u128_vector(input: &vector<u8>, offset: u64): (vector<u128>, u64)
Implementation
public fun deserialize_u128_vector(input: &vector<u8>, offset: u64): (vector<u128>, u64) {
    let (len, new_offset) = deserialize_len(input, offset);
    let i = 0;
    let vec = Vector::empty<u128>();
    while (i < len) {
        let (opt_bs, o) = deserialize_u128(input, new_offset);
        Vector::push_back(&mut vec, opt_bs);
        new_offset = o;
        i = i + 1;
    };
    (vec, new_offset)
}
Specification
pragma verify = false;

Function deserialize_option_bytes

public fun deserialize_option_bytes(input: &vector<u8>, offset: u64): (Option::Option<vector<u8>>, u64)
Implementation
public fun deserialize_option_bytes(input: &vector<u8>, offset: u64): (Option::Option<vector<u8>>, u64) {
    let (tag, new_offset) = deserialize_option_tag(input, offset);
    if (!tag) {
        return (Option::none<vector<u8>>(), new_offset)
    } else {
        let (bs, new_offset) = deserialize_bytes(input, new_offset);
        return (Option::some<vector<u8>>(bs), new_offset)
    }
}
Specification
pragma verify = false;

Function deserialize_address

public fun deserialize_address(input: &vector<u8>, offset: u64): (address, u64)
Implementation
public fun deserialize_address(input: &vector<u8>, offset: u64): (address, u64) {
    let (content, new_offset) = deserialize_16_bytes(input, offset);
    (BCS::to_address(content), new_offset)
}
Specification
pragma verify = false;

Function deserialize_16_bytes

public fun deserialize_16_bytes(input: &vector<u8>, offset: u64): (vector<u8>, u64)
Implementation
public fun deserialize_16_bytes(input: &vector<u8>, offset: u64): (vector<u8>, u64) {
    let content = get_n_bytes(input, offset, 16);
    (content, offset + 16)
}
Specification
pragma verify = false;

Function deserialize_bytes

public fun deserialize_bytes(input: &vector<u8>, offset: u64): (vector<u8>, u64)
Implementation
public fun deserialize_bytes(input: &vector<u8>, offset: u64): (vector<u8>, u64) {
    let (len, new_offset) = deserialize_len(input, offset);
    let content = get_n_bytes(input, new_offset, len);
    (content, new_offset + len)
}
Specification
pragma verify = false;

Function deserialize_u128

public fun deserialize_u128(input: &vector<u8>, offset: u64): (u128, u64)
Implementation
public fun deserialize_u128(input: &vector<u8>, offset: u64): (u128, u64) {
    let u = get_n_bytes_as_u128(input, offset, 16);
    (u, offset + 16)
}
Specification
pragma verify = false;

Function deserialize_u64

public fun deserialize_u64(input: &vector<u8>, offset: u64): (u64, u64)
Implementation
public fun deserialize_u64(input: &vector<u8>, offset: u64): (u64, u64) {
    let u = get_n_bytes_as_u128(input, offset, 8);
    ((u as u64), offset + 8)
}
Specification
pragma verify = false;

Function deserialize_u32

public fun deserialize_u32(input: &vector<u8>, offset: u64): (u64, u64)
Implementation
public fun deserialize_u32(input: &vector<u8>, offset: u64): (u64, u64) {
    let u = get_n_bytes_as_u128(input, offset, 4);
    ((u as u64), offset + 4)
}
Specification
pragma verify = false;

Function deserialize_u16

public fun deserialize_u16(input: &vector<u8>, offset: u64): (u64, u64)
Implementation
public fun deserialize_u16(input: &vector<u8>, offset: u64): (u64, u64) {
    let u = get_n_bytes_as_u128(input, offset, 2);
    ((u as u64), offset + 2)
}
Specification
pragma verify = false;

Function deserialize_u8

public fun deserialize_u8(input: &vector<u8>, offset: u64): (u8, u64)
Implementation
public fun deserialize_u8(input: &vector<u8>, offset: u64): (u8, u64) {
    let u = get_byte(input, offset);
    (u, offset + 1)
}
Specification
pragma verify = false;

Function deserialize_option_tag

public fun deserialize_option_tag(input: &vector<u8>, offset: u64): (bool, u64)
Implementation
public fun deserialize_option_tag(input: &vector<u8>, offset: u64): (bool, u64) {
    deserialize_bool(input, offset)
}
Specification
pragma verify = false;

Function deserialize_len

public fun deserialize_len(input: &vector<u8>, offset: u64): (u64, u64)
Implementation
public fun deserialize_len(input: &vector<u8>, offset: u64): (u64, u64) {
    deserialize_uleb128_as_u32(input, offset)
}
Specification
pragma verify = false;

Function deserialize_bool

public fun deserialize_bool(input: &vector<u8>, offset: u64): (bool, u64)
Implementation
public fun deserialize_bool(input: &vector<u8>, offset: u64): (bool, u64) {
    let b = get_byte(input, offset);
    if (b == 1) {
        return (true, offset + 1)
    } else if (b == 0) {
        return (false, offset + 1)
    } else {
        abort ERR_UNEXPECTED_BOOL_VALUE
    }
}
Specification
pragma verify = false;

Function get_byte

fun get_byte(input: &vector<u8>, offset: u64): u8
Implementation
fun get_byte(input: &vector<u8>, offset: u64): u8 {
    assert!(((offset + 1) <= Vector::length(input)) && (offset < offset + 1), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
    *Vector::borrow(input, offset)
}
Specification
pragma verify = false;

Function get_n_bytes

fun get_n_bytes(input: &vector<u8>, offset: u64, n: u64): vector<u8>
Implementation
fun get_n_bytes(input: &vector<u8>, offset: u64, n: u64): vector<u8> {
    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
    let i = 0;
    let content = Vector::empty<u8>();
    while (i < n) {
        let b = *Vector::borrow(input, offset + i);
        Vector::push_back(&mut content, b);
        i = i + 1;
    };
    content
}
Specification
pragma verify = false;

Function get_n_bytes_as_u128

fun get_n_bytes_as_u128(input: &vector<u8>, offset: u64, n: u64): u128
Implementation
fun get_n_bytes_as_u128(input: &vector<u8>, offset: u64, n: u64): u128 {
    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
    let number: u128 = 0;
    let i = 0;
    while (i < n) {
        let byte = *Vector::borrow(input, offset + i);
        let s = (i as u8) * 8;
        number = number + ((byte as u128) << s);
        i = i + 1;
    };
    number
}
Specification
pragma verify = false;

Function deserialize_uleb128_as_u32

public fun deserialize_uleb128_as_u32(input: &vector<u8>, offset: u64): (u64, u64)
Implementation
public fun deserialize_uleb128_as_u32(input: &vector<u8>, offset: u64): (u64, u64) {
    let value: u64 = 0;
    let shift = 0;
    let new_offset = offset;
    while (shift < 32) {
        let x = get_byte(input, new_offset);
        new_offset = new_offset + 1;
        let digit: u8 = x & 0x7F;
        value = value | (digit as u64) << shift;
        if ((value < 0) || (value > INTEGER32_MAX_VALUE)) {
            abort ERR_OVERFLOW_PARSING_ULEB128_ENCODED_UINT32
        };
        if (digit == x) {
            if (shift > 0 && digit == 0) {
                abort ERR_INVALID_ULEB128_NUMBER_UNEXPECTED_ZERO_DIGIT
            };
            return (value, new_offset)
        };
        shift = shift + 7
    };
    abort ERR_OVERFLOW_PARSING_ULEB128_ENCODED_UINT32
}
Specification
pragma opaque;
pragma verify = false;

Function serialize_u32_as_uleb128

fun serialize_u32_as_uleb128(value: u64): vector<u8>
Implementation
fun serialize_u32_as_uleb128(value: u64): vector<u8> {
    let output = Vector::empty<u8>();
    while ((value >> 7) != 0) {
        Vector::push_back(&mut output, (((value & 0x7f) | 0x80) as u8));
        value = value >> 7;
    };
    Vector::push_back(&mut output, (value as u8));
    output
}
Specification
pragma verify = false;

Function skip_option_bytes_vector

public fun skip_option_bytes_vector(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_option_bytes_vector(input: &vector<u8>, offset: u64): u64 {
    let (len, new_offset) = deserialize_len(input, offset);
    let i = 0;
    while (i < len) {
        new_offset = skip_option_bytes(input, new_offset);
        i = i + 1;
    };
    new_offset
}
Specification
pragma verify = false;

Function skip_option_bytes

public fun skip_option_bytes(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_option_bytes(input: &vector<u8>, offset: u64):  u64 {
    let (tag, new_offset) = deserialize_option_tag(input, offset);
    if (!tag) {
        new_offset
    } else {
        skip_bytes(input, new_offset)
    }
}
Specification
pragma verify = false;

Function skip_bytes_vector

public fun skip_bytes_vector(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_bytes_vector(input: &vector<u8>, offset: u64): u64 {
    let (len, new_offset) = deserialize_len(input, offset);
    let i = 0;
    while (i < len) {
        new_offset = skip_bytes(input, new_offset);
        i = i + 1;
    };
    new_offset
}
Specification
pragma verify = false;

Function skip_bytes

public fun skip_bytes(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_bytes(input: &vector<u8>, offset: u64): u64 {
    let (len, new_offset) = deserialize_len(input, offset);
    new_offset + len
}
Specification
pragma verify = false;

Function skip_n_bytes

public fun skip_n_bytes(input: &vector<u8>, offset: u64, n: u64): u64
Implementation
public fun skip_n_bytes(input: &vector<u8>, offset: u64, n:u64): u64 {
    can_skip(input, offset, n );
    offset + n
}
Specification
pragma verify = false;

Function skip_u64_vector

public fun skip_u64_vector(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_u64_vector(input: &vector<u8>, offset: u64): u64 {
    let (len, new_offset) = deserialize_len(input, offset);
    can_skip(input, new_offset, len * 8);
    new_offset + len * 8
}
Specification
pragma verify = false;

Function skip_u128_vector

public fun skip_u128_vector(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_u128_vector(input: &vector<u8>, offset: u64): u64 {
    let (len, new_offset) = deserialize_len(input, offset);
    can_skip(input, new_offset, len * 16);
    new_offset + len * 16
}
Specification
pragma verify = false;

Function skip_u256

public fun skip_u256(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_u256(input: &vector<u8>, offset: u64): u64 {
    can_skip(input, offset, 32 );
    offset + 32
}
Specification
pragma verify = false;

Function skip_u128

public fun skip_u128(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_u128(input: &vector<u8>, offset: u64): u64 {
    can_skip(input, offset, 16 );
    offset + 16
}
Specification
pragma verify = false;

Function skip_u64

public fun skip_u64(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_u64(input: &vector<u8>, offset: u64): u64 {
    can_skip(input, offset, 8 );
    offset + 8
}
Specification
pragma verify = false;

Function skip_u32

public fun skip_u32(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_u32(input: &vector<u8>, offset: u64): u64 {
    can_skip(input, offset, 4 );
    offset + 4
}
Specification
pragma verify = false;

Function skip_u16

public fun skip_u16(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_u16(input: &vector<u8>, offset: u64): u64 {
    can_skip(input, offset, 2 );
    offset + 2
}
Specification
pragma verify = false;

Function skip_address

public fun skip_address(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_address(input: &vector<u8>, offset: u64): u64 {
    skip_n_bytes(input, offset, 16)
}
Specification
pragma verify = false;

Function skip_bool

public fun skip_bool(input: &vector<u8>, offset: u64): u64
Implementation
public fun skip_bool(input: &vector<u8>, offset: u64):  u64{
    can_skip(input, offset, 1);
    offset + 1
}
Specification
pragma verify = false;

Function can_skip

fun can_skip(input: &vector<u8>, offset: u64, n: u64)
Implementation
fun can_skip(input: &vector<u8>, offset: u64, n: u64){
    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
}
Specification
pragma verify = false;

Module Specification

pragma verify;
pragma aborts_if_is_strict;

native fun serialize<MoveValue>(v: &MoveValue): vector<u8>;