1. ホーム
  2. memory

[解決済み] Ethereum Solidityで、"memory "というキーワードは何のためにあるのですか?

2023-01-12 22:38:58

質問

コントラクトのサンプルを見ていると、メソッド内で配列が"memory"で宣言されている場合とされていない場合があります。この違いは何ですか?

どのように解決するのですか?

を使用せずに メモリ キーワードがない場合、Solidity は変数の宣言を ストレージ .

Solidityのリード開発者であるchrisethは、「ストレージは、仮想構造を持つ大きな配列と考えることができます...この構造は、実行時に変更することはできません。

つまり、ストレージの構造はコントラクトレベルの変数宣言に基づいてコントラクト作成時に決定され、将来のメソッド呼び出しによって変更されることはありません。しかし -- そのストレージの内容は sendTransaction 呼び出しによって変更することができます。このような呼び出しは「状態」を変更するので、コントラクトレベルの変数が「状態変数」と呼ばれる所以です。つまり、コントラクトレベルで宣言された変数 uint8 storagevar; は、uint8 (0-255) の任意の有効な値に変更できますが、uint8型の値のための「スロット」は常に存在することになります。

関数内で変数を宣言する際に メモリ キーワードを使わずに変数を宣言した場合、solidity は記憶構造を使おうとします。これは現在コンパイル可能ですが、予期せぬ結果をもたらす可能性があります。 メモリ は、メソッド実行時に変数のための空間のチャンクを作成し、そのメソッドで将来使用するためにそのサイズと構造を保証するようにsolidityに指示します。

メモリ はコントラクトレベルで使用することはできません。メソッド内のみです。

を参照してください。 のエントリ "メモリキーワードとは何ですか?それは何をするのか?"。 をご覧ください。ここにそれを引用します。

Ethereum Virtual Machineには、アイテムを格納できる3つの領域があります。

1つ目は「ストレージ」で、すべてのコントラクトの状態変数が存在する場所です。すべてのコントラクトは独自のストレージを持ち、それは関数呼び出しの間で永続的であり、使用するのはかなり高価です。

2つ目は "メモリ "で、これは一時的な値を保持するために使用されます。これは(外部)関数呼び出しの間に消去され、使用料が安くなります。

3つ目は「スタック」で、これは小さなローカル変数を保持するために使用されます。ほとんど無料で使用できますが、限られた量の値しか保持できません。

ほとんどすべての型について、使用するたびにコピーされるため、格納する場所を指定することはできません。

いわゆる格納場所が重要な型は、構造体と配列です。例えば関数呼び出しでこのような変数を渡す場合、そのデータはメモリ内に留まるか、ストレージ内に留まることができれば、コピーされることはありません。つまり、呼び出された関数内でその内容を変更することができ、その変更は呼び出し側でまだ見ることができます。

どのタイプの変数に関係するかによって、保存場所のデフォルトがあります。

  • ステート変数は常にストレージに格納されます
  • 関数の引数は常にメモリ上にある
  • 構造体、配列、マッピング型のローカル変数は、デフォルトでストレージを参照します。
  • 値型のローカル変数(つまり、配列でも構造体でもマッピングでもない)はスタックに格納されます。