Inheritance & External Contracts - Discussion

Hi Carlos.

I copied to contract address from the deployed contracts tab, so it should be correct, but I guess I will try a few more times.

Thanks for your help bro!

1 Like

I completed the course and my certificate inherited my nick name, not my real name. Is there a way to reorder the certificate with my real name? I guess I should update the name field in the academy…?

Its still possible to have another display name here on the forums right? I like being Kraken :slight_smile:

1 Like

Congratulations man! :partying_face:

Well you can have a nickname in the forum diferent than the Academy (you can have your real name in the academy, so all certificates goes with your real name…and you can have the Mighty Kraken here in the forum :slight_smile:)

Please write an email to our amazing Support team at: [email protected] , they are waiting for you to help you with the certificate name change :nerd_face:

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

Carlos Z.

1 Like

So im having trouble with my external contract guys. I cant seem to find out what it is im doing wrong so ill post a screenshot of my screen for you to take a look at. Been on this for 2days now. Sadly im no long on leave so im back working on the ship and not able to sit here all day trying to figure this stuff out like id like too. Please help. Ill be on tomorrow to try again

Duuuuka -__-

Hey @DUUKA_SMASH

The compiler is telling you that _from, _to and _amount are not defined in line 16.
You function addTransaction indeed has parameters called from,to, amount (without underscore).

Fix those and you should be able to move forward.

Happy learning,
Dani

2 Likes

Clearly I’ve been working to late and 3hrs of sleep has been beating me down more than i thought. Goodness i don’t know how i missed that even after watching the video a couple times the past two nights before passing out. I guess ill go to bed early tonight. Thanks again…How embarrassing lol.

2 Likes

Don’t be embarrassed @DUUKA_SMASH! :relaxed:
We’ve all done things like this when learning for the first time :sweat_smile: By getting others to point out the obvious mistakes to you, you won’t make them over and over again — but you need to ask these questions to find out what they are in the first place :slight_smile:
You probably realise from @dan-i’s solution, that it’s really important to learn how to understand what the error message from the compiler is telling you. If you work at that, then you’ll be able to debug your code much more quickly :muscle:

3 Likes

Hi I am doing external contracts and there is an error saying that the function addTransaction from Government contract hasn’t been called (unreachable code).
call to Goverment.getTransaction errored: VM error: invalid opcode. invalid opcode The execution might have thrown. Debug the transaction to get more information.
The result is when I call getTransaction from Government contract, the transactionLog at index 0 returns nothing after successfully transferring between 2 other contracts (seems that its consistent with the error notification) Could you please help explain? Thanks

pragma solidity 0.7.5;

contract Goverment{
    struct Transaction {
        address from;
        address to;
        uint amount;
        uint txId;
    }
    
    //create an array [ ] of transaction object:
    Transaction [] transactionLog; //1st transaction will have ID = 0
    
    function addTransaction (address _from, address _to, uint _amount) external {
        
        Transaction memory _transaction = Transaction(_from, _to, _amount, transactionLog.length);
        transactionLog.push(_transaction);       //push into the array transactionLog;
        
        // we can combine two lines to save up space
        // transactionLog.push( Transaction(_from,_to, _amount, transactionLog.length) );
        
        // we can create an event for transactionLog
        
    }
        
    function getTransaction (uint _index) public view returns (address, address, uint){
        
        return (transactionLog[_index].from, transactionLog[_index].to, transactionLog[_index].amount); 
    }
}        

    

pragma solidity 0.7.5;

// memory - temporary storage used in function execution
// calldata - ssave arguments/ input to our functions
// string, array, mapping, struct

import "./Ownable.sol";
import "./Destructible.sol";


//GovermentInterface include the contract definition and contract address 
interface GovermentInterface{
    function addTransaction (address _from, address _to, uint _amount) external;
} 



