axelar-cgp-sui

Module 0xa0::abi

This module implements ABI encoding/decoding methods for interoperability with EVM message format.

ABI Specification: https://docs.soliditylang.org/en/v0.8.26/abi-spec.html

use 0x1::vector;

Struct AbiReader

struct AbiReader has copy, drop
Fields
bytes: vector<u8>
head: u64
pos: u64

Struct AbiWriter

struct AbiWriter has copy, drop
Fields
bytes: vector<u8>
pos: u64

Function new_reader

public fun new_reader(bytes: vector<u8>): abi::AbiReader
Implementation
public fun new_reader(bytes: vector<u8>): AbiReader {
    AbiReader {
        bytes,
        head: 0,
        pos: 0,
    }
}

Function new_writer

public fun new_writer(length: u64): abi::AbiWriter
Implementation
public fun new_writer(length: u64): AbiWriter {
    let mut bytes = vector[];
    let mut i = 0;

    while (i < 32 * length) {
        bytes.push_back(0);
        i = i + 1;
    };

    AbiWriter {
        bytes,
        pos: 0,
    }
}

Function into_bytes

public fun into_bytes(self: abi::AbiWriter): vector<u8>
Implementation
public fun into_bytes(self: AbiWriter): vector<u8> {
    let AbiWriter { bytes, pos: _ } = self;

    bytes
}

Function into_remaining_bytes

public fun into_remaining_bytes(self: abi::AbiReader): vector<u8>
Implementation
public fun into_remaining_bytes(self: AbiReader): vector<u8> {
    let AbiReader { bytes, head: _, pos: _ } = self;

    bytes
}

Function read_u256

public fun read_u256(self: &mut abi::AbiReader): u256
Implementation
public fun read_u256(self: &mut AbiReader): u256 {
    let mut var = 0u256;
    let mut i = 0;
    let pos = self.pos;

    while (i < 32) {
        var = (var << 8) | (self.bytes[i + pos] as u256);
        i = i + 1;
    };

    self.pos = pos + 32;

    var
}

Function read_u8

public fun read_u8(self: &mut abi::AbiReader): u8
Implementation
public fun read_u8(self: &mut AbiReader): u8 {
    self.read_u256() as u8
}

Function skip_slot

public fun skip_slot(self: &mut abi::AbiReader)
Implementation
public fun skip_slot(self: &mut AbiReader) {
    self.pos = self.pos + 32;
}

Function read_bytes

public fun read_bytes(self: &mut abi::AbiReader): vector<u8>
Implementation
public fun read_bytes(self: &mut AbiReader): vector<u8> {
    let pos = self.pos;

    // Move position to the start of the bytes
    let offset = self.read_u256() as u64;
    self.pos = self.head + offset;

    let var = self.decode_bytes();

    // Move position to the next slot
    self.pos = pos + 32;

    var
}

Function read_vector_u256

public fun read_vector_u256(self: &mut abi::AbiReader): vector<u256>
Implementation
public fun read_vector_u256(self: &mut AbiReader): vector<u256> {
    let mut var = vector[];
    let pos = self.pos;

    // Move position to the start of the dynamic data
    let offset = self.read_u256() as u64;
    self.pos = self.head + offset;

    let length = self.read_u256() as u64;

    let mut i = 0;

    while (i < length) {
        var.push_back(self.read_u256());
        i = i + 1;
    };

    self.pos = pos + 32;

    var
}

Function read_vector_bytes

Decode ABI-encoded ‘bytes[]’

public fun read_vector_bytes(self: &mut abi::AbiReader): vector<vector<u8>>
Implementation
public fun read_vector_bytes(self: &mut AbiReader): vector<vector<u8>> {
    let mut var = vector[];

    let pos = self.pos;
    let head = self.head;

    // Move position to the start of the dynamic data
    let offset = self.read_u256() as u64;
    self.pos = head + offset;

    let length = self.read_u256() as u64;
    self.head = self.pos;

    let mut i = 0;

    while (i < length) {
        var.push_back(self.read_bytes());

        i = i + 1;
    };

    // Move position to the next slot
    self.pos = pos + 32;
    self.head = head;

    var
}

