EIP-170 컨트랙트 코드 크기 제한 (Contract code size limit)

최종 확정 · EVM·실행 · 원문 상태 Final · 2016-11-04 작성

블록체인에 배포할 수 있는 컨트랙트 코드의 최대 크기를 24,576바이트(0x6000)로 제한합니다. 이보다 큰 코드를 배포하려 하면 컨트랙트 생성이 실패합니다.

왜 필요한가

이더리움에서 컨트랙트를 호출할 때 호출 자체에는 정해진 양의 가스만 듭니다. 그런데 호출된 컨트랙트의 코드가 크면, 노드가 그 코드를 디스크에서 읽고 가상머신(VM)에서 실행할 수 있게 준비하고 블록이 올바르다는 증명(머클 증명)에 코드 데이터를 넣는 비용이 코드 길이에 비례해 커집니다. 내는 수수료는 그대로인데 네트워크가 치르는 비용은 코드가 클수록 늘어나는 불균형이 있었던 것입니다. 원문은 당시 가스 수준에서는 견딜 만하지만, 가스 한도가 올라가면 더 큰 문제가 되고, 특히 블록의 유효성 증명을 검증해야 하는 미래의 라이트 클라이언트에게 불편해진다고 지적합니다. 그래서 블록체인에 저장할 수 있는 코드 크기에 상한을 두되, 당시 가스 한도로 실제 만들 수 있는 것보다 약간 높은 값으로 정해 기존 사용에 지장이 없게 했습니다.

무엇이 바뀌나

지금

EIP-170 이후

누구에게 영향이 있나

심층 설명

MAX_CODE_SIZE와 발효 조건

상한값 MAX_CODE_SIZE는 0x6000, 즉 2**14 + 2**13 = 24,576바이트입니다. 적용 시점은 FORK_BLKNUM 2,675,000이고 대상은 CHAIN_ID 1(메인넷)입니다. block.number >= FORK_BLKNUM일 때, 컨트랙트 생성의 초기화(initialization) 코드가 MAX_CODE_SIZE바이트보다 긴 데이터를 반환하면 컨트랙트 생성은 out of gas 오류로 실패합니다. 검사 대상은 초기화 코드 자체의 길이가 아니라 초기화가 반환하는 데이터, 즉 실제로 저장될 코드의 길이입니다.

막으려는 문제: O(n) 비용의 2차(quadratic) 취약점

컨트랙트 호출(call)은 일정한 가스만 소모하지만 호출이 유발하는 실제 작업은 코드 길이 n에 비례합니다. 원문이 꼽는 세 가지는 디스크에서 코드를 읽는 비용, VM 실행을 위해 코드를 전처리하는 비용, 블록의 유효성 증명(proof-of-validity)용 머클 증명에 O(n) 데이터가 추가되는 비용입니다. 지불하는 가스는 상수인데 유발 비용은 선형이므로, 이를 반복하면 네트워크 부담이 비례 이상으로 커질 수 있는 구조였습니다.

당시에는 왜 급하지 않았고, 왜 미리 막았나

원문은 당시 가스 수준에서는 이 비용이 최적은 아니어도 수용 가능하다고 평가합니다. 다만 동적 가스 한도 규칙 때문에 가스 한도가 곧 크게 오를 수 있고 그 경우 문제가 커진다고 봤습니다. 당시의 서비스 거부(DoS) 공격만큼 심각하지는 않지만 유효성·무효성 증명을 검증할 미래의 라이트 클라이언트에게 특히 불편한 문제라고 지적합니다.

비파괴적 도입 방식

해결책으로 블록체인에 저장할 수 있는 객체 크기에 하드 캡을 뒀습니다. 상한값을 당시 가스 한도로 실제 배포 가능한 크기보다 약간 높게 잡아, 기존에 가능하던 배포를 막지 않으면서(non-disruptively) 미래의 위험만 차단하도록 설계했습니다.

적용 포크와 상태

이 EIP는 Spurious Dragon 하드포크(EIP-607)에 포함되어 블록 2,675,000부터 적용되었습니다. 상태는 Final로, 명세가 확정되어 더 이상 바뀌지 않습니다.

EIP 원문 · ← EIPs