contract Bank is Ownable, Destructible { // name of contract, not name of file 
    //state variables (contract scope)
    
    GovermentInterface govermentInstance = GovermentInterface(0xDA0bab807633f07f013f94DD0E6A4F96F8742B53);
    // we are instancing an instance of GovermentInterface using the address
    
    mapping(address => uint) balance;    // input an address of owner (key), get a uint balance (value)
    
    event depositDone (address indexed depositedTo, uint amount); // indexed so we can query later based on address for ie
    
    function deposit() public payable returns (uint){ //remove ownlyOwner because there are many owers deposioting into this Contract
        // add "payable" because this to to receive money 
        // no view or pure because we will modify the mapping
        // require(msg.sender == owner); << no need if defined earlier in contract 
        // only ownder is authorized to add balance
        
        balance[msg.sender] += msg.value; // only for internal tracking (contract's balance is sum of indidvidual balance)
       
        emit depositDone (msg.sender, msg.value); //fire event 
        
        return (balance[msg.sender]);
    }
    
    function withdraw(uint amount) public returns (uint){
        //the withdraw function header also includes returns(uint). This is not mandatory to include, and the function can still operate effectively without returning a value. 
        //But as it’s been included in the function header -> include a return statement in the function body.
        //msg.sender is an address and payable
        
        //Option 1: send to other address
        
        //address payable toSend = '0x5B38Da6a701c568545dCfcB03FcB875f56beddC4' // any other addresses
        //toSend.transfer(amount);
        
        //Option 2: withdraw and sent to onlyOwner 
        require (balance[msg.sender] >= amount, "Balance not sufficient");
        //only the remaining gas after require() has thrown will be refunded, and not the gas consumed for executing require() itself and any code executed previously.
        
        balance[msg.sender] -= amount; // effects (update the contract state for reduction in balance)
        //it’s important to modify the contract state before you actually perform the transfer of funds out of the contract,
        //just in case there is an attack after the transfer, but before the state is modified to reflect this operation. 
        
        msg.sender.transfer(amount); //transfer is built-in method in msg.sender, safer to do this because it has built-in error handling like in "require"
        return balance[msg.sender];
        
    }
    
    function getBalance() public view returns (uint){ //return actual new balance
        return (balance[msg.sender]);
     }
     
     function transfer(address recipient, uint amount) public {
         
         //check balance of msg.sender
         require (balance[msg.sender] >= amount, "Balance not sufficient");
         require (msg.sender != recipient, "Dont transfer money to yourself"); 
         
         uint previousSenderBalance = balance[msg.sender]; //before and after transfer
         
         return _transfer(msg.sender, recipient, amount); // input transfer amount, with or without "return" works fine 
         
         govermentInstance.addTransaction(msg.sender, recipient, amount); 
         // we made a call to seperate external contract 
         
         assert (balance[msg.sender] == previousSenderBalance - amount); //validate
         // assert will not generate error unless we have something wrong 
         // use to avoid conditions which should never, ever be possible
     }
     
     function _transfer(address from, address to, uint amount) private {
         balance[from] -= amount;
         balance[to] += amount;
     }
        
        
}

Hello All!
Anyone having issues with the recording about 3/4 ways where it stopped and seems like it’s just searching. I am unable to complete slide 2. My internet is up and firing, so I know it’s not that. I refreshed the browser multiple times and no luck.

Ty!

Hi @gwen

A function ends as soon as it reaches a return statement therefore govermentInstance.addTransaction(msg.sender, recipient, amount); will never be executed.

 return _transfer(msg.sender, recipient, amount); 
         
 govermentInstance.addTransaction(msg.sender, recipient, amount); 

Cheers,
Dani

2 Likes

Hi @rallen221,

Are you still having problems with this? Occasionally, I also experience that same problem and usually what ends up working for me is logging out of the Acadamy and back in again, and then returning to the video and starting to watch a short while before you got the stuck “searching” icon. Sometimes, when the image keeps freezing for a few seconds (but the audio continues just fine) but without the complete freeze with the “searching” icon, I often find just exiting that lecture and then entering again sorts that.

