Solidity Payable Functions - Discussion

I assume you are attempting to spend funds from a wallet to another wallet. If that´s the case, there is no way to program a contract to spend from another wallet.

You can how ever deposit funds to contract with a wallet and withdraw from the contract with another wallet. Remember to deduct balances before doing the transfers/interactions by the way, for security reasons. (to prevent re-entrancy attack)

i have tried the following, and i manage to send money from one account to another

function send(address payable _receiver) public payable {
                        _receiver.send(msg.value);
                }
1 Like

You can also just do the following, keep in mind that from solidity version 0.8, you have to convert an address into payable to be able to transfer to it.

function send(address _receiver) public payable {
                        payable(_receiver).transfer(msg.value);
                }

Carlos Z

Hi, I have a quick question about the transfer function. My code was working perfectly fine before I tried to make it payable and transfer ether with it. Now even though I have set it to payable in the function header it still keeps giving a message saying the function needs to be payable to send value. Below is my current relevant code and a screenshot of the error revert message Remix keeps giving me. Any help would be greatly appreciated, thanks!

function transfer(address recipient, uint amount) public payable {
       require(balance[msg.sender] >= amount, "Insuficient Balance"); 
       require(msg.sender != recipient, "Cannot Transfer to Yourself"); 
       uint previousSenderBalance = balance[msg.sender];    
       _transfer(msg.sender, recipient, amount);
       GovernmentInstance.addTransaction(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; 
    } 

There is a difference when sending eth, is not the user who pay to transfer to another user, its the contract who will.

Check this simple contract I made to show you the difference between transfer from a user to another inside the contract and withdraw or deposit eth on the contract.

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.7;

contract contractPayable{

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 {
        require(balance[msg.sender] >= amount, "not enough balance to withdraw");
        balance[msg.sender] -= amount;
        payable(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 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;
    }

}
1 Like

Oh ok, I got it now and it is working fine. Thank you!

1 Like

Can we put the msg.value as the total balance of an wallet, like when someone is connected on my SC and he want to send money, the amount must be the balance of the wallet. Thanks

Hi @Lamasticot
That would cause an insufficient gas error. There should be some balance left in the wallet for gas payment.