6

is this code valid? https://ethereum.stackexchange.com/a/8484/10138 I just don't see how Mortal(mortal) - an instantiation of the Mortal contract with one parameter - is possible when Mortal takes no parameters!

2 Answers 2

4

I can see why you're confused. The key thing to know here is that typename(X) looks the same as functionname(parametername) but is actually a totally different operation you may well be familiar with, casting.

For those who don't know, casting is about changing the type of a variable, usually from a simpler type to a more complex type that typically inherits from it. For example, you may want to cast a uint32 to the larger-but-still-compatible uint64 type. To do that, you preface the name of the variable you want to cast with the name of the type you want to cast it to, and then surround it with parentheses like this:

uint64(mycurrentvariablewhichisauint32)

In the case of your question, we are specifically looking at a lesser known feature of the Solidity language: contracts all inherit from the "address" type, and therefore address types can be casted to contract types.

Given this information, it's easy to see what's going on in the snippet you reference. As Badr points out, the confusingly named address "mortal" is assumed by the snippet to be the address of an already instantiated copy of a mortal type contract (or technically mortal-interface-compatible since it doesn't have to be exactly mortal it just has to include the function signatures mortal includes, usually because it inherited from it). However, in order to actually call one of the mortal functions you have to tell solidity that this particular address is a contract of type mortal. You do that by casting the address to the mortal type:

Mortal(theaddressofthecontractwhichisactuallyamortaltypecontract)

This is not a call to the constructor for Mortal, which would look like new Mortal() and would generate its own brand new address from scratch. Make sense?

3
  • So, basically, we're downcasting an address to mortal: kind of like an Object to String (in Java)? Commented Jun 14, 2017 at 3:33
  • Yup! I always feel like the terms upcasting and downcasting should be reversed but since it is going from a base class to a derived class it would indeed be a downcast. Commented Jun 14, 2017 at 4:58
  • @JeffColeman I'm curious why you think the terminology for upcasting and downcasting should be reversed? When I see "down" I think "lower-level" so it makes sense to me, you're casting to something more specific. Upcasting is higher-level and in general will always be guaranteed to work (assuming the interface is implemented correctly), whereas downcasting requires that you know the underlying type ahead of time. Commented Feb 28, 2021 at 9:15
3

you mean this snippet code :

function checkMortal(address mortal) {
    if (Mortal(mortal).owner() == 0) {
        // You know it is dead.
    } else {
        // You know it is alive.
    }
}

the Mortal(mortal) in this case is an instantiation of the Mortal contract, it is similar to

function checkMortal(address mortal) {

Mortal M=Mortal(mortal);
        if (M.owner() == 0) {
            // You know it is dead.
        } else {
            // You know it is alive.
        }
    }
5
  • Yes, but why can it be instantiated? There's no constructor for Mortal with one parameter, which is called when an instantiation of the Mortal contract (with one parameter) is created. I can see Mortal M=Mortal() being valid, but not Mortal M=Mortal(someParameter). Commented Jun 13, 2017 at 22:04
  • forget the POO vision, here the constructor is a function executed once when the contract is created. so when you call it using its address its mean that you are not calling its constructor.
    – Badr Bellaj
    Commented Jun 13, 2017 at 22:41
  • What's POO stand for? And is there a name for this pattern that you are talking about (Contract(Address))? Commented Jun 14, 2017 at 2:31
  • @JossieCalderon that is not the code that is doing the instantiating. What Badr means is that the function has been passed the address of an already instantiated copy of mortal. The code Mortal(passedInAddress) is simply casting the address type to a "Mortal" type so that one of its functions can be called. Now that I wrote that out, I think it probably deserves a whole separate answer, so I'll write one. Commented Jun 14, 2017 at 3:11
  • Poo or OOP for oriented object programing,
    – Badr Bellaj
    Commented Jun 14, 2017 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.