I hope you’ve either already resolved it, or the above tricks help you to move on. But let us know if you’re still having problems. I know it can be really frustrating!

  1. What is the base contract?

The base contract refers to a contract that a derived contract inherits from.

  1. Which functions are available for derived contracts?

The ones available in the base contract.

  1. What is hierarchical inheritance?

This describes where a single contract acts as a base contract for multiple other contracts (derived contracts).

1 Like
  1. What is the base contract?
    Base contract is the contract that is inherited, aka the parent contract

  2. Which functions are available for derived contracts?
    All public and internal state variables and scoped functions are available to derived contracts.

  3. What is hierarchical inheritance?
    Is when a single contract as the base contract for multiple derived contracts.

1 Like

Hi everyone, I am unable to understand and answer the below question from the quiz-
If you call a function in contract A, which calls a function in Contract B, what will msg.sender be in Contract B’s function?

Can someone explain this?

Hi @hashmiabrar1,

msg.sender is always available to use within a function, and it refers to the address that calls the function in which it is used.

So, if you call a function in contract A, if msg.sender appears in that function’s code, it will refer to your address.

As well as users having wallet addresses, each smart contract gets its own address when it is deployed. So, if the function we called in contract A contains a function call which invokes another function in contract B, the caller of this second function will not be a user, but a smart contract — smart contract A. So, can you also now see that if msg.sender is used in the code in contract B’s function body, it will refer to contract A’s address?

This can be hard to conceptualise at first, so if anything is still unclear, or if my explanation raises further questions, then just let us know and we’ll help you further :slight_smile:

1 Like
  1. What is the base contract?
    The base contract is one member of an inheritance relationship that Solidity supports. This relationship allows other contracts are derived from the base contract to re-use the base contract’s code without having to re-implement it in the derived contract.
  2. Which functions are available for derived contracts?
    All public and internal scoped functions of a base contract are available to any contracts that are derived from them.
  3. What is hierarchical inheritance?
    In a hierarchical inheritance the same contract is the base contract for many derived contracts.
1 Like
  1. What is the base contract?
    The base contract is the “parent” contract.
  2. Which functions are available for derived contracts?
    All functions that are public or internal are able to work/run on the contract that inherits from it.
  3. What is hierarchical inheritance?
    Hierarchical inheritance is again similar to simple inheritance. Here, however, a single contract acts as a base contract for multiple derived contracts.
1 Like

Hello, I was trying to follow your Using Internal Visibility Level class and for some reason I get the following error:
browser/HelloWorld.sol:83:41:
DeclarationError: Undeclared identifier. emit
personDeleted(name,senior,owner);
I even copy the filip github

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

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

}
Ownable.sol
pragma solidity 0.5.12;

contract Ownable{
//When the Hello World contract is deployed the owner
// button is depolyed
//address public owner;

address private owner;
//if we make the owner variable private,
// the Ownable contract will be 
//only contract that will be accessed the
//owner variable. 
//HelloWOrld or Destroyable can't access it. 
modifier onlyOwner(){
    require(msg.sender == owner);
    _; //Continue execution
}

constructor() public{
    owner = msg.sender;
}

}

1 Like

Hi @siratoure95, hope you are ok.

The error in your code is on the deletePerson function, when you emit the event, your are sending 3 parameters to the event, emit personDeleted(name, senior, owner); , the problem here is that you are sending the owner variable which you have not defined in your HelloWorld, the owner variable is declared in the Ownable Contract has PRIVATE, which means that ONLY the contract have access to that variable.

So you have 2 options for that case:

  • Create a getOwner public function in Ownable.
  • Switch the owner variable to public or internal.

Try it and let me know how it goes :nerd_face:

Carlos Z

  1. What is a base contract?
    Base contract is actually a “parent” contract.
  2. Which functions are available for derived contracts?
    All public and internal scoped functions, as well as state variables.
    3.What is hierarchical inheritance?
    Where a single contract acts as a base contract for multiple derived contracts.
1 Like