solidity基础 -- 映射
在区块链的智能合约开发领域,Solidity 作为以太坊上最主流的编程语言之一,拥有诸多强大特性助力开发者构建复杂且高效的去中心化应用。其中,映射(Mapping)是一个极为关键的数据结构,它为合约中的数据存储与检索提供了便捷、高效的方式。
本篇代码为自己结合资料总结,如有错误还请各位随时指出并进行修改~感恩包容理解!
另所有本篇以及以前出现的代码均可以在本人GitHub GitHub - solidity学习代码 上找到
一、映射的基础概念
在 Solidity 中,映射如同一个神奇的 “账本”,能够以键值对的形式存储数据。以代码中的 mapping(address => uint ) public balances; 为例,它创建了一个从以太坊地址(address 类型)到无符号整数(uint 类型)的映射关系,通俗来讲,就是可以针对不同的以太坊地址记录对应的余额数值。这就像是现实世界银行给每个客户设立账户并记录存款余额,只不过这里的 “账户” 是以太坊地址,“余额” 是合约中所关心的各种数值信息。
映射是一种键值对的数据结构,类似于传统编程语言中的哈希表或字典。在Solidity中,映射用于将一个值(键)映射到另一个值(值)。其基本语法如下:
mapping(_KeyType => _ValueType) _mappingName;
_KeyType
:键的类型,可以是任何基本类型,如address
、uint
、bytes32
等,但不能是复杂类型如结构体或数组._ValueType
:值的类型,可以是任何类型,包括基本类型、复杂类型、甚至是另一个映射._mappingName
:映射的名称,用于在合约中引用该映射.
例如,在上面的代码中,mapping(address => uint) public balances;
定义了一个名为balances
的映射,它将address
类型的键映射到uint
类型的值.这意味着我们可以用一个地址作为键,来存储和检索与该地址相关的余额信息.
映射的操作
设置值
要为映射设置值,可以直接使用赋值操作符=
.例如:
balances[msg.sender] = 123;
这行代码将调用者(msg.sender
)的地址作为键,将值123
存储到balances
映射中.这意味着调用者的余额被设置为123.
获取值
获取映射中的值也非常简单,只需通过键来访问:
uint bal = balances[msg.sender];
这里,我们通过调用者的地址作为键,从balances
映射中获取其余额,并将其存储在变量bal
中.
删除值
如果需要删除映射中的某个键值对,可以使用delete
关键字:
delete balances[msg.sender];
这将删除调用者地址对应的键值对,并将值恢复为其类型的默认值.对于uint
类型,其默认值是0,所以删除后,调用者的余额会变成0.
嵌套映射
Solidity中的映射可以嵌套,即值类型可以是另一个映射.这为存储更复杂的数据关系提供了可能.例如:
mapping(address => mapping(address => bool)) public isFriend;
这里定义了一个名为isFriend
的嵌套映射,它将两个address
类型的键映射到一个bool
类型的值.这可以用来表示两个地址之间的朋友关系.例如:
isFriend[msg.sender][address(this)] = true;
二、写在介绍后
总结下本篇出现的全部代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract Mapping {mapping(address => uint ) public balances;mapping(address => mapping (address => bool )) public isFriend;function examples() external {balances[msg.sender] = 123;uint bal = balances[msg.sender];uint bal2 = balances[address(1)];balances[msg.sender] = 456;balances[msg.sender] += 456; //默认值 + 546delete balances[msg.sender];//删除会恢复到默认值,而不是说真的删除isFriend[msg.sender][address(this)] = true;}
}
如果你在Remix上运行 那么就会发现有橙色提醒
这段代码是一个 Solidity 合约,展示了以太坊智能合约中的映射数据结构。
以下是每个部分的作用:
`mapping(address => uint) public balances;` 这行代码创建了一个映射(一种键值对数据库),其中地址作为键,对应的值为无符号整数,用于表示账户余额。
同样的概念也适用于 isFriend,它将地址对与表示友谊状态的布尔值进行映射。
该合同有一个名为 examples() 的外部函数,其功能为:
将调用者(msg.sender)的余额设置为 123,使用 balances[msg.sender] = 123; 语句。
通过映射访问该值并将其存储在名为 bal 的新变量中:uint bal = balances[msg.sender];。
然而,当尝试通过 uint bal2 = balances[address(1)]; 获取另一个地址(address(1))的余额时,Solidity 提示声明了一个未使用的局部变量。
错误发生
是因为您声明了一个新变量(bal2),但在代码中任何地方都没有使用它。您可以这样解决:要么删除声明并赋值给 bal2 的那行代码,要么在合约的其他地方实际使用它的值,例如:
无符号整数型变量 bal 被赋值为 balances 中 msg.sender 所对应的值。//...
如果 balances[address(1)] 的值为 0 ,则执行以下操作(即如果地址 1 的余额为零,则执行以下操作)}
这样一来,变量 bal2 就不会再被视为未使用了。
三、映射的注意事项
- 映射中的键值对数量是无限的,但实际存储的键值对数量取决于合约的使用情况.
- 映射中的键是唯一的,但值可以重复.
- 由于区块链的不可变性,映射中的数据一旦写入,就无法被修改或删除,只能通过覆盖或使用
delete
关键字将其恢复为默认值. - 映射的使用会消耗Gas,因此在设计合约时,应尽量优化映射的使用,避免不必要的操作。
四、实际应用
映射在智能合约中有着广泛的应用,例如:
- 代币合约:用于存储每个地址持有的代币数量.
- 去中心化金融(DeFi)合约:用于记录用户的存款、借款等信息.
- 投票合约:用于记录每个地址的投票结果.
- 游戏合约:用于存储玩家的游戏数据,如分数、等级等.
通过合理地使用映射,我们可以构建出高效、可靠的智能合约。
本篇代码为自己结合资料总结,如有错误还请各位随时指出并进行修改~感恩包容理解!
相关文章:
solidity基础 -- 映射
在区块链的智能合约开发领域,Solidity 作为以太坊上最主流的编程语言之一,拥有诸多强大特性助力开发者构建复杂且高效的去中心化应用。其中,映射(Mapping)是一个极为关键的数据结构,它为合约中的数据存储与…...

