19069f9b695ba02616c954de24bdc026.png

映射 Mapping

在映射中,人们可以通过键(Key)来查询对应的值(Value),比如:通过一个人的 id 来查询他的钱包地址。

声明映射的格式为 mapping(_KeyType => _ValueType),其中 _KeyType 和 _ValueType 分别是 Key 和 Value 的变量类型。例子:

6dcb52ebbc07e5331fe5ea57671a4bad.jpeg

映射的规则

规则 1:映射的 _KeyType 只能选择 solidity 默认的类型,比如 uint,address 等,不能用自定义的结构体。而 _ValueType 可以使用自定义的类型。下面这个例子会报错,因为 _KeyType 使用了我们自定义的结构体:

5ece66372811173bdaf05c7ac389f8b9.jpeg

规则 2:映射的存储位置必须是 storage,因此可以用于合约的状态变量,函数中的 stoage 变量。不能用于 public 函数的参数或返回结果中。

规则 3:如果映射声明为 public,那么 solidity 会自动给你创建一个 getter 函数,可以通过 Key 来查询对应的 Value。

规则 4:给映射新增的键值对的语法为 _Var[_Key] = _Value ,其中 _Var 是映射变量名,_Key 和 _Value 对应新增的键值对。例子:

78689b802fd1b5063500ff49e5aad02b.jpeg

控制流

Solidity 的控制流与其他语言类似,主要包含以下几种:

if-else

6faacd1bc45f5e8698c0b0454e9fff18.jpeg

for 循环

ea71ada07762d55373e24aa12b258736.jpeg

while 循环

a6d6536f26f07714eb140e14bdbc6e5e.jpeg

do-while 循环

a4bc6336eb81846cc05c6b3281b8128e.jpeg

三元运算符

三元运算符是 solidity 中唯一一个接受三个操作数的运算符,规则 条件? 条件为真的表达式:条件为假的表达式。此运算符经常用作 if 语句的快捷方式。

70b41f1d05658e60ae3321d42bbced87.jpeg

另外还有 continue(立即进入下一个循环)和 break(跳出当前循环)关键字可以使用。

用 solidity 实现插入排序

写在前面:90% 以上的人用 solidity 写插入算法都会出错。

插入排序

排序算法解决的问题是将无序的一组数字,例如 [2, 5, 3, 1],从小到大一次排列好。插入排序(InsertionSort)是最简单的一种排序算法,也是很多人学习的第一个算法。它的思路很简答,从前往后,依次将每一个数和排在他前面的数字比大小,如果比前面的数字小,就互换位置。示意图:

e0027cbc0d61946a8d8786ff511b179a.jpeg

插入排序 
python 代码

我们可以先看一下插入排序的 python 代码:

dd1683f651c87cce43d586f82f69e73b.jpeg

改写成 solidity 后有 BUG!

一共 8 行 python 代码就可以完成插入排序,非常简单。那么我们将它改写成 solidity 代码,将函数,变量,循环等等都做了相应的转换,只需要 9 行代码:

d1735003aa86369a360719434bbf4e4b.jpeg

那我们把改好的放到 remix 上去跑,输入 [2, 5, 3, 1]。BOOM!有 bug!改了半天,没找到 bug 在哪。我又去 google 搜」solidity insertion sort」,然后发现网上用 solidity 写的插入算法教程都是错的,比如:Sorting in Solidity without Comparison

正确的 solidity 插入排序

花了几个小时,在 Dapp-Learning 社群一个朋友的帮助下,终于找到了 bug 所在。solidity 中最常用的变量类型是 uint,也就是正整数,取到负值的话,会报 underflow 错误。而在插入算法中,变量 j 有可能会取到-1,引起报错。

这里,我们需要把 j 加 1,让它无法取到负值。正确代码:

35d8685beaadca73b94eceafa85fe5a0.jpeg

运行后的结果:

d1ca68cca80ccf0b16ae31a7acfbbe44.jpeg

总结

这一讲,我们介绍了 solidity 中映射类型、控制流,并且用 solidity 写了插入排序。看起来很简单,但实际很难。这就是 solidity,坑很多,每个月都有项目因为这些小 bug 损失几千万甚至上亿美元。掌握好基础,不断练习,才能写出更好的 solidity 代码。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