Массивы солидности сохраняются путем записи размера массива в первый слот хранения, а затем записи данных в последующие слоты. Итак, разбив 2 утверждения:
mstore(add(_output, _offst), _input)
Поскольку первый слот массива указывает на размер массива, этот оператор устанавливает размер _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))
}
}