Ethereum Smart Contract Programming

Hi, does anybody know in the Dog (array & structs) contract how do you get to display the dogs age, Fillip showed us how to call the dogs name but never how to call the age ? Thank you

Just replace .name with .age.

Mappings assignment

the limitation is it is not operating on any stored information, itā€™s extremely limited and only really parroting back what is put in and itā€™s address
+
If the address has not previously passed it a dog it only responds with nothing (which is lousy error handling at least)

Solution - bring back the array but have protected hash type values?

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 {

DogContract dc = DogContract(0x76A846CD2aC2E028626A3d1f5ddf32d3a468423D);

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

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

I donā€™t really agree on the first part. But maybe you can clarify what you mean? The issue with the mapping in this video is that we can overwrite our previously added dog.

Thanks for reply f

I think Iā€™m trying to get my head around what this would actually be used forā€¦ it canā€™t be used for more than one dog therefore is less use than the previous array example.
It does have a purpose when the address is used, and it becomes apparent this is used for validating an address for security purposes, but it can only validate one?

Maybe youā€™ve gone from a simple example to a practical example and I got lost somewhere. I did see the solution and it made sense.

Hi @filip, sorry to bother you again. after watching the video about payable functions, I tried to add a dog using 10 000 wei. The transaction is successful as expected, however, I can see that the value of the transaction is 10 000 wei.


we have put the give back excess condition in the costs modifier though. Is that the log we expected? I get that it is the value that I sent, but as is, the blockchain will record that I spent 10 000 wei on this transaction, wonā€™t it? is it just up to the developers to set the proper events so that if some excess amount is given back, it is recorded?

thanks in advance for your help

Solution to the getbalance exercise:

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

Yes, the blockchain will record what you are sending in your transaction. Then itā€™s completely up to the smart contract to either accept or deny that function call. Or log whatever has happened.

Hi does anybody here know how to get a value back from a smart contract function , I have it like this
In my js. file the function multiply () { let val = parseInt($("#cal").val());
instance.multiply.sendTransaction(val,{ from: accounts[0], gas : 300000}, function(error, result){
if (error){

            alert(error);
        }
        else {
            $("#message").html(result.toString());
        }

} sends a value to the smart contract function :
function multiply (uint num) public returns (uint){
num = testNum;
testNum += 1 ;
return testNum;
}
in which i thought that It would return the result ( testNum += 1) , but it returns the txHash ā€¦ How can I pass a value to the smart contract function from my js. function that returns it back and then it displays it ? Sorry for the noob question, I may be waaay off on something, Im really trying to understand this and Im stuckā€¦ thx guys :wink:

There is unfortunately no way to do that. Because we donā€™t know when the smart contract is done executing. When we send a tx to the smart contract it needs to be mined and put in a block on the blockchain before we know what the return value is. Itā€™s not like a local program. The result is returned after the network has found consensus of the result.

Therefore you need to do like you saw me do in the course lectures. Where you need to wait for the receipt and then query the blockchain for the answer.

Aha, what about emiting an event and listening to it in the js. file, then outputing it ?

Somebody on stack overflow suggested it, so in my function I wrote :
function multiply (uint num) public {
testNum = num ;
emit emitNum (testNum);

}

event emitNum (
uint eventNum
);
//and im my js. after the txHash returns in the form of the result, I call the event :
var event = instance.emitNum(function(error, result) {
if (!error)
$("#message").html(result);

                    console.log(result);
            });

I have no errors , everything compiles ok, the txHash returns from the transaction, after that nothing happensā€¦ Am I calling the event the wrong way, should I type the name of the contract then call the event ? Like :
instance.emitNum(function(error, result)
Thx :slight_smile:

First of all, in the future when you post code. Make sure itā€™s nicely formatted when you post it. If you look at your post parts of it is formatted as code and some as normal text. It makes it very time consuming for me to read it. :slight_smile:

Yes, you can do it with events. But Iā€™m not sure Web3.js supports listening for events, it might depend on the version.

As for the code, you are trying to call the event from JS. You should start a listener, not call the event itself.

I would still recommend you to follow the code in the course. Itā€™s the easiest way to accomplish this.

function getexternalBalance() public view returns(uint){
    return appinterface.getBalance();
    
}

Well, I get error when I run my external contract it worked before but not anymore, I have used the right amount of wei each time?

The error i get is:

" transact to ExternalAppartment.addexternalAppartment errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value. Debug the transaction to get more information. "

Please edit your post and translate it to engligh so other people can understand your question as well. Also, please format your post as well so that itā€™s easier for me to read. There is code tool here on the forum you can use when you write. But you have only parts of your post in code and the rest in plain text, makes it really hard for me to comprehend.

Back to the issue at hand, what error do you get and when do you get it?

Hi @filip in the ā€œSolution + Control Flowā€ I was expecting more a solution to allow the owner to own many dogs instead of just preventing him to add more dogs.

Also the ā€œreplace the if with require/assertā€ was not really clear, in fact I tried to put the require inside an ifstatement as you did in the next video :wink:

So here my code: https://github.com/firepol/smart-contract-programming/blob/master/DogContract/DogContractMoreDogs.sol

pragma solidity 0.5.1;

contract DogContract {

    struct Dog {
        string name;
        uint age;
    }

    mapping(address => Dog[]) dogs;

    function addDog(string memory _name, uint _age) public {
        Dog memory newDog = Dog(_name, _age);
        dogs[msg.sender].push(newDog);
    }

    function getLatestDog() public view returns (string memory) {
        Dog[] memory ownedDogs = dogs[msg.sender];
        Dog memory newestDog = ownedDogs[ownedDogs.length - 1];
        return newestDog.name;
    }

}

Also as you see, instead of getDog, I renamed the function to getLatestDog, but in my free time Iā€™ll modify my version to print to string the entire array of dogs and re-add the function to get the dog by id.

Hi @filip for the ā€œData Location Assignmentā€ assignment, my solution was to replace ā€œmemoryā€ with storage, like so:

    function updateBalance(uint id, uint balance) public {
         User storage user = users[id];
         user.balance = balance;
    }

This works too, maybe you can explain the difference, also in term of costs?

Your solution is more elegant of course:

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

Good job, thatā€™s one solution to the issue.

As for the require/assert you can see my solution here: https://github.com/filipmartinsson/Solidity-0.5.1/blob/master/Error-assignment.sol

I hope that clears up what I meant.