Well I know of one way that should work.
Use web3js or geth console and invoke whatever function/transaction. If you use the .sendTransaction()
method it will return the transaction hash, which you will then use to look up your transaction status.
Next, using Etherscan API you can use the transaction endpoint:
https://etherscan.io/api?module=localchk&action=txexist&txhash=<<TX HASH>>
The response should look like this:
{"status":"1","message":"OK","result":"False"}
Next use the Etherscan transaction API. It will not tell you if it is pending, but if the transaction was a success/error it will return a different response:
https://api-rinkeby.etherscan.io/api?module=transaction&action=getstatus&txhash=<<TX HASH>>&apikey=<<API KEY>>
{"status":"1","message":"OK","result":{"isError":"0","errDescription":""}}
If isError
is 0
then it was successful/ If isError
is 1
then the transaction failed.
To sum it up, as long as you get the transaction hash from the .sendTransaction()
(so you know it's a valid transaction), you can now hit the first endpoint with the ?action=txexists
, which will return if the tx exists. Then you can hit the second endpoint to see if the TX passed or failed. So prior to you needing to hit the second endpoint, you will know the TX is pending since it does not exist yet.
If the above method is too confusing for you then below is how Etherscan.io currently gets pending transactions.
I pulled it from their website source code.
var interval;
var loopcounter = 1;
// startTxPendingCheck is a global window variable set by another script
if (startTxPendingCheck) {
var div = document.getElementById('spinnerwait');
div.style.display = 'block';
interval = setTimeout(checkForConfirmedTx, 2000);
function checkForConfirmedTx() {
if (loopcounter < 45) {
$.ajax({
url: "/api?module=localchk&action=txexist&txhash=" + txHash,
type: "GET",
success: function(data) {
if (data.result == "True") {
window.location.href = "/tx/" + txHash;
}
},
dataType: "json"
})
loopcounter = loopcounter + 1;
interval = setTimeout(checkForConfirmedTx, 20000);
} else {
stopInterval();
}
}
function stopInterval() {
console.log("stopInterval called");
var div = document.getElementById('spinnerwait');
div.style.display = 'none';
clearTimeout(interval);
}
function startInterval() {
console.log("startInterval called");
clearTimeout(interval);
var div = document.getElementById('spinnerwait');
div.style.display = 'block';
interval = setTimeout(checkForConfirmedTx, 5000);
}
}
Technically, it should be "a transaction pool", not "the transaction pool": each node has a set of transactions that it knows (or cares to know) about that are waiting to be confirmed from all users (not just your own) -- its own transaction pool. Thus, if there are n Ethereum nodes, there are n transaction pools. Transactions may disappear from tx pools if the node runs out of memory allocated to its tx pool or, I suppose, it filters them out when it receives them (e.g., if it doesn't meet its gas price requirement, it could filter it out). Note that the tx pool is specifically for pending transactions (your question 7 suggests confusion about that point).
If your transaction has been broadcast to the network, it may not appear on any particular node, even without malicious actors, for several reasons. These include
- evicted from a node's tx pool (so it used to be there, but no longer is),
- has not yet reached the node,
- network partitioning (hopefully this doesn't happen).
To answer your question more specifically, no, you cannot assume an unmined tx is in any tx pool (not even your own). Even if your transaction is not in any tx pool, you can't be sure it won't be mined unless you send a "cancelling" transaction with the same nonce and that transaction is mined (though someone could still roll back the network). The reason why you cannot assume the transaction won't be mined otherwise is because someone might have stored your transaction and could rebroadcast it at a later date. Or, less maliciously, a node may have gone offline during, e.g., a high-fee period while caching your transaction and then coming back when fees are low.
Until you find a node where your transaction appears other than your own, you can't be sure its been broadcast. You can set up multiple nodes on the Internet and see if they appear in any of their transaction pools.
Best Answer
It is included in the blockchain. The user still has to pay for the gas used to process the transaction, even if the transaction reverted. The exception to this, of course, is if the account sending the transaction doesn't have enough ETH to cover the tx fee and the ETH sent. In this case, the transaction can't be included in the blockchain at all because it can't cover the fee.
The transactions are included in the block, so you can check the transaction as you would any other. Use
eth.getTransaction()
with the transaction hash to check it. Alternatively you can use Etherscan to visually check it (see here for an example in a recent block. If you are using Rinkeby, you'll want to use https://rinkeby.etherscan.io/You should be getting a response whether it failed or not (unless, of course, you didn't have ETH to send the transaction in the first place). Your transaction may be waiting to be mined.