반업주부의 일상 배움사

[Solidity] 컨트랙트 업그레이드 프록시 패턴 :: Contract Upgrade Proxy Pattern 본문

IT 인터넷/Blockchain

[Solidity] 컨트랙트 업그레이드 프록시 패턴 :: Contract Upgrade Proxy Pattern

Banjubu 2022. 8. 16. 12:42
반응형

 

스마트 컨트랙트는 한 번 배포하면 수정이 안 되죠.

그런데 만약 데이터와 컨트롤(함수)을 분리하면 어떨까요.

데이터는 그대로 두고 함수만 바꾸는거죠. (업그레이드)

프록시를 쓰면 가능해요.

 

BanjubuNFT_v1.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;

import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

contract BanjubuNFT_v1 is Initializable, ERC721Upgradeable, OwnableUpgradeable, UUPSUpgradeable {
    string internal _a;

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }
    
    function initialize(string memory a) initializer public {
        __ERC721_init("BanjubuNFT", "BJBNFT");
        __Ownable_init();
        __UUPSUpgradeable_init();

        _a = a;
    }

    function getA() external view virtual returns (string memory) {
        return _a;
    }

    function _authorizeUpgrade(address newImplementation) internal onlyOwner override {}
}

 

프록시로 배포해요.

const Factory = await hre.ethers.getContractFactory('BanjubuNFT_v1')
const contract = await hre.upgrades.deployProxy(Factory, ['AAA'], {
  initializer: 'initialize',
})
await contract.deployed()

 

그러면 implementation contract 와 proxy contract 가 생성되요.

implementation: 0x105B16DFA4e4500E6BD481FE9aA0e296b3c975ed

proxy: 0x8185ad2A73916922c96325c449fbf26403481097

 

 

데이터는 proxy 컨트랙트에 있어요.

이제 업그레이드를 하죠.

 

BanjubuNFT_v2.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;

import "./BanjubuNFT_v1.sol";

contract BanjubuNFT_v2 is BanjubuNFT_v1 {
    function setA(string memory a) external {
        _a = a;
    }

    function getA() external view override returns (string memory) {
        revert('getA() is deprecated');
    }

    function getA2() external view returns (string memory) {
        return _a;
    }
}

 

배포할게요.

const PROXY = '0x8185ad2A73916922c96325c449fbf26403481097'
const Factory = await hre.ethers.getContractFactory('BanjubuNFT_v2')
await hre.upgrades.upgradeProxy(PROXY, Factory)

 

implementation contract 는 새로운 컨트랙트지만 proxy는 그대로에요.

데이터는 그대로고 함수만 변경된거죠.

implementation: 0xE81FBE0A81CDaf9Bd1cEC70a7839730d91eDf186

proxy: 0x8185ad2A73916922c96325c449fbf26403481097

 

v2 코드대로 getA()는 사용할 수 없고 getA2()로 데이터를 가져올 수 있네요.

 

setA()로 데이터를 변경할 수도 있어요.

 

 

 

 

 

영어, 중국어 공부중이신가요?

홈스쿨 교재. 한 권으로 가족 모두 할 수 있어요!

 

한GLO 미네르바에듀 : 네이버쇼핑 스마트스토어

한글로 영어가 된다?! 한글로[한GLO]는 영어 중국어 일어 러시아어 스페인어가 됩니다!!

smartstore.naver.com

 

반응형
LIST
Comments