Solidity

代理合約不更新商店數據

  • November 11, 2018

我想設置一個我的使用者可以與之互動的代理契約。代理合約是儲存使用者目前年齡的商店合約。當我打電話writeData更新我的年齡時,我希望它會呼叫我的邏輯合約來在那裡執行更新。

當我在 Remix 中執行以下程式碼時,我無法更新userData映射。當我進入 30 歲時,兩個契約都返回 0,所以我假設呼叫失敗。但是,如果我在邏輯合約上呼叫 writeData,它就會寫得很好。我認為我的委託呼叫有問題。

我正在關注https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/(在基於 Delegatecall 的代理模式下)並且我的狀態變數排序正確,所以我不期望它不小心寫信給我的代理地址。

我在這裡做錯了什麼?

儲存/代理合約

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)));
 }
}

邏輯合約

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;
 }

}

原來這條線是關閉的:

logicContract.delegatecall(bytes4(keccak256("writeData(uint8)",_age)));

它應該是:

logicContract.delegatecall(bytes4(keccak256("writeData(uint8)")),_age);

引用自:https://ethereum.stackexchange.com/questions/62089