Solidity依然是对开发者最友好的语言,不过有些开发技巧有点反常识

Solidity是一种类似于JavaScript的语言,用来编写区块链智能合约。目前来看,Solidity依然是全球最受欢迎的智能合约开发语言,它支持静态类型,继承和库等特性,加上周围开发生态的支持,如truffle和web3,让开发和部署一个DApp简单了很多。一个有经验的JavaScript开发者可以很快上手Solidity开发,但如果要用好Solidity就必须要了解Solidity和区块链的特性,而有些特性有点“反常识”,下面让我们来一起学习一下。

计算很贵

这点是开发dapp的最需要牢记的一点了,因为区块链是全网共识,也就是说每次修改一个状态一个变量都需要全网的节点达成一致,这是很昂贵的操作,所以当我们要修改变量的状态时,先想想这一点。

慎用循环

想象这样一个游戏场景:一个游戏中有3个队伍,每个用户可以投入一定的eth加入任意一个队伍,游戏结束时拥有最多用户的队伍将获胜,根据用户投入的多少瓜分10eth的奖金。

开发者会遇到的问题是,游戏结束的时候如何给用户结算用户赢得了多少eth?

你可能会说我可以这样做:

定义三个数组,对应三个队伍,然后用数组记录参与此队伍的用户地址

游戏结束的时候找到数组长度(length)最长的一个数组,对应的这个队伍就是获胜的队伍

然后再用for循环遍历这个数组,将用户赢得的eth算出来,写入到用户的合约账户中

用户可以随时提币

第三点中涉及到了一个for循环和写入操作,如果有10个用户的话,相当于循环10次修改合约状态10次。如果这个量级增加到几千的话,那就有点可怕了,因为这整个操作消耗的gas可能会超过一个区块的gas limit,从https://etherscan.io/blocks这个网站我们可以看到最近的几个区块的gas limit大概是8,000,000 gas/block,如果超过这个数字则你的写入操作都会失败。从用户角度来说,获胜的用户永远无法得到自己应得的eth,结果用户骂娘走人,游戏死掉。

所以记住,慎用循环,最好不要使用未知循环次数的循环。

mapping and iteration

是中非常常用的一种数据类型, 是一种类似于的结构。不但可以定义一个,甚至可以定义以及的多重嵌套,不过就本码农看来,定义1-3级(mapping出现4次)的场景比较多,超过4级(mapping出现4次)的就不是很多了。

mapping (address => Player) public mapAddrToPlayer; // 1级mapping (uint => mapping (address => mapping (uint => mapping (uint => uint)))) public mapPlayerEthByTree; // 4级

虽然很常用,可以却不能遍历的所有,拿这个结构来说,是用户的地址,如果我想遍历所有的地址,拿到用户信息,是做不到的。如果想遍历,需要单独维护一个数组来存储所有用户的地址()。

now其实不是now

我们一般写代码时,获得的就是当时的时间,而在中获得的却是未来的某一个时刻的时间,这个时间就是包含当前计算这个交易所在区块的时间。

过程是这样的,我在X的时间发送了一笔交易,交易中有一个计算要得到当前的,之后这个交易在时间Y被打包成区块,最后在时间Z发送到链上。最终的值是Y,它们之间的关系是X

所以不可靠,在使用的时候一定要注意着一点。

不支持浮点数

中不支持浮点数,所以处理浮点数的时候要通过整数来表示。另外做除法的时候结果也不会出现浮点数,除法结果是,除法结果是。

因为类型有溢出的问题,所以在处理数学的加减乘乘方以及根号的运算时,我们通常用来处理。

foo.add(bar) // 加法foo.mul(bar) // 乘法foo.sub(bar) // 减法

你在开发过程中遇到了哪些坑?欢迎留言。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181114G0017K00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券