Events Assignment

pragma solidity 0.7.5;

contract bank {
    mapping(address => uint) balance;
   
    address owner;
    
    event balanceAdded(uint amount, address indexed depositedTo);
    event balanceTransfered(address indexed depositedTo, address indexed recipientTo, uint amount);
    
    modifier onlyOwner {
        require(msg.sender == owner);
        _;  // run the function
    }
    
    constructor(){
        owner = msg.sender;
    }
  
    function addBalance(uint _toAdd) public 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 {
        //check balance of msg sender.
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        require(msg.sender != recipient);
        
        uint previousSenderBalance = balance[msg.sender];
        _transfer(msg.sender, recipient, amount);
        
        emit balanceTransfered (msg.sender, recipient, amount);
        
        assert(balance[msg.sender] == previousSenderBalance - amount);
    
        // event logs and other checks
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount; 
        balance[to] += amount;
    } 
    
} 

    
1 Like

Here is my solution:

By the way, I was not able to find a copy of the code file for HelloWorld.sol, so I just wrote out this function (from the video):

event transferMade(address indexed recipient, uint indexed amount, address indexed 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 transferMade(recipient, amount, msg.sender);
    }

^ this emits an indexed event for the recipient and sender addresses of the transfer, and the amount.

1 Like

pragma solidity 0.8.9;

contract Bank{
mapping (address=>uint)balance;
address owner;

event balanceAdded (uint amount, address depositedTo);
event balanceTransferred (uint amount, address sender,address recipient);

modifier onlyOwner{
    require (msg.sender==owner);
    _;
}

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, "Dont transfer money to yourself");
   
   uint previousSenderBalance = balance[msg.sender];
   
    _transfer(msg.sender, recipient, amount);
    
    assert(balance[msg.sender]== previousSenderBalance - amount);
}

function _transfer(address from, address to, uint amount) private {

    balance[from] -= amount;
    balance[to] += amount;
    emit balanceTransferred (amount, from, to);
}

}

1 Like

Hi @moragarcia75,

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

A couple of comments…

  • It’s better to emit the event at the very end of the function which completes the transaction i.e. transfer() not _transfer().
    _transfer() is what we call a helper function .
    Another important factor here is that if you emit an event in a helper function, you are restricting your ability to reuse that helper function. It will be more reuseable if we can call it from another function when we may not want to emit the same event — either a different one, or no event at all. That way we can reuse the helper function whenever we just want its functionality (i.e. the operations, or computation, that it performs).

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

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

event amountTransfered(address indexed sender, address indexed recipient, uint amount);

function transfer(address recipient, uint amount) public {
    require(balance[msg.sender] >= amount, "Balance is not sufficient");
    require(msg.sender != recipient, "You cannot transfer to yourself");

    uint previousBalance = balance[msg.sender];

    _transfer(msg.sender, recipient, amount);

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

    assert(balance[msg.sender] == previousBalance - amount);
}

1 Like
pragma solidity 0.7.5;

contract Bank {
    
 mapping (address => uint) balance; 
 address owner; 
 
 event balanceAdded(uint amount, address depositedTo);
 event transferSent(uint amount, address sentFrom, address sentTo);

 // When placed in a function this will run first
 modifier onlyOwner {
     require(msg.sender == owner);
     _; // run the function that called this
 }
 
 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);
     
     emit transferSent(amount, msg.sender, recipient);
     
     assert(balance[msg.sender] == previousSenderBalance - amount);
     
 }
 
 function _transfer(address from, address to, uint amount) private {
     balance[from] -= amount;
     balance[to] += amount;
 }
 
 
}

Two events were added, one for adding the balance and one for the transfer

1 Like

Hi @alp257,

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

Just one observation…
In general an emit statement is probably better placed after an assert statement.

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

1 Like

Hi @Shadowstep2003,

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

Just one observation…
In general an emit statement is probably better placed after an assert statement.

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

event transfer(uint _amount, address indexed _from, address indexed _to);

1 Like

Hi @CryptoByNight,

Your transfer event declaration looks good, but can we also see how you are emitting it in your transfer() function?

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 transfer(amount, msg.sender, recipient)
    }
1 Like

