3

I have built a contract which provides a simple method for storing some data in a property of my contract on the blockchain.

I can interface with my contract using web3.js and I have no issue doing so.

The problem is that I only want to be able to set the property if it has NOT already been set. As such the contract method checks for a zero value and returns an arbitrary error code ("0001") if it has already been set. If it has not been set "0000" is returned.

When I execute the method (through javascript) my callback is immediately called. The result contains the transaction hash for an as of yet unmined transaction. When the transaction is mined there are no further calls to the callback, and at no point is the error code (mentioned above) made available asynchronously within my javascript code.

As such I can not update my interface accordingly when there is an 'error'.

I can poll the transaction hash and check for the point at which it is mined, but because even in the error case the transaction is mined, this is of little use.

web3.js loses a lot of its utility if there is no way of discerning the response of mining a transaction on the blockchain. Have I missed something?

Thanks

1

1 Answer 1

2

Transactions does not return the error code, like you say. There's been talk of allowing that though.

Return values on non-constant functions is really only useful in contract-to-contract calls. For external calls (i.e. transactions) Events is one solution, or sometimes you could solve it through a combination of transacting, checking when tx is mined (or not) and then doing some form of assertion on the contract state.

Events is the simplest way to make sure that a transaction resulted in a certain outcome.

Events can be filtered by id, which means you can add a specific event to a specific function, knowing that the event with that id will be fired iff that code is executed.

Events can also be filtered by the hash of the transaction that generated the event, which means you can send a transaction, get the tx hash, then use that to only watch the events generated by that transaction. If there is an event with that particular hash, that is proof that the tx went through, and if the tx is succesfully mined but no event log was created, then it certainly did not go through.

That being said, Events add to the gas-cost so is not the most efficient way, and should be avoided if possible. Sometimes you can verify by checking if the tx is mined, and then do a call to the contract to see if it changed as expected. Needless to say that's not always an option, or as safe.

1
  • BTW, personally I tend to use events with the same name as the function they're called in, except with the first letter capitalized. Also they all return an 'error' param (sometimes that's the only param), and error codes are also standardized, making it possible for me to use standardized javascript for transacting. Basically: call function -> get hash -> listen to event with same name as function but first letter capitalized -> check error param -> callback with error if errorcode != 0, otherwise not. Mar 16, 2016 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.