Mix: reading a string from javascript

tcimolitcimoli Cagliari - ItalyMember Posts: 35
edited May 2016 in Solidity
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;
}

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

....
Post edited by tcimoli on

Comments

  • tcimolitcimoli Cagliari - ItalyMember Posts: 35
    edited May 2016
    I solved it by trying... It seems that if you do not put the declaration "constant" in the function, it returns a pointer to something.

    So this solved the problem:

    function getString() constant returns (string){
    return s;
    }

    Strangely, I have not found it in any documentation.
  • smalltalksmalltalk Member Posts: 16
    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.
  • tcimolitcimoli Cagliari - ItalyMember Posts: 35
    Sorry, I have not understood what you mean. What am I returned if I do not use "constant"?
  • smalltalksmalltalk Member Posts: 16
    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.
  • tcimolitcimoli Cagliari - ItalyMember Posts: 35
    edited May 2016
    Thank you for your answer. But it did not work.

    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
    Post edited by tcimoli on
  • smalltalksmalltalk Member Posts: 16
    edited May 2016
    Ah sorry I was wrong just remembered that a possible state change call to chain always returns a transaction receipt.

    Try this instead with the call function added:

    function provaDue(){
    var res = contracts['Sample'].contract.getSomethingNotConstant.call();
    alert(res);
    }
  • tcimolitcimoli Cagliari - ItalyMember Posts: 35
    Well, now it always returns zero, even if the counter field is set to something else.

  • smalltalksmalltalk Member Posts: 16
    Just realised you do not have a return in your function, try changing it to:

    function getSomethingNotConstant() returns (uint){
    return counter;
    }
  • tcimolitcimoli Cagliari - ItalyMember Posts: 35
    edited May 2016
    Many thanks!! Now it works fine.

    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?

  • smalltalksmalltalk Member Posts: 16
    edited May 2016
    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

    https://forum.ethereum.org/discussion/6704/sending-ether-from-a-contract-to-another-fails#latest




  • tcimolitcimoli Cagliari - ItalyMember Posts: 35
Sign In or Register to comment.