3

I am using Truffle with Ganache and MetaMask. I have a struct in my contract containing many fields as string data type

struct User {
        string firstName;
        string lastName 
        string dateOfBirth;
        string addressOfUser;
        string emailId;
        string password;
    }  
mapping (string => User) registeredUsers;  
function registerUser(string _firstName, string _lastName,string _dateOfBirth, string _addressOfUser, string _emailId, string _password) public returns (string) {
        totalRegisteredUsers++;
        string memory userId = generateId(_firstName, _lastName);
        registeredUsers[userId] = User(_firstName, _lastName, _dateOfBirth, _addressOfUser, _emailId,  _password);
        return userId;
    }

In the front end code, I have a form which inputs these details and then calls the registerUser method of the contract

register: function() {
    let firstName = $("#first-name").val();
    let lastName = $("#last-name").val();
    let dob = $("#date-of-birth").val();
    let address = $("#address").val();
    let emailId = $("#email-id").val();
    let password = $("#password").val();
    App.contracts.Identity.deployed().then(function(instance) {
      instance.registerUser.call(firstName, lastName, dob, address, emailId, password).then(function(userId) {
        $("#user-id").html("User id is : " + userId);
      });
    });
  }
</code>

When i try to run this, I always get the following error : 
<code> 
Uncaught (in promise) Error: Invalid JSON RPC response: {"id":2,"jsonrpc":"2.0","error":{"code":-32603}}
    at Object.InvalidResponse (inpage.js:445)
    at inpage.js:445
    at inpage.js:336
    at inpage.js:18
    at u (inpage.js:18)
    at inpage.js:18
    at inpage.js:18
    at a (inpage.js:18)
    at c (inpage.js:18)
    at inpage.js:18

However, if i modify the struct to have only one string field, say

struct User {
        string firstName;
    }

It works perfectly fine and the user Id is displayed correctly. Is this problem due to size of the contract becoming too big?

1

Setting aside concerns about the contents of data and the choice of casting everything as a string, there are a few things to check/try.

  1. You seem to be on budget but close for the ABI. Your maximum is 16 fixed-length or 8 strings (because they count for 2).
  2. The generateId function is suspect and not shown.
  3. Gas estimation has been known to fail, so you might need to bump the gas up on the client side with {gas: 5000000}. It is useful and exploratory to bump it up high (not beyond the network gaslimit) to confirm it's a factor, and then calibrate from there if you're on the right track.

The network gasLimit needs more explanation. This is a network property voted on by the miners. In the ganache-cli simulation, it defaults to a conservative 3,000,000. That may not be enough. You can increase that with a command-line parameter. $ ganache-cli -l 7000000 - 7 million.

The gasLimit issue is good to rule out so you can know if your issue is about transaction cost, logic in the contract, or the way you're calling it.

If cost doesn't seem to be the issue, then the next thing I would do is load it in Remix and make sure the contract itself performs and returns values as expected. With those two things out of the way, you would be able to focus on the way the client interacts with it.

Hope it helps.

UPDATE

Here's a cleaned up version that address multiple concerns with the style of the contract.

pragma solidity 0.5.1;

contract Stringy {

    struct User {
        bytes32 firstName;
        bytes32 lastName;
        uint dateOfBirth;
        bytes32 email;
    } 

    mapping (address => User) registeredUsers;  // address is the natural key to use
    address[] public userAddressList;

    event LogNewUser(address user, bytes32 firstName, bytes32 lastName, uint dateOfBirth, bytes32 email);

    function isUser(address user) public view returns(bool isIndeed) {
        return(registeredUsers[user].dateOfBirth > 0);
    }

    function registerUser(bytes32 _firstName, bytes32 _lastName, uint _dateOfBirth, bytes32 _email) public returns (bool success) {
        require(!isUser(msg.sender));
        require(_firstName != 0x0);
        require(_lastName != 0x0);
        require(_dateOfBirth > 0);
        require(_email > 0x0);

        registeredUsers[msg.sender] = User(_firstName, _lastName, _dateOfBirth, _email);
        userAddressList.push(msg.sender);
        emit LogNewUser(msg.sender, _firstName, _lastName, _dateOfBirth, _email);
        return true;
    }

}
  • Hi Rob. thanks for your help. I increased the gas in truffle.js to 6000000, but the error still persists. Also, if I interact with the contract through truffle console, the contract runs exactly as intended. The issue arises when I interact with the contract through the browser. – anuyog Apr 15 '18 at 5:45
  • Here is the entire code github.com/anuyog1004/EthIdManagement – anuyog Apr 15 '18 at 5:50
  • The contract seems fine. I changed constant to pure in one spot and changed the pragma to have no ^ which I would recommend. Those tweaks just clean up warnings and uncertainty. The gas cost to deploy is only 1.8M. When you say the problems only pop up when accessing through the browser, I'm not 100% sure what you mean. The ganache-gui is quite new and I'm no guru. You may be chasing an issue with the tooling itself. I'd be inclined to carry one making a JS app using console commands that are known to work. – Rob Hitchens - B9lab Apr 15 '18 at 6:01

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.