EIP1967-实现可升级智能合约

EIP1967-实现可升级智能合约

EIP1967实现可升级的合约(逻辑和数据存储分离)

https://eips.ethereum.org/EIPS/eip-1967

解决upgrade-safe
https://docs.openzeppelin.com/upgrades-plugins/1.x/faq#what-does-it-mean-for-a-contract-to-be-upgrade-safe

通过使用逻辑处理与存储分离的模式,来实现智能合约升级。

通过以下代码进行理解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
contract Proxy {
mapping(address => uint) private balances; // 余额

address private impl;

function upgradeTo(address _addr) {
impl = _addr;
}

// 当调用的代理
fallback() external payable virtual {
_fallback();
}
function _fallback() internal virtual {
_beforeFallback();
_delegate(_implementation());
}


// 调用
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())

// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)

// Copy the returned data.
returndatacopy(0, 0, returndatasize())

switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
}

部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

const { ethers, upgrades } = require("hardhat");

async function main() {

// acc = ethers.getSigners()
const [owner] = await ethers.getSigners();

// Deploying
const sbt = await ethers.getContractFactory("SBT");
const instance = await upgrades.deployProxy(
sbt,
[
"Soulbound Token",
"SBT",
owner.address,
],
{
initializer: "initialize",
kind: "transparent",
unsafeAllow: ['delegatecall'] // 遇到unsafe upgrade错误,可以强行使用
}
);

let ret = await instance.deployed();
console.log(ret)

// await upgradeProxy(proxyAddress, implementationFactory, { unsafeAllow: ['delegatecall'] });

// Upgrading
// const BoxV2 = await ethers.getContractFactory("BoxV2");
// const upgraded = await upgrades.upgradeProxy(instance.address, BoxV2);
}

main();
  • Copyrights © 2021-2024 youngqqcn

请我喝杯咖啡吧~