I want to setup a proxy contract that my users can interact with. The proxy contract is a store contract with stores the user's age for now. When I call writeData
to update my age, I expect it to call my logic contract to run the update there.
When I run the code below in Remix, I am unable to update the userData
mapping. When I enter an age of 30, it returns 0 for BOTH contracts so I assume the call is failing. However, if I call writeData on the logic contract, it writes just fine. I assume there is something wrong with my delegatecall.
I am following https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/ (under Delegatecall-based proxy pattern ) and I have my state variables ordered correctly so I don't expect it to write to my proxy address by accident.
What am I doing wrong here?
Storage/Proxy Contract:
pragma solidity ^0.4.23;
// Storage contract
contract HealthcareStorage {
mapping (address => uint8) public userData;
address public logicContract;
address public owner;
constructor(address _logicContract) public {
logicContract = _logicContract;
owner = msg.sender;
}
function updateContract(address _newAddress) public returns (bool) {
require(msg.sender == owner);
logicContract = _newAddress;
return true;
}
function writeData(uint8 _age) public {
logicContract.delegatecall(bytes4(keccak256("writeData(uint8)",_age)));
}
}
Logic Contract:
pragma solidity ^0.4.23;
import { HealthcareStorage } from "./HealthcareStorage.sol";
// Logic contract - Upgradeable
contract HealthcareLogic{
mapping (address => uint8) public userData;
function writeData(uint8 _age) public returns (bool) {
userData[msg.sender] = _age;
return true;
}
}