How to show transaction on metamask when balance is 0 - ethereum

I'm using ethers.js and trying to call for a method on a contract using
myContract.myMethod(amount, {"value": ethers.utils.parseEther((price * amount).toFixed(2))});
the toFixed() is not important here (it's only because calculations with multiply and float gives answers like 12.000000002 and it's not passing the validation from the contract
I'm using metamask for the user to interact with the contract, the problem is when I have balance 0, and I'm trying to call for myMethod I get an error: 'insufficient funds for gas * price + value' but I want it to be that metamask will open and show the transaction, and it will be the one that will show the 'insufficient fund' error without getting an error in my code (this is mostly for user-friendly from the metamask UI). I haven't found any answer about it in the ethers.js documentation and I saw some sites that implement this logic somehow (for example https://opensea.io/).
Example how it opens in opensea site:
Is it possible to do this through ethers.js or any other way?
Thank you.

Related

Get error message shown in the status of the transaction in EVM blockchain

I couldnt figure out how to get the status of the transactions i.e "Fail with error "001010".
The ability to show error message, or the revert reason. depends on the EVM client (GoEthereum, Erigon, Ganache, Ethereum Tester, etc.) There is no bulletproof "standard".
The clients store only the receipt field status that is 0 or 1 (=success)
The clients do not store the revert reason (I might be wrong on this one and this has changed lately)
To get the actual error message you need to replay the transaction and a certain block height using a special eth_call JSON-RPC.
Here is a Javascript library for doing it and a related blog post about the topic.

Force sending a transaction using ethers

I am using ethers js and want to send a transaction forcefully that might result in an error. Metamask allows me to do so, and so does remix, by hitting 'force send' - but when I do a contract call in my ethers code through a JSON RPC, it gives me an error saying 'transaction reverted: '
How can I force send a transaction programatically?
Solved - I was able to do this by overriding gas limit and gas price.
In order to do so, overrides object with preset param gasLimit should be passed as last parameter. See more at ethers docs
Reference to ethers library maintainer comment here

How can one obtain the message from state-reverting exception using ethereum clients, when self did not broadcast transaction?

Suppose an ethereum smart contract has external function "foo" whose logic has state-reverting exception require(1 == 0, 'error: you broke the simulation!');.
If ethereum-client A broadcasts transaction "txA" which is a function call on foo, how can ethereum-client B access the state-reverting message corresponding to "txA"?
edit: by "how can", I mean how can a developer practically enable ethereum-client B to access this data. i.e. Can you please point me in the direction of the correct (lower-level.. not webui) api/rpc call from a particular tool?
Clearly this is possible since block explorers provide such messages for failed transactions. I read through some of the source of etherscan, but their javascript is minimized and not easily readable.
Thanks in advance!
See this: https://ethereum.stackexchange.com/questions/39817/are-failed-transactions-included-in-the-blockchain
Failed transactions often are included in the chain.
What you sometimes see, if you're using e.g. MetaMask, is a popup saying "this transaction will fail" that happens before the transaction is sent to the chain. This is MetaMask trying to be helpful and prevent you wasting gas. But you can force send the transaction anyway, and you'll get a failed/reverted transaction posted on-chain (like this one for this Solidity source).
So to answer the original question, if TxA was posted on-chain, then client B will process it and get the revert message itself. If TxA was not posted on-chain, then there is no record of it.

Gas required exceeds limit

I'm trying to deploy the following contract on Ropsten using an injected web3 environment (i.e. metamask) on remix.ethereum.org/
pragma solidity ^0.4.16;
contract Coin {
// The keyword "public" makes those variables
// readable from outside.
address public minter;
mapping (address => uint) public balances;
// Events allow light clients to react on
// changes efficiently.
event Sent(address from, address to, uint amount);
// This is the constructor whose code is
// run only when the contract is created.
function Coin() public {
minter = msg.sender;
}
}
I've been able to create contracts with ease using remix before. I'm not sure what has changed, but I can't create contracts at all because of the gas limit thing. I've even gone as far as setting the gas limit to 2 full Ethers (i.e. value 1 ether with max of 2). I have close to 3 ethers in my metamask wallet. The remix "Account" dropdown also displays my metamask address correctly so it seems that the injected environment is connected.
When I try to create this contract I can't get past the gas required exceeds limit 2 error. I'm scratching my head as to why this simple contract would exceed the cost of 2 full Ethers.
Other parameters for remix in use:
optimize=false&version=soljson-v0.4.20+commit.3155dd80.js
Is there a setting on remix that I've forgotten? I'm Trying to deploy this from Chrome.
edit: I'm still scratching my head on this one. I was able to create the contract above for a brief moment after refreshing my page, but I came in today to try and run the code from https://www.ethereum.org/token and I can't get past the exceeds gas error with a value of 20 Gwei and a limit of 3000000. Note, I tried using the simple sample contract above and I'm back to where I was when I started - even the simple "Coin" contract above apparently exceeds the gas limit.
edit 2: Well, I think I'm getting somewhere. I've changed the compiler version from "soljson-v0.4.20+commit.3155dd80.js" to "soljson-v0.4.19+commit.c4cbbb05.js". Then I refresh the page 3 times. After that I wait a couple of minutes and things seem to be working again. There is something else happening here because when I reject the transaction in metamask and then return to remix to create again, I encounter the gas exceeded error. I don't believe the issue here is metamask as I've tried to connect locally using testrpc - localhost:8545 - and experience the same issue. All I can say is that the same code that I try to create fails to submit because of the gas error most of the time but occasionally works regardless of compiler version.

VM Exception in solidity

I am using testrpc and truffle to test my smart contract before deploying it to the real network.
In my contract, each node has to register in the contract by calling the function register, after that he can send or receive messages to/from contract( the blockchain )
The problem is, when an address ( let say account 1 from testrpc accounts) call the functions (send or receive ) the transaction doesn't occur and this message appears
VM Exception while processing transaction: invalid JUMP at
But when I use another unregistered account to call this function, it works.
Although no messages have been sent or received but no exceptions..
Any idea how I can solve this.
Thanks
Unless your using an old version of solc to compile your solidity the chance of this being an optimization problem is almost none.
Now, what does this mean then, it can happen when for example you run a modifier and it doesn't work. or if you try to call a function you are not allowed to and it throws. For example, it happens a lot after an ICO finishes and you try to use a function that can't be used anymore due to a date constraint it returns an Invalid Jump
I can't see your code but I think you might have reversed your if condition in your modifier and now it returns true if the user is not registered.