Openzeppelin

覆蓋繼承的函式可見性

  • March 6, 2021

我有一個看起來像這樣的契約:

pragma solidity ^0.6.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract SwappableToken is ERC20 {
 constructor(string memory name, string memory symbol, uint initialSupply) public ERC20(name, symbol) {
       _mint(msg.sender, initialSupply);
 }
 function _approve(address owner, address spender, uint256 amount) public override {
       super._approve(owner, spender, amount);
   }
}

但是,這樣做時,我得到: TypeError: Overriding function visibility differs.

_approve方法具有可見性,internal但我想做它public(為什麼?測試瘋狂的東西就是一切。是的,我知道這對生產來說是一個糟糕的主意)

不能從基礎合約中覆蓋函式的可見性嗎?

我將如何製作一個 ERC20,任何人都可以為任何所有者和發件人呼叫批准功能,而無需重寫整個契約?

_approve 方法具有內部可見性

virtual顯式可見性和修飾符的整個想法override是在編譯時擷取開發人員錯誤。因此,您將與編譯器的目標發生衝突。您最終會對您嘗試測試的東西進行功能更改,這通常是朝著錯誤方向邁出的一步。

_approve

樣式指南建議使用_forprivateinternal函式名稱。偉大的。有一個對應的external功能,approve()那就是 not internal。它是 ERC20 介面的一部分。

與其為了測試目的而修改程式碼,不如創建一個可訪問的函式。就像是:

function getPrivateResult() ... {
  return _getPrivateResult();
}

function setPrivateThing(args) ... guards .. {
  _setPrivateThing(args);

外部getPrivateResult()函式將是介面的一部分(帶有 override),但介面將在 上保持沉默_getPrivateResult()

如果您確實需要一個臨時腳手架進行測試,請考慮以下內容:

function deleteMeTestingOnly(args) ... { // signal auditors this should have been removed
 _approve(args);
}

這種模式可以幫助你堅信合約的內部狀態應該 100% 可以從外部發現。此外,如果您仔細觀察,該private函式可以保存重要的邏輯(一次),並且可能有多個從外部到它的路由。

function case1(address user) ... onlyTrustedContract ... {
 _setPrivateThing(user);
}

function case2(address user) ... onlyOwner ... {
 _setPrivateThing(user);

function case3() ... {
 _setPrivateThing(msg.sender);
}

這可以幫助您避免混亂的問題,例如只有所有者、我的一個契約或我的一個使用者,有時通過 msg.sender 和一些東西得到一個論點,然後……和……。

根據定義,該private/internal _setPrivateThing()函式不會是已定義介面的一部分,但三種情況都是。

希望能幫助到你。

引用自:https://ethereum.stackexchange.com/questions/94312