我不确定这是一般的比特操纵相关问题还是以太坊特有的问题。但是我正在阅读以太坊规范的一部分,我对比特相关的操作感到困惑。
例如,在Example部分中,69
的uint32值被填充为32
字节,变为0x0000000000000000000000000000000000000000000000000000000000000045
。
这个我明白。将69
转为十六进制,即45
,然后用30个零填充。
但是值"abc">左对齐后变为0x6162630000000000000000000000000000000000000000000000000000000000
现在我很困惑。
为什么这里的0要加到右边?我知道0x616263来自哪里,这是"abc"的十六进制表示。但是当填充上面的69
的十六进制表示时,零被添加在左边,但是带有"abc"0被加到右边。为什么会这样呢?
都是大端序。在EVM中,内存是在32字节块/缓冲区中处理的。因此,即使您的数据类型是uint8
或uint32
,它仍然被管理为uint256
值(占用32字节)。
0x0000000000000000000000000000000000000000000000000000000000000045 == 69n
0x4500000000000000000000000000000000000000000000000000000000000000 == 31209586552245380797759367053122912663576675554410933276260051939632835723264n
这是整数的存储方式,即使是字节中的位也被锚定在右边:
00000011 === 3
Strings
是简单的内存缓冲区,从左到右。有一些与evm相关的事情需要记住——与所有事情一样,strings
也被保存到32字节块中。因此,如果字符串长度只有5个字节长,那么之后得到0。如果长度更大,那么在第一个块中,您将获得字符串值的长度(也右锚定,因为长度是uint256
),之后的块保存实际的字符串数据。
Big-/little-endian不仅仅是关于数据的锚点,而是关于字节顺序:
// 0x3045
// big-endian byte order
30 45
// little endian byte order
45 30