I think one of the sticking points for me was payable vs non payable addresses and how you convert from address to payable address
address payable address2 = address(uint160(address1));
I think one of the sticking points for me was payable vs non payable addresses and how you convert from address to payable address
address payable address2 = address(uint160(address1));
Looks like you’ve got it sorted now… but let us know if anything still isn’t making sense. These things can often take a while to click into place.
import "./Ownable.sol";
pragma solidity 0.5.12;
contract Destroyable is Ownable{
function close() public OnlyOwner{
address payable creator = msg.sender;
selfdestruct(creator);
}
}
Yes, I understand, the owner-address needs to be converted into a payable address (by being converted into 160-bit code and then being re-converted into the payable-address format)—or be defined to be payable right from the outset. I did not think about that when I wrote my solution but it was explained in the solution video.
Thank you so much for your reply, Jonathan.
import “./Ownable.sol”;
pragma solidity 0.5.12;
contract Destroyable is Ownable {
function close() public onlyOwner {
address payable receiver = msg.sender;
selfdestruct(receiver);
}
}
pragma solidity 0.5.12;
import "./Ownable.sol";
contract Destroyable is Ownable {
function destroy() public onlyOwner {
address payable owner = msg.sender;
selfdestruct(owner);
}
}
import "./Ownable.sol";
contract Destroyable is Ownable {
function destroy() public onlyOwner {
selfdestruct(msg.sender);
}
}
file: Destroyable.sol
import “./Ownable.sol”;
pragma solidity 0.5.12;
contract Destroyable is Ownable {
function close() public onlyOwner { //onlyOwner is custom modifier
// owner = msg.sender;
selfdestruct( msg.sender );
}
}
was correct up to figuring out the payable address … needed help so watched the next vid
My first solution was pretty much the same as what most people here came up with. A new contract Destroyable that extends Ownable with an ownerOnly destroy() function. I didn’t quite like the weird circular inheritance though and decided against multi-level inheritance so the signature of HelloWorld would disclose all contracts. After reading the solidity docs I went for the following solution.
pragma solidity 0.5.12;
contract Destroyable{
address public destructor;
constructor(address _destructor) public{
destructor = _destructor;
}
function destroy() public{
require(msg.sender == destructor, 'You cannot do that');
address payable beneficiary = address(uint160(destructor));
selfdestruct(beneficiary);
}
}
HelloWorld.sol
import "./Ownable.sol";
import "./Destroyable.sol";
pragma solidity 0.5.12;
contract HelloWorld is Ownable, Destroyable(msg.sender){
...
}
This feels a bit more composable to me. Plus it adds some flexibility as to who may destroy the contract. Not sure if this is really a valid use case though. Would appreciate some feedback if this approach makes sense at all.
1. OWNABLE FILE:
pragma solidity 0.5.12;
contract Ownable{
address public owner;
modifier onlyOwner(){
require(msg.sender == owner);
_; //Continue execution
}
constructor() public{
owner = msg.sender;
}
}
2. DESTROYABLE FILE:
import “./Ownable.sol”;
pragma solidity 0.5.12;
contract Destroyable is Ownable{
function destroy() public onlyOwner {
selfdestruct( msg.sender );
}
}
3.HELLOWORLD FILE
import “./Destroyable.sol”;
pragma solidity 0.5.12;
contract HelloWorld is Destroyable {…
Self Destructing Contract
pragma solidity 0.5.12;
import “./Ownable.sol”;
contract Destroyable is Ownable {
function destroy() public onlyOwner {
selfdestruct(msg.sender);
}
}
HelloWorld Contract
pragma solidity 0.5.12;
import “./Ownable.sol”;
import “./Destroyable.sol”;
contract HellowWorld is Ownable, Destroyable{}
Nice solution @rou369
… also, check this post out — it explains how you can make an additional adjustment in terms of the inheritance. I think you’ll find it interesting.
Yeah, i was on the tight track actually. Next time i’ll try harder!
pragma solidity 0.5.12;
import ‘./Destroyable.sol’;
contract HelloWorld is Destroyable{
struct Person {
uint id;
string name;
uint age;
uint height;
bool senior;
}
event personCreated(string name, bool senior);
event personDeleted(string name, bool senior, address deletedBy);
uint public balance;
modifier costs(uint cost){
require(msg.value >= cost);
_;
}
mapping (address => Person) private people;
address[] private creators;
function createPerson(string memory name, uint age, uint height) public payable costs(1 ether){
require(age < 150, "Age needs to be below 150");
require(msg.value >= 1 ether);
balance += msg.value;
//This creates a person
Person memory newPerson;
newPerson.name = name;
newPerson.age = age;
newPerson.height = height;
if(age >= 65){
newPerson.senior = true;
}
else{
newPerson.senior = false;
}
insertPerson(newPerson);
creators.push(msg.sender);
assert(
keccak256(
abi.encodePacked(
people[msg.sender].name,
people[msg.sender].age,
people[msg.sender].height,
people[msg.sender].senior
)
)
==
keccak256(
abi.encodePacked(
newPerson.name,
newPerson.age,
newPerson.height,
newPerson.senior
)
)
);
emit personCreated(newPerson.name, newPerson.senior);
}
function insertPerson(Person memory newPerson) private {
address creator = msg.sender;
people[creator] = newPerson;
}
function getPerson() public view returns(string memory name, uint age, uint height, bool senior){
address creator = msg.sender;
return (people[creator].name, people[creator].age, people[creator].height, people[creator].senior);
}
function deletePerson(address creator) public onlyOwner {
string memory name = people[creator].name;
bool senior = people[creator].senior;
delete people[creator];
assert(people[creator].age == 0);
emit personDeleted(name, senior, owner);
}
function getCreator(uint index) public view onlyOwner returns(address){
return creators[index];
}
function withdrawAll() public onlyOwner returns(uint) {
uint toTransfer = balance;
balance = 0;
msg.sender.transfer(balance);
return toTransfer;
}
}
import "./chp5-ex01-c4-parentChild-ownable.sol";
pragma solidity 0.5.12;
contract Destroyable is Ownable{
function selfDestruct() public onlyOwner {
//edit, correction after video.
address payable receiver = msg.sender;
selfdestruct(receiver);
// original:
// selfdestruct(msg.sender);
}
//Trying to use the owner variable from its parent contract
// in selfdestruct function but i cant compile after ward.
}
And then you import and add the contract name to the derived contract header.
Hi @Crypto_James,
The full contract we need to see is your contract Destroyable, as that’s the new one for this assignment. We also need to see your contract Ownable, but only if any additional modifications were necessary there (sometimes they are, sometimes they’re not, depending on how you construct Destroyable).
Your amendments to the beginning of contract HelloWorld, so that it inherits contract Destroyable, are correct
Hi @guillaume_M-D,
Your original solution was absolutely fine:
selfdestruct(msg.sender);
You don’t need the additional step shown in the video. In fact your original solution is better, as it’s more concise. Have a look at this post for further details.
You can use the owner
variable instead of msg.sender
, but owner
is a non-payable address, so you need to convert it into a payable address in either of the following two ways:
/* METHOD 1 - convert to payable address in contract Ownable */
// contract Ownable
address payable public owner;
// contract Destroyable
selfdestruct(owner);
/* METHOD 2 - convert to payable address in contract Destroyable */
// contract Ownable - no change
address public owner;
// contract Destroyable
selfdestruct(address(uint160(owner)));
// or if you prefer...
address payable receiver = address(uint160(owner));
selfdestruct(receiver);
I hope that clears things up for you. Just let us know if you have any further questions.
oo thank you sir,
It was late yesterday when i finished the course and it was actually two of the questions that stayed on my pad
I tried googling about converting address, but I was probably to drained.
The first method is actually what I’d prefer/see as the cleanest logical way.
It brings a new question, is there situation where you don’t want the owner address payable?
I actually needed a visual example for converting addresses, again thanks a lot!