Skip to content

Cells、Builders 和 Slices

Cells 是 TON 区块链中的一种低级原语,表示数据。一个 Cell 由 1023 位数据和最多 4 个对其他 Cells 的引用组成。Cells 是只读且不可变的。Builders 是用于构建 Cells 的不可变结构。Slices 是解析 Cells 的一种方式。

beginCell

solidity
fun beginCell(): Builder

创建一个新的空的 Builder

使用示例:

solidity
let fizz: Builder = beginCell();

Builder.endCell

solidity
extends fun endCell(self: Builder): Cell;

Builder 的扩展函数。

Builder 转换为普通的 Cell

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Cell = b.endCell();

Builder.storeUint

solidity
extends fun storeUint(self: Builder, value: Int, bits: Int): Builder;

Builder 的扩展函数。

将一个无符号的 bitsvalue 存储到 Builder 的副本中,$0 ≤$ bits $≤ 256$。返回该副本。

尝试存储负的 value 或提供不足或超出范围的 bits 数会抛出异常,错误代码为 exit code 5整数超出预期范围

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Builder = b.storeUint(42, 6);

Builder.storeInt

solidity
extends fun storeInt(self: Builder, value: Int, bits: Int): Builder;

Builder 的扩展函数。

将一个有符号的 bitsvalue 存储到 Builder 的副本中,$0 ≤$ bits $≤ 257$。返回该副本。

尝试提供不足或超出范围的 bits 数会抛出异常,错误代码为 exit code 5整数超出预期范围

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Builder = b.storeUint(42, 7);

Builder.storeBool

solidity
extends fun storeBool(self: Builder, value: Bool): Builder;

Builder 的扩展函数。

将一个 Bool value 存储到 Builder 的副本中。如果 valuetrue,写入 $1$ 作为单个位,否则写入 $0$。返回该 Builder 的副本。

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Builder = b.storeBool(true);  // 写入 1
let buzz: Builder = b.storeBool(false); // 写入 0

Builder.storeSlice

solidity
extends fun storeSlice(self: Builder, cell: Slice): Builder;

Builder 的扩展函数。

将一个 Slice cell 存储到 Builder 的副本中。返回该副本。

使用示例:

solidity
let b: Builder = beginCell();
let s: Slice = emptyCell().asSlice();
let fizz: Builder = b.storeSlice(s);

Builder.storeCoins

solidity
extends fun storeCoins(self: Builder, value: Int): Builder;

Builder 的扩展函数。

将范围为 $0 .. 2^{120} − 1$ 的无符号 Int value 存储(序列化)到 Builder 的副本中。value 的序列化由一个 $4$ 位无符号大端整数 $l$ 组成,这是最小的整数 $l ≥ 0$,使得 value $< 2^{8 * l}$,然后是 $8 * l$ 位无符号大端表示的 value。如果 value 不在支持的范围内,会抛出范围检查异常。返回该 Builder 的副本。

尝试存储超出范围的 value 会抛出异常,错误代码为 exit code 5整数超出预期范围

这是存储 nanoToncoins 的最常见方式。

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Builder = b.storeCoins(42);

Builder.storeAddress

solidity
extends fun storeAddress(self: Builder, address: Address): Builder;

Builder 的扩展函数。

address 存储到 Builder 的副本中。返回该副本。

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Builder = b.storeAddress(myAddress());

Builder.storeRef

solidity
extends fun storeRef(self: Builder, cell: Cell): Builder;

Builder 的扩展函数。

将一个引用 cell 存储到 Builder 的副本中。返回该副本。

由于单个 Cell 最多可存储 $4$ 个引用,尝试存储更多会抛出异常,错误代码为 exit code 8Cell 溢出

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Builder = b.storeRef(emptyCell());

Builder.refs

solidity
extends fun refs(self: Builder): Int;

Builder 的扩展函数。

返回 Builder 中已存储的 Cell 引用的数量,作为 Int

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Int = b.refs(); // 0

Builder.bits

solidity
extends fun bits(self: Builder): Int;

Builder 的扩展函数。

返回 Builder 中已存储的数据位的数量,作为 Int

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Int = b.bits(); // 0

Builder.asSlice

solidity
extends fun asSlice(self: Builder): Slice;

Builder 的扩展函数。

Builder 转换为 Slice 并返回。别名为 self.endCell().beginParse()

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Slice = b.asSlice();

Builder.asCell

solidity
extends fun asCell(self: Builder): Cell;

Builder 的扩展函数。

Builder 转换为 Cell 并返回。别名为 self.endCell()

使用示例:

solidity
let b: Builder = beginCell();
let fizz: Cell = b.asCell();

Cell.beginParse

solidity
extends fun beginParse(self: Cell): Slice;

