Builders and Slices
In TVM, the Cell type contains only metadata of the cell: level, hashes, and depths. To read actual data, TVM need to load cell from celldb, key-value storage of the node, which stores cells by their representation hashes. CTOS instruction loads a cell by its metadata from Cell type, and provides a Slice, a read-only wrapper for the cell's content. To simplify coding cell deserializers in smart contracts, instead of behaving like a simple bit/ref array, Slice is a "read cursor": it allows loading a piece of data from the beginning of the slice, returning that data and the slice that contains remaining data. On the other hand, there is a Builder type, which provides a convenient way to serialize data to a cell. Only the Cell type can be used outside of TVM: in output actions and in persistent storage.
Builder
Builder provides a way to construct a cell from a sequence of values of the following TVM types: integers, cells (as references), slices, and builders. Tuples, continuations, and null are not serializable.
For example, serialize the following numbers to a cell:
1 (uint4)
2 (uint4)
-1 (int8)First, create an empty builder using NEWC:
NEWC // returns empty builder x{}Then, put a number on the stack:
1 INT // stack: x{} 1And call STU ("STore Unsigned integer") to store integer into builder (swapping builder and value to meet STU input order):
SWAP // stack: 1 x{}
4 STU // stack: x{0001}Then, store the other two numbers:
2 INT // x{0001} 2
SWAP // 2 x{0001}
4 STU // x{00010010}
-1 INT // x{00010010} -1
SWAP // -1 x{00010010}
8 STI // x{0001001011111111}And, finally, ENDC instruction finalizes the builder to a cell.
Slice
Slice allows reading data back from a cell, field by field. For example, deserialize bitstring x{0001001011111111} created above.
CTOS ("Cell TO Slice") loads a Cell to a Slice.
// assume a cell with bitstring x{0001001011111111} is on the stack
CTOS // x{0001001011111111}Then, call LDU ("LoaD Unsigned integer") to read first value (uint4).
4 LDU // 1 x{001011111111}LDU takes the first 4 bits from a slice and creates a new slice without these 4 bits: x{0001|001011111111} slices into a number 0001 and a slice x{001011111111}.
Similarly, read another two numbers:
4 LDU // 1 2 x{11111111}
8 LDI // 1 2 -1 x{}A common way to ensure there is no data left inside the slice is to call ENDS.
Last updated on