Solidity

DApp 開發 - 如何更新 dapp 並保留現有數據

  • July 22, 2020

與分離應用程序和數據庫的 Web 應用程序相比,我們可以更新應用程序並保留現有數據。

你能建議我如何更新 dapp 並保留現有數據嗎?

DApp 唯一的數據源通常是智能合約程式碼和區塊鏈數據,沒有(集中式)數據庫或源。整個流程完全發生在客戶端和區塊鏈之間。升級你的 Dapp(前端)並不一定意味著你必須更新你的數據(智能合約)。根據 DApp 的託管位置,您可以重新部署它並仍然引用相同的智能合約。另一方面,智能合約一旦部署,就是不可變的。無法更新或刪除部署到網路的任何智能合約或交易。

有些模式可以幫助您將數據與業務邏輯分離,或幫助升級(替換)您的智能合約。在部署您的第一個契約之前,您需要預先為此進行設計。

永恆的儲存

一種常見的模式是使用永恆儲存。這是一個智能合約,僅包含數據、某種鍵/值儲存,沒有其他業務邏輯。這類似於更傳統的 Web 應用程序中的數據庫。

一個基本的例子

contract EternalStorage {

   mapping(bytes32 => uint) uIntStorage;

   function getUint(bytes32 _key) external view returns(uint) {
       return uIntStorage[_key];
   }

   function setUint(bytes32 _key, uint _value) external {
       uIntStorage[_key] = _value;
   }

   function deleteUint(bytes32 _key) external {
       delete uIntStorage[_key];
   }
}

將儲存合約與業務邏輯分開可以讓您保留數據,同時仍然可以靈活地更改邏輯。

更多細節和範常式式碼


代理契約

另一種常見的方法是使用代理架構模式,它允許您使用新部署的合約,就好像您的主邏輯已升級一樣。所有消息呼叫都通過代理合約,該合約會將它們重定向到最新部署的合約邏輯。要升級,需要部署新版本的合約,並更新代理以引用新的合約地址。

一個基本的例子

contract Proxy {

   address delegate;
   address owner = msg.sender;

   function upgradeDelegate(address newDelegateAddress) public {
       require(msg.sender == owner);
       delegate = newDelegateAddress;
   }

   function() external payable {
       assembly {
           let _target := sload(0)
           calldatacopy(0x0, 0x0, calldatasize)
           let result := delegatecall(gas, _target, 0x0, calldatasize, 0x0, 0)
           returndatacopy(0x0, 0x0, returndatasize)
           switch result case 0 {revert(0, 0)} default {return (0, returndatasize)}
       }
   }
}

更多細節和範常式式碼


這兩種模式通常結合起來,將業務邏輯與數據儲存分開,並允許通過代理合約升級業務邏輯。

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