solidity v0.5.0的重大改变

不知不觉,solidity已经走到了0.5版本,随着solidity 0.5.0 nightly build版本的面世,相信1.0版本也将在不久的未来与开发者见面.做为一个大版本更新,新版引入了不少新特性,也废弃了不少关键字,好比编程

  •     .call()不只能够获知远程调用执行成功与否,还将得到远程调用执行的返回值
  •     ABI解码作了新的处理规范,有效防护了"短地址攻击"
  •     address地址类型细分红 address和 address payable
  •     uintY和 bytesX不能直接转换
  •     回退函数必须显式声明为 external可见性
  •     构造函数必须用 constructor关键字定义
  •     用于抛出异常的 throw关键字弃用, 函数状态可变性修饰符必须用 view,不能混用 constant和 view

    ...数组

下面咱们将对这些改变一一予以详细介绍,供你们参考。
显式声明app

函数可见性

  •     函数可见性必须显式声明. 以前, 函数若是不显式声明,将默认 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类型

ABIide

  •     字面值必须显式转换成类型才能使用 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=.call(sig,a,b,c)如今必须写成 (boolresult,bytes memory data)=.call(sig,a,b,c).

不容许的写法函数

在以前版本的solidity编译,如下不容许的写法只会致使 warnings报警,如今将直接 errors报错.ui

  •     不容许声明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关键字定义.
  •     不容许调用没有括号的基类构造函数.
  •     不容许在同一继承层次结构中屡次指定基类构造函数参数.
  •     不容许调用带参数但具备错误参数计数的构造函数.若是只想在不提供参数的状况下指定继承关系,请不要提供括号.

其余.net

  •     do...while循环里的 continue再也不跳转到循环体内,而是跳转到 while处判断循环条件,若条件为假,就退出循环.这一修改更符合通常编程语言的设计风格.
  •     实现了C99风格的做用域:
  •     变量必须先声明,后使用.以前,是能够先使用,后声明,如今会致使编译报错.
  •     只能在相同或嵌套做用域使用.好比 if(){...}, do{...}while();, for{...}块内声明的变量,不能用在块外.
  •     变量和结构体的循环依赖递归限制在256层.
  •     pure和 view函数在EVM内部采用 staticcall操做码实现(EVM版本>=拜占庭),而非以前的 call操做码,这使得状态不可更改(state changes disallowed)在虚拟机层面获得保证.

--------------------- 
做者:angciyu 
来源:CSDN 
原文:https://blog.csdn.net/angciyu/article/details/84852385 
版权声明:本文为博主原创文章,转载请附上博文连接!设计