🐶
Solidity

Solidity Error: Payable Function & Balance Check

By Ondřej Dolanský on 11/27/2024

Learn how to fix Solidity transaction errors related to payable functions and insufficient balance to avoid common pitfalls when interacting with smart contracts.

Solidity Error: Payable Function & Balance Check

Table of Contents

Introduction

The error "The called function should be payable" occurs in Solidity when you attempt to send Ether to a function that is not designed to receive it. To resolve this, you need to understand how Solidity handles Ether transfers within contracts.

Step-by-Step Guide

The error "The called function should be payable" arises when you try to send Ether to a Solidity function that isn't equipped to handle it. Here's a breakdown:

1. Payable Functions:

In Solidity, functions are not allowed to receive Ether by default. To enable a function to accept Ether, you mark it as payable.

function receiveEther() public payable {
    // This function can now receive Ether
}

2. Common Causes & Solutions:

  • Calling a Non-Payable Function with Value: Ensure you're not attempting to send Ether to a function that isn't declared as payable. Double-check the function signature in your contract.

    function myFunction() public {  // Missing 'payable'
        // ... 
    }
  • Incorrect Contract Address: Verify that you're interacting with the correct contract address. Sending Ether to the wrong address will result in this error if the recipient contract doesn't have a payable fallback function.

  • Insufficient Funds: Confirm that the sending address has enough Ether to cover both the transaction fee (gas cost) and the amount of Ether being sent.

3. Debugging Tips:

  • Remix: Utilize the debugger in Remix to step through your code execution and pinpoint the exact line causing the error.
  • Console Logs: Add console.log statements (if using a framework like Hardhat) to track the flow of your code and variable values.

Example:

// This will cause an error if called with value
function doSomething() public { 
    // ...
}

// Correct: Function is now payable
function doSomethingElse() public payable { 
    // ...
} 

Key Points:

  • Always mark functions that should receive Ether as payable.
  • Thoroughly test your contracts to catch these errors during development.

Code Example

This Solidity code demonstrates the "The called function should be payable" error. It defines a contract with a function to receive Ether (receiveEther) and a function not designed to receive Ether (doSomething). Calling doSomething with a value will cause the error because it's not marked as payable. The solution is to add the payable modifier to doSomething to allow it to accept Ether.

pragma solidity ^0.8.0;

contract PayableExample {

    // State variable to store the contract's balance
    uint256 public contractBalance;

    // Function to receive Ether - marked as 'payable'
    function receiveEther() public payable {
        contractBalance += msg.value;
    }

    // Function NOT designed to receive Ether
    function doSomething() public {
        // This function does not accept Ether
        // If called with value, it will throw an error
    }

    // Function to check the contract's balance
    function getBalance() public view returns (uint256) {
        return contractBalance;
    }
}

Explanation:

  1. receiveEther(): This function is declared as payable, allowing it to accept Ether. The msg.value property is used to access the amount of Ether sent with the transaction.

  2. doSomething(): This function is not declared as payable. Attempting to send Ether to this function will result in the "The called function should be payable" error.

  3. getBalance(): This function is a view function that returns the contract's current balance.

How to Reproduce the Error:

  1. Deploy this contract (e.g., using Remix).
  2. Call the doSomething() function and try to send some Ether along with the transaction.
  3. You will encounter the "The called function should be payable" error.

Solution:

To fix the error, you would need to modify the doSomething() function and mark it as payable:

function doSomething() public payable { 
    // Now this function can accept Ether
} 

Remember: Always carefully consider which functions in your contract should be able to receive Ether and mark them as payable accordingly.

Additional Notes

  • The payable keyword modifies a function's behavior, explicitly allowing it to receive Ether. Without it, the function is designed to work solely with data and state changes.
  • This error is a security measure in Solidity. If functions could receive Ether by default, it could lead to vulnerabilities where contracts unintentionally become money sinks.
  • Fallback functions can also be payable. A fallback function is executed when a contract receives Ether without a specific function being called. If your contract needs to accept Ether in a general way, make sure the fallback function is marked payable.
  • Gas considerations are crucial. Even if a function is payable, the transaction can still fail if the sender doesn't provide enough gas to cover the execution cost.
  • Testing with different scenarios is essential. Simulate transactions with varying amounts of Ether and from different addresses to ensure your contract handles Ether transfers correctly.

