1.17 Storage, Memory, Calldata 同學通訊錄

閱讀時間約 5 分鐘
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;
}
}
    尋大神腳印, 亦步亦趨。
    留言0
    查看全部
    發表第一個留言支持創作者!
    從 Google News 追蹤更多 vocus 的最新精選內容