Cell 的扩展函数。

打开 Cell 以进行解析,并将其作为 Slice 返回。

使用示例:

solidity
let c: Cell = emptyCell();
let fizz: Slice = c.beginParse();

Cell.hash

solidity
extends fun hash(self: Cell): Int;

Cell 的扩展函数。

计算并返回 Cell 的哈希值,作为 Int

使用示例:

solidity
let c: Cell = emptyCell();
let fizz: Int = c.hash();

Cell.asSlice

solidity
extends fun asSlice(self: Cell): Slice;

Cell 的扩展函数。

将 Cell 转换为 Slice 并返回。别名为 self.beginParse()

使用示例:

solidity
let c: Cell = emptyCell();
let fizz: Slice = c.asSlice();

Slice.loadUint

solidity
extends mutates fun loadUint(self: Slice, l: Int): Int;

Slice 的扩展变异函数。

Slice 加载并返回一个无符号的 lInt,$0 ≤$ l $≤ 256$。

尝试指定超出范围的 l 值会抛出异常,错误代码为 exit code 5整数超出预期范围

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeInt(42, 7).asSlice();
let fizz: Int = s.loadUint(7);

Slice.preloadUint

solidity
extends fun preloadUint(self: Slice, l: Int): Int;

Slice 的扩展函数。

Slice 预加载并返回一个无符号的 lInt,$0 ≤$ l $≤ 256$。不会修改 Slice

尝试指定超出范围的 l 值会抛出异常,错误代码为 exit code 5整数超出预期范围

尝试预加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeInt(42, 7).asSlice();
let fizz: Int = s.preloadUint(7);

Slice.loadInt

solidity
extends mutates fun loadInt(self: Slice, l: Int): Int;

Slice 的扩展变异函数。

Slice 加载并返回一个有符号的 lInt,$0 ≤$ l $≤ 257$。

尝试指定超出范围的 l 值会抛出异常,错误代码为 exit code 5整数超出预期范围

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeInt(42, 7).asSlice();
let fizz: Int = s.loadInt(7);

Slice.preloadInt

solidity
extends fun preloadInt(self: Slice, l: Int): Int;

Slice 的扩展函数。

Slice 预加载并返回一个有符号的 lInt,$0 ≤$ l $≤ 257$。不会修改 Slice

尝试指定超出范围的 l 值会抛出异常,错误代码为 exit code 5整数超出预期范围

尝试预加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeInt(42, 7).asSlice();
let fizz: Int = s.preloadInt(7);

Slice.loadBits

solidity
extends mutates fun loadBits(self: Slice, l: Int): Slice;

Slice 的扩展变异函数。

Slice 加载 $0 ≤$ l $≤ 1023$ 位,并将其作为单独的 Slice 返回。

尝试指定超出范围的 l 值会抛出异常,错误代码为 exit code 5整数超出预期范围

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeInt(42, 7).asSlice();
let fizz: Slice = s.loadBits(7);

Slice.preloadBits

solidity
extends fun preloadBits(self: Slice, l: Int): Slice;

Slice 的扩展函数。

Slice 预加载 $0 ≤$ l $≤ 1023$ 位,并将其作为单独的 Slice 返回。不会修改原始的 Slice

尝试指定超出范围的 l 值会抛出异常,错误代码为 exit code 5整数超出预期范围

尝试预加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeInt(42, 7).asSlice();
let fizz: Slice = s.preloadBits(7);

Slice.skipBits

solidity
extends mutates fun skipBits(self: Slice, l: Int);

Slice 的扩展变异函数。

Slice 加载所有但第一个 $0 ≤$ l $≤ 1023$ 位。

尝试指定超出范围的 l 值会抛出异常,错误代码为 exit code 5整数超出预期范围

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeInt(42, 7).asSlice();
s.skipBits(5);                   // 所有但前 5 位
let fizz: Slice = s.loadBits(1); // 仅加载 1 位

Slice.loadBool

solidity
extends mutates fun loadBool(self: Slice): Bool;

Slice 的扩展变异函数。

Slice 加载单个位并返回一个 Bool 值。如果加载的位等于 $1$,读取为 true,否则读取为 false

尝试在 Slice 不包含此 Bool 时加载会抛出异常,错误代码为 exit code 8Cell 溢出

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell 下溢

使用示例:

solidity
let s: Slice = beginCell().storeBool(true).asSlice();
let fizz: Bool = s.loadBool(); // true

Slice.loadCoins

solidity
extends mutates fun loadCoins(self: Slice): Int;

Slice 的扩展变异函数。

Slice 中加载并返回一个无符号的 Int 值,范围为 $0 .. 2^{120} - 1$,该值通常表示 nanoToncoins 的数量。

