智能合约语言 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官方文档

深刻浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。

☛ 个人知识星球为各位解答区块链技术问题,欢迎加入讨论。

☛ 关注公众号“深刻浅出区块链技术”第一时间获取区块链技术信息。

相关文章
相关标签/搜索