Please submit your solution to the Events Assignment here. Or feel free to ask questions if you need help.
pragma solidity 0.7.5;
contract Bank {
mapping (address => uint) balance;
address owner;
event balanceAdded(uint amount, address depositedTo) ;
event amountTransferred(uint amount, address toAddress, address fromAddress); //answer
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, "Can't transfer money to yourself");
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
assert(balance[msg.sender] == previousSenderBalance - amount);
emit amountTransferred(amount, recipient, msg.sender); //answer
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
My solution to the Events assignment:
pragma solidity 0.7.5;
contract Bank {
mapping(address => uint) balance;
address owner;
event balanceAdded(uint amount, address indexed depositedTo);
event transferMade(address indexed depositedTo, uint amount); *// added as an event for the transfer()*
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, "Don't transfer tokens to yourself");
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
emit transferMade(msg.sender, amount); *// added to emit the event*
assert(balance[msg.sender] == previousSenderBalance - amount);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
pragma solidity 0.7.5;
// EVENTS
contract myBank {
mapping(address => uint) balance;
address owner;
event balanceAdded(uint amount, address depositedTo);
event transferHistory(uint amount, address depositedTo, address depositedFrom ); // MY TRANSFER function
constructor() {
owner = msg.sender;
}
function addBalance(uint _toAdd) public returns(uint) {
balance[msg.sender] = 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 {
_transfer(msg.sender, recipient, amount);
emit transferHistory(amount, recipient, msg.sender); // HERE IS MY ANSWER
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
pragma solidity 0.7.5;
contract Bank {
mapping(address =>uint) balance;
event addBalanceTransaction(uint amount, address depositedTo);
event transferTransaction(uint amount, address Sender, address Receiver);
function addBalance(uint _toAdd) public returns (uint){
balance[msg.sender] += _toAdd;
emit addBalanceTransaction(_toAdd, msg.sender);
return balance[msg.sender];
}
function getBalance() public view returns (uint){
return balance[msg.sender];
}
function transfer(address recipient, uint amount) public {
_transfer(msg.sender, recipient, amount);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
emit transferTransaction(amount, from, to); **//my answer**
}
}
Hi @jon_m! I decided to put the emit keyword below the _transfer function because as discussed by Filip we can reuse the function and I think by putting emit inside the _transfer function itself we don’t have to rewrite emit again and save a little of gas. I would really appreciate your comment on my answer. Thanks man!
pragma solidity 0.7.5;
contract Bank {
mapping(address => uint) balance;
event depositDone(uint amount, address indexed depositedTo);
event transferDone(address indexed recipient, uint amount, address indexed sender);
function deposit(uint amount) public returns (uint) {
balance[msg.sender] += amount;
emit depositDone(amount, 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 transferDone(recipient, amount, msg.sender);
assert(balance[msg.sender] == previousSenderBalance - amount);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
Hey @zai, hope you are great!
Good job on your assignment, about your question, I tried your code on remix, addBalance with the owner, then do a transfer to another address.
Transaction Cost (according to remix): 51720 gas.
Now I moved the event transferTransaction
from _transfer
function to transfer
just to see if the gas fee is different (so we can validate your question save a little gas
.
By just doing that and repeat the same process (addBalance, transfer to another account) my Transaction Cost was: 28319 gas.
So apparently, if you have your event transferTransaction
inside your private function _transfer
it will cost more gas at the end of your transfer
function execution.
Try it your self and let me know your results
If you have any more questions, please let us know so we can help you!
Carlos Z.
@thecil Oh okay. My Bad! I was thinking that what if we reuse the _transfer function in the future then we are not going to rewrite emit as well. But I don’t know how it works though.
Thanks for the reply @thecil. I really appreciate it.
Hi @Jethrodog,
Have a look again at the name of your 1st event parameter for transferMade: deposited
To
This is the name that will be given to the 1st piece of data when this event is emitted.
Now look at your 1st argument in your emit statement for this transferMade event: msg.sender
Note that this transaction is different to the one performed when addBalance() is called.
With addBalance() the msg.sender is the “to” address, whereas with transfer() the msg.sender is the “from” address, and so you need to change the 1st argument in your emit statement from msg.sender. What do you need to change it to?
In fact, it would make sense to include both a “from” and a “to” address in the Transfer event, because the transaction is from one user to a different user within the same smart contract. Whereas addBalance() only deposits an amount to one user within the smart contract, because the amount doesn’t come from another user within the same contract, but is transferred in from outside the smart contract by the same user (to themselves).
Hi @zai,
I’ve just been reading your discussion with @thecil about the position of your emit statement for the Transfer event.
Another important factor here is that if you emit the event in the helper function _transfer, you are actually restricting your ability to reuse it in the future. It will be more reuseable if we can call _transfer() from another function when we may not want to emit that same event — either a different one, or no event at all. That way we can reuse it whenever we just want its functionality (i.e. the operations, or computation, that it performs).
I therefore think 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.
You’re also missing the require and assert statements in transfer(). These are important to ensure the inputs and output are valid.
I hope that makes sense It’s really good that you are thinking about these deeper issues
pragma solidity 0.7.5;
contract Bank{
mapping(address => uint) balance;
address owner;
constructor() {
owner=msg.sender;
}
modifier onlyOwner{
require(msg.sender==owner);
_;
}
event balanceAdded (uint indexed amount, address indexed depositedTo);
event transferamtTo (uint indexed amount, address indexed transferTo);
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 {
//check balance of sender
require(balance[msg.sender] >=amount);
require(msg.sender!=recipient);
uint previousSenderBalance= balance[msg.sender];
_transfer (msg.sender,recipient,amount);
emit transferamtTo(amount,recipient);
assert(balance[msg.sender]== previousSenderBalance-amount);
//event log and further checks
}
function _transfer(address from, address to, uint amount) private{
balance[from]-= amount;
balance[to] += amount;
}
I’ve tried this way:
pragma solidity 0.7.5;
contract Bank {
mapping(address => uint) balance;
address owner;
event balanceAdded(uint amount, address depositedTo);
event balanceTransferred(address from, address to, uint amount);
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);
require(msg.sender != recipient, "Don't send funds to yourself");
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
emit balanceTransferred(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;
}
}
type or paste code here
says transaction successful,
under logs I have information:
logs [ { “from”: “0x3328358128832A260C76A4141e19E2A943CD4B6D”, “topic”: “0x57b8b6f4dc5a1165fcd29bf31d4713a94784438bdd54ca61302f2a2ede9bcb1b”, “event”: “balanceTransferred”, “args”: { “0”: “0x5B38Da6a701c568545dCfcB03FcB875f56beddC4”, “1”: “0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB”, “2”: “400”, “from”: “0x5B38Da6a701c568545dCfcB03FcB875f56beddC4”, “to”: “0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB”, “amount”: “400” } } ]
pragma solidity 0.7.5;
contract Bank {
mapping(address => uint) balance;
address owner;
event balanceAdded(uint amount, address depositedTo);
event transferFunds(uint amount, address sentFrom, address sentTo);
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 {
// check balance of msg.sender
require(balance[msg.sender] >= amount, "Balance not sufficient");
require(msg.sender != recipient, "Do not send to yourself");
// Save the senders balance
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
// event logs and further checks
// Confirm senders balance reduced by amount sent.
assert(balance[msg.sender] == previousSenderBalance - amount);
emit transferFunds(amount, msg.sender, recipient);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
pragma solidity 0.7.5;
contract BankOfNico {
mapping(address => uint) balance;
address owner;
event coinsMinted(uint amount, address indexed depositedTo); // indexed kryword to force node to index address of event
event coinsMoved(uint amount, address from, address to);
modifier onlyOwner {
require(msg.sender == owner, "Error! Only the owner of the address can transfer");
_;
}
constructor(){
owner = msg.sender;
}
function addBalance(uint _toAdd) public onlyOwner returns(uint) {
balance[msg.sender] += _toAdd;
emit coinsMinted(_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, "Not enough funds!");
require(msg.sender != recipient, "Don't sends money to yourself!");
uint prevBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
emit coinsMoved(amount, msg.sender, recipient);
assert(balance[msg.sender] == prevBalance - amount);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
event transferLog(uint amount, address indexed fromAddress, address indexed depositedTo);
function transfer(address recipient, uint amount) public onlyOwner {
//check balance of msg.sender
require(balance[msg.sender] >= amount, "Insufficient funds");
require(msg.sender != recipient, "Cannot transfer tokens to yourself");
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
//event logs and further checks
emit transferLog(amount, msg.sender, recipient); // <<<<=========== event called here.
assert(balance[msg.sender] == previousSenderBalance - amount);
}
pragma solidity 0.7.5;
contract Bank {
mapping(address => uint) balance;
address owner;
modifier OnlyOwner{
require(msg.sender == owner);
_;
}
event balanceAdded(uint amount, address depositedTo);
event transferListener(address depositedFrom, address depositedTo, uint amount);
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);
require(msg.sender != recipient, “Don’t send funds 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 transferListener(from, to, amount);
}
}
@thecil so did i do it right?? i mean i know its mediocre but is it like, written correctly? like would this work for a contract, like what would you do to improve my event??
Hi @Carlosvh96, hope you are great.
Yes I have tested your contract and it does work well, also both of the events works as expected.
Indeed is a good job and well intended code, easy to read/understand.
If you have any more questions, please let us know so we can help you!
Carlos Z.
Here is my Events solution for logging transfer from, to and amount.
pragma solidity 0.7.5;
contract BANK {
mapping(address => uint) balance;
address owner;
modifier onlyOwner {
require(msg.sender == owner);
_;
}
constructor(){
owner = msg.sender;
}
event balanceAdded( uint amount, address depositedTo);
--"event transferSent(address depositedTo, address depositedFrom, uint amount);"--
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 to yourself");
--"emit transferSent(msg.sender, recipient, amount);"--
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;
}
}