跳到主要内容

cell与cell包 (BoC)

cell

cell是TON区块链上的一种数据结构。cell能够存储多达1023位,并且可以拥有最多4个对其他cell的引用。



cell包

cell包 (BoC) 是一种将cell序列化为字节数组的格式,这一格式在 TL-B schema 中有进一步描述。



在TON上,所有东西都由cell构成,包括合约代码、存储的数据、区块等,实现了过程中的流线型和强大的灵活性。



cell序列化

让我们分析我们的第一个cell包示例:



1[8_] -> {
24[0AAAAA],
7[FE] -> {
24[0AAAAA]
}
}

在此示例中,我们有一个1位大小的根cell,它有2个链接:第一个指向一个24位cell,第二个指向一个7位cell,后者又有一个链接指向一个24位cell。

为了使此框架按预期工作,需要将cell转换为单一的字节序列。为此,首先,我们只利用唯一的cell类型,下面3个中的2个如下所示:

1[8_]
24[0AAAAA]
7[FE]
备注

为了只留下唯一的cell,需要进行比较。为此,我们需要比较cell的哈希

1[8_]      -> index 0 (root cell)
7[FE] -> index 1
24[0AAAAA] -> index 2

现在,让我们计算上述3个cell的描述。这些描述由2个字节组成,存储了有关数据长度和数据链接数量的标志信息。

第一个字节 - 引用描述符 - 计算为 r+8s+32l,其中 0 ≤ r ≤ 4 是cell引用(链接)的数量,0 ≤ s ≤ 1 对于异类cell为1,对于普通cell为0,0 ≤ l ≤ 3 是cell的层级

第二个字节 - 位描述符 - 等于 floor(b / 8) + ceil (b / 8),其中 0 <= b <= 1023 是cell中的位数。这个描述符代表cell数据的完整4位组的长度(但如果不为空至少为1)。

结果是:

1[8_]      -> 0201 -> 2 refs, length 1
7[FE] -> 0101 -> 1 ref, length 1
24[0AAAAA] -> 0006 -> 0 refs, length 6

对于不完整的4位组的数据,在序列的末尾添加1位。这意味着它表示组的结束位,并用于确定不完整组的真实大小。让我们添加以下位:

1[8_]      -> C0     -> 0b10000000->0b11000000
7[FE] -> FF -> 0b11111110->0b11111111
24[0AAAAA] -> 0AAAAA -> do not change (full groups)

现在让我们添加引用索引:

0 1[8_]      -> 0201 -> refers to 2 cells with such indexes
1 7[FE] -> 02 -> refers to cells with index 2
2 24[0AAAAA] -> no refs

并将其全部组合在一起:

0201 C0     0201  
0101 FF 02
0006 0AAAAA

并通过将相应的字符串连接成一个单一的字节数组来拼接它们: 0201c002010101ff0200060aaaaa,大小14字节。

显示示例
func (c *Cell) descriptors() []byte {
ceilBytes := c.bitsSz / 8
if c.bitsSz%8 ! = 0 {
ceilBytes++
}

// calc size
ln := ceilBytes + c.bitsSz / 8

specBit := byte(0)
if c.special {
specBit = 8
}

return []byte{byte(len(c.refs)) + specBit + c.level*32, byte(ln)}
}

来源

打包cell包

让我们打包上一节直接提到的cell。我们已经将其序列化为一个扁平的14字节数组。

因此,我们根据其架构构建header。

