Inheritance & External Contracts - Discussion

@TommyBrook Thanks for reaching out!
To make the compiler work, you will have to change

to pragma solidity >0.5.12;

In your code the version is limited to 0.5.12 hence you are getting the error :slight_smile:

1 Like

Thanks, Taha.
But how can I change the code to make work with compilers 0.6.0 and above?
What if I want to have pragma solidity 0.6.0; only? without the >
That was my intention behind the question.

I still get errors using your method though:

browser/External 2.sol: Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use “SPDX-License-Identifier: UNLICENSED” for non-open-source code. Please see https://spdx.org for more information.

browser/External 2.sol:4:1: TypeError: Contract “HelloWorld” should be marked as abstract.
contract HelloWorld {
^ (Relevant source part starts here and spans across multiple lines).
browser/External 2.sol:5:5: Missing implementation:
function createPerson(address creator, string memory name, uint age, uint height) public payable ;

browser/External 2.sol:5:5: TypeError: Functions without implementation must be marked virtual.
function createPerson(address creator, string memory name, uint age, uint height) public payable ;

@filip
In the external contract video this is the code you used:

pragma solidity 0.5.12;

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

contract ExternalContract{
        
    HelloWorld instance = HelloWorld (Address);
    
    function externalCreatePerson (string memory name, uint age, uint height) public payable{
    instance.createPerson.value (msg.value) (name, age, height);      
    }
}

This is the code that you posted in Github:

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(<ADDRESS>);

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

Why did you add msg.sender in the last line? Adding msg.sender actually does not allow me to create a person. It gives me this error instead:

" transact to ExternalContract.externalCreatePerson errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information."

@TommyBrook
Yes,

pragma solidity >0.6.0; this will work with compilers 0.6.0 and above

Use
pragma solidity 0.6.0;

This is not an error only warning hence can be ignored

[quote=“TommyBrook, post:66, topic:9641”]
browser/External 2.sol:4:1: TypeError: Contract “HelloWorld” should be marked as abstract.
contract HelloWorld {
^ (Relevant source part starts here and spans across multiple lines).
browser/External 2.sol:5:5: Missing implementation:
function createPerson(address creator, string memory name, uint age, uint height) public payable ;

For these error, can you upload on GitHub and provide a link?

1 Like

@TommyBrook

function createPerson(address creator, string memory name, uint age, uint height) public payable;
}

If you see the function createPerson first parameter is address creator hence we need to define an address which is msg.sender in this case.

If we try to read and debug your error :slight_smile: we can clearly read that it says the value you are trying to send is more than your balance.

Hope this answers the question.

Please feel free to ask more questions if you have :slight_smile:

1 Like

pragma solidity 0.5.12;
import ‘./Destroyable.sol’;

contract HelloWorld is Destroyable{

import “./Ownable.sol”;
pragma solidity 0.5.12;

contract Destroyable is Ownable {

function destroy() public onlyOwner {
address payable receiver = msg.sender;
selfdestruct(receiver);
}
}

1 Like

what does “map” mean?
image
The file name is “inherit”(the child contract)
in the video the name before “browser” was the same as file’s name.

1 Like

Hello @sajede.k, hope you are OK.

Now, have you checked the name of your contract? the map should be the name of it.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

1 Like

Hello
yes you’re right :slight_smile:
thanks a lot.

1 Like

Hello,
when I deploy the external contract, I run into this error although I used the codes in the GitHub (I mean they are reliable and functions are payable) and my balance is 1 ether when I’m creating person(just like what we did in previous codes):


could anybody help with it?

1 Like

Hello @sajede.k, hope you are great.

Could you please share your code? so we can review it to help you get the error.
The console said the function should be payable... and the value that you send should be less than your current balance.

I will be glad to help you, but i need to see the code. :nerd_face:

You can use the “Preformatted Text” Button to encapsulate any kind of code you want to show.


function formatText(){

let words = “I’m a preformatted Text box, Please use me wisely!”

}

prefromatted_text-animated

Carlos Z.

1 Like

Hello,
Thanks a lot
But i used codes that Fillip posted in github.
I also checked the steps with the vedio again.
Please tell me about the steps,should i deploy the ownable.sol and destroyable.sol before helloworld.sol for example?
In his code(in External contract folder) there was this line “helloworld is ownable,destroyable”
But at the beginning these contracts weren’t imported(i mean /.ownable…) which i added, is it correct?

1 Like

Hi @sajede.k,

No, you just need to deploy HelloWorld first, as Ownable and Destroyable will automatically be inherited. Make sure you are deploying HelloWorld from the CONTRACT dropdown and not Destroyable or Ownable.

The imports have actually been missed off in the code in Filip’s GitHub. You are right that whichever contracts are inherited in the contract header, should also be imported at the very top of the file.

After you have deployed HelloWorld you need to remember to copy the contract address (there is an icon you can click to do this next to the address which is just below the heading Deployed Contracts, and above all the function calls when you’ve expanded them). Then, before deploying contract External, you must remember to paste the HelloWorld contract address where it says <ADDRESS> in the following line of code in contract External:

HelloWorld instance = HelloWorld(<ADDRESS>);

If you haven’t done this before deploying External, then this will result in the error you are getting.

If you are still getting the error after making sure you’ve done what I’ve explained above, then the only other way we can help you is to see your code in the way that @thecil has already explained. Even if you say you’ve used the exact same code as in Filip’s GitHub, there could still be a copy-and-paste or formatting error somewhere which is causing it.

Anyway, try what I’ve suggested above first, and if that doesn’t resolve your issue, then we’ll take it from there.

1 Like

addressThanks a lot.
yes I pasted the addres of contract


this is the external contract and the error I get.

and following code is Helloworld

pragma solidity 0.5.12;
import ‘./Destroyable.sol’;

import ‘./Ownable.sol’;

contract HelloWorld is Ownable, 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(100 wei){

  require(age < 150, "Age needs to be below 150");

  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;

}

}

Hi @sajede.k,

Your createPerson function in HelloWorld has the following parameters:

function createPerson(string memory name, uint age, uint height) ... {...}

But you have an additional address parameter in your interface:

function createPerson(address creator, string memory name, uint age, uint height) ... ;

… and externalCreatePerson is also trying to call createPerson with this additional address argument:

instance.createPerson.value(msg.value)(msg.sender, name, age, height);

msg.sender doesn’t need to be explicity stated as an argument and passed to createPerson, because the caller’s address can be accessed automatically within createPerson with msg.sender , anyway. I’m not exactly sure why this is giving you the actual error you are getting, but if you remove msg.sender from the function call, and also the addtional parameter  address creator  from the interface, then you should find you no longer get the error. I can see why you’ve added these two extra address references, because they are included in Filip’s code in GitHub. This is actually an error and needs to be corrected (@thecil). Can you see why you don’t need these additional address references? I’m pretty sure Filip doesn’t include them in the actual video, but I’ll watch it again just to check.

I’m sure you are already, but don’t forget that you also need to call the exernalCreatePerson function with at least 100 wei (because this is what is required by createPerson in the external contract, which is called from within externalCreatePerson, and the payment is passed with the code .value(msg.value) .

I hope this resolves your issue, but let us know if you’re still having problems.

2 Likes

Thanks a lot.
you’re right. That worked.
I had noticed that but I thought I have forgotten that from the video.
checked the video, you’re right it wasn’t in the video.
any way I really appreciate your help I’m glad finally deployed an external C :grinning:

1 Like

To change the code to compile with solidity compiler 0.6.0 and above:

  1. you must make the contract abstract
  2. you must make the function virtual

abstract contract HelloWorld {
function createPerson{string memory name, uint age, uint height) virtual public payable;
}

1 Like

Hello Filip,

I made my contract the same as yours, but got an error at the “contract ExternalContract”

What is the reason?

pragma solidity 0.5.12;

//interface
contract HelloWorld{
function createPerson(string memory name, uint age, uint height) public payable costs(1 ether){
}

contract ExternalContract{

HelloWorld instance = HelloWorld(0x5B38Da6a701c568545dCfcB03FcB875f56beddC4);

function createPerson(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);
    
}

}

I get this error message when trying to compile the external contract:
browser/externalContract.sol:10:52: SyntaxError: This looks like an address but has an invalid checksum. Correct checksummed address: “0xDCB77B866fE07451e8F89871EdB27b27aF9F2AFC”. If this is not used as an address, please prepend ‘00’. For more information please see https://solidity.readthedocs.io/en/develop/types.html#address-literals
HelloWorldMapping instance = HelloWorldMapping(0xdcb77b866fe07451e8f89871edb27b27af9f2afc);

The code: pragma solidity 0.5.12;

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

contract externalContract{

HelloWorldMapping instance = HelloWorldMapping(0xdcb77b866fe07451e8f89871edb27b27af9f2afc);

function createPerson(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); 
}

}

Whats wrong?
^----------------------------------------^

1 Like

Are you sure that is the correct address of your HelloWorldMapping contract?

Remember that the instance will look on a address to find the contract and then create the interface, if the address is not the correct one, that error could happen, meaning you have to verify the address of the contract that you want to instantiate.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.