智能合約語言 Solidity 教程系列6 - 結構體與映射

本文首發於深刻淺出區塊鏈社區 原文連接:智能合約語言 Solidity 教程系列6 - 結構體與映射原文已更新,請讀者前往原文閱讀html

Solidity 教程系列第6篇 - Solidity 結構體與映射。 Solidity 系列完整的文章列表請查看分類-Soliditygit

寫在前面

Solidity 是以太坊智能合約編程語言,閱讀本文前,你應該對以太坊、智能合約有所瞭解, 若是你還不瞭解,建議你先看以太坊是什麼github

本系列文章一部分是參考Solidity官方文檔(當前最新版本:0.4.20)進行翻譯,另外一部分是Solidity深刻分析,這部分請訂閱區塊鏈技術專欄閱讀。編程

結構體(Structs)

Solidity提供struct來定義自定義類型,自定義的類型是引用類型。 咱們看看下面的例子:數組

pragma solidity ^0.4.11;

contract CrowdFunding {
    // 定義一個包含兩個成員的新類型
    struct Funder {
        address addr;
        uint amount;
    }

    struct Campaign {
        address beneficiary;
        uint fundingGoal;
        uint numFunders;
        uint amount;
        mapping (uint => Funder) funders;
    }

    uint numCampaigns;
    mapping (uint => Campaign) campaigns;

    function newCampaign(address beneficiary, uint goal) public returns (uint campaignID) {
        campaignID = numCampaigns++; // campaignID 做爲一個變量返回
        // 建立一個結構體實例,存儲在storage ,放入mapping裏
        campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
    }

    function contribute(uint campaignID) public payable {
        Campaign storage c = campaigns[campaignID];
        // 用mapping對應項建立一個結構體引用
        // 也能夠用 Funder(msg.sender, msg.value) 來初始化.
        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;
    }
}

上面是一個簡化版的衆籌合約,但它可讓咱們理解structs的基礎概念,struct能夠用於映射和數組中做爲元素。其自己也能夠包含映射和數組等類型。數據結構

不能聲明一個struct同時將自身struct做爲成員,這個限制是基於結構體的大小必須是有限的。 但struct能夠做爲mapping的值類型成員。app

注意在函數中,將一個struct賦值給一個局部變量(默認是storage類型),實際是拷貝的引用,因此修改局部變量值的同時,會影響到原變量。編程語言

固然,也能夠直接經過訪問成員修改值,而不用必定賦值給一個局部變量,如campaigns[campaignID].amount = 0函數

映射(Mappings)

映射類型,一種鍵值對的映射關係存儲結構。定義方式爲mapping(_KeyType => _KeyValue)。鍵類型容許除映射、變長數組、合約、枚舉、結構體外的幾乎全部類型()。值類型沒有任何限制,能夠爲任何類型包括映射類型。學習

映射能夠被視做爲一個哈希表,全部可能的鍵會被虛擬化的建立,映射到一個類型的默認值(二進制的全零表示)。在映射表中,並不存儲鍵的數據,僅僅存儲它的keccak256哈希值,這個哈希值在查找值時須要用到。 正由於此,映射是沒有長度的,也沒有鍵集合或值集合的概念。

映射類型,僅能用來做爲狀態變量,或在內部函數中做爲storage類型的引用。

能夠經過將映射標記爲public,來讓Solidity建立一個訪問器。經過提供一個鍵值作爲參數來訪問它,將返回對應的值。 映射的值類型也能夠是映射,使用訪問器訪問時,要提供這個映射值所對應的鍵,不斷重複這個過程。 來看一個例子:

pragma solidity ^0.4.0;

contract MappingExample {
    mapping(address => uint) public balances;

    function update(uint newBalance) public {
        balances[msg.sender] = newBalance;
    }
}

contract MappingUser {
    function f() public returns (uint) {
        MappingExample m = new MappingExample();
        m.update(100);
        return m.balances(this);
    }
}

注意: 映射並未提供迭代輸出的方法,能夠自行實現一個這樣的數據結構。參考iterable mapping

參考視頻

咱們也推出了目前市面上最全的視頻教程:深刻詳解以太坊智能合約語言Solidity 目前咱們也在招募課程體驗師,能夠點擊連接瞭解。

參考文檔

Solidity官方文檔

深刻淺出區塊鏈 - 系統學習區塊鏈,打造最好的區塊鏈技術博客。

☛ 個人知識星球爲各位解答區塊鏈技術問題,歡迎加入討論。

☛ 關注公衆號「深刻淺出區塊鏈技術」第一時間獲取區塊鏈技術信息。

相關文章
相關標籤/搜索