1

I use private geth + web3js (in truffle this works good)

Here is an example worked as expected:

the first contract:

pragma solidity ^0.4.24;
import "./Second.sol";

contract First {
    Second private _oSecond;
    int32 public _nRes1;

    constructor(address oSecond) public payable {
        _oSecond = Second(oSecond);
        _nRes1 = 3;
    }
    function TestError() public {
        _oSecond.State();
        //_oSecond._nRes2();  // the problem call is here
        _nRes1 = 5;
    }
}

the second contract:

pragma solidity ^0.4.24;

contract Second {
    int32 public _nRes2;

    constructor() public {
        _nRes2 = 15;
    }
    function State() public {
        _nRes2 = 17;
    }
}

web3js:

(async () => {
    await first.methods.TestError().send({from: accounts[0]});
    var nRes = await first.methods._nRes1().call({from: accounts[0]});
    console.log(nRes); 

    var nRes = await second.methods._nRes2().call({from: accounts[0]});
    console.log(nRes);
})();

The result:
5
17

But if we uncomment string "//_oSecond._nRes2();" the resul will be wrong:
3
15

No error messages!
In web3js I tried call with promises or callbacks - the same result.
In TestError I tried call different functions instead of _nRes2(), in different order, but result was the same - wrong.
If we call function wich returns Nothing, like State() - all is ok.
If we call function wich returns ANY type of value - all is not ok!
Why? How to fix it?

Geth Version is: 1.8.10-stable
Node js version is: v8.1.0
solc version is: 0.4.24
web3 version is: 1.0.0-beta.35

--- editing ---
My js code after Rob Hitchens answer:

(async () => {  
    var cRes = await first.methods.TestError().send({from: accounts[0]});  
    await web3.eth.getTransactionReceiptMined(cRes.transactionHash); // well mined!  
    sleep.sleep(30); // even 30 seconds of sleeping didn't help  

    var nRes = await first.methods._nRes1().call({from: accounts[0]});  
    console.log(nRes);  // 3  
    var nRes = await second.methods._nRes2().call({from: accounts[0]});  
    console.log(nRes);   // 15  
})();  
0

You're overlooking the asynchronous two-step nature of the chain update process. I think if you play around with the contracts in Remix you'll find they do what you think they should do.

On the client side you have problems because you are not waiting for the state changes to take effect.

It goes, sendTransaction() => transactionReceipt.

Now the tricky part. You have to wait for that transaction to be mined.

After you're sure it mined, you can call() to read values and you'll find the world makes sense again.

Have a look at this: https://gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6

To rephrase the steps above ...

// send it
return meta.sendCoin.sendTransaction(account_two, 6, { from: account_one });
})
// we've got a receipt (ack). Now we wait for confirmation. 
.then(function (txHash) {
  return web3.eth.getTransactionReceiptMined(txHash);
})
// now, it's mined
  .then(function (receipt) {
  // calls should reflect state changes

Hope it helps.

  • Thank You for helping, I did as You suggested but not succeed (( . Please, look at my edited post - I still get 3 and 15! (The expected result is 5 and 17) – Valikoo Vakh Oct 21 '18 at 17:55

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.