Solidity Payable Functions - Discussion

@filip What is wrong with my code???
I keep getting an error at msg.sender.transfer(amount);

pragma solidity 0.8.2;
contract Bank {
    
    mapping(address => uint) balance;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    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;
        **msg.sender.transfer(amount);**
        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);
                
        assert(balance[msg.sender] == previousSenderBalance - amount);
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
    
}

Capture,mkl;m

Thank you for this response. It was very helpful.

1 Like

When I use the deposit function the deposit does not show up in my getBalance function. Also, the transfer function adds the number to my getBalance instead of subtracting it and I’m not sure why.

pragma solidity 0.7.5;

contract Bankrobber {
mapping(address => uint) leftovers;

address owner;

event depositDone(uint paid, address indexed depositedAcc);

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

constructor(){
    owner = msg.sender;
}

function deposit() public payable returns (uint){
    
    emit depositDone(msg.value , msg.sender);
    return leftovers[msg.sender];
}

function getBalance() public view returns (uint){
    return leftovers[msg.sender];
}

function transfer(address receevuh, uint guap) public {
    require (leftovers[msg.sender] >= guap, "Balance is insufficient");
    require (msg.sender != receevuh, "You waste money on gas during self-transactions.");
    
    uint PreviousBalance = leftovers[msg.sender];
    
    _moneymoves(receevuh, msg.sender, guap);
    
    assert(leftovers[msg.sender] == PreviousBalance - guap);
    
}

function _moneymoves(address to, address from, uint guap) private {
    leftovers[from] -= guap;
    leftovers[to] += guap;
}

}

You are missing to add the value from msg.value to the leftovers mapping, also there is no need to return the value, thats why you have getBalanec, so it should be:

function deposit() public payable {
    leftovers[msg.sender] = leftovers[msg.sender] + msg.value;
    emit depositDone(msg.value , msg.sender);
}

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

1 Like

Great and quick reply, thank you.

thanks that solved everything. To think I could possibly have solved it on my own had I known that but I had such a hard time trying to find the problem I ended up watching the video. Im really starting to get this down and I couldnt do it without this great community, Thanx alot

1 Like

You are very welcome!

Hello everyone,
how can I get the value of the total amount of Eth owned by the contract?
Thanks

Hello Filip,

I tend to have difficulties saving my work on Solidity. Every contract i make, when i close my pc, goes without being saved.

How do i save everything / contract i make? Your Help is highly needed.

1 Like

I am pretty new here and was wondering exactly the same.
I simple keep the code in txt files on my pc.

Hi @Ako1

If you are using a local / temporary blockchain, all data are erased when you turn it off.

Reards,
Dani

Hi @MyName

You can return address(this).balance in your smart contract or use the web3 method web3.eth.getBalance

Happy coding,
Dani

1 Like

Hi Samuel,

i just faced the same issue. Aparently it is a change from solidity 0.7 to 0.8 as describer [here].(https://docs.soliditylang.org/en/v0.8.3/080-breaking-changes.html)

It says that you can only use the transfer function on objects of type address payable. Since msg.sender is only of type address I converted it as follows:

    function withdraw(uint amount) public returns (uint){
        require(balance[msg.sender]>=amount);
        
        address payable myAddress = payable(msg.sender);
        balance[msg.sender]-=amount;
        myAddress.transfer(amount);
        return balance[msg.sender];
    }

Regards Christoph

3 Likes

Thanks for the link, Christoph! I was a bit stuck too…

1 Like

Hey Jon, could I please draw your attention to this code? I moved forward because I was not able to enter my code in the previous assignment since I have to wait for a reply due to the 3 consecutive messages error thingy majiggy. Have you seen it? Anywho, the logs part comes back in this code but for some reason, the value of the balance does not come back at 10 to the power of 18 as my good buddy Filip states it should or at least the way it does in his contract (T.C. 8:31 in the Payable Functions video). Could you please let me know what I am missing? Also, I will enter the code once you have the time to look into the other messages, too. Thank you very much, kind Sir!

pragma solidity 0.7.5; 

contract Bank{
    
    // storage - permanent storage of data (state variables)
    
    // memory - temporary storage used in function execution 
    
    // callData - save arguments/inputs to our functions 
    
    // strings, arrays, mappings, structs 
    
    mapping(address => uint) balance; 
    
    address owner; 
    
    event depositDone(uint amount, address indexed depositedTo); 
   
    
    modifier onlyOwner {
        require(msg.sender == owner); 
        _; // run the modifier 
    }
    
    
    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 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); 
        
    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount; 
        balance[to]  += amount; 
        
    }

Hi Joseph,

There’s nothing wrong with your code. I’ve copied and pasted it into Remix, deployed it and called the deposit function with 1 ether, and the emitted depositDone event correctly logs the deposit amount in wei:

"amount": "1000000000000000000"

When you input the value to be sent in the Value field, are you making sure that you also change the unit of currency from wei to ether in the dropdown which is next to it? If you input 1 wei, then you are depositing 1 wei and the event will log:

"amount": "1"

To deposit 1 ether, you need to input:

  • 1 ether
  • 1000 finney
  • 1000000000 gwei (10^9)
    or
  • 1000000000000000000 wei (10^18)

When you deposit 1 ether, you will also see that the sender’s address account balance in the Account field reduces by 1 ether.

Just also be aware that the amount logged by the event is the amount deposited, not the user’s balance (although these will obviously be the same for the first deposit).

1 Like

Hello Jon,

Thanks for your valuable feedback. You drew my attention to something that I had missed. Thank you for reminding me that need to specify the value that I am depositing (wei, gwei, finney, ether). I will make it a point not to miss that. Talk soon!

1 Like

Hello,

I am kind of stuck on payable functions assignment. I think my code is correct, but when I try to “withdraw” the 30 ETH into my address 30 ETH does not add to my wallet. The wallet only increases in small increments. I know this isn’t the project, but is there something im missing here?

pragma solidity 0.7.5;

contract Bank {
    
    mapping(address => uint) balance;
    address owner
    
    //declaring an event for logs
    event depositDone(uint amount, address indexed depositedTo);
    
    // everytime contract launches, this fires off once
    constructor() {
        owner = msg.sender;
    }
    
    
    
    function deposit() public payable returns (uint)  {
        balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender); //emitting event for logs
        return balance[msg.sender];
    }
    
    
    function getBalance() public view returns (uint) {
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public returns (uint) {
        msg.sender.transfer(amount);
    }
    
    // error  handling using require and assert function
    function transfer(address recipient, uint amount) public {
        require(msg.sender != recipient, "You cannot send money to yourself");
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        
        //saving previous balance
        uint previousSenderBalancer = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
        
        assert(balance[msg.sender] == previousSenderBalancer - amount);
        // assert checks to see if code does what it is supposed to do. Similar to in-line unit testing
        
    }
    
    // naming convention for functions that are labeled private, the transfer function calls this function.
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
        
        
    }
}

image

Got an error in _transfer anyone know what the issue is?

Do payable functions work with ERC20 tokens too?

1 Like