Summary

Topic Description Solution
Payable Functions Solidity functions don't accept Ether by default. Declare functions that should receive Ether as payable.
Calling Non-Payable Function with Value Sending Ether to a function without the payable modifier. Add the payable modifier to the function definition.
Incorrect Contract Address Sending Ether to the wrong contract address. Double-check the contract address and ensure it has a payable fallback function.
Insufficient Funds The sending address lacks enough Ether for the transaction fee and the sent amount. Verify sufficient balance in the sending address.
Debugging Tips Identifying the source of the error. Use Remix debugger or add console.log statements for tracking code execution.

Conclusion

To avoid the "The called function should be payable" error in your Solidity contracts, ensure any function intended to receive Ether is explicitly marked with the payable modifier. This practice enhances the security and clarity of your smart contracts by preventing unintended Ether transfers. Remember to test your contracts thoroughly, simulating various transaction scenarios to guarantee they handle Ether transfers as expected. By understanding and correctly implementing the payable modifier, you can create more robust and secure decentralized applications.

References

  • Payable function error: The called function should be payable if you ... Payable function error: The called function should be payable if you ... | Mar 10, 2021 ... The error "The called function should be payable" when compile a contract from REMIX is a general error that indicates an excess of GAS cost in ...
  • Normal function showing error asking to make it Payable - Smart ... Normal function showing error asking to make it Payable - Smart ... | Below is the prograame in solidity I wrote which assigns value to elements of an array. pragma solidity 0.8.16 ; contract arr { uint i = 0 ; people[] public person ; struct people { uint256 num ; string name ; } function plus(string memory naam , uint256 nu) public { person[i].num = nu ; person[i].name = naam ; i++ ; } } Instead of push function I want to put values like this . While compilation and deploy...
  • arrays - "The called function should be payable if you send value ... arrays - "The called function should be payable if you send value ... | Apr 6, 2022 ... This is my first post on this stack exchange site and it comes after a couple of hours of banging my head against this error's wall. In short, I ...
  • I am getting "The called function should be payable if you send ... I am getting "The called function should be payable if you send ... | Dec 21, 2021 ... I am trying to write a smart contract for jackpot game which calculates users' rate and randomly selects one user but I am getting "The called function should ...
  • VM Error deploying ERC777 with Remix - Contracts - OpenZeppelin ... VM Error deploying ERC777 with Remix - Contracts - OpenZeppelin ... | Using remix, compiler on 0.6.12 and I keep getting this error when trying to deploy basic erc777 from open zeppelin tutorials. Constructor params are “1000”,[“0x5B38Da6a701c568545dCfcB03FcB875f56beddC4”] creation of GLDToken errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information. pragma so...
  • Why the gas cost strangely so big when deploy. · Issue #15061 ... Why the gas cost strangely so big when deploy. · Issue #15061 ... | Description Why deploy the code failed. The error log is as following: gas 1000000000000000000 gas transaction cost 984375000000005328 gas execution cost 984374999999815072 gas revert The transacti...
  • The transaction has been reverted to the initial state error - Smart ... The transaction has been reverted to the initial state error - Smart ... | Hey guys, I am facing an error which is transact to LotteryEscrowParent.callPurchaseItem errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. In the following function:- function callPurchaseItem( uint256 tokenId, address tokenAddress, address collectionContract, uint256 price )public{ Lo...
  • Errors Handling in solidity from zero to hero (Require- Assert- Revert ... Errors Handling in solidity from zero to hero (Require- Assert- Revert ... | Errors Handling
  • I tried deploying this contract and i gave me this error - Contracts ... I tried deploying this contract and i gave me this error - Contracts ... | I tried deploying this contract and i gave me this error "creation of VelaCoin pending... creation of VelaCoin errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information." // SPDX-License-Identifier: MIT pragma solidity 0.8.19; // abstract contract Context { function _msgSender() internal...

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait