更明确的要求

重写(Ovrride)

重写fuction明确要求如下:

  • 被重写的function一定是virtual或在interface里
  • 重写function包含多个来源时,必须明确标明所有来源
  • 需要加ovrride关键字
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
pragma solidity >=0.4.25;

contract A {
    function foo() virtual public pure returns(uint256) {
        return 1;
    }
}
contract B {
     function foo() virtual public pure returns(uint256) {
        return 1;
    }
}
interface C {
	// 接口的方法一定是external,我想可能考虑到在interface不需要内部调用
     function foo()  external pure returns(uint256);
}
contract HelloWorld is A, B,C {
    
    function foo() override(A,B,C) public pure returns(uint256) {
        return 2;
    }
}

public vs external

array length

array length 只读,不可以通修改length 来改变array的大小。可以使用 pop/push 函数

abstract合约

允许有未实现方法,未实现的方法需要关键字virtual

1
2
3
4
5
6
abstract contract D {
    function foo() virtual public pure returns(uint256) {
        return get();
    }
    function get() virtual  public pure returns(uint256);
}

Libraries

Libraries必需实现所有方法

语义和句法变化

fallback function

V0.6.0之前,fallback function长这样子的:

1
2
function()  external {
}

【含义是这样子的】:发送给合约的交易,data为空或在合约code中找不到可以调用的函数,则一律调用fallback function

V0.6.0,fallback function的功能被拆分成两个函数,是长这样子的:

1
2
 fallback()  external  {}
 receive() external payable {} //no data,因为要接收ETH必须为payable

【异同】若合约中没有定义receive function,fallback和之前版本的fallback功能一致;若定义了receive function,则先考虑receive function。

array push

对于:

1
2
 uint256[] arr;
 arr.push(1); 

V0.6.0之前数组的push会返回最新的长度,之后则不返回。

function type

0.6之前,获取external function的合约地址:

1
address(myFunction)

之后:

1
myFunction.address

新特性

try/catch

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pragma solidity >=0.6.0 <0.8.0;

interface DataFeed { function getData(address token) external returns (uint value); }

contract FeedConsumer {
    DataFeed feed;
    uint errorCount;
    function rate(address token) public returns (uint value, bool success) {
        //超过十次调用错误则废弃该函数
        require(errorCount < 10);
        try feed.getData(token) returns (uint v) {
            return (v, true);
        } catch Error(string memory /*reason*/) {
            // getData函数提供了此错误说明,如require(sex!=1 ||  , "sex must be 1")
            errorCount++;
            return (0, false);
        } catch (bytes memory /*lowLevelData*/) {
            // assert或运行错误,比如整除0
            errorCount++;
            return (0, false);
        }
    }
}

struct和enum可以声明在文件层面

在solidity0.6.0之前,下面声明是编译错误

1
2
3
4
5
6
struct A {
    string a;
}
contract Vote {

}

变量注释

支持变量注释检查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.21 <0.7.0;

/** @title Shape calculator. */
contract ShapeCalculator {
    /// @dev Calculates a rectangle's surface and perimeter.
    /// @param w Width of the rectangle.
    /// @param h Height of the rectangle.
    /// @return s The calculated surface.
    /// @return p The calculated perimeter.
    function rectangle(uint w, uint h) public pure returns (uint s, uint p) {
        s = w * h;
        p = 2 * (w + h);
    }
}

Yul and Inline Assembly

Yulinline Assembly增加新关键字: leave ,退出当前函数

address 转换为 address payable

旧方式

1
2
3
function foo(address  addr) public {
        address payable a = address(uint160(addr));
}

新方式

1
2
3
function foo(address  addr) public {
        address payable a = payable(addr);
}

参考

[1] Solidity v0.6.0 Breaking Changes

[2] Solidity 0.6.x features: fallback and receive functions

[3] Function Types