Hi all, I am using Mix. I want to perform a set and a get on a string field on a contract. I am using javascript to do it. The setting operation is fine, I can see that the contract field change. However, when I perform a get, I receive something weird.
For instance, if I set the field to "Hello", then i receive "0x84e365cffc401ba68f317ab127e8f9d99a5098adf902ea628260cfa044179770". Why is that so? Do I have to cast something? (If I try the job with an int value, it works) Thank you.
Here is the contract code:
contract Sample { string s;
function Sample() { }
function setString(string d) { s = d; } function getString() returns (string){ return s; } }
Here is a piece of the the javascript code: ......
function set() { var key = document.getElementById('setField').value; var res = contracts['Sample'].contract.setString(key); }
function get() { var res = contracts['Sample'].contract.getString(); document.getElementById('getField').value = res; }
The reason is that you are not sending any gas. Even though the getString will not use any gas the VM doesn't know until its runs so it basically raises an error. The side effect of adding constant is the VM now definitely knows you don't need gas as no state will be change and therefore no error is raised.
if you don't want to use constant then you have to give it gas, for example:
var res = contracts['Sample'].contract.getString({from:eth.accounts[0], gas: 20000000});
It won't use any gas as no transaction will be created but the VM doesn't know that until you run it. If you don't supply the account information the VM will just reject it. The return you are seeing is actually an error from the VM although not particular useful one!
In fact you don't need the gas argument as the default will be fine as it won't be using any.
var res = contracts['Sample'].contract.getString({from:eth.accounts[0]});
So remove the constant and add the account information and see if that solves your problem.
Following your suggestion, here is the method I am calling (counter is an integer):
function getSomethingNotConstant() returns (uint){
counter;
}
Here is the calling:
function provaDue(){
var res = contracts['Sample'].contract.getSomethingNotConstant(
{from:web3.eth.accounts[0], gas: 20000000});
alert(res);
}
I still get a pointer : 0x929fd274d9baafc137df4d6fc6c70b9e69f07d01e5b6f66a530737196ebafa26
and, I have still some doubts: 1) is it possible to specify gas and ether when invoking a method from web3? for instance here: var res = contracts['Sample'].contract.getSomethingNotConstant();
2) when invoking a method from another contract using call, how do I specify the entry point? (i.e. the function I want to be invoked). The following is not working: bool success = sec.call.value(1).gas(55555)("ping"); It always end up in the unnamed function
3) sending money from a contract to a contract, can I use send? The following never worked: contractDestination..send(111);
4) the problems I still have (1,2,3) are due to the use of Mix?
1) you can specify gas and ether from web3: contracts['Sample'].contract.getSomethingNotConstant({from:eth.accounts[0], gas: 2500000});
3) I have never used send to transfer ethers from one contract to another. Not sure this is needed as you can use the other methods I outlined in the other thread
Comments
So this solved the problem:
function getString() constant returns (string){
return s;
}
Strangely, I have not found it in any documentation.
var res = contracts['Sample'].contract.getString({from:eth.accounts[0], gas: 20000000});
It won't use any gas as no transaction will be created but the VM doesn't know that until you run it. If you don't supply the account information the VM will just reject it. The return you are seeing is actually an error from the VM although not particular useful one!
In fact you don't need the gas argument as the default will be fine as it won't be using any.
var res = contracts['Sample'].contract.getString({from:eth.accounts[0]});
So remove the constant and add the account information and see if that solves your problem.
Following your suggestion, here is the method I am calling (counter is an integer):
function getSomethingNotConstant() returns (uint){ counter; }
Here is the calling:
function provaDue(){ var res = contracts['Sample'].contract.getSomethingNotConstant( {from:web3.eth.accounts[0], gas: 20000000}); alert(res); }
I still get a pointer : 0x929fd274d9baafc137df4d6fc6c70b9e69f07d01e5b6f66a530737196ebafa26
Try this instead with the call function added:
function provaDue(){
var res = contracts['Sample'].contract.getSomethingNotConstant.call();
alert(res);
}
function getSomethingNotConstant() returns (uint){
return counter;
}
I am trying t summarize the work done so far here:
https://docs.google.com/document/d/16AMvxFyiGIq-9zKnnNO1btpFuM8lIeVkQ_R3Xj5_DiM/edit?usp=sharing
(Please, fell free to read it and comment)
and, I have still some doubts:
1) is it possible to specify gas and ether when invoking a method from web3? for instance here:
var res = contracts['Sample'].contract.getSomethingNotConstant();
2) when invoking a method from another contract using
call
, how do I specify the entry point? (i.e. the function I want to be invoked). The following is not working:bool success = sec.call.value(1).gas(55555)("ping");
It always end up in the unnamed function
3) sending money from a contract to a contract, can I use send? The following never worked:
contractDestination..send(111);
4) the problems I still have (1,2,3) are due to the use of Mix?
https://forum.ethereum.org/discussion/6822/how-does-solidity-call-work
contracts['Sample'].contract.getSomethingNotConstant({from:eth.accounts[0], gas: 2500000});
3) I have never used send to transfer ethers from one contract to another. Not sure this is needed as you can use the other methods I outlined in the other thread
https://forum.ethereum.org/discussion/6704/sending-ether-from-a-contract-to-another-fails#latest