Why does modifying an object's property cause an lvalue error when those only apply to arrays/mappings?

contract Parent {
  mapping (address=>Child) public childObjects;

  function modify(address grantee, address newGrantee) external {
    Child child = childObjects[address(grantee)];
    child.grantee = address(newGrantee); // Error: Expression has to be an lvalue

    delete childObjects[address(grantee)];
    childObjects[address(newGrantee)] = child;

contract Child {
    address public grantee;
    // This is a full object with functions and code

Things attempted:

  • Adding storage wherever possible, but it doesn't make sense here as I'm not modifying an array or similar object. Well I am but the error occurs before then.
  • Changing modify from external to public

Is child just a pointer to the mapping? How would I specify storage in this case?

  • 1
    You cannot assign a contract's property (global variable) from some other contract's function. You need to add a setter function in the first contract, and call that function in the other contract. – goodvibration Sep 4 at 14:40
  • Ohh duhh, thank you, this error message could use some improvement. – Anthony Lusardi Sep 4 at 14:41
  • 1
    And hmmm... looking at your code, I'd just use a constructor instead. Keep in mind that if you add a setter function, then you also need to worry about permissions, otherwise anyone on the network will be able to call that function. – goodvibration Sep 4 at 14:46
  • Yeah I think I'm going to construct a new object separately, selfdestruct the old one, and just point at the new one. Agreed on permissions, this was just the minimal code that had the issue. – Anthony Lusardi Sep 4 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.