Suppose we have a contract:
contract C {
uint256 a;
uint256 b;
function setA(uint256 aval) {
a = aval;
}
function setB(uint256 bval) {
b = bval;
}
function getA() constant returns (uint256) {
return a;
}
function getB() constant returns (uint256) {
return b;
}
}
and we try to set values, get them and store them into an array using web3.js:
var ABI = [{"constant":false,"inputs":[{"name":"bval","type":"uint256"}],"name":"setB","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"getB","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"getA","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"aval","type":"uint256"}],"name":"setA","outputs":[],"type":"function"}];
var contractAddress = "0x11111222222222222222";
var contract = web3.eth.contract(contractAddress, ABI);
var numbers = [];
// Set the values
contract.call().setA(100);
contract.call().setB(200);
// Get them and add them to the array
var a = contract.call().getA();
numbers.push(a);
var b = contract.call().getB();
numbers.push(b);
Can b be added to the array before a? I know that web is asynchronous for most methods but does this apply to contract method invocation as well?
Best Answer
There are both synchronous and asynchronous versions of:
myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, defaultBlock] [, callback]);
as documented in https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-methods
Using the synchronous version:
b
will always be in the array aftera
.To use the asynchronous version, you pass a callback, like:
The order of the array will depend on what's done in the callback/s.
Note that
sendTransaction
should be used for setting the values and this won't work:You need to use:
contract.setA.sendTransaction(100, callback);
and all the other code needs to be inside thecallback
, becausesendTransaction
is only asynchronous. Furthermore, thecallback
ofsendTransaction
will only return a transaction hash and you need to poll until getTransactionReceipt is notnull
to know that the transaction has been mined and the value ofa
has been set.