アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

Solidityのstorage,memoryキーワードとは何か?

Solidityのlibraryのメソッドはだいたいこんな形の定義になる。

function (StructHoge storage self, uint _val) {

最初の引数にstorageキーワードをつけないとコンパイルエラーになっちゃうから必須のキーワードのようだ。
で、このstorageが何のために必要なのかよくわからなかったので調べてみたら公式ドキュメントに詳しく記載があった。

Frequently Asked Questions — Solidity 0.4.19 documentation


これ自体はmemoryについての説明ではあるけどここで、比較としてstorageについても出てくる。
ドキュメントの内容をまとめると

  • storage: このキーワードをつけた変数はContractのストレージ上のアドレス(つまりポインタ)として扱われる。基本的に関数の中で参照型(配列や文字列やStruct)の変数を定義した場合、デフォルトではstorageとみなされる。関数内のみで使用する新たな参照型の領域を確保したい場合はmemory宣言が必要
  • memory: このキーワードをつけた変数はメモリ上に新たな領域が確保される。基本的に関数の引数に参照型を定義した場合はデフォルトではmemoryとなりその変数データはメモリ上から読み込まれる。storageを宣言した場合は、ストレージ上のアドレスをさすものとして扱われ、ストレージ上のデータを参照する

な感じかな。つまりlibraryのfunctionで宣言している第1引数は呼び出し元のContractのストレージ上のデータを直接操作しているってことになる。
公式ドキュメントのmemory宣言をせずにuint[]を定義したContractを実際に作ってみて動かすとなかなかに面白い動きをしてた。

基本的にメソッド引数のstoragememoryキーワードはコンパイラが縛っているのでlibraryとcontractでつけ間違えることはないんだけど、関数内の参照型変数についてはwarningしか出ないし場合によっては実行後の結果が上手くかみ合う場合もあるので注意が必要かも。