尝试在 Slice 中不存在此 Int 值时加载会抛出异常,错误代码为 exit code 8Cell overflow

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
let s: Slice = beginCell().storeCoins(42).asSlice();
let fizz: Int = s.loadCoins();

Slice.loadAddress

solidity
extends mutates fun loadAddress(self: Slice): Address;

Slice 的扩展变异函数。

Slice 中加载并返回一个 Address

尝试在 Slice 中不存在此 Address 时加载会抛出异常,错误代码为 exit code 8Cell overflow

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
let s: Slice = beginCell().storeAddress(myAddress()).asSlice();
let fizz: Address = s.loadAddress();

Slice.loadRef

solidity
extends mutates fun loadRef(self: Slice): Cell;

Slice 的扩展变异函数。

Slice 中加载下一个引用,并将其作为 Cell 返回。

尝试在 Slice 中不存在此引用 Cell 时加载会抛出异常,错误代码为 exit code 8Cell overflow

尝试加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
let s: Slice = beginCell().storeRef(emptyCell()).asSlice();
let fizz: Cell = s.loadRef();

let s: Slice = beginCell()
    .storeRef(emptyCell())
    .storeRef(emptyCell())
    .asSlice();
let ref1: Cell = s.loadRef();
let ref2: Cell = s.loadRef();

Slice.refs

solidity
extends fun refs(self: Slice): Int;

Slice 的扩展函数。

返回 Slice 中的引用数量,作为 Int

使用示例:

solidity
let s: Slice = beginCell().storeRef(emptyCell()).asSlice();
let fizz: Int = s.refs();

Slice.bits

solidity
extends fun bits(self: Slice): Int;

Slice 的扩展函数。

返回 Slice 中的数据位数量,作为 Int

使用示例:

solidity
let s: Slice = beginCell().storeRef(emptyCell()).asSlice();
let fizz: Int = s.bits();

Slice.empty

solidity
extends fun empty(self: Slice): Bool;

Slice 的扩展函数。

检查 Slice 是否为空(即不包含数据位和引用)。如果为空,返回 true,否则返回 false

使用示例:

solidity
let s: Slice = beginCell().storeRef(emptyCell()).asSlice();
let fizz: Bool = s.empty();                     // false
let buzz: Bool = beginCell().asSlice().empty(); // true

Slice.dataEmpty

solidity
extends fun dataEmpty(slice: Slice): Bool;

Slice 的扩展函数。

检查 Slice 是否没有数据位。如果没有数据,返回 true,否则返回 false

使用示例:

solidity
let s: Slice = beginCell().storeRef(emptyCell()).asSlice();
let fizz: Bool = s.dataEmpty();  // true

let s2: Slice = beginCell().storeInt(42, 7).asSlice();
let buzz: Bool = s2.dataEmpty(); // false

Slice.refsEmpty

solidity
extends fun refsEmpty(slice: Slice): Bool;

Slice 的扩展函数。

检查 Slice 是否没有引用。如果没有引用,返回 true,否则返回 false

使用示例:

solidity
let s: Slice = beginCell().storeRef(emptyCell()).asSlice();
let fizz: Bool = s.refsEmpty();                     // false
let buzz: Bool = beginCell().asSlice().refsEmpty(); // true

Slice.endParse

solidity
extends fun endParse(self: Slice);

Slice 的扩展函数。

检查 Slice 是否为空(即不包含数据位和引用)。如果不为空,则抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
let emptyOne: Slice = emptySlice();
emptyOne.endParse(); // nothing, as it's empty

let paul: Slice = "Fear is the mind-killer".asSlice();
try {
    paul.endParse(); // throws exit code 9
}

Slice.hash

solidity
extends fun hash(self: Slice): Int;

Slice 的扩展函数。

计算并返回 Slice 的哈希值,作为 Int

使用示例:

solidity
let s: Slice = beginCell().asSlice();
let fizz: Int = s.hash();

Slice.asCell

solidity
extends fun asCell(self: Slice): Cell;

Slice 的扩展函数。

Slice 转换为 Cell 并返回。别名为 beginCell().storeSlice(self).endCell()

使用示例:

solidity
let s: Slice = beginCell().asSlice();
let fizz: Cell = s.asCell();
let buzz: Cell = beginCell().storeSlice(s).endCell();

fizz == buzz; // true

Address.asSlice

solidity
extends fun asSlice(self: Address): Slice;

Address 的扩展函数。

Address 转换为 Slice 并返回。别名为 beginCell().storeAddress(self).asSlice()

使用示例:

solidity
let a: Address = myAddress();
let fizz: Slice = a.asSlice();
let buzz: Slice = beginCell().storeAddress(a).asSlice();

fizz == buzz; // true

