I want to know who is still able to call an original overwritten function in case of inheritance.
Let's assume I have the following setup:
contract A{
address public owner;
function A(){
owner = msg.sender;
}
function doSomething(){
// does something
}
}
contract B is A{
function doSomething(){
require(msg.sender == owner);
// do something like A but restrict this function execution to owner
super.doSomething();
}
}
If I deploy contract B
can some external account that is not the owner still call doSomething
of parent contract A
? Or could some malicious contract execute the following:
contract EvilDoer{
function doSomethingEvil{
A contractB = A(addressOfdeployedB);
contractB.doSomething();
}
}
Or are overwritten functions shielded from external use?
EDIT: Overloading
Maybe it would be interesting and helpful to me and others to elaborate on the following as well: What happens in case of function overloading, i.e. if the signature in the child class is different from its parent (e.g. assume function doSomething(uint256 someNumber){...}
in contract B
)?
Best Answer
Last question first: overloading concept applies to Solidity but, as for other programming languages supporting overloading functions, i.e. C++, they are not related to each other in any way.
Functions with same name but different parameters are identified by different signatures, so they are actually different functions. If
ContractA
definesdoSomething()
,ContractB
definesdoSomething(string myString)
, andContractB
inherits fromContractA
, final ContractB will have two valid functions that user can call:doSomething()
anddoSomething(string myString)
. Visibility also is part of the signature, but it can't be overloaded.Main question now. From the outside of the contract, you cannot call a base function that has been overridden. This is because what you are calling from the outside is the final contract implementation, no matter how you define the interface on the client to call it.
If you defines
You are simply defining another - and more restrictive - pointer to
ContractB
and to its implementation ofdoSomething()
. And its implementation is the last one.But hei, I know default function visibility is public, what if I define explicitly the base function in
ContractA
asexternal
?Not much, because you cannot override a function changing its extended signature. Visibility and return parameters are part of the extended function signature, so the compiler throws an error:
If you want to compile you need to use the same
external
modifier also in theContractB
function, and then again, the last implementation of function wins in any case.Please note that changing visibility or return parameters it's not considered an overload neither, because functions are identified by signatures, contracts can't have two functions with the same signature and different extended attributes.
For more information about inheritance topics you can read the official documentation, in particular the information about the
super
keyword and the final inheritance graph of the contract.