Events Assignment

Here’s the event I added to to the transfer() function:

event transactionCompleted(uint amount, address sender, address recipient);

function transfer(address recipient, uint amount) public {
     
     require(balance[msg.sender] >= amount, "Balance not sufficient");
     require(msg.sender != recipient, "Don't transfer money to yourself");
     
     uint previousSenderBalance = balance[msg.sender];
     
     _transfer(msg.sender, recipient, amount);
     
     assert(balance[msg.sender] == previousSenderBalance - amount);
     
     emit transactionCompleted(amount, msg.sender, recipient);
 }
1 Like

Hey Jon, could you give me a hand with my code, please? I really do not understand why I am not getting any logs here. I have added the screenshot of my device that shows my code. I am still messing with my code here in remix and I have looked at it a few times but still can not figure out the issue with it. Could you please give me a hand here?

Thank you in advance.

Joseph

Screen Shot 2021-05-21 at 2.00.03 PM

Screen Shot 2021-05-21 at 2.01.05 PM

Look Jon, this one fired event logs… what’s the deal with this?

Screen Shot 2021-05-21 at 2.31.39 PM

I got the events to log and I really did not do anything in particular. It eventually just fired. I worked on the other tutorial. It fired events and then I got the tutorial here to fire events.

Screen Shot 2021-05-21 at 2.37.21 PM

Hey Joseph,

I’m not entirely sure I understand the problem, but the event is emitted when you call the function with the emit statement, which in the Bank contract is addBalance(), and not when you call getBalance(). Is that what’s happened? In your first screen shot, it looks like you have called getBalance() and tried to find event data for that call. Whereas in your final screen shot you have found the event data in the transaction logs because you are looking at the transaction generated by the addBalance() function call.

We emit an event when an actual “event” happens i.e. some change in the contract state has occurred. We don’t emit events for getters, because when we call those, we are only retrieving data and the getter is only reading the contract state, not changing it.

Does that answer your question?

You didn’t get confused with your test contract, because you only have one function to call there :wink:

You will have noticed that when you call getters (e.g. the getBalance function) to just read data and retrieve it, you get CALL data in the Remix console. If you click on the down arrow to view their data, there won’t be any event logs. I think maybe that’s what you did at first.

But when you call a function which changes the contract state and generates an actual transaction, the confirmed transaction data appears with a green tick in the console. When you click on the down arrow with one of those that has fired an event, you will see the event data in the logs there.

Ok Jon, so after doing a few tutorials and getting some more hands-on, I can now speak a bit more educated on the topic, however, there still seems to be some confusion.

Referring to the tutorial that is relevant to the course, I can see that I actually did code the event and the trigger correctly. However, when I look for the log, I am not able to see the log so I am lead to believe that I did not code it correctly or that I made some mistakes somewhere along the road. Should the events be logged? I am under the impression that it is important, and that the event is logged for future reference. I have been lead to believe that the log is the actual proof that the event was both coded and triggered appropriately. Am I off?

1 Like

No, you are correct.

Is the problem that you are looking for the event data by clicking on the down arrow for CALL data (generated by a successful call to a getter), instead of clicking on the down arrow for the confirmed transaction data (generated by the function with the emit statement), where the logged event data will be…?

I’ve gone into more detail about this in my 2nd reply.

It’s easy to click on the wrong receipt in the console because the window is so narrow… When I’m looking at the detailed transaction data, I often drag the console section up so it’s much bigger. That way it’s easier to see what you’re doing and what you’re clicking on.

Also, sometimes the latest confirmation receipt doesn’t show at the bottom and you need to scroll down to see it. That can also cause you to click on the wrong down arrow :sweat_smile:

This is one the annoying things about the Remix interface. Remix has loads of great features, but this isn’t one of them! :upside_down_face:

I’m looking for the data in the log. That is what we were shown to do here in the tutorial, bro and that is what I am attempting to do. What strikes me as odd is that the actual log was shown after doing nothing different. It just showed up after doing the other tutorial in the log and then coming back.

But you’re telling me that it was coded in remix correctly, right? So, I should feel ok to move forward, right?

Yes, that’s what I’m telling you to do too… but you need to look in the logs for the right receipt, as in click on the down arrow for the receipt that was generated by the function call that emits the event. If you look in the logs for a CALL confirmation, and not a transaction confirmation, or if you look in the wrong transaction confirmation, then the event data won’t be there. I’m pretty sure from what you’ve explained and your screen shots, that that’s what has happened.

Yes, your code looks correct, but please save my eyes by posting your code formatted so I can clearly see it and also run it to test it :pray: otherwise it’s difficult to confirm that your code is definitely correct.

But your code does look correct from what I can see, and it’s really good that you have done your own little test contract for the events — that’s a great way to learn and check things :+1:

However, at some point you do really need to make sure you are able to find the confirmation receipt (in the console) that corresponds to the function call you want to check the data for. Before clicking on the down arrow, you can ensure that you are looking at the right receipt because the “receipt header” in the console (before expanding it) will include the function name e.g. Bank.addBalance(uint256)  or  Bank.getBalance()
You need to make sure you are looking at the logs in the receipt for Bank.addBalance(uint256)

