Ethereum Smart Contract Programming

Mapping Assignment for Ethereum Smart Contracts UPDATED

(I’m not sure I’m posting this in the right section so please advise me if it’s out of place.)

The problem that we have created in the initial mapping video is that one address can only be mapped to one dog. Therefore one address cannot own multiple dogs.

At the moment I’m not sure how to correct this error so I’ll be looking forward to one of the next videos. :slight_smile:

1 Like

Thank you for watching :wink:

When you do multi line strings you need to use a specific quotation mark, namely this one `, while you used this one ’.

I know that toshitimes forum sometimes encodes these quotation marks a bit weird. So copy pasting might not work.

Filip,

Thank you. I never use that particular quotation mark so I couldn’t figure out what I had copied incorrectly.

Exercise to call getBalance function in DogContract from ExternalContract:

DogContract:

pragma solidity 0.5.1;

import “./animal2.sol”;

contract DogContract is AnimalContract{

modifier costs(uint amount) {
    require(msg.value >= amount);
    _;
    // refund the difference when user sends more than the required amount
    if(msg.value > amount) {
      msg.sender.transfer(msg.value-amount);
    }
}

function addDog(string memory _name, uint _age) public payable costs(10000) returns (uint) {
    return _addAnimal(_name, _age, AnimalType.DOG);
}

  function getBalance() public view returns(uint) {
  return address(this).balance;
}

}

ExternalContract:

pragma solidity 0.5.1;

contract DogContract{

function addDog(string memory _name, uint _age) public payable returns (uint);

function getBalance() public view returns (uint);

}

contract ExternalContract {
// Interact with DogContract
//
DogContract dcInstance = DogContract(0x0971B5d216af52c411C9016BBc63665b4E6f2542);

function addExternalDog(string memory _name, uint _age) public payable returns (uint){
    return dcInstance.addDog.value(msg.value)(_name, _age);
}
function externalGetBalance() public view returns (uint) {
    return dcInstance.getBalance(); 
}

}

Does anyone else get an error when you try to replace “string” with “int”?
contract testContract{

string output;

constructor(string memory _output) public{
output = _output;
}

function testOutput() public view returns(string memory){
return output;
}
function setOutput(string memory _output) public{
output = _output;
}
}

If you are talking about having string as the input parameter you also need to remove memory. You don’t need that for integers.

Yeah, I just realized that after messing around with it. I guess I’ll find out why we can’t use memory in the next video.

1 Like

Wow! i did it in my firt shot… @filip you are a good teacher! YEAH!!!

2 Likes

For mappings assignment is the error not being able to store multiple objects in a address? Also if I skipped directly to the EOS section will the cause me any problems because I didn’t learn the other stuff?

1 Like

Yes, and that it will get overwritten if you try to add a second one.

1 Like

Great job Blank! I found the same issue when playing with the code

1 Like

For the ethereum memory assignment the bug was that the changes were written to memory and not to storage (long term).

the fix ==>

function updateBalance(uint id, uint balance) public {
  users[id].balance = balance;
}
3 Likes

Thanks! I also had this issue and now it is resolved

External contract assignment:
pragma solidity 0.5.1;

//interface for DogContract
contract DogContract{
function addDog(string memory _name, uint _age) public payable returns (uint);

 function getBalance() public view returns (uint) ;

}

contract ExternalContract{
DogContract dcInstance = DogContract(0x086a96DA3613A016eCb9477f667EF067b6671F1C);

function addExternalDog(string memory _name, uint _age) public payable returns (uint){
    return dcInstance.addDog.value(msg.value)(_name,_age);
}

function getExternalBalance()public view returns (uint){
    
    return dcInstance.getBalance();
}

}

HOWEVER, this code does not return the change. If I pay 3000 wei, it will not return the excess.

1 Like

Hi Filip!
in the video arrays and structs I think there is a “bug” in your code. I didnt get why you put the -1 at the end of line 13, so i just skipped it and my contract worked just fine. Then i check also arbitrary values and figured out that this last statement doesnt affect the returned id at all. So for example when i put 12 it still works for me, see code below:

pragma solidity 0.5.1;

contract DogContract {
    
    struct Dog {
        string name;
        uint age;
    }
    
    Dog[] dogs;
    
    function addDog(string memory _name, uint _age) public returns (uint) {
        return dogs.push(Dog(_name, _age)) -12;
    }
    
    function getDogsName(uint _id) public view returns (string memory) {
        return dogs[_id].name;
    }
}

So the returned uint is not used anywhere in the code. So leaving out the whole return statement also works fine for me (i still can use the getDogsName function properly!):

function addDog(string memory _name, uint _age) public {
    dogs.push(Dog(_name, _age));
}

EDIT: just watched the next episode, and there you also deleted the return value, so i guess it was not necessary, right? One final question i have: is there a console log i can use to check some values? For example how can i print something to the console to see the value of it?

I think you have misunderstood why we return the integer. We return the integer from the function to get the ID where it was saved in the array. So when we add the first dog, it will get id 0 in the array. Then we want to addDog function to return that ID. If we didn’t have the -1 it would return 1, not 0. So we need that -1.

The contract will work without it. But it’s not as clear.

And be VERY careful with adding for example -12. Because of integer overflow, which comes later in the course. Could have dangerous effects in a real world scenario. Look for example what the functions returns when you have -12 in the return statement.

When it should have returned 0.

And BTW, we did not remove the integer in the next video because it wasn’t necessary. We remove it in the next video because we switch from storing the dogs in an array to storing them in a mapping. Then we don’t need to return the array position anymore.

ahhh lol ok sorry for the misunderstanding :sweat_smile::joy: I could replicate what you posted, so thank you! So I think I got it now, just correct me if im wrong:

  • we need to return the uint because different persons can add dogs, and without the uint they would not know where their dog is stored in the array (because actors do not neccecarely communicate with each other)
  • when we do it with adresses this process is automated
  • when we push a value to an array like dogs.push(...) then the push function returns the index of the next free position in this array (thats why we add -1).

Sorry again I was too fast with my conclusion on my initial post :sweat_smile: And thanks for clarification and the fast feedback, really helped me!

Yes that’s correct. Good job on grasping it!!

The only small error is in your third point: The dogs.push() automatically returns the length of the array (which after we have added 1 element is 1. But the ID is 0). But that’s the same as the next free position. So you could think of it like that.

@filip,

I am stuck on the “Inheritance Programming Assignment”. I even copied your code from github directly and still get errors.

When you run the transferOwnership function, you need to do so from the owner account. Otherwise you won’t pass the modifier.