True, but the base contract is any parent contract in any inheritance structure, not just the parent contract in a hierarchical inheritance structure, which is what you have descibed here.
For example, in a single inheritance structure: âcontract B is A {...} â A is the base/parent contract.
In the following multi-level inheritance structure:
contract B is A {...}
contract C is B {...}
⌠both A and B are base contracts.
Q3
Correct⌠but D only needs to inherit from A (and not also from B and C) for this to be hierarchical inheritance. Hierarchical inheritance describes a relationship where multiple derived contracts (B, C & D) are all derived from a single base/parent contract (A).
By D also inheriting from its siblings (B and C) you are also adding multiple inheritance to your overall structure. Multiple inheritance is where a single derived contract (D) inherits from multiple base/parent contracts (A, B and C).
Let us know if anything is unclear, or if you have any questions.
Q2 âWhich functions are available for derived contracts?
Yes⌠but not all functions in the parent contract.
Functions with public or internal visibility are available for derived contracts, but those with private or external visibility are not inherited. The same applies to state variables. You are correct about modifiers and events: all of these are inherited.
Yeh, donât worry, I know the the questions could sometimes be clearer.
When we refer to functions we usually just mean the ones with the function keyword at the beginning. You are correct that modifiers and events could also be seen as special types of functions, but we usually refer to them as modifiers and events (the same with constructors).
Anyway, as long as you understand that for a function to be inherited it needs to be marked with either public or internal visibility, then thatâs the key information with this question.
State variables are the same, but there are only 3 visibility types with state variables: public, internal and private (no external). And with state variables, if you donât explicitly mark the visibility, then it will be treated as internal by default. So the only state variables that arenât inherited are those you mark private.
Itâs straight forward with modifiers and events: they are all inherited (which makes sense because we donât add a visibility type for either of these.
If the external contract has selfdestruct called on it, do calls to that contract fail? (from remix it doesnât fail when calling through the interface after removing the deployed contract)
is there a way to check if the contract has been removed before attempting to use it?
When does the interface get validated against the contract functions? (I purposely misspelled the function name and from remix it seems its a runtime error when calling the function instead of a compile-time error)
the base contract is the parent contract which is inherit
There is a is-a relationship between base and derived contracts and all public and internal scoped
functions and state variables are available to derived contracts.
3.a single contract acts as a base contract for multiple derived contracts.
Hi Filip
Just doing some coding on my own as you have suggested at the end of the old 101 ethereum smartcontract course
Just wondering how to multiply the values of two integers once you click transact?
Can that be done?
Do you mean when you call a function externally from Remix (click the orange button)?
Are your 2 integers parameters you have input, or are they stored in state variables?
Either way, after calling the function you need to perform the multiplication within your function body by referencing the integers by their identifiers (parameter names or state variable names). If the integers are stored in a mapping or in an array, then you need to reference them within that data structure.
If you want to return the result to the caller, then you would include a return statement. Otherwise, if you want to store the result somewhere within your contract, you need to assign the result to wherever you want to store it e.g.
// 2 integers input as parameters, multiplied, then stored in state variable
uint public result;
function multiplyNumbers(uint numA, uint numB) public {
result = numA * numB;
}
/* The integer mapped to the caller's address in the mapping is multiplied
by 2 and updated, and the result is also returned to the caller*/
mapping (address => uint) public currentNum;
function addMyNumber(uint num) public {
currentNum[msg.sender] = num;
}
function myNumberX2() public returns(uint newNumber) {
return currentNum[msg.sender] *= 2; // more concise way to code line below
// return currentNum[msg.sender] = currentNum[msg.sender] * 2;
}
Obviously, there are all sorts of possible variations on the above two examples, but hopefully this gives you an idea, if this is the kind of thing you want to do.
Sorry itâs taken me a while to get back to you on these questions.
A disadvantage of using selfdestruct in any contract is that once destroyed, the contractâs public and external functions can still be called by users from an external service, without the transactions reverting or error messages being generated. This is a serious problem if ether is sent to the destroyed contract, because it will be lost.
However, when I add a function to Government allowing it to be destroyed by triggering selfdestruct(), once Government has been destroyed, the external function call to addTransaction(), during execution of the transfer() function, fails, and the transfer reverts, preventing any ether being paid as a transaction fee to the Government contract.This seems to contradict your findings, unless Iâve misunderstood what you meanâŚ
My understanding is that, in practice, use of selfdestruct() is not encouraged, and other types of security mechanisms are built into smart contracts instead, such as the implementation of proxy contracts. You will learn more about the practicalities of this if you go on to take the Smart Contract Security course.
If you do some of your own research about selfdestruct() you will find that it is by no means a perfect security solution, and comes with specific weaknesses and disadvantages. However, its relatively straightforward and easy-to-understand functionality makes it ideal to use in an introductory example of how inheritance works. And to be honest, weâve used it more as a way to demonstrate how inheritance works and is coded in Solidity, rather than to teach you selfdestruct() for its own particular merits.
As far as I am aware, there isnât. This is linked to the disadvantage I mentioned above. Those responsible for the destroyed contract would need to notify all potential users that it should no longer be called.
If you get the external contractâs function name wrong in the interface, and also in the function call itself, then this will not be picked up by the compiler, because both contracts are compiled and then deployed separately. You have rightly identified that a bug such as this, if it wasnât identified and resolved during testing, would cause each external function call to revert.
In practice, the interface would be provided or published by those responsible for the external contract, and so this in itself is a form of validation. Before deployment on the mainnet, the external function call would also have been tested to ensure that it has been implemented appropriately, according to the interface, and will execute successfully.
I hope this goes some way towards answering your questions. Let me know if anything is unclear, or if you have any further questions.
I am a bit confused cause I just saw the tutorial and it touches on Inheritance and then I come here and people are speaking about something different. It makes me feel like I am in the twilight zone⌠Too ru ru Too ru ru ru⌠lol
Can someone please help me out here? I am having issues with the code I am working on in the inheritance video. I am not self-destructing a contract. At I am the wrong place? lol
It says I got a âParseErrorâ expected ; but got âContractâ. What gives here? Please and thank you!
I canât help but notice that you donât seem to have worked methodically through the course. You seem to be jumping around a lot between the sections. I mention this because, unless you take the time to work methodically through all the material, and complete and submit all the assignments yourself before looking at the solutions, then you wonât be getting the most out of the course, and itâs not surprising that some of the solutions wonât make sense to you. There are always alternative solutions to these assignments, and unless you submit your own code, you wonât receive any personalised feedback. So, before reading on and seeing my answer to your question about the model solution, if you havenât already â and I canât see your submitted code for this assignment â I highly recommend that you attempt this assignment yourself first.
The code given in the article is an example of how selfdestruct() can be implemented. It is to be used as guidance and is not set in stone. The prescribed aspects of implementing selfdestruct (i.e. what has to be included in the code) is:
It takes one argument which must be a payable address: selfdestruct(address payable owner); (This is usually the contract owner but doesnât have to be)
It must be placed within a function
We are free to define this âwrapperâ function as we wish i.e. we can choose the name, visibility etc.
So, to analyse the code given in the solution:
Weâve just decided to call the âwrapperâ function destroy, but it could be called close (as in the article), or any other name which we think suitably describes the action that this function performs.
Like in the article, we have also given our function public visibility. But not because we have to. This is so that it can be (i) inherited (ii) called from an external service (e.g. Remix or the frontend of a dapp) by the contract owner, who has an external address.
Like in the article we have also given our function an onlyOwner modifier. Again, not because we have to, but because we want to prevent the contract being destroyed by anyone other than the contract owner.
As required, receiver is a payable address. However, there are more concise ways to code this. Any alternative that involves passing a payable address to selfdestruct() is valid. It needs to be a payable address so that, when selfdestruct() is called, the ether balance remaining in the contract can be transferred to the caller.
Thanks for letting us know about this, but where have you actually seen this link? Iâve tried to find where itâs posted so I can remove it, but the only reference to it in this discussion topic is your own post
No, donât worry, you are in the right place, and not stuck in the twilight zone Itâs just that this is the discussion topic for the whole section on inheritance and external contracts, which covers a lot of lessons/videos.
The posts mentioning âself-destructionâ refer to the assignment in this section, which you most likely havenât reached yet, which is why they make no sense to you at the moment.
The key piece of information in your error message is that the compiler expected a semi colon. This actually refers to the missing semi colon at the end of your import statement on the line above. The compiler doesnât actually recognise lines or whitespace, so itâs not until it gets to contract on the next line that it protests and tells us that the next character it was expecting was a semi colon and not the word contract.