Angular 11课程实践:构建高效单页应用的支持代码
本文还有配套的精品资源,点击获取 简介:Angular 11是Google支持的前端框架,适合构建复杂的单页应用(SPA)。本课程将深入介绍Angular核心特性,如组件化、依赖注入、数据绑定和路由,并且涵盖Ang…...

测试用例颗粒度说明
当我们在编写测试用例时,总是会遇到一个问题:如何确定测试用例的颗粒度?测试用例过于粗糙,可能无法全面覆盖系统的细节;而颗粒度过细,又会导致测试重复、冗余。掌握合适的颗粒度,不仅可以提高测…...

ESP32 IDF VScode出现头文件“无法打开 源 文件 ”,并有红色下划线警告
问题背景: ESP32 IDF VScode出现头文件“无法打开 源 文件 ”,并有红色下划线警告: 解决办法: 在工程里面的.vscode文件夹下,检查是否存在c_cpp_properties.json文件,如果没有可以手动创建添加。如图…...

Windows安装ES单机版设置密码
下载ES ES下载链接 我用的是7.17.26 启动前配置 解压之后打开D:\software\elasticsearch-7.17.26\bin\elasticsearch-env.bat 在elasticsearch-env.bat文件中修改jdk的路径 修改前 修改内容 if defined ES_JAVA_HOME (set JAVA"D:\software\elasticsearch-7.17.26\…...
Linux Docker
Docker 的定义 Docker 是一个开源的容器化平台,它允许开发者将应用程序及其依赖项打包成一个可移植的容器。容器是一种轻量级、独立的运行环境,与传统的虚拟机不同,容器共享主机操作系统的内核,通过隔离的文件系统、进程空间和网…...

MSE学习
MSE简介 媒体源拓展(Media Source Extensions,简称 MSE)是一个由 W3C 制定的标准,它允许 JavaScript 代码通过 AJAX 请求获取媒体数据,并将其提供给 HTML 的 <video> 或 <audio> 元素进行播放。 MSE特点…...

0-基于蚁群优化和带注意力机制的循环神经网络的新型混合算法用于解决旅行商问题(HAL science)(完)
文章目录 AbstractI INTRODUCTIONII 旅行商问题的正式描述III STATE OF THE ARTIV 使用的混合化技术原理4.1 Principle of ACO4.2具有注意机制的自动编码器模型V 蚁群优化与具有注意机制的神经网络的混合5.1 基本思想5.2 解决步骤5.2.1 模型训练5.2.2 寻找解VI EXPERIMENTS6.1 …...

MIUI显示/隐藏5G开关的方法,信号弱时开启手机Wifi通话方法
5G网速虽快,手机功耗也大。 1.取消MIUI强制的5G,手动设置4G的方法! 【小米澎湃OS, Xiaomi HyperOS显示/隐藏5G开关的方法】 1.1.小米MIUI系统升级后,被强制连5G,手动设置开关被隐藏,如下图: 1…...

挑战20天刷完leecode100
2025.1.5 二分查找 1 搜索插入位置 就是简单的二分查找 注意开闭就行 这里有一句话就是nums是升序的 如果他不是严格递增 就是有相同的数字的情况下应该怎么写? int lower_bound(vector<int>& nums, int target) {int left 0, right (int) nums.size() - 1; …...
Java列表示例
示例1:使用ArrayList创建并操作列表 ArrayList是List接口最常用的实现之一,它内部使用数组来存储元素,因此对于随机访问具有很高的效率。但是,当涉及到频繁的插入或删除操作时,它的性能可能会受到影响,因为…...
Objective-C语言的网络编程
Objective-C语言的网络编程 引言 在现代软件开发中,网络编程逐渐成为一个不可或缺的部分,特别是在移动应用和分布式系统中。Objective-C 是一种主要用于 iOS 和 macOS 开发的编程语言,它在网络编程方面也有着丰富的支持。在这篇文章中&…...
安卓OCR使用(Google ML Kit)
OCR是一个很常用的功能,Google ML Kit提供了OCR能力,用起来也很简单,本文介绍一下使用方法。 1. 相关概念 名词概念解释TextBlock块一个段落Line行一行文本Element元素单词;对汉字来说,类似"开头 (分隔符)中间&…...

《机器学习》——贝叶斯算法
贝叶斯简介 贝叶斯公式,又称贝叶斯定理、贝叶斯法则,最初是用来描述两个事件的条件概率间的关系的公式,后来被人们发现具有很深刻的实际意义和应用价值。该公式的实际内涵是,支持某项属性的事件发生得愈多,则该属性成…...

【博主推荐】 Microi吾码开源低代码平台,快速建站,提高开发效率
🍬引言 🍬什么是低代码平台? 低代码平台(Low-Code Platform)是一种使开发人员和业务用户可以通过图形化界面和少量的编程来创建应用程序的开发工具。与传统的编程方式相比,低代码平台大大简化了开发过程&a…...
网站自动签到
我研究生生涯面临两个问题,一是写毕业论文,二是找工作,这两者又有很大的冲突。怎么解决这两个冲突呢?把python学好是一个路子,因此从今天我要开一个专栏就是学python 其实我的本意不是网站签到,我喜欢在起点…...

C 语言奇幻之旅 - 第16篇:C 语言项目实战
目录 引言1. 项目规划1.1 需求分析与设计1.1.1 项目目标1.1.2 功能需求1.1.3 技术实现方案 2. 代码实现2.1 模块化编程2.1.1 学生信息模块2.1.2 成绩管理模块 2.2 调试与测试2.2.1 调试2.2.2 测试2.2.4 测试结果 3. 项目总结3.1 代码优化与重构3.1.1 代码优化3.1.2 代码重构 3.…...

项目实战——使用python脚本完成指定OTA或者其他功能的自动化断电上电测试
前言 在嵌入式设备的OTA场景测试和其他断电上电测试过程中,有的场景发生在夜晚或者随时可能发生,这个时候不可能24h人工盯着,需要自动化抓取串口日志处罚断电上电操作。 下面的python脚本可以实现自动抓取串口指定关键词,然后触发…...

04、Redis深入数据结构
一、简单动态字符串SDS 无论是Redis中的key还是value,其基础数据类型都是字符串。如,Hash型value的field与value的类型,List型,Set型,ZSet型value的元素的类型等都是字符串。redis没有使用传统C中的字符串而是自定义了…...

【MySQL学习笔记】MySQL的索引
MySQL索引 1、索引概述2、 索引的数据结构2.1 BTree索引结构2.2 Hash索引结构2.3 InnoDB选择BTree的原因 3、索引分类4、索引的语法5、SQL性能分析5.1 SQL执行频率5.2 慢查询日志5.3 profile详情5.4 explain执行计划 6、索引使用规则6.1 最左前缀法则6.2 范围查询6.3索引失效情…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...