1 Like

Great solution @Ernest_SG :muscle:

The only comment I would make is that TransactionCompleted isn’t really specific enough for an appropriate event name. “Transaction” could refer to either of our transactions (deposit or transfer) and any additional types of transaction that are added later. You could use this same “general” event for all transactions, and add an additional string parameter for the transaction type. The name of each type of transaction could then be added as a fixed string in each of the separate emit statements e.g.

event TransactionCompleted(string transaction, uint amount, address sender, address recipient);

emit TransactionCompleted("Transfer", amount, msg.sender, recipient);
emit TransactionCompleted("Desposit", _toAdd, msg.sender, address(0));

Notice, that the number of arguments and their values in the emit statements must correspond with the number of parameters and their data types in the event definition. This means that any of the arguments that aren’t relevant for a particular transaction would still need to be included and logged as zero values.

Or you could change the event name to something more specific to a transfer, and just use it as an event exclusive to transfers, and have separate event definitions for each type of transaction.

Let me know if you have any questions :slight_smile:

2 Likes

Thanks, Jon. I’ll be working on it in the next few days and moving forward, too. Appreciate ya!

1 Like

Hey Jon, would you kindly show us an example of how you’d name the string as a general event and then how you would name the additional string parameters?

Please, kind Sir?

Thank you, kind Sir!

Hey Joseph,

Which string do you mean? If you mean an example of how to name an event declaration, which could be used for several different related events, each emitted by different functions (and which is different to the example I’ve outlined in the post above, for the different transactions in our Bank contract) then maybe this will help…

/* This event could be used to log all changes in status
   of the offers available in a marketplace */
event offers( /* parameters */ );
/* only one generic event would need to be declared, with common
   parameters for all types of update to the available offers */
event offers(string updateType, uint offerID, uint price, address owner);

/* The same event would be emitted by each function which executes a different
   type of update to the available offers. The 1st fixed string argument 
   describes the type of update made by each function */
emit offers("new", .............. );
emit offers("removed", .......... );
emit offers("priceChange", .......);
emit offers("sold", ..............);

Let me know if I’ve misunderstood the sort of example you were looking for :sweat_smile:

1 Like

No Sir, this is the one I was referring to. Thank you very much! I have to put in a few hours at the language school where I no longer was working but now do as this piece of crap exchange where I deposited my money has decided to rip me off.

******* Everyone should be careful with this place called Bitcoin Evolution / GSI Markets. They operate in Latin America. I deposited 500.00 USD there and I have been asking them for over three months to cancel all dealings yet they still refuse to liquidate the rest of my funds and disburse them to me. They claim to have bots that can trade and what not and they suck! They just lose your money. I hope no one else puts their money in that place. I must now put in some hours as I have to recover from this piece of crap rip off of that exchange but I will be past it in a couple of months. On top of all this, my baby’s mom is still sick and worsening.

Anywho, guys BE CAREFUL WITH BITCOIN EVOLUTION / GSI MARKETS. THEY ARE A RIP-OFF, SCAMMERS, LIARS, AND THIEVES!

Thank you very much, Jon! Talk to you tomorrow again! The LORD Jesus bless you!

pragma solidity 0.7.5; 

contract Bank{
    
    // storage - permanent storage of data (state variables)
    
    // memory - temporary storage used in function execution 
    
    // callData - save arguments/inputs to our functions 
    
    // strings, arrays, mappings, structs 
    
    mapping(address => uint) balance; 
    
    address owner; 
    
    event balanceAdded(uint amount, address depositedTo); 
    event transferEvent(uint amount, address transferredFrom, address transferredTo); 
    
    modifier onlyOwner {
        require(msg.sender == owner); 
        _; // run the modifier 
    }
    
    
    constructor(){
        owner = msg.sender; 
    }
    
    
    function addBalance(uint _toAdd) public onlyOwner returns (uint) {
        balance[msg.sender] += _toAdd; 
        emit balanceAdded(_toAdd, msg.sender); 
        return balance[msg.sender]; 
    }
    
    
    function getBalance() public view returns (uint){
        return balance[msg.sender]; 
    }
    
    
    function transfer(address recipient, uint amount) public {
        require(balance[msg.sender] >= amount, "Balance not sufficient"); 
        require(msg.sender != recipient, "Don't transfer money to yourself"); 
        uint previousSenderBalance = balance[msg.sender]; 
        _transfer(msg.sender, recipient, amount); 
        assert(balance[msg.sender] == previousSenderBalance - amount); 
        emit transferEvent(amount, msg.sender, recipient); 
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount; 
        balance[to]  += amount; 
        
    }
    
    
    } 
1 Like

You are the man, brother! Thank you very much,

1 Like

great thanks a lot, so instead of transactionCompleted I should simply change the event name to something more specific like depositCompleted right?

1 Like