与将应用程序和数据库分开的web应用程序相比,我们可以更新应用程序并保存现有数据。
你能建议我如何更新dapp并保存现有的数据吗?
发布于 2020-07-22 11:35:11
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
复制相似问题