結(jié)構(gòu)體

2022-05-12 17:01 更新

Solidity 提供了一種以結(jié)構(gòu)的形式定義新類型的方法,如下例所示:

// 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;
    }
}

該合約不提供眾籌合約的全部功能,但它包含理解結(jié)構(gòu)所需的基本概念。結(jié)構(gòu)類型可以在映射和數(shù)組中使用,它們本身可以包含映射和數(shù)組。

結(jié)構(gòu)不可能包含自己類型的成員,盡管結(jié)構(gòu)本身可以是映射成員的值類型,也可以包含其類型的動態(tài)大小的數(shù)組。這個限制是必要的,因為結(jié)構(gòu)的大小必須是有限的。

請注意,在所有函數(shù)中,結(jié)構(gòu)類型如何分配給具有數(shù)據(jù)位置的局部變量storage。這不會復(fù)制結(jié)構(gòu),而只會存儲一個引用,以便對局部變量成員的賦值實際上寫入狀態(tài)。

當(dāng)然,您也可以直接訪問該結(jié)構(gòu)的成員,而無需將其分配給局部變量,如 .campaigns[campaignID].amount = 0

筆記

在 Solidity 0.7.0 之前,允許包含僅存儲類型(例如映射)成員的內(nèi)存結(jié)構(gòu),并且像 上面示例中的分配將起作用并且只是默默地跳過這些成員。campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0)


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號