EIP-2930 선택적 접근 목록 (Optional access lists)

최종 확정 · 수수료·가스 · 원문 상태 Final · 2020-08-29 작성

거래가 접근할 주소와 저장 키 목록을 미리 담는 새 거래 유형(타입 1)을 추가합니다. 목록에 적은 접근은 할인된 가스를 미리 내고 목록 밖 접근도 가능하지만 더 비쌉니다.

왜 필요한가

EIP-2929는 처음 접근하는 계정과 저장소의 가스 비용을 올렸습니다. 그런데 가스를 고정해 놓고 호출하는 기존 컨트랙트는 이런 인상으로 깨질 위험이 있습니다. 이 EIP는 거래가 사용할 계정과 저장 슬롯을 미리 적고 그 비용을 선불하게 해, 실제 실행에서는 SLOAD와 EXT 계열 명령어가 100가스만 들게 합니다. 그 결과 EIP-2929로 인한 파손을 막을 뿐 아니라, 과거 EIP-1884의 비용 인상 때문에 멈춘 컨트랙트도 다시 움직일 수 있게 합니다. 또 하나의 목적은 접근 목록이라는 형식과 그 처리 로직 자체를 도입하는 것입니다. 원문은 이 형식이 블록 단위 증인(witness), ReGenesis, 시간이 지나며 정적 상태 접근으로 옮겨 가는 작업 등 여러 용도로 재활용될 수 있다고 밝힙니다.

무엇이 바뀌나

지금

EIP-2930 이후

누구에게 영향이 있나

심층 설명

타입 1 거래의 형식

EIP-2718의 TransactionType 1로 도입됩니다. TransactionPayload는 rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signatureYParity, signatureR, signatureS])입니다. 서명 요소 signatureYParity, signatureR, signatureS는 keccak256(0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList]))에 대한 secp256k1 서명입니다. YParity는 서명 y값의 짝홀(짝수 0, 홀수 1)이고, chainId는 해당 체인에서만 거래가 유효하게 합니다. ReceiptPayload는 rlp([status, cumulativeGasUsed, logsBloom, logs])입니다. FORK_BLOCK 12244000부터 적용됩니다.

접근 목록의 구조와 검증

accessList는 [[{20 bytes}, [{32 bytes}...]]...] 형식이어야 합니다. 각 항목은 20바이트 주소 하나와 0개 이상의 32바이트 저장 키 목록으로 이뤄집니다. 원문의 process_access_list 파이썬 코드가 검증 로직이자 코드로 된 명세 역할을 합니다. 목록의 주소와 키는 실행 시작과 동시에 EIP-2929가 도입한 accessed_addresses, accessed_storage_keys 전역 집합에 바로 등록됩니다. 같은 주소나 키를 중복해 넣는 것도 허용되는데, 중복된 횟수만큼 가스를 내야 하며 그 외에 실행 흐름이나 결과에는 차이가 없습니다.

가스 계산

실행 시작 시점, 즉 EIP-2028 규칙에 따른 21000 + 4 * zeroes + 16 * nonzeroes 시작 가스를 걷는 것과 같은 때에 접근 목록 비용을 추가로 걷습니다. 주소당 ACCESS_LIST_ADDRESS_COST(2400가스), 저장 키당 ACCESS_LIST_STORAGE_KEY_COST(1900가스)입니다. 원문 예시처럼 주소 2개와 키 2개를 담으면 ACCESS_LIST_ADDRESS_COST * 2 + ACCESS_LIST_STORAGE_KEY_COST * 2를 냅니다. 거래 데이터와 달리 바이트당 과금은 하지 않습니다. 항목당 비용에 목록 데이터의 대역폭 비용과 해당 계정·키를 실제로 접근하는 비용이 함께 들어 있기 때문입니다.

목록 내 접근을 할인하는 이유

이유는 두 가지입니다. 첫째, 거래가 접근 목록을 최대한 쓰도록 유도하기 위해서입니다. 둘째, 저장소 읽기가 미리 알려져 있으면 거래 처리가 쉬워지기 때문입니다. 클라이언트는 거래를 받는 시점에 데이터베이스에서 해당 데이터를 미리 읽어 두거나 증인(witness)을 요청할 수 있고 그게 아니라도 블록을 받을 때 데이터를 병렬로 읽을 수 있습니다. 예측 가능한 상태 접근이 네트워크 전체의 처리 효율을 높인다는 설계입니다.

중복 허용과 서명 범위의 설계

중복을 허용한 것은 단순함을 극대화하기 위해서입니다. 중복을 막으려면 목록 안 항목끼리만 막을지, 거래의 발신자·수신자·새로 만들어지는 컨트랙트와의 중복까지 막을지 같은 기준 문제가 생깁니다. 항목당 가스를 걷기 때문에 같은 값을 두 번 넣으면 비용만 늘고 이득이 없어, 실제로 체인이 불필요하게 커지는 일은 없을 것으로 봅니다. 또 서명이 거래 데이터뿐 아니라 거래 타입까지 포함해 이뤄지므로, 서명된 거래가 다른 타입의 거래로 재해석되는 일을 막습니다.

하위 호환성

이 EIP는 목록에 없는 예상 밖의 SLOAD와 계정 접근을 더 비싸게 만듭니다. 다만 가스를 선불로 걷는 구조라서, 가스를 고정해 보내는 로컬 호출에는 영향을 주지 않습니다. 그래서 과거의 가스 인상들이 일으킬 수 있었던 방식으로 컨트랙트를 깨뜨리지는 않습니다. 그래도 저장소 접근에 크게 의존하는 애플리케이션은 경제성이 상당히 떨어질 수 있다고 원문은 밝힙니다.

보안 고려 사항

접근 목록은 실시간으로 만들기 어려운 상황이 많고 거래 생성과 서명 사이 시차가 크거나 생성기의 단순함이 중요한 환경(하드웨어 지갑 등)에서는 더 어렵습니다. 다만 초기 할인을 10%로 잡았기 때문에 목록을 만들지 않고 단순 거래를 보내도 부담이 거의 없습니다. 도구가 발전하고 목록 생성이 성숙해지면 목록 밖 상태 접근 비용을 이후 하드포크에서 점차 올릴 것으로 원문은 예상합니다. 블록 크기 면에서는 목록 사용으로 평균 블록 크기가 커지지만 바이트당 비용이 저장 키 1900 / 32 = 59.375, 주소 2400 / 20 = 120으로 calldata보다 훨씬 비싸서 최악의 경우 블록 크기는 늘지 않습니다. 평균 크기 증가도 거래 수신 시점의 사전 읽기와 병렬 로딩으로 일부 상쇄됩니다.

EIP 원문 · ← EIPs