10

I am trying to update the value of one of the props in a struct in a solidity contract.

updating a variable works fine if it is not in a struct. but when i try to update a value in a struct like in the contract below, gas is used to update the contracts as i would expect, but when i read the updated value, it has not been changed.

Can anyone see how my contracts definition is incorrect?

My contract is defined as:

Users.sol

pragma solidity ^0.4.17;

contract Users {
    struct User {
        string firstName;
        string lastName;
    }
    mapping(address => User) public users;

    function getFirstName() public view returns (string) {
        User memory user = users[msg.sender];
        return user.firstName;
    }

    function setFirstName(newName) public {
        User memory user = users[msg.sender];
        user.firstName = newName;
    }
}

i'm new to working with solidity so any help is appreciated.

Shane Fontaine
  • 18,036
  • 20
  • 54
  • 82
X0r0N
  • 364
  • 1
  • 5
  • 17

2 Answers2

13

This line:

User memory user = users[msg.sender];

Should use storage instead:

User storage user = users[msg.sender];

If you use memory, then you're making a copy of the struct in memory and then updating that. If you use storage, you'll get a reference to the struct in storage, so your modifications will be persisted.

user19510
  • 27,999
  • 2
  • 30
  • 48
  • 1
    thanks for the reply. sorry, that doesnt work. i have also tried editing the value directly with: function setName(string newName) public { temps[msg.sender].name = newName; }, but this does not work either. – X0r0N Mar 11 '18 at 22:52
  • That should work too (modulo setName vs. setFirstName and temps vs. users). Can you describe how you're calling the function? – user19510 Mar 11 '18 at 22:54
  • If you're calling from web3.js or the like, make sure you're sending a transaction and not just doing a call, which does not modify state. – user19510 Mar 11 '18 at 22:55
  • function setFirstName(string newName) public { users[msg.sender]. firstName = newName; }. i am using web3 on react-native, which works fine when interacting with contracts. i only have this issue with structs. i am calling the function from custom redux middleware (which i have tested to work) export const setFirstName = newName => ({ type: 'set first name', promise: ({ contracts, coinbase }) => contracts.Users.setFirstName(newName, { from: coinbase }) }); – X0r0N Mar 11 '18 at 23:04
  • Why don't you start by putting your code in Remix and verifying that it works there? Then you can debug what's going on in the rest of the stack... perhaps the address is wrong or your most recent code isn't actually getting deployed, or something like that. – user19510 Mar 11 '18 at 23:05
  • I just noticed the code in your question isn't syntactically correct. Please double check what the exact code you're using now is and edit your question to include that version of the code. – user19510 Mar 11 '18 at 23:07
  • it looks like it is working on remix as expected. i may need to debug my redux middleware. thanks for you help. if i find the solution i will put it on this thread. – X0r0N Mar 11 '18 at 23:16
0

i rephrased the questing with a better example. i don't think i should delete this thread because there are many ways to phrase a question. instead, it may be more useful to provide a link to the solution:

Updating a Value in a Struct

X0r0N
  • 364
  • 1
  • 5
  • 17