How to send an Ethereum transaction in Solidity from a smart contract

In this tutorial, we are going to learn how to send a transaction from a smart contract in Solidity and how to run a function when the smart contract receives a transaction.

In this tutorial, we are going to learn how to send a transaction from a smart contract in Solidity and how to run a function when the smart contract receives a transaction.

That's useful in many situations like when you want to withdraw the Ethereum that's in your smart contract or send it to someone else when a specific function is called.

Before we dive in, an important thing to know is that you can only send Ethereum to a payable address and not to an address. These are distinct types in Solidity. To convert an address into a payable address, you can simply do:

address recipient = 0x5b8f1310A956ee1521A7bB56160451C786289aa9;

// convert to a payable address
address payable payableRecipient = payable(recipient);

How to send Ethereum from your smart contract

We have 3 functions to send Ethereum:

  • transfer – uses 2300 gas and throws an error if the transaction fails
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract A {
    function sendETH(address payable _recipient) public payable {
        _recipient.transfer(msg.value);
    }
}
  • send – uses 2300 gas and returns a boolean indicating if the transaction was successfully or not
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract A {
    function sendETH(address payable _recipient) public payable {
        bool wasSentSuccessfully = _recipient.send(msg.value);
        require(wasSentSuccessfully, "Failed to send Ether");
    }
}
  • call – forwards all the gas sent when calling the function or sets the gas itself and returns a bool indicating if the transaction was completed successfully or not
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract A {
    function sendETH(address payable _recipient) public payable {
        // call will also return data about the transaction
        (bool wasSent, bytes memory data) = _recipient.call{value: msg.value}("");
        require(wasSent, "Failed to send Ether");
    }
}

The call function is the one that's recommended at the moment but the others work too.

All these functions allow you to send Ethereum to other smart contracts or wallets.

How to run a function when your smart contract receives Ethereum

Your smart contract can define 2 function that will be executed when your smart contract receives Ethereum.

These functions are receive and fallback.

If the transaction that was sent contains data (ie. if msg.data is not empty), receive will be called if you defined it in your smart contract.

If the transaction has no data (msg.data is empty) or if it has data but receive is not defined, fallback will be called.

Here is how to define these functions:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract A {
    receive() external payable {
        // do something here when the smart contract receives ETH
    }
    
    fallback() external payable {
        // do something here when the smart contract receives ETH
    }
}

If both functions are defined like in the example, receive will be executed if msg.data is not empty, otherwise, fallback will run.

How to get the balance of your smart contract in Solidity

If you want to check the balance of an address in Solidity, you can read the balance property of a variable of type address. In other words, store the address you want to check the balance of in a variable of type address and then just call .balance on that variable.

Example:

address testAddress = 0x5b8f1310A956ee1521A7bB56160451C786289aa9;
// get the balance:
testAddress.balance

If you want to check the balance of your smart contract inside that smart contract's code, use this code:

address(this).balance;

address(this) will get the address of the smart contract and .balance will get its balance.

And that's it 🎉

Thank you for reading this article