智能合約開發
結構體
結構體把數個相關變數綁成一筆有名字的紀錄——想像表格中的一列,例如把一個 Position 的擁有者地址、存入金額與到期時間組合在一起。定義結構體讓你得到一個自訂的複合型別,可以儲存、傳遞,並放進陣列與映射裡,而不必同時擺弄一堆平行的零散變數。
在儲存中,結構體的欄位按宣告順序排列,而 EVM 會盡量把小欄位打包在一起:若數個值能連續地塞進一個 32 位元組的槽(例如一個 uint128、一個 uint64 與一個 bool),它們就共用同一個槽;而會超出當前槽的欄位則另起新槽。把小欄位重新排列、讓它們相鄰,是經典的 gas 最佳化,因為每寫入一個儲存槽就要付一次 SSTORE。動態成員(結構體內的映射或動態大小陣列)各自佔用一個槽,指向由雜湊推導出的位置。
在語言的其餘部分,結構體的行為取決於它所在的資料位置:把儲存結構體複製到記憶體會複製每一個欄位(耗 gas),而把記憶體結構體傳給內部函數則是傳參考。只有當結構體位於儲存時,映射才可作為其成員。在 ABI 上,結構體被編碼為元組(tuple),所以外部呼叫者看到的是依序排列的欄位,而非它的名稱。
struct Packed { // 1 slot: 128 + 64 + 8 bits all fit in 256
uint128 a;
uint64 b;
bool c;
}
struct Loose { // 3 slots: the uint256 splits the small fields
uint128 a;
uint256 big;
uint128 d;
}相同資料、兩種排列、差異極大的儲存成本。
欄位順序影響的是成本而非正確性:把小型別相鄰宣告,可把三個儲存槽壓成一個,把寫入從三次 SSTORE 降為一次。
另見