Solidity 调用父类函数

Solidity 派生类调用父类函数有两种方法:

  • 使用父级合约名称调用

  • 使用super调用

使用父级合约名称调用

使用父级合约名称调用,格式为:<parent contract>.<method>。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract X {
   function foo() internal pure returns(uint) {
      return 1;
   }
}

contract Z is X {
   function test() external pure returns(uint) {
      // X 为父级合约名称,foo为父级合约的方法名称
      uint result = X.foo();
      return result;
   }
}

使用super调用

使用super调用,格式为:super.<method>。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract X {
   function foo() internal pure returns(uint) {
      return 1;
   }
}

contract Z is X {
   function test() external pure returns(uint) {
      // supper 表示父级合约,foo为父级合约的方法名称
      uint result = supper.foo();
      return result;
   }
}

多重继承的super调用

在多重继承中使用super调用,将会调用所有父级合约(基类)的方法。

  X 
/   \
Y   Z
\   /
  T
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract X {
   event log(string message);

   function foo() public virtual {
      emit log("X.foo");
   }
}

contract Y is X {
   function foo() public virtual override {
      emit log("Y.foo");
      super.foo();
   }
}

contract Z is X {
   function foo() public virtual override {
      emit log("Z.foo");
      super.foo();
   }
}

contract T is Y,Z {
   function foo() public override(Y,Z) {
      super.foo();
   }
}

我们部署合约 T 后,调用它的方法 foo(),查看输出结果如下:

[
   {
      "from": "0x93f8dddd876c7dBE3323723500e83E202A7C96CC",
      "topic": "0x41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50",
      "event": "log",
      "args": {
         "0": "Z.foo",
         "message": "Z.foo"
      }
   },
   {
      "from": "0x93f8dddd876c7dBE3323723500e83E202A7C96CC",
      "topic": "0x41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50",
      "event": "log",
      "args": {
         "0": "Y.foo",
         "message": "Y.foo"
      }
   },
   {
      "from": "0x93f8dddd876c7dBE3323723500e83E202A7C96CC",
      "topic": "0x41304facd9323d75b11bcdd609cb38effffdb05710f7caf0e9b16c6d9d709f50",
      "event": "log",
      "args": {
         "0": "X.foo",
         "message": "X.foo"
      }
   }
]

可以看到 Y,Z 的 foo 方法都被调用,而 Z 的 foo 方法只被调用了一次。

Solidity 是通过回退状态的方式来处理异常错误。Solidity 发生异常时,会撤消当前调用和所有子调用改变的状态,同时给调用者返回一个错误标识。Solidity 提供了require 、assert 和 ...