Solidity

契約繼承以在代理模式中共享相同的儲存以實現可升級性

  • March 30, 2020

請在這裡忍耐一下,我一直試圖自己弄清楚但無法解決。我正在嘗試使用代理模式學習可升級性。https://blog.gnosis.pm/solidity-delegateproxy-contracts-e09957d0f201

我們可以通過構造一個完整的 Kombucha 實例(現在沒有參數)來測試這個設置,構造一個 KombuchaProxy 實例,將完整的 Kombucha 實例的地址作為第一個參數。

當我檢查 Kombucha 實例變數時,它們仍處於預設值,但它們應該具有在實例化其實例時賦予 Kombucha 代理的值,因為 KombuchaProxy 和 Kombucha 都繼承了 KombuchaData。



pragma solidity ^0.6.0;


contract ProxyData {
   address public proxied;
}

contract Proxy is ProxyData {
   constructor(address _proxied) public {
       proxied = _proxied;
   }

   receive () payable external {}

   fallback () external payable {
       address addr = proxied;
       assembly {
           let freememstart := mload(0x40)
           calldatacopy(freememstart, 0, calldatasize())
           let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 32)
           switch success
           case 0 { revert(freememstart, 32) }
           default { return(freememstart, 32) }
       }
   }
}

contract KombuchaData is ProxyData {
   event FilledKombucha(uint amountAdded, uint newFillAmount);
   event DrankKombucha(uint amountDrank, uint newFillAmount);

   uint public fillAmount;
   uint public capacity;
   string public flavor;
}


contract KombuchaProxy is Proxy, KombuchaData {
   constructor (address proxied, string memory _flavor, uint _fillAmount, uint _capacity)
       public
       Proxy(proxied)
   {
       // the body is identical to our original constructor!
       require(_fillAmount <= _capacity && _capacity > 0);
       flavor = _flavor;
       fillAmount = _fillAmount;
       capacity = _capacity;
   }
}




contract Kombucha is KombuchaData{

   function fill(uint amountToAdd) public {
       uint newAmount = fillAmount + amountToAdd;
       require(newAmount > fillAmount && newAmount <= capacity);
       fillAmount = newAmount;
       emit FilledKombucha(amountToAdd, newAmount);
   }
   function drink(uint amountToDrink) public {
       uint newAmount = fillAmount - amountToDrink;
       require(newAmount < fillAmount);
       fillAmount = newAmount;
       emit DrankKombucha(amountToDrink, newAmount);
       // this mess of hashes just here to pad out the bytecode
   }
}

我嘗試了部署的契約,它們按預期工作。

KombuchaProxy 不應該更新 Kombucha 契約。它更新自己的儲存。

代理的整個想法是它包含數據並指向另一個具有程式碼的合約。

為了在 Remix 中測試這一點,我在 KombuchaProxy 地址實例化了 Kombucha 合約。現在您可以執行 Kombucha 功能填充和飲用。更改將在 KombuchaProxy 合約儲存中。

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