# 撰寫可升級合約 ## 部署可升级合约 1. 不寫 `constructor` 寫 init function,並確保此 function 只能被執行依次 ```solidity= contract MyContract { uint256 public x; bool private initialized; function initialize(uint256 _x) public { require(!initialized, "Contract instance has already been initialized"); initialized = true; x = _x; } } ``` 2. 所有調用的父合約都不能有 constructor ```solidity= import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; contract BaseContract is Initializable { uint256 public y; function initialize() public initializer { y = 42; } } contract MyContract is BaseContract { uint256 public x; function initialize(uint256 _x) public initializer { BaseContract.initialize(); // Do not forget this call! x = _x; } } ``` 2. 使用可升級的智能合約庫 ``@openzeppelin/contracts-upgradeable` ```solidity= // @openzeppelin/contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol pragma solidity ^0.6.0; ... contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable { ... string private _name; string private _symbol; uint8 private _decimals; function __ERC20_init(string memory name, string memory symbol) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name, symbol); } function __ERC20_init_unchained(string memory name, string memory symbol) internal initializer { _name = name; _symbol = symbol; _decimals = 18; } ... } ``` 4. 避免直接設定初始值 ```solidity= contract xxx { string test = 13; // X function initialize() public initializer { test = 42; // O } } ``` 5. 避免建立實例並賦值,可以使用傳參的方式 ```solidity= contract wrong is Initializabl{ ERC20 public token; function initialize() public initializer { token = new ERC20("Test", "TST"); // X } } contract right is Initializabl { IERC20Upgradeable public token; function initialize(IERC20Upgradeable _token) public initializer { token = _token; } } ``` 6. 避免在合約中使用 `selfdestruct`, `delegatecall` 7. ## 升级已部署的合约 ## 管理代理管理员权限 ## 在测试中使用 ### Reference https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable https://blog.openzeppelin.com/proxy-patterns/
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up