Testing my contract locally with truffle. I have a function with the signature:

function purchase(address buyer, address seller, bytes16 bookId, uint tokens) public onlyOwner returns(bool success)

In truffle console I call this function as:

  BookStore.deployed().then(function(instance){return instance.purchase(
'0xab67c3985384f5f4dc2fa828662f1f0601f81e62', //buyer
'0xd74ea687cc995cbbc1af6cf81106b31e32b4aa4f', //seller
[108, 120, 118, 13, 168, 153, 70, 225, 139, 168, 108, 184, 185, 58, 173, 17], //id
 5) //tokens
;}).then(function(result){return result;});

When I debug the transaction I see that tokens has the value 2.316897056402557e+76! But I'm passing 5.. what is happening?

  • Have you tried new BigNumber(5) with the necessary imports? – Lauri Peltonen Aug 15 '18 at 6:07
  • installed bignumber.js per directions here github.com/MikeMcl/bignumber.js I've changed the above 5 to new BigNumber('5') but this now results in the error TypeError: toBigNumber(...).round is not a function. Any suggestions? – Simon Rubin Aug 15 '18 at 6:32
  • I think the following one works for you : Math.round(<YourNumber>).toBigNumber() – Mehmet Doğan Aug 15 '18 at 15:01
  • TypeError: Math.round(...).toBigNumber is not a function – Simon Rubin Aug 15 '18 at 23:20

Issue was related to the array of bytes I was passing for the bookId field. Replacing these bytes with the hex value of the bookId fixed the weird value for tokens. My hunch is that the array takes up > 16bytes and this overflowed into uint tokens value.


Re: The hunch, no.

Your expectation is misaligned. This is a state-changing function is not marked view or pure (read-only) and this correct because you do, indeed, want the function to update the state. We don't see the code, but this appears to be a "set", not a "get".

Now, in all such state-changing situations, the expected result of the callback is a transaction receipt, not the return value. Return values are returned to other contracts but not to the EOA that initiated the transaction. You get a receipt as an acknowledgement that the transaction has been submitted to your node, presumably to be passed on to the network. The transaction hash returned is a unique identifier for the transaction so you can check up on it.

You do not get the result because the result isn't knowable until the transaction is mined. You can check/wait for the transaction to be included in a block (by the returned hash), and then check on the new state.

This is a confusing topic. It's logical but it takes some time to get a feel for the logic of it. Have a look at this explainer: https://blog.b9lab.com/calls-vs-transactions-in-ethereum-smart-contracts-62d6b17d0bc2

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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