State array variable not getting saved

jgostylojgostylo Member Posts: 5
I hope someone can show me what I am doing wrong.

My current dev environment is testrpc and truffle. I downloaded these a week ago so I am pretty up to date.

I make a very simple contract:

contract MyTest { address owner; address[] admins; function MyTest() { owner = msg.sender; } function addAdmin(address _address) returns(uint length){ admins.push(_address); return admins.length; } function countAdmins() returns(uint length){ return admins.length; } }


Then I run unit tests on the contract:

contract('MyTest', function(accounts) { it("should add my last account as an admin", function(done){ var testContract = MyTest.deployed(); var adminCount1; var adminCount2; testContract.addAdmin.call(accounts[9]).then(function(length){ adminCount1 = length.toNumber(); //adminLength = length.toNumber(); return testContract.countAdmins.call(); }).then(function(length){ adminCount2 = length.toNumber(); assert.equal(adminCount1, adminCount2, "For some reason these are not equal."); }).then(done).catch(done); }); }

Running the unit test shows that when addAdmin is called the return of admins.length is 1. This state does not seem to be saving because when I call countAdmins the admins.length return is 0. I was wondering if there was some issue where the first transaction would need to be mined before the state was saved (although I thought that testrpc automatically mined everything immediately) so I did a setTimeout on the second call for 30 seconds and the results I got were the same.

Please let me know what I am doing wrong.

Comments

  • jgostylojgostylo Member Posts: 5
    Ok, I discovered my mistake. I am not sure the reason though.

    There is a difference in the test code between
    testContract.addAdmin.call(accounts[9]) - and-
    testContract.addAdmin(accounts[9])

    I don't currently know enough to know what that difference is. The return value for addAdmin() was an address where addAdmin.call() was the return value of the function. If someone could enlighten me on the particulars of this I would be grateful!
  • rroschinrroschin Member Posts: 5
    @jgostylo As I know .call() is there to 'simulate' the contract call, not to actually send it with transaction to be in blockchain.
    So when you do testContract.addAdmin() or testContract.addAdmin.sendTransaction() you generate a transaction and get hash.
    When you do testContract.addAdmin.call() you just invoke contract code on your node, and it returns what you do in 'return' section, but does not save any state.

    Looks like you also need 'constant' keyword near 'function countAdmins() returns(uint length)', since this function does not change the state, only reads it, so there will be no transaction and you will get your result.

    Hope that helps, or just correct me, I have almost the same problem here :)
Sign In or Register to comment.