Struct.toCell

solidity
extends fun toCell(self: Struct): Cell;

任意结构类型 Struct 的扩展函数。

Struct 转换为 Cell 并返回。

使用示例:

solidity
struct GuessCoin {
    probably: Int as coins;
    nothing: Int as coins;
}

fun coinCell(): Cell {
    let s: GuessCoin = GuessCoin{ probably: 42, nothing: 27 };
    let fizz: Cell = s.toCell();

    return fizz; // "x{12A11B}"
}

Struct.fromCell

solidity
extends fun fromCell(self: Struct, cell: Cell): Struct;

任意结构类型 Struct 的扩展函数。

Cell 转换为指定的 Struct 并返回该 Struct

尝试传递布局与指定 Struct 不同的 Cell 或加载超过 Cell 容量的数据会抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
struct GuessCoin {
    probably: Int as coins;
    nothing: Int as coins;
}

fun directParse(payload: Cell): GuessCoin {
    return GuessCoin.fromCell(payload);
}

fun cautiousParse(payload: Cell): GuessCoin? {
    let coin: GuessCoin? = null;
    try {
        coin = GuessCoin.fromCell(payload);
    } catch (e) {
        dump("Cell payload doesn't match GuessCoin Struct!");
    }
    return coin;
}

Struct.fromSlice

solidity
extends fun fromSlice(self: Struct, cell: Slice): Struct;

任意结构类型 Struct 的扩展函数。

Slice 转换为指定的 Struct 并返回该 Struct

尝试传递布局与指定 Struct 不同的 Slice 或加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
struct GuessCoin {
    probably: Int as coins;
    nothing: Int as coins;
}

fun directParse(payload: Slice): GuessCoin {
    return GuessCoin.fromSlice(payload);
}

fun cautiousParse(payload: Slice): GuessCoin? {
    let coin: GuessCoin? = null;
    try {
        coin = GuessCoin.fromSlice(payload);
    } catch (e) {
        dump("Slice payload doesn't match GuessCoin Struct!");
    }
    return coin;
}

Message.toCell

solidity
extends fun toCell(self: Message): Cell;

任意消息类型 Message 的扩展函数。

Message 转换为 Cell 并返回。

使用示例:

solidity
message GuessCoin {
    probably: Int as coins;
    nothing: Int as coins;
}

fun coinCell(): Cell {
    let s: GuessCoin = GuessCoin{ probably: 42, nothing: 27 };
    let fizz: Cell = s.toCell();

    return fizz; // "x{AB37107712A11B}"
}

Message.fromCell

solidity
extends fun fromCell(self: Message, cell: Cell): Message;

任意消息类型 Message 的扩展函数。

Cell 转换为指定的 Message 并返回该 Message

尝试传递布局与指定 Message 不同的 Cell 或加载超过 Cell 容量的数据会抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
message(0x777) TripleAxe {
    prize: Int as uint32;
}

fun directParse(payload: Cell): TripleAxe {
    return TripleAxe.fromCell(payload);
}

fun cautiousParse(payload: Cell): TripleAxe? {
    let coin: TripleAxe? = null;
    try {
        coin = TripleAxe.fromCell(payload);
    } catch (e) {
        dump("Cell payload doesn't match TripleAxe Message!");
    }
    return coin;
}

Message.fromSlice

solidity
extends fun fromSlice(self: Message, cell: Slice): Message;

任意消息类型 Message 的扩展函数。

Slice 转换为指定的 Message 并返回该 Message

尝试传递布局与指定 Message 不同的 Slice 或加载超过 Slice 容量的数据会抛出异常,错误代码为 exit code 9Cell underflow

使用示例:

solidity
message(0x777) TripleAxe {
    prize: Int as uint32;
}

fun directParse(payload: Slice): TripleAxe {
    return TripleAxe.fromSlice(payload);
}

fun cautiousParse(payload: Slice): TripleAxe? {
    let coin: TripleAxe? = null;
    try {
        coin = TripleAxe.fromSlice(payload);
    } catch (e) {
        dump("Slice payload doesn't match TripleAxe Message!");
    }
    return coin;
}

emptyCell

solidity
fun emptyCell(): Cell;

创建并返回一个空的 Cell(没有数据和引用)。别名为 beginCell().endCell()

使用示例:

solidity
let fizz: Cell = emptyCell();
let buzz: Cell = beginCell().endCell();

fizz == buzz; // true

emptySlice

solidity
fun emptySlice(): Slice;

创建并返回一个空的 Slice(没有数据和引用)。别名为 emptyCell().asSlice()

使用示例:

solidity
let fizz: Slice = emptySlice();
let buzz: Slice = emptyCell().asSlice();

fizz == buzz; // true