最新内容会更新在主站深入浅出区块链社区

原文链接:智能合约语言 Solidity 教程系列6 - 结构体与映射

写在前面

Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解,

如果你还不了解,建议你先看以太坊是什么

本系列文章一部分是参考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的值类型成员。

注意在函数中,将一个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官方文档

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

智能合约语言 Solidity 教程系列6 - 结构体与映射的更多相关文章

  1. 智能合约语言 Solidity 教程系列4 - 数据存储位置分析

    写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 这部分的内容官方英文文档讲的不是很透,因此我在参考Soli ...

  2. 智能合约语言 Solidity 教程系列5 - 数组介绍

    写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 本文前半部分是参考Solidity官方文档(当前最新版本: ...

  3. 智能合约语言Solidity教程系列2 - 地址类型介绍

    智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...

  4. 智能合约语言 Solidity 教程系列3 - 函数类型

    Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...

  5. 智能合约语言 Solidity 教程系列8 - Solidity API

    这是Solidity教程系列文章第8篇介绍Solidity API,它们主要表现为内置的特殊的变量及函数,存在于全局命名空间里. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应 ...

  6. 智能合约语言 Solidity 教程系列9 - 错误处理

    这是Solidity教程系列文章第9篇介绍Solidity 错误处理. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文 ...

  7. 智能合约语言 Solidity 教程系列10 - 完全理解函数修改器

    这是Solidity教程系列文章第10篇,带大家完全理解Solidity的函数修改器. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编 ...

  8. 智能合约语言 Solidity 教程系列7 - 以太单位及时间单位

    这是Solidity教程系列文章第7篇介绍以太单位及时间单位,系列带你全面深入理解Solidity语言. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所 ...

  9. 智能合约语言 Solidity 教程系列2 - 地址类型介绍

    Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是 ...

随机推荐

  1. C# 排序技术研究与对比

    一. 排序场景 一维数组排序 多维数组排序 集合排序,例如Dictionary ,List<T>, 自定义类集合排序等 DataTable排序 二. 排序实现和测试 1. 一维数组排序 1 ...

  2. centos6.9(Linux系统)安装VMware tools教程

    VMware tools是虚拟机上虚拟硬件的驱动,可以实现鼠标的无缝移出移入,剪贴板共享,共享文件夹等功能.很多的Linux系统初学者,在安装centos6.9系统时,没有安装VMware tools ...

  3. 利用可变参数模拟Printf()函数实现一个my_print()函数和调用可变参数注意的陷阱!

    可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 例如,对于函数: void test(char a ...

  4. SpringMVC RequestMapping 详解

    SpringMVC RequestMapping 详解 RequestMapping这个注解在SpringMVC扮演着非常重要的角色,可以说是随处可见.它的知识点很简单.今天我们就一起学习Spring ...

  5. 安装memcached

    简介 memcached是免费和开放源代码的高性能分布式内存对象缓存系统,旨在通过减轻数据库负载来加速动态Web应用程序.其有以下特点: 基于简单的文本行协议 全部数据按照k/v形式存放在内存中,无持 ...

  6. HBase表预分区与压缩

    1.建立HBase预分区表.sql语句如下: create 'buyer_calllogs_info_ts', 'record', {SPLITS_FILE => 'hbase_calllogs ...

  7. poj1611 解题报告

    并查集学习过之后做了几道相关联系,这里贴出1611 The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions:  ...

  8. ##5.2 Nova计算节点-- openstack pike

    ##5.2 Nova计算节点 openstack pike 安装 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ##5.2 Nova计算节点 # co ...

  9. Prim算法模板

    //Gang #include<iostream> #include<cstring> #include<algorithm> #include<cstdio ...

  10. PHP入门怎么选?大学生适合学习吗?

    大学毕业,面对竞争激烈的社会,理想总是很丰满,现实却很残酷.在硕士.博士都随处可见的今天,本科和大专文凭就显得苍白无力,在面试官问你"有没有工作经验"的时候,你是不是只想起实习期间 ...