Function write_u256

public fun write_u256(self: &mut abi::AbiWriter, var: u256): &mut abi::AbiWriter
Implementation
public fun write_u256(self: &mut AbiWriter, var: u256): &mut AbiWriter {
    let pos = self.pos;
    let mut i = 0;

    while (i < 32) {
        let exp = ((31 - i) * 8 as u8);
        let byte = (var >> exp & 255 as u8);
        *&mut self.bytes[i + pos] = byte;
        i = i + 1;
    };

    self.pos = pos + 32;

    self
}

Function write_u8

public fun write_u8(self: &mut abi::AbiWriter, var: u8): &mut abi::AbiWriter
Implementation
public fun write_u8(self: &mut AbiWriter, var: u8): &mut AbiWriter {
    self.write_u256(var as u256)
}

Function write_bytes

public fun write_bytes(self: &mut abi::AbiWriter, var: vector<u8>): &mut abi::AbiWriter
Implementation
public fun write_bytes(self: &mut AbiWriter, var: vector<u8>): &mut AbiWriter {
    let offset = self.bytes.length() as u256;
    self.write_u256(offset);

    // Write dynamic data length and bytes at the tail
    self.append_u256(var.length() as u256);
    self.append_bytes(var);

    self
}

Function write_vector_u256

public fun write_vector_u256(self: &mut abi::AbiWriter, var: vector<u256>): &mut abi::AbiWriter
Implementation
public fun write_vector_u256(
    self: &mut AbiWriter,
    var: vector<u256>,
): &mut AbiWriter {
    let offset = self.bytes.length() as u256;
    self.write_u256(offset);

    let length = var.length();
    self.append_u256(length as u256);

    let mut i = 0;
    while (i < length) {
        self.append_u256(var[i]);
        i = i + 1;
    };

    self
}

Function write_vector_bytes

public fun write_vector_bytes(self: &mut abi::AbiWriter, var: vector<vector<u8>>): &mut abi::AbiWriter
Implementation
public fun write_vector_bytes(
    self: &mut AbiWriter,
    var: vector<vector<u8>>,
): &mut AbiWriter {
    let offset = self.bytes.length() as u256;
    self.write_u256(offset);

    let length = var.length();
    self.append_u256(length as u256);

    let mut writer = new_writer(length);
    let mut i = 0;

    while (i < length) {
        writer.write_bytes(var[i]);
        i = i + 1;
    };

    self.append_bytes(writer.into_bytes());

    self
}

Function append_u256

fun append_u256(self: &mut abi::AbiWriter, var: u256)
Implementation
fun append_u256(self: &mut AbiWriter, var: u256) {
    let mut i = 0;
    while (i < 32) {
        self.bytes.push_back(((var >> ((31 - i) * 8 as u8)) & 255 as u8));
        i = i + 1;
    };
}

Function append_bytes

fun append_bytes(self: &mut abi::AbiWriter, var: vector<u8>)
Implementation
fun append_bytes(self: &mut AbiWriter, var: vector<u8>) {
    let length = var.length();
    if (length == 0) {
        return
    };

    self.bytes.append(var);

    let mut i = 0u64;

    while (i < 31 - (length - 1) % 32) {
        self.bytes.push_back(0);
        i = i + 1;
    };
}

Function decode_bytes

fun decode_bytes(self: &mut abi::AbiReader): vector<u8>
Implementation
fun decode_bytes(self: &mut AbiReader): vector<u8> {
    let length = self.read_u256() as u64;
    let pos = self.pos;

    let mut bytes = vector[];
    let mut i = 0;

    while (i < length) {
        bytes.push_back(self.bytes[i + pos]);
        i = i + 1;
    };

    bytes
}