Hi @CryptoByNight,

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

1 Like
pragma solidity 0.7.5;

contract Bank {
    
    mapping(address => uint) balance;
    address owner;
    
    event balanceAdded(uint amount, address indexed depositedTo);
    event transferLog(uint amount, address toAddress, address fromAddress);
    
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
    
    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, "Do not transfer money to yourself.");
        
        uint previousSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);

        assert(balance[msg.sender] == previousSenderBalance - amount);

        // My answer:
        emit transferLog(amount, recipient, msg.sender);
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
}
1 Like

Hi @Crownie,

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

Just one observation…
In general an emit statement is probably better placed after an assert statement.

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

Thank you for that tip!

1 Like
    mapping(uint => User) users;

    struct User{
        uint id;
        uint balance;
    }
    event balanceUpdate(uint amount, address depositedTo);

    function addUser(uint id, uint balance) public {
        users[id] = User(id, balance);
        emit balanceUpdate(balance, id);
    }

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

    function getBalance(uint id) view public returns (uint) {
        return users[id].balance;
    }

}

I always get an error message at emit. Maybe some of you can tell me what I did wrong. Thanks in advance.

Hi @PaulS96

You get a compiler error because the second parameter in your event declaration is an address data type …

… but the corresponding argument in the emit statement has a uint data type …

An emit statement has to emit values with the same data types as those defined in the corresponding event declaration.

The reason why the event declaration given to you in the video has a  uint amount  parameter and an  address depositedTo  parameter is because it is meant to be used in the addBalance function in our Bank contract, and not in the MemoryAndStorage contract. It also has the name balanceAdded (instead of balanceUpdate). Try implementing it there instead, and then posting your solution again.

You can also continue with your implementation of the event in MemoryAndStorage. Giving it the name balanceUpdate would suggest that emitting it with data from the updateBalance function would be a more logical choice. You will need to change the names of the parameters in the event declaration, so that they better describe the data that is actually logged, and you will also need to change the data type of the second parameter.

Let me know if anything is still unclear, or if you have any questions about how to correct this.

1 Like

@jon_m
Thank you for your feedback. What is your opinion on the altered solution below? I changed the address parameter to uint. Is this something you can do or do you advise against such practices? Thanks in advance for your answer

pragma solidity 0.7.5;
contract MemoryAndStorage {

    mapping(uint => User) users;

    struct User{
        uint id;
        uint balance;
    }
    event balanceUpdate(uint amount, uint depositedTo);

    function addUser(uint id, uint balance) public {
        users[id] = User(id, balance);
    }

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

    function getBalance(uint id) view public returns (uint) {
        return users[id].balance;
    }

}
1 Like

Hi @PaulS96,

This works now :ok_hand:  Your balanceUpdate event and corresponding emit statement are both correctly coded. The emit statement is in the correct position in the updateBalance() function body and will log appropriate data when the function is successfully executed.

Some additional comments …

Notice that the updateBalance() function updates the user’s existing balance by replacing it with the new one. This is different to what happens in the addBalance() function in our Bank contract, where an amount is added to the exisiting balance.

This is an important distinction to understand, because the updateBalance() function isn’t actually processing a deposit like the addBalance() function is. Instead, it’s replacing the previous “total balance” with a new “total balance”, presumably for an amount being deposited by the user elsewhere.

You could deal with this by changing the names of the parameters in your event declaration to ones that better describe what the logged data represents e.g.

event balanceUpdate(uint newBalance, uint userID);

Just let me know if you have any further questions.

1 Like

Hi, there is my solution for event assignement

pragma solidity ^0.8.7;
contract Events{
    
    mapping(address=>uint) balance;
    address owner;
    // emit on call of the addBalance function
    event balanceAdded(uint _amount,address depositor);
    // emit on call of transfert function
    event transfertDone(uint indexed _amount,address indexed sender,address indexed recipient);
    
    constructor(){
        owner=msg.sender;
    }
    
    modifier onlyOwner(){
        require(msg.sender==owner);
        _;
    }
    
    // disable the self transfert
    modifier noReentrance(address _sender, address _recipient){
        require(_sender!=_recipient,"cannot send funds to yourself");
        _;
    }
type or paste code here