저자: 비탈릭, 이더리움 창립자, 번역자: 0xjs@골든파이낸스
이더리움에서는 최근까지 "가스"라는 단일 자원으로 가격이 책정되는 유한한 자원을 사용했습니다. 가스는 주어진 트랜잭션이나 블록을 처리하는 데 필요한 '계산'의 양을 측정하는 단위입니다. 가스는 여러 유형의 "노력"을 결합한 것으로, 특히 다음과 같은 것들이 있습니다.
예를 들어, 제가 보낸 이 트랜잭션(https:// etherscan.io/tx/0xc5195b64cc333b8098d71fbd0f032e05d4545917e3b0be8d123ab06e1ad7998e)비용은 총 47,085' 가스입니다. 이는 (i) '기본 비용' 21,000 가스, (ii) 일부 트랜잭션이 포함된 호출 데이터 바이트를 만들기 위한 1556 가스, (iii) 스토리지 읽기 및 쓰기 16,500 가스, (iv) 로그 생성 2149 가스, (v) 스토리지 쓰기 16,500 가스, (vi) 스토리지 쓰기 16,000 가스, (vii) 스토리지 읽기 및 쓰기 16,500 가스, (ix) 스토리지 읽기 및 쓰기 16,500 가스 등으로 세분화되어 있습니다. 로그 생성에 2149 가스, 나머지는 EVM 실행에 사용됩니다. 사용자가 지불해야 하는 트랜잭션 수수료는 트랜잭션이 소비하는 가스에 비례합니다. 블록은 최대 3천만 개의 가스를 포함할 수 있으며, 가스 가격은 EIP-1559 타겟팅 메커니즘을 통해 지속적으로 조정되어 평균 1천 5백만 개의 가스가 블록에 포함되도록 합니다.
이 접근 방식은 한 가지 큰 효율성이 있습니다. 하나의 가상 자원으로 통합되기 때문에 매우 단순한 시장 설계로 이어집니다. 트랜잭션을 최적화하여 비용을 최소화하고, 블록을 최적화하여 가능한 가장 높은 수수료(MEV 제외)를 부과하는 것이 비교적 쉬우며, 비용을 절약하기 위해 특정 거래를 다른 거래와 묶도록 장려하는 이상한 인센티브도 없습니다. 하지만 이 접근 방식은 이질적인 자원을 상호 교환 가능한 것으로 취급하지만 네트워크가 처리할 수 있는 실제 잠재적 한계는 그렇지 않다는 점에서 큰 비효율성을 가지고 있습니다. 이 문제를 이해하는 한 가지 방법은 다음 그래프를 보는 것입니다:
가스 제한은 다음 제약 조건을 적용합니다: x1*데이터 + x2*계산<N. 실제 기본 보안 제약 조건은 일반적으로 최대(x1*데이터, x2*계산)<N에 더 가깝습니다. 이 차이로 인해 가스 제약 조건은 실제로 안전한 블록을 불필요하게 제외하거나 실제로 안전하지 않은 블록 또는 이 둘을 혼합한 블록을 허용하게 됩니다.
보안 제한이 다른 ? 보안 제한이 다른 리소스가 있다면, 1차원 가스는 처리량을 최대 몇 배까지 감소시킬 수 있습니다. 그 결과 다차원 가스 개념에 대한 관심이 오랫동안 있어 왔으며, 현재 EIP-4844를 통해 실제로 이더리움에서 다차원 가스를 실행하고 있습니다.이 기사에서는 이 접근 방식의 이점과 향후 개선 전망에 대해 살펴봅니다.
블롭: 덴쿤의 다차원 가스
올해 초, 이더리움의 평균 블록 크기는 150kB였으며, 이 중 상당 부분이 롤업 데이터(보안 목적으로 온체인에 데이터를 저장하는 레이어 2 프로토콜)였습니다. 롤업 트랜잭션의 비용은 이더 L1의 해당 트랜잭션보다 약 5~10배 낮지만, 많은 사용 사례에서는 여전히 너무 높습니다.
콜데이터의 가스 비용(현재 0이 아닌 바이트당 가스 16, 0 바이트당 가스 4)을 줄여 롤업을 더 저렴하게 만드는 것은 어떨까요? 전에도 해본 적이 있고 앞으로도 할 수 있습니다. 최악의 블록 크기는 30,000,000/16 = 1,875,000개의 0이 아닌 바이트이며, 네트워크는 이미 그 크기의 블록을 거의 처리할 수 없습니다. 비용을 4배 더 줄이면 최대 용량이 7.5MB로 증가하여 보안에 큰 위험을 초래할 수 있습니다.
이 문제는 결국 각 블록에 별도의 롤업 친화적인 데이터 공간("블롭"이라고 함)을 도입함으로써 해결되었습니다. 덴쿤 하드포크 이후 이더리움 블록에는 (i) 최대 3천만 개의 가스, (ii) 6개의 블롭이 포함될 수 있으며, 각 블롭에는 약 125KB의 통화 데이터를 포함할 수 있는 등 두 리소스의 가격과 한도가 서로 다릅니다. 두 리소스 모두 별도의 EIP-1559와 유사한 가격 메커니즘을 통해 조정된 별도의 가격을 가지며, 블록당 평균 1,500만 개의 가스와 3개의 블롭을 사용하는 것을 목표로 합니다.
그 결과 롤업 비용은 100배 감소하고 롤업 거래량은 3배 이상 증가한 반면 이론적 최대 블록 크기는 약간만 증가했습니다: 1.9MB에서 ~2.6MB로
롤업 거래 수수료는 Growthepie.xyz에서 계산합니다. 2024년 3월 13일에 발생한 덴쿤 포크는 다차원 가격 책정 방식의 블롭을 도입했습니다.
다차원 가스 및 무국적 클라이언트
가까운 미래에 무국적 클라이언트를 위한 저장 증명에서도 비슷한 문제가 발생할 것입니다. 무국적 클라이언트는 많은 양의 데이터를 로컬에 저장할 필요 없이 블록체인을 검증할 수 있는 새로운 유형의 클라이언트입니다. 무국적 클라이언트는 해당 블록의 트랜잭션이 닿아야 하는 이더의 특정 부분에 대한 증명을 수락함으로써 이를 수행합니다.
스테이트리스 클라이언트는 블록 실행과 관련된 상태별 부분(예: 계정 잔액, 코드, 스토리지)의 현재 값 증명과 함께 블록을 받습니다. 이를 통해 노드는 스토리지 자체 없이도 블록의 유효성을 검사할 수 있습니다.
저장소 읽기는 읽기 유형에 따라 2100~2600가스의 비용이 들지만, 저장소 쓰기는 더 많은 비용이 듭니다. 평균적으로 한 블록은 약 1000번의 스토리지 읽기 및 쓰기(이더 잔액 확인, SSTORE에서 SLOAD로 호출, 컨트랙트 코드 읽기 및 기타 작업 포함)를 수행합니다. 그러나 이론적 최대치는 30,000,000/2100 = 14,285회 읽기입니다. 상태 비저장 클라이언트의 대역폭 부하는 이 수에 비례합니다.
현재 계획은 이더넷의 상태 트리 설계를 머클 패트리샤 트리에서 버클 트리로 전환하여 상태 비저장 클라이언트를 지원하는 것입니다. 그러나 버클 트리는 양자 저항성이 없으며 최신 STARK 증명 시스템에 최적화되어 있지 않습니다. 따라서 버클을 완전히 건너뛰거나 몇 년간의 버클 전환 후 STARK가 더 성숙해지면 업그레이드하여 이원화된 머클 트리와 STARK를 통해 상태 비저장 클라이언트를 지원하는 데 많은 관심이 쏠리고 있습니다.
바이너리 해시 트리 브랜치에 대한 STARK 증명은 많은 강점을 가지고 있지만, 증명을 생성하는 데 시간이 오래 걸린다는 주요 약점이 있습니다: 버클 트리는 초당 10만 개 이상의 값을 증명할 수 있지만, 해시 기반 STARK는 일반적으로 초당 몇 천 개의 해시만 증명할 수 있으며 각 값을 증명하기 위해서는 " 브랜치"가 필요합니다.
최고로 최적화된 증명 시스템(예: Binius 및 Plonky3)과 특수 해시(예: Vision-Mark-32)에서 현재 예측되는 수치를 고려하면, 실제로 1초 이내에 14,285개 값이 아닌 1,000개 값을 증명할 수 있는 상태가 한동안 유지될 가능성이 높습니다. 각 블록은 평균적으로는 괜찮지만, 최악의 경우 (공격자가 공개할 수 있는) 최악의 블록은 네트워크를 중단시킬 수 있습니다.
이 상황에 대처하는 "기본" 방법은 가격을 재조정하는 것입니다. 즉, 스토리지 읽기 비용을 높여 블록당 최대값을 더 안전한 수준으로 낮추는 것입니다. 그러나 이 작업을 너무 많이 수행했기 때문에 다시 수행하면 너무 많은 애플리케이션이 너무 비싸질 것입니다. 더 나은 접근 방식은 다차원 가스: 스토리지 액세스를 개별적으로 제한하고 과금하여 평균 사용량을 블록당 1,000개의 스토리지 액세스로 유지하되 블록당 제한을 예를 들어 2,000개로 설정하는 것입니다.
더 일반적으로 다차원 가스
또 다른 고려할 만한 자원은 상태 크기 증가로, 전체 노드가 전체 상태를 보유해야 하는 이더리움 상태의 크기를 늘리는 작업입니다. 상태 크기 증가의 독특한 점은 상태 증가를 제한하는 정당성은 피크가 아닌 장기적인 지속적인 사용량에서 비롯된다는 것입니다. 따라서 스테이트 크기 증가 작업(예: 0에서 0이 아닌 SSTORE, 컨트랙트 생성)에 별도의 가스 차원을 추가하는 것은 가치가 있을 수 있지만, 다른 목표를 위해 특정 평균 사용량을 목표로 유동 가격을 설정할 수는 있지만 블록당 한도는 전혀 설정하지 않을 수 있습니다.
이것은 다차원 가스의 강력한 기능 중 하나를 보여줍니다: (i) 각 자원의 이상적인 평균 사용량과 (ii) 블록당 안전한 최대 사용량은 얼마인지 등의 질문을 개별적으로 할 수 있게 해줍니다. 블록당 최대치를 기준으로 가스 가격을 설정하는 것이 아니라 평균 사용량과 2? 매개변수를 설정하는 2? 자유도를 기준으로 설정하고 네트워크에 안전한 수준을 기준으로 각 매개변수를 조정합니다.
부분적으로 누적된 보안 고려사항이 있는 두 개의 리소스와 같이 더 복잡한 경우에는 옵코드 또는 리소스에 일정량의 여러 유형의 가스 비용을 부과하여 처리할 수 있습니다(예: 0에서 0이 아닌 SSTORE는 5,000개의 무상태 클라이언트 가스 증명과 20,000개의 스토리지 확장 가스 비용이 들 수 있음).
트랜잭션당 최대화: 다차원 가스를 얻는 더 약하지만 간단한 방법
x1을 데이터의 가스 비용, x2를 계산의 가스 비용이라고 하면, 1차원 가스 시스템에서는 트랜잭션의 가스 비용을 다음과 같이 쓸 수 있습니다: gas=x1*데이터+x2*계산
새로운 체계에서는 트랜잭션의 가스 비용을 가스=최대(x1*데이터, x2*계산)
즉, 데이터와 계산을 더한 값을 기준으로 트랜잭션에 요금을 부과하는 대신, 두 자원 중 어느 쪽이 더 많이 소비하는지에 따라 트랜잭션에 요금이 부과됩니다. 이는 더 많은 차원을 포함하도록 쉽게 확장할 수 있습니다(예: max(...,x3*storage_access)).
보안은 유지하면서 처리량을 어떻게 늘릴 수 있는지 쉽게 알 수 있을 것입니다. 블록의 이론적 최대 데이터 양은 여전히 1차원 가스 체계와 동일하게 GASLIMIT/x1입니다. 마찬가지로 이론적 최대 연산량도 1차원 가스 체계와 동일하게 GASLIMI/x2입니다. 그러나 데이터와 계산을 소비하는 모든 트랜잭션의 가스 비용은 감소합니다.
이것은 제안된 EIP-7623에서 최대 블록 크기를 줄이면서 블롭 수를 더 늘리기 위해 사용된 방식과 거의 유사합니다. EIP-7623의 정확한 메커니즘은 약간 더 복잡합니다. 현재의 콜데이터 가격인 바이트당 16 Gas를 유지하되 바이트당 48 Gas의 "바닥" 가격을 추가하고, 트랜잭션은 (16 * 바이트 + 실행_가스) 및 (0 * 바이트)에서 동일한 가격을 지불합니다. 48 * 바이트). 결과적으로 EIP-7623은 대부분의 애플리케이션의 비용을 일정하게 유지하면서 블록의 이론적 최대 트랜잭션 호출 데이터를 약 1.9MB에서 약 0.6MB로 줄입니다. 이 접근법의 장점은 현재의 1차원 GAS 체계에 비해 거의 변경되지 않기 때문에 구현이 매우 쉽다는 것입니다.
두 가지 단점이 있습니다.
1. 블록의 다른 모든 트랜잭션이 해당 자원을 거의 사용하지 않음에도 불구하고 한 자원을 많이 차지하는 트랜잭션에는 여전히 불필요하게 많은 비용이 청구됩니다.
2. 데이터 집약적이고 컴퓨팅 집약적인 트랜잭션을 하나의 묶음으로 결합하여 비용을 절감하도록 인센티브를 제공합니다.
데이터와 기타 리소스를 호출하는 트랜잭션 모두에 대해 EIP-7623 스타일 규칙은 이러한 단점에도 불구하고 충분히 가치가 있다고 생각합니다. 그러나 (훨씬 더 많은) 개발 노력을 기울일 의향이 있다면 더 바람직한 접근 방식이 있습니다.
다차원 EIP-1559: 더 어렵지만 이상적인 전략
먼저 "일반" EIP-1559가 어떻게 작동하는지 살펴봅시다. EIP-4844에서 블롭을 위해 도입된 버전이 수학적으로 더 우아하기 때문에 이 버전에 집중하겠습니다.
우리는 초과 블롭이라는 하나의 매개변수를 추적합니다. 각 블록 동안 다음과 같이 설정합니다:
excess_blobs <-- max(excess_blobs + len(block.blobs) - TARGET, 0)
여기서 TARGET = 3입니다. 즉, 블록에 목표보다 많은 블롭이 있으면 excess_blobs가 증가하고 블록에 목표보다 적은 블롭이 있으면 감소합니다. 그런 다음 blob_basefee = exp(excess_blobs / 25.47)로 설정하며, 여기서 exp는 지수 함수 exp(x)의 근사치입니다.
즉, 액세스_블롭이 ~25배 증가할 때마다 블롭 기본 비용이 ~2.7배 증가합니다. 블롭이 너무 비싸지면 평균 사용량이 감소하고, 액세스_블롭이 감소하기 시작하면 자동으로 가격이 다시 낮아집니다. 블롭의 가격은 평균적으로 블록이 절반으로 가득 차도록, 즉 각 블록에 평균 3개의 블롭이 포함되도록 지속적으로 조정됩니다.
단기간에 사용량이 급증하는 경우 각 블록에 최대 6개의 블롭이 포함될 수 있으며, 이 경우 거래가 우선순위 수수료를 높여 서로 경쟁할 수 있습니다. 그러나 일반적인 경우 각 블롭은 인센티브로 blob_basefee와 약간의 추가 우선순위 수수료만 지불하면 포함됩니다.
이러한 종류의 가스 가격은 이더리움에서 수년 동안 존재해 왔습니다: 2020년에 EIP-1559는 매우 유사한 메커니즘을 도입했습니다. EIP-4844를 통해 이제 가스 및 블롭에 대해 두 개의 개별적인 변동 가격을 갖게 되었습니다.
< /p>
2024년 5월 8일 1시간 동안의 가스 기본 비용. 출처: ultrasonic.money
원칙적으로, 우리는 는 스토리지 읽기 및 기타 유형의 작업에 대해 개별적으로 유동적인 요금을 추가할 수 있지만, 다음 섹션에서 자세히 설명할 주의 사항이 있습니다.
사용자 입장에서는 하나의 기본 수수료를 지불하는 대신 두 개의 기본 수수료를 지불하게 되지만, 지갑에서 이를 추상화하여 예상 수수료와 지불할 수 있는 최대 수수료만 표시할 수 있기 때문에 현재와 매우 유사한 경험을 할 수 있습니다.
블록 빌더의 경우, 대부분의 경우 가장 좋은 전략은 현재와 동일하게 작동하는 모든 것을 포함하는 것입니다. 대부분의 블록은 가스나 블롭 측면에서 모두 채워지지 않은 상태입니다. 어려운 상황은 블록 한도를 초과할 만큼 충분한 가스나 블롭이 있는 경우로, 빌더는 수익을 극대화하기 위해 다차원적인 냅색 문제를 잠재적으로 해결해야 합니다. 그러나 합리적으로 좋은 근사치가 존재하더라도 이 경우 독점 알고리즘을 개발하여 수익을 최적화함으로써 얻는 이득은 MEV를 사용하여 동일한 작업을 수행함으로써 얻는 이득보다 훨씬 작습니다.
개발자의 주요 과제는 현재 하나의 가격과 하나의 제한을 중심으로 설계된 EVM과 주변 인프라의 기능을 여러 가격과 여러 제한을 수용하는 설계로 재설계해야 한다는 것입니다. 애플리케이션 개발자의 한 가지 문제는 최적화가 조금 더 어려워진다는 것입니다. A는 더 많은 콜데이터를 사용하고 B는 더 많은 실행을 사용하는 경우, 콜데이터가 저렴하면 더 저렴하고 콜데이터가 비싸면 더 비싸기 때문에 어떤 경우에는 A가 B보다 더 효율적이라고 단정적으로 말할 수 없게 된다는 것입니다. 그러나 개발자는 장기적인 과거 평균 가격에 최적화하여 상당히 좋은 결과를 얻을 수 있습니다.
다차원 가격 책정, EVM 및 하위 호출
블롭이나 EIP-7623, 심지어 콜데이터의 "완전한" 다차원 가격 책정 구현에서도 나타나지 않는 문제가 한 가지 있는데, 이는 다음과 같이 시도하면 해결될 수 있는 문제가 아닙니다. 상태 액세스나 다른 리소스에만 가격을 책정하려고 하면 서브콜의 가스 한도라는 문제가 발생합니다.
EVM의 가스 한도는 두 곳에 존재합니다. 첫째, 각 트랜잭션은 해당 트랜잭션에서 사용할 수 있는 총 가스 양을 제한하는 가스 한도를 설정합니다. 둘째, 컨트랙트가 다른 컨트랙트를 호출할 때 해당 호출은 자체 가스 한도를 설정할 수 있습니다. 이를 통해 컨트랙트는 신뢰하지 않는 다른 컨트랙트를 호출하면서도 호출 후 다른 계산을 수행할 수 있는 가스가 남아있도록 할 수 있습니다.
< /p>
계정은 거래 추적을 추상화하여 한 계정이 다른 계정을 호출하고 호출자에게 제한된 양의 가스만 제공하여 호출자가 할당된 모든 양의 가스를 소비하더라도 외부 호출이 계속 실행되도록 보장합니다. 호출은 수신자가 할당된 가스를 모두 소비하더라도 계속 실행될 수 있습니다.
문제는 가스를 여러 실행 유형 간에 다차원으로 만들려면 각 가스 유형에 대해 여러 제한을 제공하기 위해 하위 호출이 필요하며, 이는 EVM을 매우 심층적으로 변경해야 하고 기존 애플리케이션과 호환되지 않을 수 있다는 점입니다.
이것이 다차원 가스 제안이 일반적으로 데이터와 실행이라는 두 가지 차원에 머무는 이유 중 하나입니다. 데이터(트랜잭션 콜데이터든 블롭이든)는 EVM 외부에서만 할당되므로 콜데이터나 블롭의 개별 가격을 책정하기 위해 EVM 내부에서 변경할 필요가 없습니다.
이 문제에 대한 "EIP-7623 스타일 솔루션"을 생각해낼 수 있습니다. 실행 중 스토리지 작업에 대해 4배를 청구하고, 분석의 단순화를 위해 스토리지 작업당 10,000개의 가스를 사용한다고 가정하고, 트랜잭션이 종료되면 refund min(7500 * storage_operations, execution_gas)을 계산하는 간단한 구현입니다. 결과적으로 환불금을 공제하고 나면 사용자는 다음과 같은 금액을 지불하게 됩니다.
execution_gas + 10000 * storage_operations - min(7500 * storage_operations, execution_gas)
이것은 다음과 같습니다:
. max(execution_gas + 2500 * storage_operations, 10000 * storage_operations)
이것은 EIP-7623의 구조를 반영합니다. 또 다른 접근 방식은 스토리지_운영과 execution_gas를 실시간으로 추적하고 옵코드가 호출될 때 얼마나 올라가는지에 따라 최대(execution_gas + 2500 * 스토리지_운영, 10000 * 스토리지_운영)를 더 많이 또는 더 적게 충전하는 것입니다. 2500 또는 10000 가스. 이렇게 하면 가스 일수를 과도하게 할당해야 하는 트랜잭션을 방지할 수 있으며, 이는 대부분 환불을 통해 회수됩니다.
서브콜에 대한 세분화된 라이선스는 제공되지 않습니다. 서브콜은 저렴한 스토리지 작업을 수행하기 위해 트랜잭션의 '허용량'을 모두 소모할 수 있습니다. 하지만 서브콜을 만드는 컨트랙트가 한도를 설정하고 서브콜 실행이 완료된 후에도 메인 콜이 수행해야 하는 사후 처리를 수행할 수 있는 충분한 가스가 남아 있도록 보장할 수 있는 좋은 방법이 있습니다.
제가 생각할 수 있는 가장 간단한 "완전한 다차원 가격 책정 솔루션"은 서브콜 가스 한도를 비례로 처리하는 것입니다. 즉,
? 다차원 한도가 각각 ?1...??? 인 다양한 유형의 실행이 있다고 가정합니다. 현재 실행 시점에서 남은 가스가 ?1...??? 라고 가정합니다. 서브콜 가스 한도 S를 가진 연산자를 CALL이 호출한다고 가정합니다. s1=S, s2=s1/g1*g2, s3=s1/g1*g3 등으로 가정합니다. 즉, 첫 번째 유형의 가스(실제로는 VM 실행)를 권한이 있는 "계정 단위"로 취급한 다음 다른 유형의 가스를 할당하여 서브콜이 각 빌드 유형에 대해 동일한 비율의 사용 가능한 가스를 얻도록 합니다. 호환성. 이전 버전과의 호환성을 희생하면서 다른 유형의 가스 간에 보다 "중립적인" 체계를 만들고 싶다면 서브콜 가스 제한 매개변수가 남은 가스의 작은 부분을 나타내도록 하면 됩니다(예: [1...63] / 64). .63] / 64).
그러나 어느 경우든 가스의 다차원 실행을 도입하기 시작하면 내재된 추악함이 증가한다는 점을 강조할 필요가 있습니다.
따라서 우리의 과제는 복잡한 절충을 하는 것입니다. 상당한 L1 확장성 이점을 안전하게 확보하기 위해 EVM 수준에서 더 추악한 것을 받아들일 것인지, 그렇다면 프로토콜 경제학과 애플리케이션 개발자에게 가장 적합한 특정 제안은 무엇일까요?
아마도 위에서 언급한 것 중 어느 것도 아니며, 더 우아하고 더 나은 것을 생각해낼 수 있는 여지는 여전히 남아 있습니다.
피드백과 검토를 제공해 주신 Ansgar Dietrichs, Barnabe Monoton, Davide Crapis에게 특별히 감사드립니다.