データ位置


動的なデータ型を宣言するとき、それらを格納する場所を指定する必要があります.動的データ型はarrays , strings , struct などの3つの場所のいずれかstorage , memory and calldata は通常指定される.
使用storage 場所として、データがブロックに格納されている間、メモリはデータが保存されていることを意味しますmemory と宣言された関数が実行を終えた後に消去されます.他の場所calldata 関数への入力パラメータとして渡される格納変数に使用されます.
 //SPDX-License-Identifier: Unlicense
pragma solidity >=0.7.0 <0.9.0;

contract StorageLocation {
    Person[] public persons;

    struct Person {
        string name;
        uint age;
        address personAddress;
    }

    constructor() {
       Person memory newperson = Person({
           name: "Jamie",
           age: 33,
           personAddress: msg.sender
       });

       Person memory personTwo = Person({
           name: "Bones Man",
           age: 33,
           personAddress: msg.sender
       });
       persons.push(newperson);
       persons.push(personTwo);
    }

    function loadPerson() public view returns ( Person[] memory ){
        return persons;
    }

    function changeDataone() public view {
        Person memory person = persons[0];
        person.age = 56;
    }

    function changeDataTwo() public {
        Person storage person = persons[0];
        person.age = 76;
    }

    function receiveAsCallData(uint256[] calldata a) public {
        //you can not modify a
    }
}
上記のスマート契約は、単純なスマート契約です.スマート契約の最上位で、我々は1の配列を定義しましたPerson これはユーザ定義のstructです.の配列Person 変数に格納されますpersons . The persons 変数は状態変数であるので、ブロックチェーンに格納されますstorage .
コンストラクタ関数を見て、2つあることがわかりますPerson 作成した型をPerson[] 配列persons . The newperson コンストラクタ内部の変数はメモリに保存され、コンストラクタ関数が実行された後に破棄されます.newperson structを作成した後、persons 永久記憶のための配列.一時的なnewperson コンストラクタ関数が実行を終了した後、メモリ内の変数は破棄されます.
両方ともよく見てくださいchangeDataone 関数とchangeDataTwo .あなたはそれに気づくでしょうchangeDataone 関数は、personという変数を作成し、メモリに保存します.Person memory person = persons[0];
Doing it this way reads the data of the
人物array at index of 0and stores it in a person variable in memory. Attempting to change 人.年齢to 56 will not be successful because we are not referencing the storage location of 人物. At the termination of the function the メモリのデータが消去されているので、記憶変数は同じままです.
動的データ型で変更を継続するには、その変数の格納場所を参照する必要があります.機能changeDataTwo そうする.試してみるRemix
契約が展開されるとき、2Person 構造体はpersons 実行して表示できるコンストラクタを経由した配列loadPerson . 関数を実行するchangeDataone そして、もし最初ならPerson structは説明通り変更されました.次に、関数changeDataTwo そして、あなたはpersons 変数が更新されました.
第三の場所calldata は入力パラメータを関数に渡すために使われる.変数の格納calldata 変数が変更できないことを意味します.使用calldata ガスを節約する可能性があるEVM 使用したときに保存されたデータをコピーしませんmemory 場所として.

概要


使用するmemory 場所を変更せずに状態に格納されている動的なデータを読み取るか、動的なデータ型の一時的なストアが必要です.
使用するstorage 変更の目的のために状態に格納された動的データへの参照を望む場合.
関数に入力として渡された動的データ型の値を変更しない場合は、calldata . 使用calldata ガスを節約するのに役立つEVM はデータのコピーを行わない.