Solidity – How to Send Ether with a Smart Contract

errorganachemetamasksolidity

I have Solidity contract that is meant to send ether to someone. Unfortunately it's giving me a cryptic error message after I confirm the transaction in MetaMask.

I'm testing on a local ethereum network running on ganache and the project was built using a react truffle box.

Contract:

pragma solidity ^0.4.24;

contract Sender {
    uint256 public balance;

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

    function getBalance() public returns (uint) {
        return address(this).balance;
    }

}

JavaScript

userInputHandler = (event) => {
    this.setState({amountToPay: event.target.value})

    const contract = require('truffle-contract')
    const sender = contract(Sender);
    sender.setProvider(this.state.web3.currentProvider);

    this.state.web3.eth.getAccounts((error, accounts) => {
        sender.deployed().then((instance) => {

            console.log("Seems to explode after here" );
            return instance.sendTransaction({
                from: accounts[0],
                to: accounts[4],
                value: this.state.web3.toWei(this.state.amountToPay, "ether"),
                gas: "220000"}).then((result) => {

                console.log("result: " + result);
        })
    })
})

};

ErrorMessage

inpage.js:1
MetaMask - RPC Error: Error: Error: [ethjs-rpc] rpc error with payload
{
"id": 8476063269707,
"jsonrpc": "2.0",
"params": ["0xf87182011a85174876e80083035b609406c1939f6cbb68d42333f140cae815cc36d341b0880de0b6b3a764000080822d46a011d708c9d53a5e7e9195c32fab4f6f3cad259887436eadd521d93ac853541455a0176061761d6d14c063eb2b0c359457dec982d72d52f19bdf33fa8f5be20ed939"],
"method": "eth_sendRawTransaction"
} Error: VM Exception while processing transaction: revert

Uncaught (in promise) Error: Error: Error: [ethjs-rpc] rpc error with payload  Error: VM Exception while processing transaction: revert

Solution
send seems to be some kind of reserved word or function that was getting overridden. I changed the function name to sendMoney and all suggestions from @Jaime which fixed my problems.

Best Answer

The error is that your contract can not receive ether because it doesn't have a fallback function. Just add this to it:

function () public payable{
}

This will allows your contract to accept ether.

Another thing is that in your send function you have:

msg.sender.transfer(msg.value);

but should be

 _receiver.transfer(msg.value);

Also, is not clear what are you trying to do in your js code, are you trying to send ether to the contract, or are you trying to use the 'send' function?

In the first case (sending ether to the contract use):

web3.eth.sendTransaction({....})

In the second case (trying to use the send function in your contract), having your contract instance as 'contractInstance' you can do something like this:

var account = web3.eth.accounts[0]; 
var mycontract = web3.eth.contract(ABI);
var contractInstance = mycontract.at('contractaddress...')
contractInstance.send('0x...',{'value':web3.toWei(myvalue,'ether')} function(err,res){
        if(err){
            console.log('transaction failed')
        }
    })

hope this helps

Related Topic