Solidity--5.0重大更新

前言

随着solidity 0.5.0 nightly build版本的稳步推进,正式版也将在不久的将来与开发者见面.作为一个大版本更新,新版引入了很多特性,也废弃了很多关键字,比如

.call()不仅可以获知远程调用执行成功与否,还将获得远程调用执行的返回值

ABI解码做了新的处理规范,有效防御了”短地址攻击”

address地址类型细分成 address和 address payable

uintY和 bytesX不能直接转换

回退函数必须显式声明为 external可见性

构造函数必须用 constructor关键字定义

用于抛出异常的 throw关键字弃用, 函数状态可变性修饰符必须用 view,不能混用 constant和 view

下面我们将对这些改变一一予以介绍,最后给出一个示例代码,对比展示新旧版solidity代码写法的区别,供大家参考.

显式声明

函数可见性

函数可见性必须显式声明. 之前, 函数如果不显式声明,将默认 public可见性.

public: constructor构造函数必须声明为 public可见性,否则编译报错.

external: 回退函数(fallback function), 接口(interface)的函数必须声明为 external可见性,否则编译报错.

存储位置

结构体(struct),数组(array),映射(mapping)类型的变量必须显式声明存储位置( storage, memeory, calldata),包括函数参数和返回值变量都必须显式声明.

external 的函数参数需显式声明为 calldata.

合约与地址

contract合约类型不再包括 address类型的成员函数,必须显式转换成 address地址类型才能使用 send(), transfer(), balance等与之相关的成员函数/变量成员.

address地址类型细分为 address和 address payable,只有 address payable可以使用 transfer(), send()函数.

address payable类型可以直接转换为 address类型, 反之不能.

但是 address x可以通过 address(uint160(x)),强制转换成 address payable类型.

如果 contract A不具有 payable的回退函数, 那么 address(A)是 address类型.

如果 contract A具有 payable的回退函数, 那么 address(A)是 address payable类型.

msg.sender属于 address payable类型.

转换与填充(padding)

uintY与 bytesX

因为填充(padding)的时候, bytesX是右填充(低比特位补0),而 uintY是左填充(高比特位补0),二者直接转换可能会导致不符合预期的结果,所以现在当 bytesX和 uintY长度大小不一致(即X*8 != Y)时,不能直接转换,必须先转换到相同长度,再转换到相同类型.

10进制数值不能直接转换成 bytesX类型, 必须先转换到与 bytesX相同长度的 uintY,再转换到 bytesX类型

16进制数值如果长度与 bytesX不相等,也不能直接转换成 byteX类型

ABI

字面值必须显式转换成类型才能使用 abi.encodePacked()

ABI编码器在构造外部函数入参和 abi.encode()会恰当地处理 bytes和 string类型的填充(padding),若不需要进行填充,请使用 abi.encodePacked()

ABI解码器在解析函数入参和 abi.decode()时,如果发现 calldata太短或超长,将直接抛出异常,而不是像之前自动填充(补0)和截断处理,从而有效地遏制了短地址攻击.

.call()族函数( .call(), .delegatecall(), .staticcall())和 哈希函数( keccak256(), sha256(), ripemd160())只接受一个参数 bytes,且不进行填充(padding)处理.

.call()空参数必须写成 .call(“”)

.call(sig,a,b,c)必须写成 .call(abi.encodeWithSignature(sig,a,b,c)),其他类推

keccak256(a,b,c)必须写成 keccak256(abi.encodePacked(a,b,c)),其他类推

另外, .call()族函数之前只返回函数执行成功是否的 bool, 现在还返回函数执行的返回值,即 (bool,bytes memory). 所以之前 boolresult=<contract>.call(sig,a,b,c)现在必须写成 (boolresult,bytes memory data)=<contract>.call(sig,a,b,c).

不允许的写法

在之前版本的solidity编译,以下不允许的写法只会导致 warnings报警,现在将直接 errors报错.

不允许声明0长度的定长数组类型.

不允许声明0结构体成员的结构体类型.

不允许声明未初始化的 storage变量.

不允许定义具有命名返回值的函数类型.

不允许定义非编译期常量的 constant常量. 如 uintconstant time=now;是不允许的.

不允许 0X(X大写)做16进制前缀,只能用 0x.

不允许16进制数和单位名称组合使用. 如 value=0xffether必须写成 value=0xff*1ether.

不允许小数点后不跟数字的数值写法. 如 value=255.0ether不能写成 value=255.ether.

不允许使用一元运算符 +. 例如 value=1ether不能写成 value=+1ether.

不允许布尔表达式使用算术运算.

不允许具有一个或多个返回值的函数使用空返回语句.

不允许未实现的函数使用修饰符(modifier).

不允许 msg.value用在非 payable函数里以及此函数的修饰符(modifier)里.

废弃的关键字/函数

years时间单位已弃用,因为闰年计算容易导致各种问题.

var已弃用,请用 uintY精确声明变量长度.

constant函数修饰符已弃用,不能用作修饰函数状态可变性, 请使用 view关键字.

throw关键字已弃用,请使用 revert(), require(), assert()抛出异常.

.callcode()已弃用,请使用 .delegatecall(). 但是注意,在内联汇编仍可使用.

suicide()已弃用, 请使用 selfdestruct().

sha3()已弃用,请使用 keccak256().

构造函数

构造函数必须用 constructor关键字定义. 之前,并未强制要求,既可以用合约同名函数定义构造函数,也可以用 constructor关键字定义.

不允许调用没有括号的基类构造函数.

不允许在同一继承层次结构中多次指定基类构造函数参数.

不允许调用带参数但具有错误参数计数的构造函数.如果只想在不提供参数的情况下指定继承关系,请不要提供括号.

其他

do…while循环里的 continue不再跳转到循环体内,而是跳转到 while处判断循环条件,若条件为假,就退出循环.这一修改更符合一般编程语言的设计风格.

实现了C99风格的作用域:

变量必须先声明,后使用.之前,是可以先使用,后声明,现在会导致编译报错.

只能在相同或嵌套作用域使用.比如 if(){…}, do{…}while();, for{…}块内声明的变量,不能用在块外.

变量和结构体的循环依赖递归限制在256层.

pure和 view函数在EVM内部采用 staticcall操作码实现(EVM版本>=拜占庭),而非之前的 call操作码,这使得状态不可更改(state changes disallowed)在虚拟机层面得到保证.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容