更明确的要求
重写(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的合约地址:
之后:
新特性
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
Yul 和 inline 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