1

I'm trying to create an environment where I can test that access to a contract is restricted to a given wallet address, so I'm trying to simulate two users...

1) I'm running geth pointing to Ropsten test network, and have deployed a simple contract with Truffle, which I'm accessing locally via "truffle serve" at http://localhost:8080

2) I have two Chrome instances, "Person 1" and "Person 2" with Metamask wallets set to a separate account in each, both accounts are Ropsten accounts, created in my geth console.

3) When I point the Metamask wallets to the Ropsten network, I can successfully send transactions from each account to my contract and see the values in Ropsten via the etherscan browser, but - I can't successfully make any calls to "constant" functions, everything just returns a zero or a null (ie. in code below I can set the string, but not read it).

I think I'm on the right lines, but don't understand why my calls are not returning any data - anyone encountered similar, or have a good alternative solution to simulate two users?

[UPDATE: My scenario works if I use testrpc instead of Ropsten, so question remains - why can't I make a call to a constant function on Ropsten? ]

Thanks, Iain

contract Message {

    address public owner = msg.sender;
    string public message = "Initial Message";

    function Message() public {
      message = "No message set - by constructor";
      owner = msg.sender;
    }

    function retrieveMessage() constant
       returns (string _messageString)
    {
      _messageString = message;
    }

    function setMessage(string messageString) {
      message = messageString;
    }

}

Javascript running via http://localhost:8080 served by Truffle...

 import message_artifacts from '../../build/contracts/Message.json'

 // Messages is our usable abstraction, which we'll use through the code below.
 var Messages = contract(message_artifacts);

 refreshMessage: function() {
     var self = this;

     var meta;
     Messages.deployed().then(function(instance) {
        var result = instance.retrieveMessage.call();
        return result;
     }).then(function(value) {
        var message_element = document.getElementById("secretMessage");
        message_element.innerHTML = value + ".";
     }).catch(function(e) {
        self.setStatus("Error getting message; see log.");
     });
}
  • Put some code or more information about it cause with this is imposible know what are you doing. – Gawey Jun 14 '17 at 11:21
  • Sorry, have added the solidity code - I can successfully setMessage/getMessage when I access with Metamask pointing to localhost:8545, but can only setMessage with Metamask pointing to Ropsten - getMessage just returns null. – Iain Barclay Jun 14 '17 at 11:37
1

I have found a fix for my problem (and answer here for people who find this in the future) - in the Metamask window, even though I am deploying to Ropsten test network, it turns out that I need to set the network "tick" on localhost:8545 rather than on the Ropsten network directly - if I do this, then I get correct values returned.

Hope this helps someone...

0

Here's a cleaned up version of the contract with a restriction added. I'm just keeping this as simple as possible. You can play with that in Remix and confirm it works, including the access restriction.

pragma solidity ^0.4.6;

contract Message {

    address public owner;
    string public message;

    function Message() public {
      message = "Initial Message";
      owner = msg.sender;
    }

    function retrieveMessage() constant
       returns (string _messageString)
    {
      return message;
    }

    // only the account that deployed the contract is allowed to do this

    function setMessage(string messageString) 
      returns(bool success) 
    {
      if(msg.sender != owner) throw; // restrict access
      message = messageString;
      return true;
    }

}

I haven't actually tested the next bit but it might hint at the right direction. You still need to wait for callbacks (promises) even though it's a constant function, so ...

refreshMessage: function() {
     var self = this;

     // some changes here
     var messages;
     Messages.deployed()
     .then(function(instance) {
       messages = instance;        
       return messages.retrieveMessage.call();
     })


     .then(function(value) {
       var message_element = document.getElementById("secretMessage");
       message_element.innerHTML = value + ".";
     }).catch(function(e) {
       self.setStatus("Error getting message; see log.");
     });
}

Hope I didn't flub the syntax with that edit.

Hope it helps.

  • Hi Rob - thanks for the clean-up, useful for me to learn the style. However, I don't think the contract is my issue - if I deploy this on testrpc I can see the message (initiated by the constructor) shown on the browser, if I deploy on Ropsten via Geth the message is null. On both testrpc and Ropsten I can send my setMessage transaction successfully, but again - the message is returned as nul on Ropsten/geth combination (and shows fine with testrpc). So I think my issue is more to do with how I'm trying to interact with Ropsten/geth than the code... thanks, Iain – Iain Barclay Jun 15 '17 at 9:14
  • Possibly someone will chime in because it's not obvious. I would focus on the deployment/migration. This rhymes with failed to deploy or some other hidden assumption. If you're using truffle, it might help to post your migration scripts. – Rob Hitchens - B9lab Jun 16 '17 at 5:08

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.