Ethereum Asked by Pakorn K on November 20, 2021
Compare to web application that separate the application and database, we can update the application and keep the existing data.
Could you suggest me how to update dapp and keep the existing data?
A DApp's only data sources are typically smart contract code and blockchain data and no (centralized) databases or sources. The entire flow happens entirely between the client and the blockchain. Upgrading your Dapp (front-end) doesn't necessarily mean you have to update your data (smart contracts) though. Depending on where the DApp is hosted, you can redeploy it and still refer to the same smart contracts. Smart contracts on the other hand are, once deployed, immutable. There is no way to update or delete any smart contract or transaction that is deployed to the network.
There are patterns that can help you to separate your data from business logic, or help upgrade (replace) your smart contracts. You need to design for this upfront before you deploy your first contract.
A common pattern is by using Eternal Storage. This is a smart contract that only contains data, sort of a key/value store, and no other business logic. This is similar to a database in a more traditional web application.
A basic example
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];
}
}
Separating your storage contract from your business logic allows you to keep your data, while still allowing the flexibility to change your logic.
Another common way is to use a proxy architecture pattern, that allows you to use new deployed contract as if your main logic had been upgraded. All message calls go through a Proxy contract that will redirect them to the latest deployed contract logic. To upgrade, a new version of your contract is deployed, and the Proxy is updated to reference the new contract address.
A basic example
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)}
}
}
}
Both patterns are often combined to separate business logic from data storage AND allowing to upgrade the business logic through proxy contracts.
Answered by wslyvh on November 20, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP