Post your solution to the inheritance assignment here. Or ask questions
Hi Filip
I donât see any link as mentioned.
your instructions/ Can yousend the âDestroyerâ link.
Thanks
Guy
Sorry about that. I have updated the lecture now
pragma solidity 0.5.12;
contract Destroyable{
address public owner;
modifier onlyOwner(){
require(msg.sender == owner);
_; //Continue execution
function close() public onlyOwner{
selfdestruct(owner);
}
}
- I opened a new file called Destruction:
import "./ownable.sol";
pragma solidity 0.5.12;
contract SelfDestruct is Ownable {
function toSuicide() public onlyOwner{
selfdestruct (msg.sender);
}
}
in the HelloWorld contract :
import "./ownable.sol";
import "./Destruction.sol";
pragma solidity 0.5.12;
contract HelloWorld is Ownable, SelfDestruct{
After looking at the solution - isnât msg.sender is already âaddress payableâ?
why do we need to convert it again to a âpayable address receiverâ?
Thanks.
Good question. I assume you are talking about this line of code.
address payable creator = msg.sender;
You are correct that msg.sender is already a payable address. But what we do in the code is not a conversion. We are saving msg.sender to a variable. And if we want the address to remain payable, we need to save it to a payable address. If we were to save msg.sender to a non-payable address variable, then it wouldnât be payable anymore.
This would be a âconversionâ (from payable msg.sender to non payable creator).
address creator = msg.sender;
I hope it became clearer now
Yes.Thank you. understand that It is not a conversionâŚbut can we avoid the saving of msg.sender as a variable and use:
function destroy() public onlyOwner {
// address payable receiver = msg.sender;
selfdestruct(msg.sender);
}
It worksâŚand only the owner can destroy the contract so it looks quite safe.
Are there any issues that I am not aware of involved?
Yes, thatâs absolutely safe. Thatâs a better solution than to use a variable as a go-between. But sometimes people find it clearer and easier to read when we break the code up into multiple steps.
created new contract Destroyable:
import "./Ownable.sol";
pragma solidity 0.5.12;
contract Destroyable is Ownable{
function destroyContract() public onlyOwner {
selfdestruct(msg.sender);
}
}
added to main contract:
import "./Ownable.sol";
import "./Destroyable.sol";
pragma solidity 0.5.12;
contract HelloWorld is Ownable, Destroyable{
Destructible contract which inherits from Ownable.
pragma solidity 0.5.12;
import "./Ownable.sol";
contract Destructible is Ownable {
function destroy() public onlyOwner {
selfdestruct(msg.sender);
}
}
HelloWorld contract which inherits from Destructible contract.
pragma solidity 0.5.12;
import "./Destructible.sol";
contract HelloWorld is Destructible{...
}
import "./Ownable.sol";
pragma solidity 0.5.12;
contract Destroyable is Ownable {
function close() public onlyOwner {
selfdestruct(owner);
}
}
Inheritance - Assignment
import"./Ownable.sol";
pragma solidity 0.5.12;
contract Destroyable is Ownable{
function DESTROY() public onlyContractOwner {
selfdestruct(msg.sender);
}
}
Dont forgett to inharit the contract by import it to its child contract âHelloWorldâ.
import"./Ownable.sol";
import"./Destroyable.sol";
pragma solidity 0.5.12;
contract HelloWorld is Ownable, Destroyable {
In this case the inheritance structure looks like:
Ownable <= Destroyable <= HelloWorld
Given that Destroyable
inherits from Ownable
, itâs not necessary to specify HelloWorld is Ownable, Destroyable
though both appear to work. It may be more informative to specify both though doing so is redundant. What is the convention in this case?
âOwnable.solâ:
pragma solidity 0.5.12;
contract Ownable {
address payable public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Caller must be contract owner");
_; // continue execution
}
constructor() public {
owner = msg.sender;
}
}
âDestroyable.solâ:
import "./Ownable.sol";
pragma solidity 0.5.12;
contract Destroyable is Ownable {
function close() public onlyOwner {
selfdestruct(owner);
}
}
âHelloWorld.solâ:
import "./Destroyable.sol";
pragma solidity 0.5.12;
contract HelloWorld is Destroyable {
// etc...
}
import â./Ownable.solâ;
pragma solidity 0.5.12;
contract Destroyable is Ownable{
function close() public onlyOwner { //onlyOwner is custom modifier
selfdestruct(msg.sender); // owner
is the owners address
}
}
In the Ownable.sol file:
pragma solidity 0.5.12;
contract Ownable {
address public owner;
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
constructor() public {
owner = msg.sender;
}
}
In the Destroyable.sol file:
import "./Ownable.sol";
pragma solidity 0.5.12;
contract Destroyable is Ownable {
function close() public onlyOwner {
selfdestruct(msg.sender);
}
}
In the HelloWorld contract file:
import "./Ownable.sol";
import "./Destroyable.sol";
pragma solidity 0.5.12;
contract HelloWorld is Ownable, Destroyable {
etc etc
There isnât much to be said about Mine.sol, except that I want the contract address to be private, for tax purposes.
pragma solidity 0.5.12;
contract Mine {
address private Me;
modifier onlyMe() {
require(msg.sender == Me);
_;
}
constructor() public {
Me = msg.sender;
}
}
CanVanish.sol is just a wrapper around selfdestruct(). It does not need the â_;â as the contract ceases to exist mid-execution of .poof():
import "./Mine.sol";
pragma solidity 0.5.12;
contract CanVanish is Mine {
function poof() public onlyMe{
selfdestruct (msg.sender);
}
}
And the requisite includes and inheritance are the only change to the business-end:
import "./Mine.sol";
import "./CanVanish.sol";
pragma solidity 0.5.12;
contract MyVaporWareContract is Mine, CanVanish{ ...
Destroyable.sol:
import â./Ownable.solâ;
pragma solidity 0.5.12;
contract Destroyable is Ownable{
function destroyContract() public onlyOwner {
selfdestruct(msg.sender);
}
}
added to HelloWorld.sol contract:
import â./Ownable.solâ;
import â./Destroyable.solâ;
pragma solidity 0.5.12;
contract HelloWorld is Ownable, Destroyable{
Destroyable is Ownable , then
function close() public onlyOwner {
selfdestruct(msg.sender);
}
Then Hello word is Destroyable.
Destroyable:
pragma solidity 0.5.12; //compiler version of solidity
import "./Ownable.sol";
contract Destroyable is Ownable {
function destroy() public onlyOwner { //onlyOwner is custom modifier
selfdestruct(owner); // `owner` is the owners address
}
}
Ownable:
pragma solidity 0.5.12; //compiler version of solidity
contract Ownable { //Ownable functions and state variables
address payable public owner; //Modified "owner" state variable to payable address
...
}
helloWorld:
import "./Ownable.sol"; //imports Ownable file in same folder
import "./Destroyable.sol";
pragma solidity 0.5.12; //compiler version of solidity
contract helloWorld is Ownable, Destroyable {
...
}