Search code examples
blockchainsoliditysmartcontractsmetamaskremix

Sending eth from one metamask wallet to another wallet in solidity


I'm trying to write a smart contract to transfer eth from one metamask wallet to another metamask wallet in solidity in remix with Injected Web 3 environment. I deployed the contract but the transaction send_ETH failed. Could anyone help me figure out why? Thank you so much

pragma solidity >=0.8.0;

// Get the latest ETH/USD price from chainlink price feed
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

contract myContract {
    address payable[] recipients;
    mapping(address => uint256) public balanceAccount;
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    function send_ETH(address payable recipient, uint256 amount) public {
        //set the minimum amount of dollar to transfer
        uint256 minimumUSD = 0.01 * 10 ** 18;
        amount = minimumUSD;
        require(getConversionRate(amount) >= minimumUSD, "You need to spend more ETH!");
        
        this.invest(amount);
        this.fund(recipient);
    }

    function invest(uint256 amount) payable external{
        //transfer amount ETH from metadata wallet to smart contract

        recordTransaction(address(this), amount, false);
        recordTransaction(owner, amount, true);
        address payable contractAddress = payable(address(this));
        contractAddress.send(amount);
    }

    function fund(address payable recipient) external {
        //transfer amount ETH from this smart contract to the recipient

        recordTransaction(address(this), address(this).balance, true);
        recordTransaction(recipient, address(this).balance, false);
        recipient.send(address(this).balance);
    }

    function recordTransaction(address recipient, uint256 deposit, bool out) private {
        if (out) {
            balanceAccount[recipient] -= deposit;
        } else {
            balanceAccount[recipient] += deposit;
        }
    }


    function getVersion() public view returns (uint256){
        AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
        return priceFeed.version();
    }

    function getPrice() public view returns(uint256){
        AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
        (,int256 answer,,,) = priceFeed.latestRoundData();
         // ETH/USD rate in 18 digit 
         return uint256(answer * 10000000000);
    }

    function getConversionRate(uint256 ethAmount) public view returns (uint256){
        uint256 ethPrice = getPrice();
        uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
        // the actual ETH/USD conversation rate, after adjusting the extra 0s.
        return ethAmountInUsd;
    }
}

Solution

  • your function invest() is wrong

       function invest(uint256 amount) payable external{
            //transfer amount ETH from metadata wallet to smart contract
    
            recordTransaction(address(this), amount, false);
            recordTransaction(owner, amount, true);
    
             //these 2 lines below are wrong
            address payable contractAddress = payable(address(this));
            contractAddress.send(amount);
        }
    

    You marked that function as payable, that's correct if you interact directly with that, but you interact with send_eth, so it needs to be payable to receive eth

    Then you saved the contract address as payable and did contractAddress.send(amount) that's mean: "contract send 'amount' to contract"

    the send() function send money from contract to an address

    also the amount var is wrong

    all eth sent are sent directly through tx information, and not through data

    the function correct:

    function send_ETH(address payable recipient) payable public {
        //set the minimum amount of dollar to transfer
        uint256 minimumUSD = 0.01 * 1e18;
        require(getConversionRate(msg.value) >= minimumUSD, "You need to spend more ETH!");
        
        this.invest(msg.value);
        this.fund(recipient);
    }
    
       function invest() internal{
            //transfer amount ETH from metadata wallet to smart contract
    
            recordTransaction(address(this), amount, false);
            recordTransaction(owner, amount, true);
        }
    

    then when calling send_eth you have to write manually the amount of eth to send, if you will make an interface for that, you can write the eth amount to send inside the tx details like:

    const transaction = {
     'to': '0x31B98D14007bDEe637298086988A0bBd31184523', //contract address 
     'value': 1, //1 eth
     'gas': 30000,
     'maxFeePerGas': 1000000108,
     'nonce': nonce,
    };