Inheritance & External Contracts - Discussion

Welcome to the forum discussion for this section. Here you can ask questions or post feedback.

7 Likes

Hi Filip. for your attention:

In the video, it is not presented how to get the HelloWorld contract address (for copying it into the "HelloWorld instance variable, I figure it out only from listening).

Also, it seems like the contract code link is not for the required code (I may wrong with that).

Thank you, I have fixed the video. It’s uploading now.

In regards to your second question about the code. I don’t fully understand what you are referring to, could you clarify?

To the Github code link. (it link’s to the memory assignment solution (sorry for the broken English previously…)

Ok, I get it. Thank you, I have updated the link :slight_smile:

hi Filip

I am currently going through the course, but unable to deploy any contracts along side your course for myself because all the accounts in Remix have been set to 0 funds. Do you know how I can add funds to at least one of the accounts in the Deploy and Run Transactions section?

Many thanks
Iris

2 Likes

I resolved this by closing and reopening remix. I copied and pasted my code as non of the files were saved.

1 Like

Are you using the javascript VM? They should have an initial balance. Maybe you solved it now by re-opening it. If you are using a testnet, you need to use a faucet to fund your account through metamask.

Hi Filip

Thanks very much for replying, I was just using VM and following the course and it was working fine, but suddenly all the accounts became value 0, so I was not able to deploy anything. Its all good now, thanks again.

Iris

1 Like

Question: How come in the lesson we create an “interface” to an external contract using the “contract” keyword and not the “interface” keyword?

Hi again :wink: @CryptoDev

Because in the course we are implementing an abstract contract, which have the same utility at the end and is more permissif than an interface.
So if you want it to be more correct we are implementing an abstract contract which gonna be use as an interface.

https://solidity.readthedocs.io/en/v0.5.3/contracts.html#abstract-contracts

The post explain well the main difference between this two declaration.

2 Likes

@filip
I’am wondering how to call getPerson from External contract to get data for msg.sender External. I tried this code but all values are 0 in my External contract view.

pragma solidity 0.5.12;
//Interface (only function headers)
contract HelloWorld{
function createPerson(string memory personName,uint personAge,uint personHeight) public payable;
function getPerson() public view returns(string memory name, uint age, uint height, bool senior, bool infant);
}

contract ExternalContract{

HelloWorld instance = HelloWorld(0x6E93aa93B8Ad072F6dc16385F1C6DE0721D716b9);

function ExternalCreatePerson(string memory name,uint age,uint height) public payable{
    //call createPerson in HelloWorld contract
    //Forward any ether to HelloWorld
    instance.createPerson.value(msg.value)(name,age,height);
}

function ExternalGetPerson() public view returns(string memory name, uint age, uint height, bool senior, bool infant){
    instance.getPerson();
}

}

1 Like

@filip The link in this video is to the solution and not to the correct version of the code as displayed in this video https://academy.ivanontech.com/products/ethereum-smart-contract-programming-101/categories/1792368/posts/5952755

1 Like

Yes, that is correct.
It links to the repository with the final contract files.
We can use them to look at if we struggle with our own code. :man_teacher:

Ivo

1 Like

@ivga80 Ivo, still having problems with external. I received this error: VM error: invalid opcode. invalid opcode The execution might have thrown.
So I commented out the loop, and this error went away, but still continued will problems. I am not sure if it is the address or msg.sender in external contract.

 import "./Ownable.sol";
pragma solidity 0.5.12;
//this is how to write a inheritance
contract HelloWorld is Ownable{

    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(toTransfer);
       return toTransfer;
   }
   /*function close() public onlyOwner{ 
   selfdestruct(owner);  
 }*/

}
pragma solidity 0.5.12;

contract Ownable {
    address internal owner;
    
    modifier onlyOwner(){
        
        require(msg.sender == owner);
        _; //Continue execution
    }
    constructor() public{
        owner = msg.sender;
    }
       
}
pragma solidity 0.5.12;

//Interface
contract Inheritance{
    function createPerson(address creator, string memory name, uint age, uint height) public payable;
}

contract ExternalContract{

    Inheritance instance = Inheritance(0xD3755576a0413ADd8Ba11B5430692630DEa74cCE);

    function externalCreatePerson(string memory name, uint age, uint height) public payable{
        //CALL createPerson in HelloWorld contract
        //Forward any ether to HelloWorld
        instance.createPerson.value(msg.value)(msg.sender, name, age, height);
    }
}

Hi, cherrybluemoon.

I’m looking at this from my mobile, but I can see that your function createperson in the contact interitance is missing its brackets, and it’s empty? I’m confused, is that suppose to create a person in the contract HelloWorld?

The createPerson function in HelloWorld takes 3 arguments. name, age, and height, so you can’t pass the msg.sender to that function.

Does it also look like you have both the contract Inheritance and the contract ExternalContract in the same file? Or is this just a typing error?

Ivo

I double checked function createPerson has all brackets.

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);
    }

I changed contract inheritance to contract HelloWorld and still have same results

pragma solidity 0.5.12;

//Interface
contract HelloWorld{
    function createPerson(address creator, string memory name, uint age, uint height) public payable;
}

contract ExternalContract{

    HelloWorld instance = HelloWorld(0x4144C06e60a5D59a77772A51c82E48b134397bb5);

    function externalCreatePerson(string memory name, uint age, uint height) public payable{
        //CALL createPerson in HelloWorld contract
        //Forward any ether to HelloWorld
        instance.createPerson.value(msg.value)(msg.sender, name, age, height);
    }
}

message received is:transaction reverted, the call function should be payable…
Those functions have “payable”

@ivga80 You were right, I had to many arguments in the external contract. Thank you for keeping me pointed in the right direction! :smiley:

1 Like

Why does inheritance not reduce gas??

What are some benefits of using inheritance as part of your code?

Your Answer

check_box Reduces code duplication

check_box Creates a clear code structure

check_box Reduces gas cost

Correct Answer

check_box Reduces code duplication

check_box Creates a clear code structure

Are you asking why? or are you saying that inheritance reduces gas?
I don’t get it.
ivo