Compiling error: TypeError: Overriding function visibility differs
Environment
OpenZeppelin 2.5,
Solidity 0.5.0,
Remix
Details
I have a token contract that is importing & inheriting the v2.5.0 version of ERC20 and ERC20 Detailed, and I’m getting the following compiling error: TypeError: Overriding function visibility differs
for the transfer
function and balanceOf
function. Both of these functions use public
in the ERC20 contract but external
in the IERC20 contract. I have my own interface for my token contract and because of the public vs external different in the ERC20 and IERC20 contract, I can’t get past this error. Not sure what to do.
Code to reproduce
pragma solidity ^0.5.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/token/ERC20/ERC20Detailed.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/token/ERC20/ERC20.sol";
contract ITestToken {
function balanceOf(address who) external view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
}
contract TestToken is ITestToken, ERC20, ERC20Detailed {
modifier myModifier() {
// custom logic
_;
}
constructor () public ERC20Detailed("MyTestToken", "MTT", 18) {
_mint(msg.sender, 100000000 * (10 ** uint256(decimals())));
}
function transfer(address to, uint256 value) public myModifier() returns (bool) {
return super.transfer(to, value);
}
}
1 Like
Oh, I think I need to inherit my Interface after ERC20 and ERC20Detailed?
1 Like
Hi @kseniya,
Do you need to declare your own ITestToken
interface? If you need to interact with an instance using an interface you could use IERC20
.
pragma solidity ^0.5.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/token/ERC20/ERC20Detailed.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/token/ERC20/ERC20.sol";
contract TestToken is ERC20, ERC20Detailed {
modifier myModifier() {
// custom logic
_;
}
constructor () public ERC20Detailed("MyTestToken", "MTT", 18) {
_mint(msg.sender, 100000000 * (10 ** uint256(decimals())));
}
function transfer(address to, uint256 value) public myModifier() returns (bool) {
return super.transfer(to, value);
}
}
@abcoathup I do need it because there are other functions in there (i left them out for simplicity). Smart contracts in my dapp are interfacing with my TestToken so I have an interface created for several functions. I thought you could override functions of smart contracts you are inheriting?
Why is ERC20 using public
when the IERC20 using external
?
1 Like
Hello @kseniya!
First, note that the error you’re getting is not because of TestToken
, but ITestToken
: you declared transfer
as a public function there, but IERC20
declares it as external
.
The reason why IERC20
declares it as external
is because it is an interface
(not a contract
!), and those can only have external
functions (which can be implemented using a public
function).
If you change ITestToken's
transferto
external, your code will compile. If
ITestTokenis your token's interface however and it is ERC20-compliant, what you should do is make it inherit from
IERC20` and only add your custom functions to it.
As to why transfer
is public
, the reason is inheritance. Note that in your code you added an override for transfer
to extend it, and called super.transfer
: this is considered an internal call by Solidity, and can only be made if the function can be internally called (i.e. internal
or public
). If transfer
's implementation in ERC20
was external
, there would be no legal way to write that override.
Hope this helps!
2 Likes