pragma solidity 0.7.5;
contract IshoboyBank {
mapping(address => uint) balance;
address owner;
address recipient;
event depositDone(uint amount, address depositedTo);
event balanceTransfer(uint amount, address depositedFrom, address recipient);
event withdrawDone(uint amount, address withdrawnTo);
modifier onlyOwner {
require(msg.sender == owner);
_; //run the function
}
constructor () {
owner = msg.sender;
}
function deposit() public payable returns (uint) {
balance[msg.sender] += msg.value; //you can even remove this line of code
emit depositDone(msg.value, msg.sender);
return balance[msg.sender];
}
function withdraw(uint amount) public returns (uint) {
require(balance[msg.sender] >= amount);
balance[msg.sender] -= amount;
msg.sender.transfer(amount);
emit withdrawDone(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 your self");
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
emit balanceTransfer(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;
}
}
function withdraw(uint amount) public returns(uint){
require(balance[msg.sender] >= amount,"Insufficient funds");
msg.sender.transfer(amount);
balance[msg.sender] -= amount;
return amount;
}
function withdraw(uint amount) public returns (uint) {
//check that user has a large enough balance to complete withdrawal
require(balance[msg.sender] >= amount);
msg.sender.transfer(amount);
}
function withdraw(uint amount) public returns (uint){
require(amount <= getBalance(), "Can't withdraw more than your balance");
msg.sender.transfer(amount);
uint previousSenderBalance = balance[msg.sender];
balance[msg.sender] -= amount;
assert(balance[msg.sender] == previousSenderBalance - amount);
}
I simply added the require line which i hope is correct ?
function withdraw(uint amount) public returns (uint){
require (balance[msg.sender] >= amount, "Balance not sufficient");
msg.sender.transfer(amount);
}
Hi @filip - so my code above seems to work, I can see I missed off the second line:
balance[msg.sender] -= amount; // which makes sense to me, my bad
but, why is the: return balance[msg.sender];
…important to have - please if you can explain to me in baby language so my head starts to understand…
Hey @JDW, hope you are well.
balance[msg.sender] -= amount
is used to update the balance of the msg.sender
in the contract, if you did not use it, the user could withdraw unlimited amount of funds because there is no variable that mention how much funds he can spend (or when he spend, you should update its balance)
that one is used to return the balance at the end of the function execution, it can be used for the front end or another function that must know the updated status of the balance of msg.sender
.
If you have any more questions, please let us know so we can help you!
Carlos Z.
1) Make sure that the user can not withdraw more than their balance
solved with:
require(balance[msg.sender] >= amount, "Insufficient funds");
2) Correctly adjust the balance of the user after a withdrawal
solved with:
balance[msg.sender] -= amount;
so the function looks like this:
function withdraw(uint amount) public payable returns (uint) {
require(balance[msg.sender] >= amount, "Insufficient funds");
balance[msg.sender] -= amount;
msg.sender.transfer(amount);
return balance[msg.sender];
}
Ok I dont understanding something here. This is a bank contract that has all the depositors funds in it correct? Now who am I? Am I the manager of these accounts. Am I the msg.sender each time I change the account at the top or am I always the top address and msg.sender? I am confused with that. And when I do a withdraw where is the money going to? The way I have it set up now is that I can add money to any account by selecting the account at the top. Then I can withdraw from my account or any account I select that I also have deposited funds. I do a check using “required” to make sure that balance[msg.sender] >= amount; And I also reduced the balance of msg.sender by the amount of the withdraw. Then I return the value of balance[msg.sender].
This seems to work but again its seems that whatever account I am using I am the msg.sender for every transaction. Because it will throw the error for insufficient balance if balance is insufficient for the withdraw. In the lecture you talked about only being able to withdraw to my account. Did you mean withdraw from my account?
Here is my code
pragma solidity 0.7.5;
contract Bank{
mapping(address => uint) balance;
address owner;
// To make sure that noboy can add balance except the owner of the contract we can make a constructor
//You can add an event function to use anywhere in the contract
event depositDone(uint amount, address depositedTo);
modifier onlyOwner{
require(msg.sender == owner);
_; // this last _; means to run the function if this condition is met.
//The modifier can also have an argument to check for a cost.
}
constructor(){
owner = msg.sender;
}
function deposit()public payable returns (uint){
balance[msg.sender] += msg.value;
//To emit an event you can call the event
emit depositDone(msg.value,msg.sender);
return balance[msg.sender];
}
function withdraw(uint amount)public returns(uint){
require(balance[msg.sender] >= amount, "Balance insufficien to make this transfer");
msg.sender.transfer(amount);
balance[msg.sender] = balance[msg.sender] - amount;
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 and the required also allows you to add statement if requirement not met.
require(balance[msg.sender] >= amount,"Balance is not sufficient");
// And now we can use require() to make sure that nobody except the owner can make a transfer
require(msg.sender != recipient,"You cannot sent money to yourself");
// We can also save the owners balance by adding a variable for previous balance before making transfer.
uint previousBalance = balance[msg.sender];
_transfer(msg.sender,recipient, amount);
//And then we can use assert() to verifiy that the owner balance has been reduced by the transfer.
//You cannot use a statement argument like for require
assert(balance[msg.sender]== previousBalance - amount);
//event logs and futher check will come later to check avaliable balances
}
function _transfer(address from, address to, uint amount)private {
//Now you can reuse this code for ohter functions. Function can only be called within this contract
balance[from] -= amount;
balance[to] += amount;
//emit balanceAdded(amount, to);
}
}
Does this not need to have “payable”?
function withdraw(uint amount) public returns(uint) {
require(balance[msg.sender] >= amount);
msg.sender.transfer(amount);
return balance[msg.sender];
}
Hey @voljumet
A function has to be payable if you send ether to it. Does not need payable otherwise.
A deposit()
function will be payable, a withdraw()
function will not.
Happy learning,
Dani
function withdraw(uint _amount) public returns(uint) {
require(balance[msg.sender] >= _amount, "Not enough balance.");
balance[msg.sender] -= _amount;
return balance[msg.sender];
}
I forgot the transfer.
function withdraw(uint _amount) public returns(uint) {
require(balance[msg.sender] >= _amount, "Balance too low for this transaction.");
balance[msg.sender] -= _amount;
msg.sender.transfer(_amount);
return balance[msg.sender];
}
pragma solidity 0.7.5;
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 withdraw (uint amount) public returns(uint){
require(balance[msg.sender] >= amount, "Balance not sufficient");
msg.sender.transfer (amount);
uint previousSenderBalance = balance[msg.sender];
assert(balance[msg.sender]== previousSenderBalance - amount);
}
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);
}
}
Well this works but is this the simplest way? I had to remove - returns (uint) - as this kept on giving me some sort of error.
function withdraw(uint amount) public {
require(balance[msg.sender] >= amount, “Balance not sufficient”);
msg.sender.transfer(amount);
uint previousSenderBalance = balance[msg.sender];
_withdraw(msg.sender, amount);
assert(balance[msg.sender] == previousSenderBalance - amount);
}
function _withdraw(address from, uint amount) private {
balance[from] -= amount;
}
function withdraw (uint amount) public onlyOwner returns(uint) {
require (balance[msg.sender] >= amount, “Balance not sufficient”);
uint previousSenderBalance = balance[msg.sender];
balance[msg.sender] = balance[msg.sender]-amount;
msg.sender.transfer(amount);
assert(balance[msg.sender] == previousSenderBalance - amount);
}
So I created a modifier enoughBalance that handles the require() check of sufficient funds of the sender like this:
modifier enoughBalance(uint amount){
require(balance[msg.sender] >= amount, "Insufficient Funds!"); //if condition is not met function will abort and throw error. Here: if balance of sender is not higher or equal to amount to send
_;
Then added modifier to function header. next transfer the funds, then decrease balance of sender, and added assert check at the end to check if balance of sender now is previousSenderBalance - amount by storing previous sender balance.
function withdraw(uint amount) public enoughBalance(amount) {
//store previousSenderBalance
uint previousSenderBalance = balance[msg.sender];
//msg.sender is exactly the same as address payable toSend = PUTADDRESSHERE, so you can define a payable adress like this. msg.sender already is a payable address!!
msg.sender.transfer(amount);
//if transfer fails for some reason contract throws error and reverts the transaction
balance[msg.sender] -= amount //decrease sender balance by amount
assert(balance[msg.sender] == previousSenderBalance - amount); //check if proccess succeeded by checking if sender balance is previouseSenderBalance minus withdrawn amount
}
pragma solidity 0.7.5;
contract Bank {
mapping (address => uint) balance;
address owner;
event depositDone(uint amount, address depositedTo) ;
event transferDone(uint amount, address toAddress, address fromAddress); //answer
modifier onlyOwner {
require(msg.sender == owner);
_;
}
constructor() {
owner = msg.sender;
}
function deposit() public payable returns (uint) {
balance[msg.sender] += msg.value;
emit depositDone(msg.value, msg.sender);
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 transferDone(amount, recipient, msg.sender); //answer
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
function withdraw(uint amount) public returns(uint){
require(balance[msg.sender] >= amount, "Issuficient balance!");
balance[msg.sender] -= amount;
msg.sender.transfer(amount);
return balance[msg.sender];
}
function getBalance() public view returns (uint) {
return balance[msg.sender];
}
}
function withdraw(uint amount) public onlyOwner returns(uint){
//handling error and check the balance is equal or greater of sender with require
require(balance[msg.sender] >= amount);
msg.sender.transfer(amount);
}