How to retrieve the return value of a contract method by sendTransaction?

czhangczhang Hong KongMember Posts: 12
edited July 2015 in web3-js
When calling a contract's method using sendTransaction, how can I get the return value from that method? For example, the tutorial token contract has the following method:
function sendToken(address receiver, uint amount) returns(bool sufficient) {
        if (balances[msg.sender] < amount) return false;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        return true;
}
And it can be executed as tokenInstance.sendToken.sendTransaction(eth.accounts[1], 100, {from: primaryAccount})

the result of sendTransaction is the transaction address, but how can I get the 'sufficient' return bool value?

Thanks
Post edited by StephanTual on

Best Answer

Answers

  • czhangczhang Hong KongMember Posts: 12
    @tym4t Arigato. Yes, agreed, then for any method to be executed as a transaction, should have no return.
  • chocolatepumpkinchocolatepumpkin Member Posts: 10
    There's still a synchronization problem I'm unable to solve.

    Suppose I am writing a test where I want to verify that the contract got executed - I want to write a test to verify the side effects are what I expected.

    I have to wait until the transaction is done. There doesn't appear to be mechanism for doing so that works or is at least not very awkward.. I've tried:

    filter events based on transactions

    web3.filter('latest'...){ //verify }).stopWatching(), but it never stops watching. I either am spacing on my nodejs knowledge or there's a bug. It also isn't guaranteed that your transaction is the the one you get an event for. So you get the transaction receipt and verify it's actually yours before you stopWatching... assuming stopWatching actually works... and this gets awkward pretty fast.

    Put specific events in the contract code itself

    This is pretty awkward. It means you have to treat code that might be called externally from JSONRPC differently than contracts internally calling its own functions. Which means you can't unit test the functions from nodejs (which you should).

    Yes I know about ether-pudding, but as usual with third party ethereum NPM stuff, I can't get it to work for usually bizzare reasons, and I'd rather get the basics working first anyways. I looked at puddings source code and can't figure out how it was synchronizing, it wasn't using any of the ideas here, I checked for those keywords...

    Is there a good, clear example of "read-modify-write-verify" test for contracts that store data and have functions that modify that data?

  • chocolatepumpkinchocolatepumpkin Member Posts: 10
    Here's code that works. I put this into the "awkward" category as well. At least it works, now I can start writing and testing contracts.

    // this should increment for realz:
    myContract.incrData.sendTransaction(function (err, result) {
    if (err) {
    console.error(err);
    return;
    }
    txhash = result;
    filter = web3.eth.filter('latest');
    filter.watch(function(error, result) {
    // XXX this should be made asynchronous as well. time
    // to get the async library out...
    var receipt = web3.eth.getTransactionReceipt(txhash);
    // XXX should probably only wait max 2 events before failing XXX
    if (receipt && receipt.transactionHash == txhash) {
    var res = myContract.getData.call();
    console.log('the transactionally incremented data was: ' + res.toString(10));
    filter.stopWatching();
    }
    });
    });

Sign In or Register to comment.