阅读(4683)
赞(10)
结构体
2022-05-12 09:45:28 更新
Solidity 提供了一种以结构的形式定义新类型的方法,如下例所示:
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.0 <0.9.0; // Defines a new type with two fields. // Declaring a struct outside of a contract allows // it to be shared by multiple contracts. // Here, this is not really needed. struct Funder { address addr; uint amount; } contract CrowdFunding { // Structs can also be defined inside contracts, which makes them // visible only there and in derived contracts. struct Campaign { address payable beneficiary; uint fundingGoal; uint numFunders; uint amount; mapping (uint => Funder) funders; } uint numCampaigns; mapping (uint => Campaign) campaigns; function newCampaign(address payable beneficiary, uint goal) public returns (uint campaignID) { campaignID = numCampaigns++; // campaignID is return variable // We cannot use "campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0)" // because the right hand side creates a memory-struct "Campaign" that contains a mapping. Campaign storage c = campaigns[campaignID]; c.beneficiary = beneficiary; c.fundingGoal = goal; } function contribute(uint campaignID) public payable { Campaign storage c = campaigns[campaignID]; // Creates a new temporary memory struct, initialised with the given values // and copies it over to storage. // Note that you can also use Funder(msg.sender, msg.value) to initialise. c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value}); c.amount += msg.value; } function checkGoalReached(uint campaignID) public returns (bool reached) { Campaign storage c = campaigns[campaignID]; if (c.amount < c.fundingGoal) return false; uint amount = c.amount; c.amount = 0; c.beneficiary.transfer(amount); return true; } }
该合约不提供众筹合约的全部功能,但它包含理解结构所需的基本概念。结构类型可以在映射和数组中使用,它们本身可以包含映射和数组。
结构不可能包含自己类型的成员,尽管结构本身可以是映射成员的值类型,也可以包含其类型的动态大小的数组。这个限制是必要的,因为结构的大小必须是有限的。
请注意,在所有函数中,结构类型如何分配给具有数据位置的局部变量storage。这不会复制结构,而只会存储一个引用,以便对局部变量成员的赋值实际上写入状态。
当然,您也可以直接访问该结构的成员,而无需将其分配给局部变量,如 .campaigns[campaignID].amount = 0
笔记
在 Solidity 0.7.0 之前,允许包含仅存储类型(例如映射)成员的内存结构,并且像 上面示例中的分配将起作用并且只是默默地跳过这些成员。campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0)
← 数组切片