Events Assignment

Nice solution, Joseph :ok_hand:

Your transfer event and corresponding emit statement are both well coded. The emit statement is in the correct position within your transfer function body, and logs appropriate data when the function is successfully executed.

A job well done! :slight_smile:

Hi Ernest,

Yeh, I think that would be better, because we have more than one event for transactions. We currently have 2 (for deposits and transfers) and we could potentially have more. It also makes the job of that particular event immediately clear to anyone reading your code. Otherwise, they need to find which function the corresponding emit statement is in, in order to confirm which transaction it relates to.

The other option is to just have one event for all types of transactions, and add an extra string parameter which defines the type of transaction e.g. string type. That way you can emit the same event for different transactions and change the argument for the string type parameter in each separate emit statement, accordingly e.g. "deposit" or "transfer" etc.

1 Like

Gotcha! Thanks a lot!

1 Like

image

I get an error msg whilst trying to deploy the contract during this exercise anyone know why its with the constructor

1 Like

You are missing a } at the end of your onlyOwner modifier. Basically you have to close the modifier body.

modifier onlyOwner(){
...
}

Carlos Z

2 Likes

lol silly mistake thanks dude

1 Like

image

Added code as below
image

image

1 Like

Hi @leon09,

Your transfer event and corresponding emit statement are both accurately coded. The emit statement is appropriately positioned after the assert statement and, as you have shown, logs the data when the function is successfully executed.

Where the addBalance() function executes a transaction that only involves 1 user address (the depositer), the transfer() function executes a transaction that involves 2 user addresses (the sender and the recipient). Therefore, it’s appropriate to include the sender’s address, as well as the recipient’s address, within the data emitted for this transfer event.

Let me know if you have any questions :slight_smile:

Added two events:

    event balanceAdded(uint amount, address indexed depositTo);
    event balanceSubtracted(uint amount);
    event balanceTransferred(address recipient, uint amount);
function subtrBalance(uint _toSubtract) public returns(uint) {
        
        require(balance[msg.sender] >= _toSubtract, "Cannot subtract more than current balance. First, add more crypto");
        
        balance[msg.sender] -= _toSubtract;
        emit balanceSubtracted(_toSubtract);
        return balance[msg.sender];
    }
1 Like

Hey guys, here’s my solution of implementing event for Transfer function

pragma solidity 0.7.5;

contract Bank {
    
    mapping(address => uint) balance;
    address owner;
    
    event balanceAdded(uint amount, address indexed sender);
    event transferDone(uint amount, address indexed sender, address indexed recipient);
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner of the contract can add balance");
        _;
    }
    
    modifier sufficient(uint amount) {
        require(balance[msg.sender] >= amount, "Insufficient funds");
        _;
    }
    
    modifier isSenderEqualReceiver(address recipient) {
        require(msg.sender != recipient, "Can not transfer to the address you are sending from!");
        _;
    }

   function transfer(address recipient, uint amount) public sufficient(amount) isSenderEqualReceiver(recipient) {
        uint prevSenderBalance = balance[msg.sender];
        _tranfer(msg.sender, recipient, amount);
        assert(balance[msg.sender] == prevSenderBalance - amount);
        emit transferDone(amount, msg.sender, recipient);
        
    }
1 Like

Hi @Acex13,

A very well-coded subtrBalance function, which nicely compliments the addBalance function :ok_hand:
A couple of observations:

  • Is access to your addBalance function still restricted to the contract owner with the onlyOwner modifier? If so, if someone other than the contract owner tries to withdraw more than their balance, the second part of the error message that is generated, “Cannot subtract more than current balance. First, add more crypto”, doesn’t make sense, because only the contract owner can add more. I’m sure you can find a way to modify your error message so that it makes sense for all users — or just remove the onlyOwner modifier so that anyone can make a deposit.

  • Your BalanceSubtracted event and its corresponding emit statement are well-coded, and you have placed the emit statement in the correct position within the subtrBalance function body. As with the addBalance function, it would probably be useful to also log the address of the user performing the transaction, as well as the transaction amount.

Your transfer event declaration looks good, but can we also see how you are emitting it in your transfer() function?
Where the addBalance and subtrBalance functions execute transactions that only involve 1 user address (depositer or withdrawer), the transfer() function executes a transaction that involves 2 user addresses (the sender and the recipient). So, it would be useful to include the sender’s address, as well as the recipient’s address, within the data emitted for the transfer event.

