Recently, I started to explore Solidity and was using Remix IDE to learn more about smart contract development. I made a very basic contract and wanted to deploy it with having ether from a testing account, but after setting the value of 1 ether and clicking on the Deploy button, the deployed transaction failed giving me the "VM error: revert" error.
This is the source code of the smart contract I created on Remix.
I wanted to deploy the contract that would have Ether in the contract's balance, so I added the receive () external payable {}
function. I assumed this fallback function was what I needed to have since the documentation for Receive Ether Function states:
This is the function that is executed on plain Ether transfers
With Value 0, the contract deployed successfully, but when I wanted to enter any other value, the deployment of the contract failed after clicking on the Deploy button with the debug window displaying the following error:
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.
I tried to raise the Gas Limit, but that also didn't fix the issue. Then I noticed that the Deploy button was displaying "Deploy - transact (not payable)" message when the cursor was hovering over the button.
It turns out the Remix IDE function buttons can have different colors depending on what they represent:
- Blue
These will be constant or pure functions. They do not create new transactions and only return a value. - Orange
These functions do not accept Ether (they are non-payable). Clicking on them create transaction and cost gas. - Red
These are payable functions that can accept a value. They create transactions and also cost gas.
The Deploy button was in orange color too, so it has a non-payable function. So how do we turn it to be payable in red color?
Solution
The reason that the Deploy button is non-payable and orange in color is due to the constructor. When deploying a contract, the constructor is called first and since there was no constructor defined in the smart contract, the default constructor (that is not payable) was called, so the transaction failed.
To make the code work, all I had to do was to add a constructor that was set with payable keyword. The added code is highlighted yellow:
After this change, the Deploy button on Remix IDE changed color from orange to red with the hover message "Deploy - transact (payable)".
The transaction worked without errors and the smart contract was deployed successfully.
When testing the deployed contract, after I clicked the "getBalance" button to run the contract function, it returned the balance of 1 ether, the same value that was used when deploying the contract.
The balance is returned in smallest unit of Wei, so the value returned for 1 Ether is 1018 Wei as shown in the image below.
Conclusion
When you start learning about Solidity using Remix IDE and trying to deploy a contract with a starting balance, the deployed transaction might fail if the Deploy button is orange color with Deploy - transact (not payable) message when hovering over with the cursor. In my case, this was due to a missing constructor in the contract source code, so the Deploy button called the default non-payable constructor when deploying the contract. By adding the payable constructor, the issue was resolved.
ash
December 9, 2021Actually the solution is unnecessary: although I was frustrated too, figuring out what's up.
The amount in value pertains to the msg.sender for each time you click either deploy or of your contract's functions: so you can not have a payable constructor, deploy it with 0 in the value input field, then input 1234 and click to trigger the receive function and it'll deposit.
However if you want to initialize the contract with some value, then you do need a payable constructor as the contract owner, initially deploying the contract, will have their msg.value correspond accordingly.