solidityでメモリを動的に割り当てる方法
場合によってはsolidityでbufferを構築したい場合があります.まず、このbufferにメモリを割り当てる必要があります.solidityではbytesのような構造しか使われていませんが、現在は対応する位置のデータをスライスしたり置換したりする操作はbytesでは容易ではありません.まずbufferにメモリを割り当てることです.直接コード:
まず、その内容bufと総容量capacityを含む構造体bufferを定義し、initメソッドを定義する(bufferは転送され、resizeにも使用できる).以太坊保は0 x 40アドレスに次の利用可能なポインタ(free pointer)を保存した.
注意関数の最初のパラメータ
利用可能なポインタのアドレスをbufのアドレスに置き換えた
ptrアドレスの指向するデータを0にする、つまりbufを0に初期化する.EVMは0 x 40アドレスのポインタが全0データを指すことを保証しないからだ.
この行の役割は、0 x 40のアドレスを更新し、次の使用可能なポインタを指すことです.EVMでは0 x 40の更新は処理されず、ユーザは自分で処理しなければならない.0 x 40の値をどのように更新しますか?開発したばかりのbufferをスキップして、次のアドレスを0 x 40に割り当てることができます.開いたばかりのスペースはcapacityサイズで、さらに上位32ビット(0 x 20)はデータの長さなので、0 x 40はptrに基づいてcapacity+32をオフセットします
struct buffer {
bytes buf;
uint capacity;
}
function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
if (capacity % 32 != 0) {
capacity += 32 - (capacity % 32);
}
// Allocate space for the buffer data
buf.capacity = capacity;
assembly {
let ptr := mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
mstore(0x40, add(32, add(ptr, capacity)))
}
return buf;
}
まず、その内容bufと総容量capacityを含む構造体bufferを定義し、initメソッドを定義する(bufferは転送され、resizeにも使用できる).以太坊保は0 x 40アドレスに次の利用可能なポインタ(free pointer)を保存した.
let ptr := mlod(0x40)
注意関数の最初のパラメータ
buffer memory buf
には、memoryキーワードがあり、bufもメモリ内にあることを示し、bufはポインタの別名であり、その値はbufオブジェクトが格納しているアドレスである.mstore(buf, ptr)
利用可能なポインタのアドレスをbufのアドレスに置き換えた
mstore(ptr ,0)
ptrアドレスの指向するデータを0にする、つまりbufを0に初期化する.EVMは0 x 40アドレスのポインタが全0データを指すことを保証しないからだ.
mstore(0x40, add(32, add(ptr, capacity)))
この行の役割は、0 x 40のアドレスを更新し、次の使用可能なポインタを指すことです.EVMでは0 x 40の更新は処理されず、ユーザは自分で処理しなければならない.0 x 40の値をどのように更新しますか?開発したばかりのbufferをスキップして、次のアドレスを0 x 40に割り当てることができます.開いたばかりのスペースはcapacityサイズで、さらに上位32ビット(0 x 20)はデータの長さなので、0 x 40はptrに基づいてcapacity+32をオフセットします