-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
getTransactionReceipt error #69
Comments
That is interesting. I should have time today/timorrow to look into the receipt issues. That isn’t your fault, it means the node is returning a root (pre-Byzantium) and staus (post-Byzantium) parameters, which it isn’t supposed to do. There is an easy fix, I will just allow both. |
Fixed in e8b23c2. Once Travis CI finishes running the tests cases, I will publish to NPM and close this ticket. |
Published to npm. Please make sure the version you sync to is Thanks again! |
Awesome Richard! Thanks a lot! |
Hello @ricmoo ! Thanks for the quick fix! It indeed worked, I now get the transaction receipt, however for some reason I only get the first event ("Mined"), and I expect to have a second one after that. I can see on etherscan that my transaction went through as expected, so I think I should have the second event log on the receipt. Do you have any idea what I could be doing wrong here? |
Heya @jennazenk, Can you send a transaction hash? You mean the transaction on Etherscan has 2 event logs, but the receipt returned only has 1? The type of all logs, I believe is “mined”; I haven’t noticed other values, but don’t usually pay attention to receipts. Do the topics match what you expect? |
Hey Richard! Thanks for coming back to me that fast! So after more investigation, I have only one event, which is called "FundUpdated", which I see on etherscan/parity ui/ and on this receipt. In the transaction receipt, I think i get the topic so the keccak256 of my event signature if Im not mistaking. In web3, on the transaction receipt I used to be able to see the event name and data directly, as per below (eg. logs.event and logs.args) : So my question is, how do I look for a specific event (like "FundUpdated") in a receipt ? I think if I run keccak256 on the signature of my event and compare it with the topic, I can determine if thats the event I am looking for. Are you aware of a better way for me to do this ? |
That is only possible because the web3 instance you are using above has the ABI. Otherwise, you are correct, there is no way to go from the You can do something like the following in ethers: var contract = new ethers.Contract(contractAddress, contractInterface, provider);
contract.onfundupdated = function(someParam) {
console.log(someParam);
// 0x00000...000ca
} But from just a receipt you would need a list of all possible events and parameters you expect. Do you need to work against the receipt? |
Yes we work a lot against the receipts; for the topics/event name I have a list of all relevant events so I can do it on my end. However, receipt.data is also encoded on the receipt; would you be ok with a PR combining the functionality of Interface.decodeParams and getTransactionReceipt, on the Contract Instance? |
The contract interface already has that functionality. :) I’m off to a client right now, but will post the code needed to parse data and topics this afternoon. I’m doing a slight refactor of them at code right now as well as running it against a new dataset of 2000-ish test cases. |
Alright cool, will wait for your update! The reason why we work w the receipt and not the event listener on the contract instance is because we need to make sure we get the event linked to a specific transaction (not sure if I'm being v clear here..); do you think that this use case will be addressed in a future refactoring? Thanks a lot! |
Here is an example of how to use the event part of the interface directly. > var abi = [ { type: 'event', inputs: [ { type: 'uint256', name: 'something' } ], name: 'FundUpdated' } ];
> var i = new ethers.Interface(abi)
Interface {
abi: [Getter],
functions: {},
events: { FundUpdated: { [Function: func] inputs: [Getter] } },
deployFunction: { [Function: func] inputs: [Getter] } }
> var info = i.events.FundUpdated()
EventDescription {
inputs: [ { type: 'uint256', name: 'something' } ],
name: 'FundUpdated',
signature: 'FundUpdated(uint256)',
topics:
[ '0xe34c389652410c46bb438dd3b75c4e2665251c032d7cf198239862e556751e6a' ],
parse: [Function] }
> var topics = [ '0xe34c389652410c46bb438dd3b75c4e2665251c032d7cf198239862e556751e6a' ];
> var data = '0x00000000000000000000000000000000000000000000000000000000000000ca'
> info.parse(topics, data)
Result {
'0': BigNumber { _bn: <BN: ca> },
something: BigNumber { _bn: <BN: ca> },
length: 1 } Right now it requires the topics and data, but soon it will support only data; in which case it will only return non-indexed parameters. But receipts provide both these, so I think it should do for your purposes. As you can see, it also created the Let me know if there is anything else you think should be there. |
Thanks again Richard! Indeed, it was possible for us to parse the interface for an event and get our data with a custom 'decodeReceiptForEvent' function. However, we were thinking, would it be interesting to have a method on the contract instance that directly decodes topics and associated data, and returns a readable receipt? |
Do you mean that you want to add something like: contract.parseTransactionReceipt(receipt);
/*
{
event: "FundUpdated",
args: {
id: 202
}
}
*/ And it uses the topics[0] to look up the matching function and calls parse with the topics and data? That would be fairly simple to add; but might have ambiguous results in the case of anonymous events. This might make more sense as a recipe in the cookbook. |
Hi @ricmoo , is there any simpler way now to parse events from receipts other than using the interface directly as you illustrate in your previous post? |
@mrwillis this is how I parse events in the transactions receipt. /**
* Parses transaction events from the logs in a transaction receipt
* @param {TransactionReceipt} receipt Transaction receipt containing the events in the logs
* @returns {{[eventName: string]: TransactionEvent}} an object with each key-value pair being the event name and event object
*/
protected getTransactionEvents(receipt: TransactionReceipt): {[eventName: string]: TransactionEvent}
{
const txEvents: {[eventName: string]: TransactionEvent} = {}
// do not get events if the contract has not been set yet. This will be true for deploy transactions which can emit events
if (!this.contract) {
return txEvents
}
// for each log in the transaction receipt
for (const log of receipt.logs)
{
// for each event in the ABI
for (const abiEvent of Object.values(this.contract.interface.events))
{
// if the hash of the ABI event equals the tx receipt log
if (abiEvent.topics[0] == log.topics[0])
{
// Parse the event from the log topics and data
txEvents[abiEvent.name] = abiEvent.parse(log.topics, log.data)
// stop looping through the ABI events
break
}
}
}
return txEvents
} |
If you use v4, interface.parseLog will figure out which event it is and parse it for you, including the name, function signature, topic and parsed values. There is also an interface.parseTransaction that will look up what function and what values the transaction represents. So, you can directly access contract.interface.parseLog if you have a contract, or you can just instantiate an Interface if you are processing the blockchain in general. |
When I log receipt from getTransactionReceipt, I get this error:
Error: invalid transaction receipt - exactly one of status and root should be present
What am I doing wrong?
My provider is a parity node running on Kovan (I used providers.JsonRpcProvider)
The text was updated successfully, but these errors were encountered: