스마트 컨트랙트가 필요한가? - 이더리움의 대표적인 DApp - 2017년 11월 런칭 이후 선풍적인 인기를 끌며 일일 거래금액 30억 이상 달성 - 이더리움 네트워크가 이러한 과부하를 버티지 못하고 사용성을 해치며 급격히 인기가 하락 - 만약 게임이 업그레이드 가능했다면? 크립토키티 서비스 추이 (출처: https://dappradar.com/) 크립토키티 CryptoKitties
컨트랙트가 필요한가? Smart Mesh 해킹 [해킹 방식] 해커가 Integer Overflow 를 이용해 토큰을 무단 복제후 판매 Parity 재단 Multisig Wallet 동결 [해킹 방식] 스마트 컨트랙트를 self-destruct 하여 출금 함수를 실행 불가하도록 공격 THE DAO 해킹사건 [해킹 방식] 스마트 컨트랙트 External call의 Re-entrancy 공격을 이용 $ 300,000,000 스마트 컨트랙트는 가치를 지닌 암호화폐를 매개하기에, 사소한 버그라고 할지라도 이것이 심각한 해킹 피해를 발생시킵니다 15% (전체 ETH양 대비) 전세계 거래소 ERC20 거래 일시 중지 이미지 출처: Coindesk
분석 “타겟 컨트랙트” 코드가 “호출 컨트랙트”의 컨텍스트에서 실행될 수 있는 호출 방식 컨트랙트가 런타임에 다른 주소의 코드를 동적으로 실행시킬 수 있음 Call Call DelegateCall Call msg.sender = 컨트랙트의 주소 msg.value = 컨트랙트가 전달하는 이더리움의 양 msg.sender = 지갑의 주소 msg.value = 지갑이 전달하는 이더리움의 양 호출 컨트랙트 타겟 컨트랙트 타겟 컨트랙트 호출 컨트랙트 Context Context Delegate Call Call DelegateCall
분석 Call A Contract B Contract 호출 컨트랙트 타겟 컨트랙트 타겟 컨트랙트가 아닌 호출 컨트랙트의 Storage 에 데이터가 저장된다. Delegate Call 을 통한 Storage 변화 DelegateCall A Storage 에 데이터 저장 A Contract 는 B Contract 의 변수 정보가 없지만 데이터를 저장할 수 있다!
분석 장점 • 데이터 마이그레이션이 필요없다. 고정된 주소의 컨트랙트에 데이터가 저장된다. • 컨트랙트의 주소가 변경되지 않는다. • 업그레이드를 지원하려고 기존 컨트랙트의 코드를 고치지 않아도 된다. 단점 • 새로운 버전의 컨트랙트가 과거 버전의 컨트랙트를 상속받음으로써 오는 제약 조건들이 존재한다.
<Proxy> </Proxy> • Version Info ContractB_v1 ContractB_v2 <Proxy> </Proxy> • Version Info ContractA_v1 ContractA_v2 컨트랙트 B 업그레이드 호출 컨트랙트 A 업그레이드 호출 ContractA Version 1 ContractB Version 1 여러 컨트랙트를 업그레이드 해야하는 상황 (문제점) 각 컨트랙트마다 업그레이드 트랜잭션을 따로 호출해야함 총 2개의 트랜잭션
<Proxy> </Proxy> • Version Info ContractB_v1 ContractB_v2 <Proxy> </Proxy> • Version Info ContractA_v1 ContractA_v2 컨트랙트 B 업그레이드 호출 ContractA Version 2 ContractB Version 1 여러 컨트랙트를 업그레이드 해야하는 상황 (문제점) 컨트랙트 A 업그레이드 트랜잭션이 먼저 성공 총 2개의 트랜잭션 컨트랙트 A 업그레이드 완료
<Proxy> </Proxy> • Version Info ContractB_v1 ContractB_v2 ContractA Version 2 ContractB Version 1 여러 컨트랙트를 업그레이드 해야하는 상황 (문제점) 업그레이드가 Atomic 하게 이루어지지 않으면 문제 발생 가능 트랜잭션 ContractA_v2 에서 ContractB_v2 함수 호출 <Proxy> </Proxy> • Version Info ContractA_v1 ContractA_v2
여러 스마트 컨트랙트를 Atomic 하게 업그레이드 Registry Contract 도입을 통해 다수의 Proxy Contract 관리 Registry Contract <Registry> • Version Info • proxies[] • upgradeToAndCalls </Registry> <Proxy> </Proxy> • Version Info ContractB_v1 ContractB_v2 <Proxy> </Proxy> • Version Info ContractA_v1 ContractA_v2
여러 스마트 컨트랙트를 Atomic 하게 업그레이드 Internal Transaction은 여러 트랜잭션으로 블록에 담기는 것이 아니라, 하나의 트랜잭션으로 처리됨 <Proxy> </Proxy> • Version Info ContractB_v1 ContractB_v2 <Proxy> </Proxy> • Version Info ContractA_v1 ContractA_v2 Internal Transactions Registry.sol
컨트랙트 만들기 “service.vvisp.json” 작성 - serviceName: 현재 서비스의 이름 - variables: Haechi 주인의 address를 상수로 사용 - contracts/Haechi - path: HaechiV1.sol 사용 - upgradeable: 업그레이드 가능 - initialize: 초기화를 위해 initialize 함수에 Gym의 주소를 전달 - contracts/Gym - path: HaechiGym.sol 사용 - upgradeable: 업그레이드 가능 - initialize: 초기화를 위해 initialize 함수에 Haechi의 주소를 전달
“.env” 작성 - NETWORK: 사용할 네트워크 명, local 사용 - PORT: local 포트 번호 - INFURA_API_KEY: infura 사용 시 필요한 api 키 - MNEMONIC: 니모닉 시드 값 - PRIV_INDEX: 니모닉으로부터 생성되는 비밀키의 index - GAS_PRICE: gas rate 설정
업그레이드 가능한 스마트 컨트랙트 만들기 배포 결과물 “state.vvisp.json” 생성 - contracts/Haechi, contracts/Gym - upgradeable: 업그레이드 가능 - address: Business 컨트랙트 주소 - fileName: 배포된 컨트랙트의 실제 파일(컨트랙트) 명 - proxy: Proxy 컨트랙트 주소 - serviceName: 현재 서비스의 이름 - registry: Registry 컨트랙트의 주소 state.vvisp.json
Library Token Contract Business Logic A Business Logic C Business Logic B Smart Contract Layer Platform Based on EVM Blockchain deploy, upgrade, test, versioning Service Frontend Smart Contract function call Developers vvisp Smart Contract Interface Library