b5ee9c72                      -> id tl-b of the BoC structure
01 -> flags and size:(## 3), in our case the flags are all 0,
and the number of bytes needed to store the number of cells is 1.
we get - 0b0_0_0_00_001
01 -> number of bytes to store the size of the serialized cells
03 -> number of cells, 1 byte (defined by 3 bits size:(## 3), equal to 3.
01 -> number of root cells - 1
00 -> absent, always 0 (in current implementations)
0e -> size of serialized cells, 1 byte (size defined above), equal to 14
00 -> root cell index, size 1 (determined by 3 size:(## 3) bits from header),
always 0
0201c002010101ff0200060aaaaa -> serialized cells

接下来,我们将上述所有内容连接成一个字节数组,得到我们最终的BoC: b5ee9c7201010301000e000201c002010101ff0200060aaaaa

cell包实现示例:序列化反序列化

特殊cell

通常,TON上运行的cell分为两大类:普通cell和特殊cell。用户处理的大多数cell是普通cell,负责携带信息。

然而,为了实现网络的内部功能,有时需要特殊cell,并且它们用于多种目的,这取决于它们的子类型。

cell层级

每个cell都有一个称为Level的属性,它由0到3的整数表示。

普通cell层级

普通cell的层级始终等于其所有引用的层级的最大值:

Lvl(c) = max(Lvl(r_0), ..., Lvl(r_i), ..., Lvl(r_e))

其中ic的引用索引,ec的引用数量。

没有引用的普通cell层级为零

特殊cell层级

特殊cell对其层级的设置有不同的规则,这些规则在此文中有描述。

cell哈希

在大多数情况下,用户使用的是层级为0的普通cell,它们只有一个哈希,称为 representation hash(或 hash infinity)。

层级为Lvl(c) = l的cellc,其中1 ≤ l ≤ 3,除了 representation hash 外,还有l"更高"的哈希。

标准cell representation hash 计算

首先,我们需要计算cell表示(类似于上面描述的cell序列化)

  1. 计算描述符字节
  2. 添加序列化cell数据
  3. 对于每个cell的引用,添加其深度
  4. 对于每个cell的引用,添加其 representation hash
  5. 计算结果的SHA256哈希

让我们分析以下示例:

无引用的cell

32[0000000F]
  1. 描述符计算

引用描述符等于 r+8s+32l = 0 + 0 + 0 = 0 = 00

位描述符等于 floor(b / 8) + ceil (b / 8) = 8 = 08

连接这些字节,我们得到 0008

  1. cell数据序列化

在这种情况下,我们有完整的4位组,所以我们不必向cell数据添加任何位。结果是 0000000f

  1. 引用深度

我们跳过这部分,因为我们的cell没有任何引用

  1. 引用哈希

我们跳过这部分,因为我们的cell没有任何引用

  1. SHA256计算

连接前面步骤的字节,我们得到 00080000000f,其SHA256为 57b520dbcb9d135863fc33963cde9f6db2ded1430d88056810a2c9434a3860f9 - 这就是cell representation hash 。

带有引用的cell

24[00000B] -> {
32[0000000F],
32[0000000F]
}
  1. 描述符计算

引用描述符等于 r+8s+32l = 2 + 0 + 0 = 0 = 02

位描述符等于 floor(b / 8) + ceil (b / 8) = 6 = 06

连接这些字节,我们得到 0206

  1. cell数据序列化

在这种情况下,我们有完整的4位组,所以我们不必向cell数据添加任何位。结果是 00000b

  1. 引用深度

深度由2个字节表示。我们的cell有2个引用,每个的深度都是零,所以这一步的结果是 00000000

  1. 引用哈希

对于每个引用,我们添加其哈希(我们上面计算过),所以结果是 `57b520dbcb9d135863fc33963cde9f6db2ded1430d88056810a2c9434a3860f957b520dbcb9d135863fc33963cde9f6db2ded1430d88056810a2c9434a3860f9

  1. SHA256计算

连接前面步骤的字节,我们得到 020600000b0000000057b520dbcb9d135863fc33963cde9f6db2ded1430d88056810a2c9434a3860f957b520dbcb9d135863fc33963cde9f6db2ded1430d88056810a2c9434a3860f9 ,其SHA256为 f345277cc6cfa747f001367e1e873dcfa8a936b8492431248b7a3eeafa8030e7 - 这就是cell representation hash

更高哈希的计算

普通cellc的更高哈希与其 representation hash 的计算类似,但使用其引用的更高哈希而不是它们的 representation hash。

特殊cell有其自己的计算更高哈希的规则,这些规则在此文中有描述。

参阅