yep it can be asserted into the modifier like this, but you should only make modifiers for blocks of code that are duplicate in your contract. if your putting code into a modifier that is only used once then you dont need a mofifier as the purpose of a modifier is to get rid of duplicate code in your contract. your function looks absolutley fine to me though so great work
pragma solidity 0.7.5;
contract Bank {
mapping(address => uint) balance;
address owner;
event depositDone(uint amount, address indexed depositedTo);
event transferredBalance(uint amount, address recipient, address fromaddress);
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 getBalance() public view returns(uint) {
return balance[msg.sender];
}
function withdraw(uint amount) public returns (uint depositedAmount) {
//msg.sender is an address
require(balance[msg.sender] >= amount);
balance[msg.sender] -= amount;
msg.sender.transfer(amount);
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 to yourself");
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount);
assert(balance[msg.sender] == previousSenderBalance - amount);
emit transferredBalance(amount, recipient, msg.sender);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
function withdraw(uint amount) public onlyOwner returns (uint){
require(balance[msg.sender] >= amount, âBalance not sufficientâ);
msg.sender.transfer(amount);
balance[msg.sender] += amount;
return balance[msg.sender];
}
I donât think the _; breaks, it just triggers the relative function to run as a step within the modifier. For example, here is a modifier from the solidity docs:
modifier noReentrancy() {
require(
!locked,
"Reentrant call."
);
locked = true;
_;
locked = false;
}
True, but in your example, its an assert
what you are using, and is also missing variables, that way i mean that the modifier will not work because of this miss place of the assertion, take a look at his arguments, where does he take ogBalance
for example?.
Keep in mind, the solidity docs are not using an assert for a modifier, rather than a simple boolean to switch.
Carlos Z
function withdraw(uint amount) public returns (uint) {
require(balance[msg.sender] >= amount, "Insufficient Funds!");
msg.sender.transfer(amount);
}
type pragma solidity 0.7.5;
contract HelloWorld {
mapping(address =>uint)balance;
address owner;
event depositDone(uint amount, address indexed depositedTo);
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 withdrawl(uint amount) public returns(uint){
msg.sender.transfer(amount);
require(balance[msg.sender] >= amount);
}
function getBalance() public view returns (uint){
return balance[msg.sender];
}
function transfer(address recipient, uint amount) public {
_transfer(msg.sender,recipient,amount);
require(balance[msg.sender] >=amount);
require(msg.sender != recipient);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to]+= amount;
}
} paste code here
function withdraw(uint amount) public returns(uint) {
require(balance[msg.sender] >= amount, "Insufficient Funds");
balance[msg.sender] -= amount;
msg.sender.transfer(amount);
return balance[msg.sender];
}
function withdraw(uint amount) public returns (uint) {
require(balance[msg.sender] >= amount, "Insufficient Balance!");
uint previousSenderBalance = balance[msg.sender];
msg.sender.transfer(amount);
balance[msg.sender] -= amount;
assert(balance[msg.sender] == previousSenderBalance - amount);
return balance[msg.sender];
}
I am still experiencing weird issues with events not showing up in the logs. Any suggestions?
pragma solidity 0.8.16;
contract Bank {
mapping(address => uint) balance;
address owner;
//event balanceAdded(uint amount, address depositedTo);
event depositDone( uint amount, address indexed depositedTo );
event withdrawDone( uint amount, address indexed withdrawTo );
event balanceTransfered(address transferedTo, address daSender, uint amount);
modifier onlyOwner {
require(msg.sender == owner );
_; // run the function
}
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 desposit() public payable returns (uint) {
balance[msg.sender] += msg.value;
emit depositDone(msg.value, msg.sender);
return balance[msg.sender];
}
function withdraw(uint amount) public returns (uint){
require(balance[msg.sender] >= amount, "Balance not sufficient");
msg.sender.transfer(amount);
balance[msg.sender] -= amount;
emit withdrawnDone(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 balanceTransfered( recipient, msg.sender, amount);
assert(balance[msg.sender] == previousSenderBalance - amount);
}
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
hey this wont be an issue since your developing locally. the evetns are being emmitted dont worry. if yu want to be absolutley sure, then you can deploy your contract on a testnet work using the injected web3 option instead of the RemixVM. then when you go to execute one of your functions metamask will pop up and you will confirm the transaction there. when the transaction completes, you can go to your tx hostry in metamask and view the txn on etherscan and you will be able to see the logs there.
so in the deploy and run transactions tab on remix change your provider to this. and then in metamask change your network to kovan. this will let you deploy your contract on the kovan testnet using metamask
then just deploy and execute your contract function as normal. (note make sure to collect some testnet ether first. you can do so by googling eth fsucet kovan and choosing one of the websites to get testent ether.)
then when you deploy your contract and execute say your deposit function, confirm in metamask and when it comletes view your tx history in metamask like so
if you click on your most recent transaction you will see an option to view the transaction on the block exploeer (etherscan.io). choose this an you will be navigated to etherscan
ive done exactly this process and as yu can see the events are being emmitted you can look at the emitted events by cllicking on the âlogsâ tab in the above image.
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.5;
//// because we do ts w message sender,
// we cannot get balance of sone else, UNLESS WE CHANGE
// THE ADDRESS WHICH IS DOING THE SC ACTION!!
//if we change to another address, in the left section
// we do get other accounts & balances,
// the msg. sender
// is that address which is doing the SC action
//which, in remix is in the left section
contract Bank {
mapping(address => uint) balance;
//state variable owner
address owner;
event depositDone(uint amount, address cryptoTo);
modifier onlyOwner {
require(msg.sender == owner);
_;
}
constructor() {
owner = msg.sender;
}
//addBalance function name replaced by deposit name, instead of onlyOwner,
// since this is for anyone to deposit Ether, and this function is payable
function deposit() public payable returns (uint) {
//user's accountaccount balance is stored in the balance mapping: "balance[msg.sender]"
// we can delete "balance[msg.sender] += msg.value;" because it is not needed
//for the bank to move crypto, it is just for internal records of who deposited crypto
// for example to know who we owe crpyto to
//it is not needed for the total balance of the smart contract
//the balance of the smart contract is the total of all the deposits
balance[msg.sender] += msg.value;
emit depositDone(msg.value, msg.sender);
return balance[msg.sender];
}
function withdraw(uint amount) public returns (uint){
require(balance[msg.sender] >= withdraw);
//msg.sender is an address
msg.sender.transfer(amount);
balance[msg.sender] = balance -= withdraw(amount)
}
function getBalance() public view returns (uint){
return balance[msg.sender];
}
//crypto is subtracted from person using the contract, msg.sender
//& is sent to receiver address by adding it to receiver's amount
//this program does not check about msg.sender's balance
//(to find out if there is enough crypto in his balance
//for this action)
function transfer(address receiver, uint amount) public {
//require that crypto sender has greater than or equal to amount sent
//the 2nd item in the (), after the condition is an ERROR MESSAGE "balance is too small"
require(balance[msg.sender] >= amount, "balance is too small");
//require that sender does not have same address value as receiver
//the 2nd item in the (), after the condition is an ERROR MESSAGE
require(msg.sender != receiver, "sender address cannot be receiver");
//part of check if amount was actually sent between these 2 addresses,
//we save the balance before transfer
//SINCE ASSERT DID NOT WORK uint earlierSenderBalance = balance[msg.sender];
//assert checks that the expected reality (earlier balance minus amount) is true
//DID NOT WORK assert(balance[msg.sender] == earlierSenderBalance - amount);
_transfer(msg.sender, receiver, amount);
}
//from address is msg.sender
//receiver is an input
//amount is input for variable amount in function above
//the user calls the function above, because it a a public function,
//after that the private function is called
//this function can also be used again by other functions
//it seems that the program knows the from address as msg.sender
// from the order of the variables in ()
//How does Solidity know that the addition and subtraction of balance
//is for ETH? it is uint, but it does not say eth.
//is uint about address automatically a number for an amount of ETH?
function _transfer(address from, address to, uint amount) private {
balance[from] -= amount;
balance[to] += amount;
}
}
function withdraw(uint withdrawAmt) public {
require(getBalance() >= withdrawAmt, "Not enough funds available on account to withdraw this amount!");
uint senderPrevBal = getBalance();
// transfers funds FROM the bank (smart contract)'s address TO msg.sender address (msg.sender being the tx initiating address)
msg.sender.transfer(withdrawAmt);
emit amtWithdrawn(withdrawAmt, msg.sender);
balance[msg.sender] -= withdrawAmt;
// meaning the tx initiator's balance in this bank will be less, not his/her own address balance...
assert(getBalance() == senderPrevBal - withdrawAmt);
}
cool solution. where are u defining this getBalance() function. nice that your trying something different here but this function is redundant as you can query the balance of the user anytime with balance[msg.sender]
Yes youâre right, it is not necessary in this case. I just used it because I already had it (we wrote it during the lectures at some point. Itâs a simple getter method âŚ
function getBalance() public view returns(uint) {
return balance[msg.sender];
}
function withdraw(uint amount) public{
require(balance[msg.sender]>=amount, "not enough balance, try again");
msg.sender.transfer(amount);
balance[msg.sender]-=amount;
}
function withdraw(uint amount) public returns(uint){
msg.sender.transfer(amount);
require(balance[msg.sender] >= amount)
balance[msg.sender] -= amount;
pragma solidity 0.7.5;
contract Bank {
mapping (address => uint) balance;
address owner;
event depositDone(uint amount, address indexed depositedTo);
modifier onlyOwner {
require(msg.sender == owner);
_; // run the function
}
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 withdraw(uint amount)public returns (uint){
// msg.sender is an address
require(balance[msg.sender] >= amount, "Balance insufficient");
msg.sender.transfer(amount);
}
function getBalance() public view returns (uint){
return balance[msg.sender];
}
function transfer(address recipient, uint amount) public{
require(balance[msg.sender] >= amount, "Balance insufficient");
require(msg.sender != recipient, "Don't transfer money to yeourself");
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;
}
}
should be updated to payable(msg.sender) using hte new version
function deposit() public payable returns (uint) {
balance[msg.sender] += msg.value;
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;
payable(msg.sender).transfer(amount);
return balance[msg.sender];
}
Question for this assignment. In my withdraw function, why do I need to use a return for balance[msg.sender] in my function. My code works even if I donât have this line of code in it.
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.5;
pragma solidity 0.7.5;
contract Bank {
mapping(address => uint) balance;
address owner;
event depositDone(uint amount, address indexed depositedTo); // paramaters we want sent to this event.
modifier onlyOwner{
require(msg.sender == owner);
_; // run the function
}
constructor(){
owner = msg.sender;
}
function deposit() public payable returns (uint) {
balance[msg.sender] += msg.value;
emit depositDone(msg.value, msg.sender);//emits the event ln 11
return balance[msg.sender];
}
function withdraw(uint amount) public returns (uint){
require(balance[msg.sender] >= amount, "Balance not sufficient");//person depositing
//msg.sender is a payable address already.
balance[msg.sender]-= amount;// Change balance in mapping
msg.sender.transfer(amount);//Withdraws actual money from account.
return balance[msg.sender]; //Why do I need the return.
}
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];
}
}