覆蓋繼承的函式可見性
我有一個看起來像這樣的契約:
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
樣式指南建議使用
_
forprivate
和internal
函式名稱。偉大的。有一個對應的external
功能,approve()
那就是 notinternal
。它是 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()
函式不會是已定義介面的一部分,但三種情況都是。希望能幫助到你。