5

I'm using testrpc, truffle, and web3 in Node. I've written my contract and pushed it to testrpc with truffle. Here's the gist of the Node code I have so far:

let fs = require('fs');
let Web3 = require('web3');
let web3 = new Web3();
let settings = require('./settings.json'); // my own settings file

let abiContractContent = fs.readFileSync(settings.contractAbiPath, 'utf8');
let abi = JSON.parse(abiContractContent);
let contract = web3.eth.contract(abi).at(settings.contractAddress);

web3.eth.defaultAccount = web3.eth.accounts[0];

I've then found two ways to call a function in my contract:

contract.myFunc(param1, param2, { gas: 200000 });

which returns what I believe is the transaction ID for the changes caused by that function call.

contract.myFunc.call(param1, param2, { gas: 200000 });

which gives me the actual return value of myFunc.

I would like to have all of these pieces of information: the transaction AND the return values. I imagine I would need to call my function using the first approach and then look up the return values using the transaction ID but I have no idea how to actually do that. Am I on the right track or should I be looking for an entirely different approach?

Corey Ogburn
  • 423
  • 6
  • 18

3 Answers3

11

Am I on the right track or should I be looking for an entirely different approach?

Yes, I would say you are on the right track, but you need to know the difference between call and transactions. Basically:

Calls:

  • happen locally
  • don't cost Ether
  • and don't affect the network

Transactions:

  • are broadcast to the network
  • do cost Ether
  • and affect the network.

Call before you make a transaction if you want the result information ASAP. However just remember that call doesn't affect the blockchain, it is basically a local interaction.

You can make a call before you make a transaction:

var result = contract.myFunc.call(param1, param2, { gas: 200000 });

Once you have your result perform the transaction:

var txHash = contract.myFunc(param1, param2, { gas: 200000 });

Also See : What is the difference between a transaction and a call?

Samuel Hawksby-Robinson
  • 1,720
  • 1
  • 13
  • 28
  • 1
    I would assume that this means the return values from call might not be the actual return values of the transaction if another transaction happens in between - so don't rely on them for security! – user253751 Mar 07 '17 at 03:07
1

Answer for using ethers.js:


// this function gets us what the tx at tx_hash returned, 
// and whether it failed or not
async function get_transaction_result(txn_hash, provider){
    const a = await provider.getTransaction(txn_hash);
    try {
        let r = await provider.call(a, a.blockNumber);
        return {'ok':true, 'result': r};
    } catch (err) {
        return {'ok':false, 'result': err};
    }
};

// // FIND ANSWER HERE //

// here we execute the contract function and get the transaction let tx = await contract.functions.myFunc(params, { gas: 200000 })

// here we see what the tx returned and whether it failed or not let tx_returned = await get_transaction_result(tx.transactionHash, my_provider)

Tudor B
  • 193
  • 1
  • 8
0

As @immibis pointed out and as I replied in the following discussion, calling a 'sendTransaction' and then fire the '.call()' does not make sense. why would you pay for it when you can get it free?

get the return value of payable function?

coindevbw
  • 121
  • 1
  • 3