2024-04-12|閱讀時間 ‧ 約 26 分鐘

1.17 Storage, Memory, Calldata 同學通訊錄

    memory, calldata, storage

    memory, calldata, storage

    StorageMemoryCalldata是用於定義變量存儲位置的關鍵字,它們各自有不同的適用情境和用法。

    Storage

    Storage是用於存儲合約狀態變量的位置。這些變量存儲在區塊鏈上,並且在合約的生命週期內持續存在。Storage變量的變化會影響合約的狀態,並且會持久化存儲在區塊鏈上。當你需要修改合約的狀態或者存儲長期存在的數據時,應該使用Storage

    Memory

    Memory是用於存儲函數內部的臨時變量的位置。這些變量只在函數被調用時存在,並且在函數結束時被清除。Memory變量可以被修改,並且可以用於函數參數和函數內部的變量。當你需要在函數內部處理暫時數據,並且不需要將數據持久化存儲在區塊鏈上時,應該使用Memory

    Calldata

    Calldata是用於存儲外部函數參數的位置。這些參數是不可修改的,並且只在函數被調用時存在。Calldata變量不能被修改,並且在函數結束時不會被清除。當你需要在外部函數中處理不可修改的數據時,應該使用Calldata

    適用情境

    • Storage:適用於需要持久化存儲在區塊鏈上的數據,例如合約的狀態變量。
    • Memory:適用於函數內部的臨時數據處理,例如函數參數和函數內部的變量。
    • Calldata:適用於外部函數的不可修改參數,例如外部函數的參數。

    用法

    • Storage:在合約的狀態變量宣告時使用。
    • Memory:在函數內部變量宣告時使用。
    • Calldata:在外部函數參數宣告時使用。


    學校通訊錄合約 - 包含添加學生資訊、查詢學生資訊和更新學生資訊的功能。

    • addStudent函數使用calldata來接收參數,因為這些參數是從外部呼叫函數時傳遞的,並且不需要修改。
    • getStudent函數使用storage來存儲學生資訊,因為這些資訊需要永久存儲在區塊鏈上,並且可以被合約中的任何函數訪問和修改。
    • updateStudent函數使用memory來臨時存儲新的學生資訊,因為這些資訊只在函數執行期間需要,並且不需要永久存儲在區塊鏈上。
    • storage 允許學校管理員更新學生的聯繫方式, 且我們將使用storage來存儲學生的資訊。
    • updateStudentContact,該函數允許學校管理員更新學生的聯繫方式。這個函數使用storage來直接修改學生資訊,因為我們需要修改存儲在區塊鏈上的數據。這種方法避免了使用臨時變量(如memory)來複製數據,從而節省了gas成本並提高了效率。
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;

    contract SchoolDirectory {
    // 使用mapping來儲存學生資訊,鍵為學生ID,值為學生資訊
    mapping(uint => Student) public students;

    // 學生資訊結構
    struct Student {
    string name;
    uint age;
    string contact;
    }

    // 添加學生資訊的函數,使用calldata來接收參數
    function addStudent(uint id, string calldata name, uint age, string calldata contact) external {
    students[id] = Student(name, age, contact);
    }

    // 查詢學生資訊的函數,使用storage來存儲學生資訊
    function getStudent(uint id) external view returns (string memory name, uint age, string memory contact) {
    Student storage student = students[id];
    return (student.name, student.age, student.contact);
    }

    // 更新學生資訊的函數,使用memory來臨時存儲資訊
    function updateStudent(uint id, string calldata name, uint age, string calldata contact) external {
    Student memory newStudent = Student(name, age, contact);
    students[id] = newStudent;
    }

    // 更新學生聯繫方式的函數,使用storage來存儲學生資訊
    function updateStudentContact(uint id, string calldata newContact) external {
    // 使用storage關鍵字來直接修改學生資訊
    students[id].contact = newContact;
    }
    }
    分享至
    成為作者繼續創作的動力吧!
    © 2024 vocus All rights reserved.