use*_*646 3 ethereum solidity smartcontracts evm
我正在学习 Solidity Assembly,但我对某些事情感到困惑。我正在查看这个名为 Seriality 的库。具体来说,这个函数:https : //github.com/pouladzade/Seriality/blob/master/src/TypesToBytes.sol#L21
function bytes32ToBytes(uint _offst, bytes32 _input, bytes memory _output) internal pure {
assembly {
mstore(add(_output, _offst), _input)
mstore(add(add(_output, _offst),32), add(_input,32))
}
}
Run Code Online (Sandbox Code Playgroud)
该函数 bytes32ToBytes 接受一个 bytes32 变量并将其存储在动态大小的字节数组中,从传入的偏移量开始。
让我困惑的是它使用了 mstore 函数两次。但是mstore函数存储了一个词,是32个字节,对吧?既然输入是 32 个字节,那么为什么它会被调用两次呢?不会调用它两次存储 2 个字,即 64 个字节?
谢谢!
Solidity 数组的存储方式是将数组的大小写入第一个存储槽,然后将数据写入后续槽。
知道mstore有如下参数:mstore(START_LOCATION, ITEM_TO_STORE),第一个mstore语句写成如下:
mstore(add(_output, _offst), _input)
Run Code Online (Sandbox Code Playgroud)
由于数组的第一个槽指向数组的大小,因此该语句是设置 的大小_output。通过将其替换为mstore(add(_output, _offst), 32)(因为大小_input是静态的),您应该能够获得相同的结果。
第二个语句 ( mstore(add(add(_output, _offst),32), add(_input,32))) 是写入数据本身的语句。在这里,我们将两个指针的位置移动了 32 个字节(因为两个数组的前 32 个字节都指向大小)并将 的值存储_input到存储数据的位置_output。
机会是,_output已经将调用此方法(这样的长度就已经被设置)之前进行初始化,因此它通常是不必要的。但是,它不痛。请注意,做出此假设的类似实现如下所示:
function test() public pure returns (bytes) {
bytes32 i = "some message";
bytes memory o = new bytes(32); // Initializing this way sets the length to the location "o" points to. This replaces mstore(add(_output, _offst), _input).
bytes32ToBytes(0, i, o);
return o;
}
function bytes32ToBytes(uint _offst, bytes32 _input, bytes memory _output) internal pure {
assembly {
mstore(add(add(_output, _offst),32), add(_input,32))
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
723 次 |
| 最近记录: |