Let me know if anything is unclear, or if you have any questions :slight_smile:

Nice solution @Anvar_Xadja :ok_hand:

Your transfer event and corresponding emit statement are both well coded. The emit statement is in the correct position within your transfer function body, and will log appropriate data when the function is successfully executed.

Your additional modifier isSenderEqualReceiver is also very well coded and implemented. Just bear in mind that we would only want to add a require() statement to a modifier if we needed to use it more than once, in order to avoid code duplication. Otherwise, it’s actually more concise just to place the require() statement directly within the function body. But I’m sure your idea here was to practise coding and implementing modifiers — which is great!

You are missing the constructor to set the contract owner’s address on deployment, and also the _transfer() helper function. Or did you mean to only include extracts from your full code? That’s OK as well, but when you’ve added a lot of your own adaptations, it’s usually best to post your full code, because that makes it easier to review, and also means we can deploy it, if necessary. It’s always nice to see the full code for an assignment where someone has put as much effort into it as you have with this one :smiley:

Just let me know if you have any questions.

1 Like

Thank you for you reviewing my code! So yeah i just added a portion of my code, but i got you, next time I’ll add a full code for easier review :slight_smile:

1 Like

my added event:

event balanceTransferInfo(address indexed sentTo, uint amount, address indexed sentBy);

called with: (placed within the ‘transfer’ function)

emit balanceTransferInfo(recipient, amount, msg.sender);

1 Like

Hi @ZacSed,

Your transfer event and corresponding emit statement are both well coded. The emit statement will log appropriate data when the transfer() function is successfully executed.

Where an emit statement is positioned within the function body is also important. Where exactly did you place yours?

At the top, declare the event:

event Transferred(uint amount, address indexed toAddress, address indexed fromAddress);

and in the transfer function, raise the event:

emit Transferred(amount, recipient, msg.sender)

1 Like

Event for transfer function -

pragma solidity 0.7.5;

contract Bank {
    
    mapping(address => uint) Balance;
    address owner;
    
    constructor(){
        owner = msg.sender;
    }
    
    event balanceAdded(uint amount, address indexed depositedTo);

    event amountTransferred(address from , address to , uint amount); //Here
    
modifier onlyOwner {
       require(msg.sender == owner,'Accessible by owner only');
       _;
    }
    
    function addBalance(uint _toAdd) public onlyOwner returns(uint){
        
        Balance[msg.sender] += _toAdd;
        emit balanceAdded(_toAdd,msg.sender);
        return Balance[msg.sender];
    }
    
    function transfer(address recipient, uint amount) public {
        
        require(Balance[msg.sender] >= amount, 'Insufficient Balance');
        require(msg.sender != recipient);
        uint previousSenderBalance = Balance[msg.sender];
        _transfer(msg.sender,recipient,amount);
        emit amountTransferred(msg.sender,recipient,amount); // Here 
        assert(Balance[msg.sender] == previousSenderBalance - amount);
        
    }
    
    function _transfer(address from, address to,uint amount) private {
        Balance[from] -= amount;
        Balance[to] += amount;
    } 
    
    function getBalance () public view returns(uint){
        return Balance[msg.sender];
    }
}
1 Like

Hi @Samm,

Your transfer event and corresponding emit statement are both well coded*. The emit statement will log appropriate data when the transfer() function is successfully executed.

Where an emit statement is positioned within the function body is also important. Where exactly did you place yours?

* apart from a missing semi colon at the end of your emit statement, but I’m sure that was just a copy-and-paste error :wink:

Hi @tanu_g,

Your transfer event and corresponding emit statement are both well coded. The emit statement will log appropriate data when the transfer() function is successfully executed.

Just a couple of minor points…

  • In general an emit statement is probably better placed after an assert statement.

  • The convention is to start the names of mappings with a lower case letter — the same as with variables, arrays, arguments, parameters and function names. The names of contracts, events and structs usually start with a capital letter. Doing the opposite will not prevent your code from compiling, but following this generally accepted convention does apply a consistency to our code, which can make it more readable.

Just let me know if you have any questions :slight_smile:

Thanks, @jon_m for the valuable points.
I’ll keep that in mind. :+1:

1 Like