BTC
ETH
HTX
SOL
BNB
시장 동향 보기
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

V God의 디자인 컨셉 발표, Ethereum의 잠재적 장단점 자세히 설명

以太坊爱好者
特邀专栏作者
이 기사는 약 16391자로, 전체를 읽는 데 약 24분이 소요됩니다
특정 프로토콜 기능을 처리하는 방법과 관련하여 이더리움과 일반 암호화폐 간에는 여전히 많은 차이점이 있습니다.
AI 요약
펼치기
특정 프로토콜 기능을 처리하는 방법과 관련하여 이더리움과 일반 암호화폐 간에는 여전히 많은 차이점이 있습니다.

여기여기, 이 재판은 교정되었습니다. 원문을 번역한 김정은에게 고마운 마음을 전하고 싶다.

원문의 작성 시기는 불확실하지만 지난 몇 년간 이더리움의 디자인 컨셉과 진화를 반성하는 출발점이라고 볼 수 있다. 혁신에 대한 반성뿐 아니라 배려 부족에 대한 반성이기도 하다.

원칙적으로

원칙적으로

Ethereum 프로토콜의 설계는 다음 원칙을 따릅니다.

  • 샌드위치 복합 모델("복잡성 계층 모델"이라고도 함): 우리는 이더리움의 기본 프로토콜이 가능한 한 단순해야 하고 인터페이스 디자인이 이해하기 쉬워야 한다고 생각합니다(개발자 지향 고급 프로그래밍이든 상관 없음). 언어 인터페이스 또는 사용자 중심 사용 인터페이스). 이러한 불가피한 복잡한 부분은 중간 계층에 배치해야 합니다. 중간 계층은 핵심 합의의 일부가 아니며 최종 사용자에게 보이지 않으며 여기에는 고급 언어 컴파일러, 매개변수 직렬화 및 역직렬화 스크립트, 스토리지 데이터 구조 모델, leveldb 스토리지 인터페이스 및 네트워킹 프로토콜이 포함됩니다. 물론 구분선이 완전히 명확하지는 않으며 때로는 적절하게 조정해야 합니다.

  • 자유: 사용자는 이더리움 프로토콜 사용을 제한해서는 안 되며 특정 이더리움 계약 또는 거래를 선호하거나 지원하지 않아야 합니다. 이는 "망 중립성" 개념의 기본 원칙과 유사합니다. 비트코인 거래 프로토콜은 이 원칙을 따르지 않습니다. 두통을 치료하기 위해 기침약을 사용하는 것과 같이 승인된 적응증 이외의 증상에 대한 약물. "승인되지 않은" 방식으로 블록체인을 사용하는 애플리케이션을 공격하기 위해 OP_RETURN 필드를 40바이트로 설정). 따라서 이더리움에서는 대략적인 인센티브 호환성을 달성하기 위해 거래 수수료만 사용하는 방법을 확고히 지원합니다. 사용자가 전체 네트워크에서 더 많은 리소스를 소비할수록 비용을 스스로 부담하더라도 더 높은 비용을 지불해야 합니다(예: Pigou). 세).

  • 일반화: 이더리움 프로토콜의 속성 및 opcode는 기본 입자와 같은 하위 수준 개념을 최대화하여 현재 쓸모 없어 보이지만 미래에는 유용할 수 있는 것을 결합하는 것을 포함하여 마음대로 결합할 수 있어야 합니다. 또한 불필요한 기능을 제거하여 저수준 개념을 보다 효율적으로 만들 수 있습니다. 이 원칙을 따르는 예는 이전처럼 모든 트랜잭션과 메시지를 기록하는 대신 dapp에 정보를 제공하는 방법으로 LOG opcode를 선택한 것입니다. 초기에 "메시지(message)"라는 개념은 완전히 "함수 호출(function call)"과 "외부 관찰자가 관심을 갖는 이벤트 정보(이벤트)"를 포함하는 다양한 개념의 집합체였으며, 이 둘은 완전히 분리 가능.

  • 어떤 기능도 가장 큰 특징이 아닙니다. 일반화 원칙을 따르기 위해 우리는 이러한 고급 사용 사례를 프로토콜의 일부로 포함하는 것을 거부하며 자주 사용하는 사용 사례에 대해서도 절대 그렇게 하지 않을 것입니다. 실제로 이러한 사용 사례를 구현하려는 경우 계약 내에서 하위 프로토콜을 생성할 수 있습니다(예: 이더리움 기반 하위 통화, 비트코인/라이트코인/도지코인 사이드체인 등). 예를 들어 Ethereum에는 Bitcoin과 유사한 "시간 잠금" 기능이 없습니다. 그러나 이 기능은 다음 프로토콜을 통해 시뮬레이션할 수 있습니다. 사용자는 처리를 위해 서명된 데이터 패킷을 특정 계약으로 보내고 데이터 패킷이 특정 계약에서 유효하면 해당 기능이 실행됩니다.

  • 위험을 회피하지 않음: 증가된 위험이 측정 가능한 이점(예: 일반적인 상태 전환, 블록 시간 50배 감소, 합의 효율성 등)을 가져오는 경우 더 높은 위험을 기꺼이 감수합니다.

  • 첫 번째 레벨 제목

블록체인 레이어 프로토콜

보조 제목

UTXO 1이 아닌 계정

비트코인과 그 변종은 UTXO 구조에 사용자의 잔액 정보를 저장하고 시스템의 전체 상태는 일련의 "사용되지 않은 출력"(이러한 "사용되지 않은 출력"을 코인으로 생각할 수 있음)으로 구성됩니다. 은유는 "수표"일 수 있습니다.). 각 UTXO에는 소유자와 자체 값 속성이 있습니다. 트랜잭션은 여러 UTXO를 소비하는 동안 여러 개의 새로운 UTXO를 생성하며 트랜잭션은 다음과 같은 유효성 요구 사항을 따릅니다.

1. 참조된 각 입력은 유효하고 사용되지 않아야 함 2. 트랜잭션 서명은 각 입력 소유자의 서명과 일치해야 함 3. 입력의 총 값은 출력의 총 값보다 크거나 같아야 함 .

이미지 설명

- 비트코인이 사용하는 삼중부기 -

그러나 이더리움은 UTXO 체계를 포기하고 더 간단한 방법으로 전환했습니다. 상태(state) 개념을 사용하여 일련의 계정을 저장하고 각 계정에는 자체 잔액과 이더리움 특정 데이터(코드 및 내부 메모리)가 있습니다. 거래 개시자의 계정 잔액이 거래 수수료를 충당하기에 충분한 경우 거래가 유효하며 해당 금액이 개시자의 계정에서 차감되고 수신 계정에 입금됩니다. 경우에 따라 수신 계정에서 실행해야 하는 코드가 있는 경우 트랜잭션이 코드 실행을 트리거하고 계정의 내부 메모리가 변경될 수 있으며 다른 계정으로 보낼 추가 메시지를 생성할 수도 있습니다. , 새로운 거래가 발생합니다.

이더리움은 UTXO의 개념을 채택하지 않지만 UTXO는 몇 가지 장점이 있습니다.

  • 더 높은 수준의 개인 정보 보호:사용자가 거래할 때마다 새 주소를 사용하면 계정 연동이 어렵습니다. 이는 보안 요구 사항이 높은 통화 시스템에 적합하지만 모든 dapp에는 적합하지 않습니다. dapp은 일반적으로 사용자의 복잡한 바인딩 상태를 추적해야 하며 dapp의 상태는 통화 시스템의 상태만큼 간단하게 나눌 수 없기 때문입니다.

  • 잠재적 확장성:이론적으로 UTXO는 특정 유형의 확장성 체계(확장성 패러다임)에 더 적합합니다. 모든 사람(TA 자신 포함)이 데이터를 잊어버리더라도 통화 소유권을 증명할 수 있는 메르켈 증거는 보유자만 있으면 되기 때문입니다. 사람은 실제로 손상되고 다른 사람은 영향을 받지 않습니다. 이더리움 계정 시스템에서 모든 사람이 계정에 해당하는 Merkle 트리의 일부를 잃으면 해당 계정은 자신에게 전송된 메시지를 포함하여 영향을 미칠 수 있는 모든 메시지를 처리할 수 없으며 처리할 수 없습니다. 그것. 그러나 UTXO만 확장 가능한 것은 아니며, UTXO에 의존하지 않고 확장하는 방법도 있다(여기서 확장은 없다, 번역가 주).

  • 계정의 이점은 다음과 같습니다.

  • 많은 공간 절약: 계정에 5개의 UTXO가 있는 경우 UTXO 모드에서 계정 모드로 전환할 때 필요한 공간이 300바이트에서 30바이트로 줄어듭니다. 구체적인 계산은 다음과 같습니다: 300 = (20+32+8) * 5(20은 주소 바이트 수, 32는 TX ID 바이트 수, 8은 액면가가 차지하는 바이트 수); = 20 + 8 + 2(20은 주소 바이트, 8은 계정 잔액 값 바이트, 2는 nonce 2바이트) 그러나 계정은 Patricia 트리에 저장해야 하므로 실제 절감액은 그리 크지 않습니다. 또한 이더리움의 트랜잭션은 비트코인(이더리움의 경우 100바이트, 비트코인의 경우 200~250바이트)보다 작습니다. 각 트랜잭션은 하나의 참조, 하나의 서명 및 하나의 출력만 생성하면 되기 때문입니다.

  • 더 강력한 호환성: UTXO 구조에는 블록체인 계층의 개념이 없으므로 기술적으로나 법적으로든 레드리스트/블랙리스트를 설정하고 이러한 "유효한 출력"의 소스를 기반으로 구분하는 것은 그다지 실용적이지 않습니다.

  • 단순성: Ethereum 코딩은 특히 복잡한 스크립트가 관련된 경우 더 간단하고 이해하기 쉽습니다. 어떤 분산형 애플리케이션도 UTXO로 (마지못해) 구현할 수 있지만, 이 방법은 본질적으로 주어진 UTXO가 출력할 수 있는 UTXO의 유형과 사용 조건을 제한하도록 스크립트에 권한을 부여합니다(예: 스크립트의 해당 응용 프로그램은 상태 루트를 변경합니다). 따라서 UTXO 구현은 이더리움이 계정을 사용하는 방식보다 훨씬 더 복잡합니다.

  • 라이트 클라이언트: 라이트 클라이언트는 상태 트리를 지정된 방향으로 스캔하여 언제든지 계정과 관련된 모든 데이터에 액세스할 수 있습니다. UTXO 패러다임에서 각 트랜잭션은 서로 다른 참조를 사용해야 하며, 이는 위에서 언급한 UTXO 루트 상태 전파 메커니즘을 사용하는 장기 실행 dapp 애플리케이션에 확실히 부담이 됩니다.

  • 우리는 특히 임의의 상태와 코드를 포함할 수 있는 지원하려는 dapp의 경우 계정의 이점이 대안보다 훨씬 크다고 믿습니다. 또한 "특징이 없는 것이 가장 큰 특징"이라는 지침 원칙에 따라 사용자가 진정으로 프라이버시를 중요하게 생각한다면 계약의 서명된 데이터 패킷 프로토콜을 통해 암호화된 "믹서 및 코인조인"을 구축할 수 있다고 믿습니다. 경로.

    계정 방식의 약점은 리플레이 공격(replay attack, 즉 동일한 트랜잭션이 반복적으로 실행되는 것을 의미)을 방지하기 위해 각 트랜잭션에 "nonce"(일련 번호)가 있어야 한다는 것입니다. 따라서 각 계정은 실시간으로 업데이트되는 난스 값을 가지고 있어야 하며, 새로운 트랜잭션이 발생할 때마다 계정의 난스 값을 자신의 난스로 1씩 증가시킵니다(트랜잭션 처리 후 이 값만큼 계정의 난스 값을 업데이트합니다). 계정 모드에서 트랜잭션에 이 소비 가능한 식별자가 첨부되지 않은 경우 트랜잭션을 반복적으로 처리할 수 있으므로 수신 계정은 비용을 지불하지 않고 계속해서 계정을 수집할 수 있으며 전송 계정은 건조됩니다. 이더리움 계정의 nonce는 시작된 트랜잭션이 처리됨에 따라 증가하므로 이 문제가 해결됩니다.) 즉, 더 이상 사용하지 않는 계정도 계정 상태에서 제거할 수 없습니다. 이 문제에 대한 간단한 해결책은 트랜잭션에 블록 번호를 포함시켜 일정 시간이 지나면 복구할 수 없게 만들고 난스를 자주 재설정하는 것입니다.

    상태에 있는 계정(예: 오랫동안 사용하지 않은 계정)을 삭제하려면 먼저 "ping"을 수행해야 하며 블록체인 프로토콜을 완전히 스캔하는 오버헤드가 매우 큽니다. 1.0에서는 이 메커니즘을 구현하지 않았으며 버전 1.1 이상에서는 이 메커니즘을 사용할 수 있습니다.

    교정 참고: 이것이 이더리움이 미래에 직면하게 될 "상태 폭발" 문제에 대한 기술적 이유입니다. 모든 상태 데이터는 완전히 보존되어야 하며 계정은 합리적으로 삭제할 수 없습니다. 블록체인 프로토콜로서 이더리움의 노드는 트랜잭션(트랜잭션)의 순서에 대한 합의에 도달해야 할 뿐만 아니라 글로벌 상태에 대한 합의에 도달해야 합니다(표현의 형식은 상태 루트가 블록에 포함되어야 함) 따라서 상태를 삭제하려면 전체 네트워크의 합의도 필요하며 그렇지 않으면 분열에 빠지게 됩니다.

    이 기사이 기사。

메르켈 패트리샤 트리(MPT)

Alan Reiner가 구상하고 Ripple 프로토콜에서 구현한 Merkle Patricia 트리/트리는 이더리움의 주요 데이터 구조로, 모든 계정 상태와 각 블록 거래 및 영수증 데이터를 저장하는 데 사용됩니다. MPT는 Merkle 트리와 Patricia 트리의 조합으로, 이 두 트리를 조합하여 생성된 구조는 다음과 같은 속성을 가집니다.

  • 임의의 키-값 쌍 집합에 해당하는 루트 해시 값은 고유하므로 특정 트리에 키-값 쌍이 존재한다고 거짓으로 주장하려는 경우 분명히 간파될 것입니다(공격자가 약 2^128 컴퓨팅을 가지고 있지 않는 한) 힘).

  • 키-값 쌍을 추가, 삭제 및 변경하는 시간 복잡도는 로그입니다.

  • MPT는 전체 상태 트리를 나타내는 효율적이고 업데이트하기 쉬운 "지문"을 제공합니다. MPT에 대한 자세한 설명: https://github.com/ethereum/wiki/wiki/Patricia-Tree.

    MPT에 대한 구체적인 설계 결정은 다음과 같습니다.

  • 노드에는 KV 노드와 불연속 노드의 두 가지 유형이 있습니다. KV 노드가 있으면 효율성이 향상됩니다. 특정 영역에서 트리가 희소한 경우 KV 노드를 트리 높이를 압축하는 "바로 가기"로 사용할 수 있기 때문입니다(자세한 내용은 MPT의 자세한 설명 참조).

  • 불연속 노드는 이진법이 아닌 16진수입니다. 이것은 조회를 더 효율적으로 만듭니다. 노드를 배치로 저장하여 16진수 트리의 조회 효율성을 이진법으로 시뮬레이션할 수 있기 때문에 지금 우리가 깨닫는 선택은 이상적이지 않습니다. 그러나 MPT 트리 구조의 구현은 매우 오류가 발생하기 쉽고 상태 루트에서 적어도 불일치를 유발하므로 1.1까지 변경을 보류하기로 결정했습니다.

  • 빈 값과 비회원 사이에는 구분이 없습니다. 이는 논리를 단순화하기 위해 수행되며, 이더리움에서 활성화되지 않은 계정의 값(잔액)은 기본적으로 0이며 빈 문자열도 0으로 표시됩니다. 그러나 이것은 일부 일반성을 희생하므로 최적이 아니라는 점을 강조해야 합니다.

  • 종료 노드와 비종단 노드의 차이점: 기술적으로 이더리움의 모든 트리는 고정 길이(즉, 키 길이) 데이터를 저장하는 데 사용되기 때문에 노드를 "종단 노드인지 여부"를 식별할 필요가 없지만 순서대로 다양성을 높이기 위해 이더리움의 MPT 구현이 그대로 다른 암호화폐에 채택될 수 있기를 바라면서 이 로고를 계속 추가할 것입니다.

  • SHA3(k)를 "보안 트리"(상태 트리 및 계정 저장소 트리)의 키로 사용: SHA3(k)를 사용하여 많은 계정(계정은 상태 트리를 최대 64레벨까지 만들 수 있음!)을 생성하고 반복적으로 SLOAD 및 SSTORE opcode는 DoS 공격을 훨씬 더 어렵게 만듭니다. 이것은 또한 트리를 열거하기 어렵게 만듭니다; 클라이언트가 열거할 수 있게 하려면 가장 쉬운 방법은 데이터베이스 매핑 sha3(k) -> k를 유지하는 것입니다.

  • 교정 참고: 여기서 의미는 k가 데이터를 저장하기 위해 Merkle 트리의 키로 사용되는 경우 분포가 매우 희박할 수 있으며 공격자는 저장을 위해 깊은 트리 경로가 필요한 계정을 쉽게 계획하고 이러한 계정을 대상으로 할 수 있다는 것입니다. 상태 접근 연산을 반복적으로 호출하면 네트워크의 노드에 과부하가 발생하지만 해시 함수의 결과는 무작위로 분포된다. .

    이 기능 역시 장점과 단점이 있는데, 한편으로는 DoS 공격이 더 어려워진다는 의미이고, 다른 한편으로는 블록 내 트랜잭션의 상태 트리 접근 경로가 거의 겹치지 않게 하여 검색할 때마다 둘 다 최악의 경우 복잡성.

    또한 이는 상태 액세스 경로가 겹치지 않기 때문에 MPT가 "무상태"를 달성하는 데 적합하지 않습니다(블록 자체는 검증에 필요한 데이터를 전달하고 검증자는 글로벌 상태를 가질 필요가 없음). 증거물의 공간 효율성도 최악이다. 물론 머클트리 증거물 자체의 공간 효율성이 높지 않다고도 할 수 있다.

RLP

RLP(재귀 길이 접두사): 재귀 길이 접두사.

RLP 인코딩은 Ethereum의 기본 직렬화 형식이며 블록, 트랜잭션, 계정 상태 및 네트워크 프로토콜 메시지 등 모든 곳에서 사용됩니다. 자세한 내용은 RLP의 공식 설명을 참조하세요: https://github.com/ethereum/wiki/wiki/RLP

RLP는 중첩된 바이트 배열3을 저장하는 것이 유일한 목적인 매우 단순화된 직렬화 형식입니다. protobuf 및 BSON과 같은 기존 솔루션과 달리 RLP는 Boolean(Boolean), float(부동 소수점), double 또는 정수(integer)와 같은 특정 데이터 유형을 정의하지 않습니다. 중첩 배열 형태로 구조를 저장하고 배열의 의미를 결정하는 것은 프로토콜에 달려 있습니다. RLP는 또한 맵 컬렉션을 명시적으로 지원하지 않습니다. 준공식적인 제안은 [[k1, v1], [k2, v2], ...]의 중첩 배열을 사용하여 키-값 쌍 컬렉션 k1, k2를 나타내는 것입니다. ... 문자열에 대한 표준 정렬에 따라.

RLP와 같은 기능을 하는 방식은 protobuf나 BSON으로 줄곧 사용되어 온 알고리즘이다. 그러나 Ethereum에서는 (1) 구현하기 쉽고 (2) 바이트 일관성이 절대적으로 보장되기 때문에 RLP를 사용하는 것을 선호합니다.

많은 언어에는 키-값 쌍 컬렉션의 명시적인 순서가 없으며 부동 소수점 형식에는 동일한 데이터에 대해 다른 인코딩과 다른 해시가 발생할 수 있는 많은 특수한 경우가 있습니다. 프로토콜을 내부적으로 개발함으로써 이러한 목표를 염두에 두고 설계되었는지 확인할 수 있습니다(이는 가상 머신과 같은 코드의 다른 부분에도 적용되는 일반적인 원칙입니다). BitTorrent에서 사용하는 인코딩 방법인 bencode는 RLP의 대안일 수 있습니다. 그러나 이진 RLP보다 약간 열등한 십진 인코딩 방법을 사용합니다.

압축 알고리즘

네트워크 프로토콜과 데이터베이스는 모두 맞춤형 압축 알고리즘을 사용하여 데이터를 저장합니다. 알고리즘은 다음과 같이 설명할 수 있습니다. 다른 값을 유지하면서 0에 대해 런렝스 인코딩 4를 사용합니다(sha3(' ')와 같은 일부 특수한 경우 제외). 예를 들면 다음과 같습니다.

압축 알고리즘이 존재하기 전에는 이더리움 프로토콜의 여러 곳에 특별한 경우가 있었는데, 예를 들어 sha3는 종종 sha3(' ')=' '로 재정의되어 계정에 코드를 저장할 필요가 없도록, 64바이트를 절약할 수 있습니다. 그러나 최근 이더리움의 데이터 구조를 비대하게 만든 이러한 모든 특수한 경우가 제거되고 대신 데이터 보존 기능이 블록체인 프로토콜 외부의 레이어, 즉 네트워크 프로토콜과 해당 삽입 사용자 데이터베이스 구현에 추가되었습니다. 이것은 모듈화 능력을 증가시키고, 합의 계층을 단순화하고, 압축 알고리즘의 지속적인 업데이트를 배포하기 비교적 간단하게 만듭니다(예를 들어, 네트워크 프로토콜의 버전 번호로 구별하고 배포할 수 있음).

트리(트리)의 용도

알림: 지식의 이 부분을 이해하려면 독자가 블룸 필터 5의 원리를 이해해야 합니다. 소개는 http://en.wikipedia.org/wiki/Bloom_filter에서 볼 수 있습니다.

이더리움 블록체인의 각 블록 헤더에는 상태 트리, 트랜잭션 트리 및 영수증 트리의 세 가지 트리에 대한 포인터가 포함되어 있습니다.

  • 상태 트리는 블록 처리 후 전체 상태를 나타냅니다.

  • 트랜잭션 트리는 블록의 모든 트랜잭션을 나타내며 이러한 트랜잭션은 인덱스를 키로 인덱싱됩니다(예: k0: 첫 번째로 실행된 트랜잭션, k1: 두 번째로 실행된 트랜잭션).

  • 영수증 트리는 각 거래에 대한 해당 영수증을 나타냅니다.

  • 트랜잭션 영수증은 RLP 인코딩 데이터 구조입니다.

  • 안에:

  • medstate: 트랜잭션이 처리된 후 상태 트리의 루트입니다.

  • gas_used: 거래가 처리된 후 사용된 가스의 양;

  • 로그: 많은 [address, [topic1, topic2...], data] 요소의 목록입니다. 이러한 요소는 트랜잭션 실행 중에 호출되는 opcode LOG0 ... LOG4에 의해 생성됩니다(주 호출 및 하위 호출 포함), 주소는 로그를 생성하는 계약의 주소, 주제는 최대 4개의 32바이트 값, 데이터는 모든 크기의 섹션 배열;

  • logbloom: 트랜잭션에 있는 모든 로그의 주소와 주제로 구성된 블룸 필터입니다.

  • 노트:

    노트:

  • UTXO: 사용되지 않은 트랜잭션 출력, 문자 그대로: 사용되지 않은 트랜잭션 출력, 즉 트랜잭션에서 입력으로 참조하지 않는 트랜잭션 출력입니다. 가치(소유권) 정보를 저장하기 위해 비트코인 ​​프로토콜에서 사용되는 데이터 구조입니다. —— 교정 참고

  • Nonce는 Number used once 또는 Number once의 약자로 암호학에서 Nonce는 한 번만 사용되는 임의의 또는 반복되지 않는 임의의 값으로 암호화 기술에서 초기 벡터와 암호화된 해시 함수 모두 중요한 역할을 합니다. 다양한 인증 프로토콜의 통신 응용 프로그램에서는 인증 정보가 재생 공격(Replay Attack)에 대처하기 위해 재사용되지 않도록 합니다. ——번역가의 메모

  • 중첩 배열: 배열을 만들고 다른 배열로 채웁니다. 배열 애완 동물과 같은:

    var cats : String[] = ["Cat","Beansprout", "Pumpkin", "Max"];
    var dogs : String[] = ["Dog","Oly","Sib"];
    var pets : String = [cats, dogs];

    ——번역가의 메모

  • run-length-encoding: 통계적 인코딩. 주요 기술은 반복되는 비트 또는 문자 시퀀스를 감지하고 발생 횟수로 대체하는 것입니다. (Baidu 백과사전) - 번역가의 노트

  • 첫 번째 레벨 제목

삼촌 블록에 대한 보상

GHOST 프로토콜은 2013년 10월 Yonatan Sompolinsky와 Aviv Zohar가 처음 제안한 놀라운 혁신입니다. 빠른 블록 생성과 관련된 문제를 해결하려는 첫 번째 진지한 시도입니다.

GHOST의 의도는 이러한 문제를 해결하는 것입니다. 짧은 블록 시간(따라서 더 빠른 확인 속도)은 더 많은 블록이 "구식"이 되어 덜 안전합니다. 채굴자 A가 네트워크에서 블록을 전파하는 데 시간이 걸리기 때문입니다. 블록을 파서 전체 네트워크에 방송하고, 방송하는 도중에 B도 그 블록을 파내면 B의 블록은 구식이고 B의 현재 채굴은 네트워크의 보안에 기여하지 않는다.

또한 중앙 집중화 문제가 있습니다. A가 컴퓨팅 파워의 30%를 가진 마이닝 풀인 경우 B는 컴퓨팅 파워의 10%를 가집니다. A는 70%의 시간 동안 오래된 블록을 생성하고(나머지 30%는 최신 블록을 생성하기 때문에 TA는 블록 전송을 기다리지 않고 "즉시" 최신 블록의 데이터를 얻었다고 볼 수 있습니다) 반면 B는 사용하지 않는 블록을 생성하는 데 걸리는 시간이 90%입니다. 블록 생성 사이의 시간 간격이 매우 짧으면 노후화율이 높아지고 A는 더 큰 컴퓨팅 파워로 채굴을 더 효율적으로 만들 것입니다. 따라서 블록 생성 속도가 너무 빠르면 네트워크 컴퓨팅 파워가 큰 마이닝 풀의 사실상 독점으로 이어지기 쉽습니다.

Sompolinsky와 Zohar에 따르면 GHOST는 어떤 체인이 가장 긴 체인인지 계산하는 과정에서 오래된 블록으로 인한 네트워크 보안 저하 문제를 해결합니다. 즉, 상위 블록과 이전 블록뿐만 아니라 사용되지 않는 담보 블록(이더리움에서는 "엉클 블록"이라고 함)도 추가하여 어떤 블록이 총 작업량이 가장 많은지 계산합니다.

두 번째 문제인 중앙 집중화 문제를 해결하기 위해 우리는 또 다른 전략을 채택했습니다: 오래된 블록에 대한 블록 보상도 제공됩니다: 오래된 블록 채굴에 대한 보상은 블록의 기본 보상의 7/8입니다. 기본 보상의 1/32를 바운티로 받습니다. 그러나 삼촌과 조카 블록에는 거래 수수료가 주어지지 않습니다.

이더리움에서 오래된 블록은 형제 블록의 7세대 이내 직계 자손 블록에 의해서만 엉클 블록으로 포함될 수 있습니다. 이러한 제한의 이유는 첫째, GHOST 프로토콜이 구식 블록의 세대간 거리를 제한하지 않으면 구식 블록의 유효성을 계산하는 데 많은 오버헤드를 소비하게 될 것이고, 둘째, 구식 블록에 대한 무제한 인센티브 정책입니다. 채굴자들이 메인 체인에서 채굴에 대한 열정을 잃게 만들 것이며 결국 계산에 따르면 레이어 7로 제한된 구식 블록 보상 정책은 부정적인 부작용 없이 원하는 효과를 대부분 제공합니다.

  • 중앙 집중화 위험 측정을 위한 시뮬레이터는 https://github.com/ethereum/economic-modeling/blob/master/ghost.py에서 찾을 수 있습니다.

  • 더 높은 수준의 토론은 여기에서 찾을 수 있습니다: https://blog.ethereum.org/2014/07/11/toward-a-12-second-block-time/

  • 교정 참고: 여기서 "포함"의 기술 형식은 다음과 같습니다. 조카 블록은 블록 헤더에서 삼촌 블록의 블록 해시 값을 참조한 다음 블록 본문에 삼촌 블록의 블록 헤더를 포함합니다.

    blocktime 알고리즘에 대한 설계 결정에는 다음이 포함됩니다.

  • 차단 시간 12초: 이미 네트워크 지연의 최소 시간 간격보다 길기 때문에 12초가 선택됩니다. 2013년 비트코인 ​​네트워크의 대기 시간 측정에 관한 논문에서는 새로 생성된 블록이 95%의 노드에 전파되는 데 걸리는 시간을 12.6초로 결정했지만 전파 시간은 블록에 비례한다고 기술했습니다. 따라서 더 빠른 통화에서는 전파 시간이 크게 단축될 것으로 예상할 수 있습니다. 전파 간격은 약 2초로 일정합니다. 그러나 안전을 위해 분석에서는 블록 전파에 12초가 걸린다고 가정합니다.

  • 조상의 7세대 이내 제한: 이 설계의 목적은 적은 수의 블록만 유지하고 이전 블록을 지우는 것입니다. 7세대의 할당 범위는 원하는 효과의 대부분을 제공하는 것으로 나타났습니다.

  • 1세대 후손 제한: (예: c(c(p(p(p(p(head))))))는 c = 자식이고 p = 부모인 경우 유효하지 않음): 이는 단순성을 위한 설계 목표이기도 하며, 앞서 언급한 시뮬레이터는 이것이 심각한 중앙 집중화 위험을 초래하지 않는다는 것을 보여줍니다. (교정 참고: 이 문장은 이해하기 어렵습니다. 한 가지 가능한 의미는 다음과 같습니다. 엉클 블록의 자손은 엉클 블록으로 사용할 수 없습니다. 즉, 메인 체인의 사이드 브랜치 세대만 엉클 블록으로 사용할 수 있습니다. .)

  • 삼촌 블록은 유효해야 합니다: 삼촌 블록은 유효한 블록이 아니라 유효한 헤더여야 합니다. 이는 블록체인 모델을 DAG로 전환하지 않고 선형 데이터 구조로 유지하면서 단순성을 위해 수행됩니다. 그러나 엉클 블록이 유효한 블록이 되도록 요구하는 것도 유효합니다.

  • 첫 번째 레벨 제목

난이도 업데이트 알고리즘

현재 Ethereum은 다음 규칙을 통해 난이도 업데이트를 수행합니다.

난이도 업데이트 규칙의 설계 목표는 다음과 같습니다.

  • 빠른 업데이트: 블록 사이의 시간은 해시 파워의 증가 또는 감소에 따라 빠르게 조정되어야 합니다.

  • 낮은 변동성: 채굴 능력이 일정하다면 난이도가 크게 변동하지 않아야 합니다.

  • 단순함: 알고리즘의 구현은 상대적으로 단순해야 합니다.

  • 메모리 부족: 알고리즘은 너무 많은 과거 블록에 의존해서는 안 되며 가능한 한 적은 "메모리 변수"를 사용해야 합니다. 최신 10개 블록이 있다고 가정하고 이 10개 블록의 헤더에 저장된 메모리 변수를 추가하면 이 블록을 알고리즘 계산에 사용할 수 있습니다.

  • Unbreakable: 알고리즘은 채굴자에게 타임스탬프를 조작하거나 채굴 풀을 반복적으로 추가하거나 삭제하도록 너무 많은 인센티브를 제공해서는 안 됩니다.

  • 첫 번째 레벨 제목

가스 및 수수료

비트코인의 모든 트랜잭션은 거의 동일하므로 네트워크 비용은 단일 단위로 모델링됩니다. 이더리움의 거래는 더 복잡하기 때문에 거래 수수료는 네트워크 대역폭 비용, 저장 비용 및 계산 비용을 포함하여 계정의 여러 측면을 고려해야 합니다. 적어도 이더리움 프로그래밍 언어는 튜링 완전하므로 트랜잭션은 대역폭, 스토리지 및 계산 비용을 얼마든지 사용할 수 있습니다. ) ) (교정 참고: 즉, 튜링 기계에서 실행 가능한 모든 프로그램이 유한한 단계 내에서 종료될 것이라고 주장할 수 있는 신뢰할 수 있는 방법이 없습니다). 무한 루프를 사용하여 서비스 거부 공격을 방지하는 것이 우리의 핵심 목표입니다.

이더리움 거래 수수료의 기본 메커니즘은 다음과 같습니다.

  • 각 트랜잭션은 소비하고자 하는 가스의 양(즉, startgas 값 지정)과 각 가스 단위에 대해 지불하고자 하는 수수료(즉, gasprice)를 지정해야 합니다. (교정 참고: 여기서 시작 가스는 지금 우리가 사용하는 가스 한도입니다.)

  • 데이터베이스 읽기 및 쓰기, 메시지 전송, 각 단계의 계산을 포함하여 트랜잭션 실행 중 모든 작업은 일정량의 가스를 소비합니다.

  • 트랜잭션이 완료되고 소비된 가스 값이 지정된 제한 값보다 작으면 트랜잭션이 정상적으로 실행되고 나머지 가스 값은 변수 gas_rem에 할당되며 트랜잭션이 완료되면 보낸 사람은 반환되는 이더를 gas_rem * gasprice의 가치, 채굴자에 대한 보상은 (startgas - gas_rem) * gasprice 가치의 에테르입니다.

  • 트랜잭션 실행 중 가스가 소진되면 모든 실행은 원래 상태로 복원되지만 트랜잭션은 여전히 ​​유효하지만 트랜잭션의 유일한 결과는 startgas * gasprice 값으로 광부에게 지불하고 다른 하나는 변경되지 않습니다.

  • 계약이 다른 계약에 메시지를 보낼 때 메시지로 인해 발생하는 하위 실행에 대한 가스 한도를 설정할 수 있습니다. 하위 실행에 가스가 부족하면 하위 실행이 복원되지만 가스는 여전히 소비됩니다. (교정 참고: 이 글을 교정한 시점(2021년 7월 9일) 기준으로 이는 변경되지 않았지만 향후 변경될 수 있습니다. "를 참조하십시오.제거를 고려할 가치가 있는 EVM 기능》)

  • 위에서 언급한 사항이 충족되어야 합니다. 예를 들면 다음과 같습니다.

  • 거래에서 가스 한도를 지정할 필요가 없다면 악의적인 사용자가 수십억 단계의 루프로 거래를 보낼 수 있습니다. 트랜잭션 처리에 시간이 오래 걸리기 때문에 아무도 처리할 수 없지만 네트워크상의 채굴자에게 미리 알릴 수 있는 사람이 없기 때문에 서비스 거부 취약점이 발생할 수 있습니다.

  • 엄격한 가스 계산에 대한 대안은 시간 제한이지만 너무 주관적이기 때문에 유용하지 않을 수 있습니다.

  • startgas * gasprice의 전체 값은 처음에 설정해야 트랜잭션 실행 중에 계정이 "파산"되지 않고 가스 요금을 계속 지불할 수 없습니다. 계정이 잔액을 다른 곳에 넣을 수 있기 때문에 실행하는 동안 잔액을 확인하는 것도 작동하지 않습니다.

  • 가스가 부족한 경우 트랜잭션 실행이 완전히 되돌려지지(롤백) 되지 않는 경우 계약은 계약이 변경되지 않도록 강력한 안전 조치를 취해야 합니다.

  • 하위 제한이 없으면 악의적인 계정이 다른 계약에 대해 서비스 거부 공격을 수행할 수 있습니다. 공격자는 먼저 피해자 계약과 합의에 도달한 다음 계산 프로세스 시작 부분에 무한 루프를 삽입한 다음 피해자 계약에 메시지를 보내거나 피해자 계약을 해결하려는 시도를 하면 전체 트랜잭션이 교착 상태가 됩니다. (교정 참고: 이 문장도 이해하기 어렵습니다.)

  • 계약이 아닌 트랜잭션 발신자에게 가스 비용을 지불하도록 요구하면 개발자 작업성이 크게 향상됩니다. 이더리움의 초기 버전은 계약을 통해 가스 비용을 지불했는데, 이로 인해 다소 심각한 문제가 발생했습니다. 각 계약은 "게이트키퍼" 코드를 구현하여 각 수신 메시지가 계약이 소비하기에 충분한 이더를 제공하도록 했습니다.

  • 가스 소비 계산에는 다음과 같은 특징이 있습니다.

  • 모든 거래에 대해 21000 가스의 기본 수수료가 부과됩니다. 이러한 수수료는 거래를 저장하는 데 사용되는 하드 드라이브 및 대역폭 공간뿐만 아니라 서명에서 발신자의 주소를 복구하도록 설계된 타원 곡선 알고리즘을 실행하는 비용을 지불하는 데 사용할 수 있습니다.

  • 트랜잭션에는 무제한의 "데이터"가 포함될 수 있습니다. 이러한 트랜잭션을 수신하는 계약이 데이터에 액세스할 수 있도록 하는 가상 머신의 특정 opcode입니다. 데이터에 대한 "고정 소비" 규칙은 0바이트당 4가스, 0이 아닌 바이트당 68가스입니다. 이 공식은 사용자가 계약으로 보낸 대부분의 트랜잭션이 일련의 32바이트 매개변수로 구성되어 있으며 대부분 선행 0바이트가 많기 때문에 발생합니다. 이 구조는 비효율적으로 보일 수 있지만 압축 알고리즘으로 인해 실제로는 매우 효율적입니다. 우리는 이 구조가 예상되는 바이트 수에 따라 매개변수를 엄격하게 래핑하는 더 복잡한 다른 메커니즘을 대체할 수 있기를 바랍니다. 그 결과 컴파일 단계의 복잡성이 크게 증가합니다. 이것은 샌드위치 콤플렉스 모델의 예외이지만 비용-편익 비율로 인해 합리적인 모델이기도 합니다.

  • 계정 저장 항목 설정에 사용되는 연산 코드 SSTORE의 소모량은 1) 0 값을 0이 아닌 값으로 변경 시 20000 gas를 소모하고, 2) 0 값을 0 값으로 변경하거나, 0 값을 0이 아닌 값으로 변경, 5000 gas 소모, 3) 0이 아닌 값을 0 값으로 변경, 5000 gas 소모, 추가로 트랜잭션이 성공적으로 실행된 후(즉, 트랜잭션이 가스를 배출하지 않고 실행됩니다). 환불 금액의 상한은 트랜잭션에 소비된 총 가스의 50%입니다. 이것은 사람들에게 저장된 항목을 지우는 작은 인센티브를 제공합니다. 이러한 인센티브가 부족하여 많은 계약의 저장 공간이 효율적으로 사용되지 않아 저장된 데이터의 급속한 확장으로 이어집니다. 이 디자인은 계약이 일단 성립되면 무기한으로 존재할 수 있다는 보장을 잃지 않고 "보관 항목에 대한 지속적인 임대" 모델의 이점을 대부분 제공합니다. 지연된 환불 메커니즘은 서비스 거부 공격을 방지할 수 있기 때문에 필요합니다. 공격자는 적은 양의 가스로 거래를 보낼 수 있으며 가스가 소진될 때까지 한 주기에 많은 저장 항목을 지울 수 있습니다. 많은 검증 컴퓨팅 성능을 제공하지만 실제로는 스토리지를 비우지 않으며 가스 비용도 많이 들지 않습니다. 50% 상한선은 거래를 패키징하는 광부가 여전히 거래를 실행하기 위한 계산 시간의 상한을 결정할 수 있도록 하기 위한 것입니다.

  • (교정 참고: 우선 SSTORE와 같은 state access opcode의 가스 소모량은 이더리움의 하드포크와 함께 여러번 변경되었습니다. 2021년 7월 현재 최신 값은 "베를린의 업그레이드 콘텐츠 개요"; 가까운 장래에 이 opcode의 값은 계속 변경될 것입니다. 둘째, 상태 데이터 확장 문제를 완화하기 위해 여기에서 가스 환불 메커니즘이 활성화되지 않았지만 사람들이 값을 변경할 수 있기 때문에 문제를 악화시켰습니다. 가스 가격 가스 가격이 낮으면 많은 양의 가비지 데이터를 쓰고, 가스 가격이 높으면 이 데이터를 클리어하여 가스를 얻는 것이 "GasToken"의 원리입니다. "London" 포크에서 가스 환불 메커니즘이 변경되는 것으로 확인되었습니다.이더리움 "런던" 업그레이드 미리보기》。)

  • 컨트랙트에서 제공하는 메시지 데이터는 비용이 없습니다. 메시지 호출 중에 실제로 데이터를 복사할 필요가 없기 때문에 호출 데이터(call data)는 단순히 부모 계약의 메모리에 대한 포인터로 간주될 수 있으며 자식 프로세스가 실행될 때 변경되지 않습니다.

  • 메모리는 무한히 확장할 수 있는 배열이지만 32바이트의 메모리를 확장할 때마다 1 가스 비용이 소모되며 32바이트 미만은 32바이트로 계산됩니다. (교정 참고: 메모리는 일반적으로 메모리로 번역되지만 이더리움의 맥락에서는 데이터를 저장하기 때문에 EVM의 세 가지 유형 중 하나이므로 그 특수성을 나타내기 위해 번역되지는 않습니다.)

  • 일부 opcode의 계산 시간은 매개변수에 따라 크게 달라지며 가스 오버헤드 계산은 동적으로 변경됩니다. 예를 들어, EXP 비용은 기하급수적입니다(10가스 + 10가스/바이트, 즉 x^0 = 1가스, x^1 ... x^255 = 2가스, x^256 ... x^65535 = 3 가스 등). 복사 opcode(예: CALLDATACOPY, CODECOPY, EXTCODECOPY)에는 1가스 + 1가스/32바이트의 오버헤드가 있습니다(반올림, LOG opcode에 대한 규칙은 유사함). 메모리 확장의 오버헤드는 여기에 포함되지 않습니다. 포함되면 사각 공격 벡터가 됩니다(50,000 CALLDATACOPY, 매번 50,000 gas 소모, 계산량은 50,000^2이어야 하지만, 동적 충전 규칙을 사용하지 않으면 ~50,000 gas만 지불하면 됩니다. ).

  • Opcode CALL(및 CALLCODE)은 값이 0이 아닌 경우 추가 9000 가스 비용이 듭니다. 모든 값 전송으로 인해 아카이브 노드의 히스토리 스토리지가 크게 증가하기 때문입니다. 연산의 실제 소모량은 6700이지만 이를 기준으로 수신자에게 자동으로 부여되는 가스 값을 강제로 증가시키며 이 값은 최소 2300 이상임을 유의하시기 바랍니다. 이것은 거래를 수락하는 지갑이 적어도 로그를 생성하기에 충분한 가스를 갖도록 하기 위해 수행됩니다. (교정 메모: "참조"제거를 고려할 가치가 있는 EVM 기능》)

  • 가스 메커니즘의 또 다른 중요한 부분은 가스 가격 자체에 구현된 경제성입니다. 비트코인에서 기본 접근 방식은 광부가 게이트키퍼 역할을 하고 최소 수수료를 동적으로 설정하는 순전히 자발적인 수수료를 받는 것입니다. 이더리움에서는 트랜잭션 발신자가 가스를 얼마든지 설정할 수 있습니다. 이 방법은 채굴자와 거래자가 수요와 공급에 따라 가격을 결정할 수 있는 "시장 경제"의 구현이기 때문에 비트코인 ​​커뮤니티에서 매우 인기가 있습니다. 그러나 이 접근 방식의 문제점은 거래 처리가 시장 원칙을 따르지 않는다는 것입니다. 트랜잭션 처리는 마이너가 발신자에게 제공하는 서비스로 생각할 수 있지만(직관적으로 들릴 수 있음) 실제로 마이너가 처리하는 모든 트랜잭션은 네트워크의 모든 노드에서 처리되어야 하므로 대부분의 트랜잭션 처리 비용은 모두 부담됩니다. 폐기 여부를 결정하는 채굴자가 아닌 제3자 기관에 의해 처리됩니다. 따라서 '공유지의 비극' 문제가 발생할 가능성이 매우 높다.

    첫 번째 레벨 제목

가상 기기

Ethereum Virtual Machine은 트랜잭션 코드를 실행하는 엔진이며 Ethereum과 다른 시스템의 핵심 차이점이기도 합니다. 가상 머신은 "계약 및 메시지 모델"과 별도로 고려되어야 합니다. 예를 들어 SIGNEXTEND opcode는 가상 머신의 기능이지만 실제로 "계약은 다른 계약을 호출하고 하위 호출에 대한 가스 제한을 지정할 수 있습니다"는 "계약 및 메시지 모델"의 일부입니다.

EVM의 설계 목표는 다음과 같습니다.

  • 간단함: 가능한 적은 수의 낮은 수준의 opcode, 가능한 한 적은 데이터 유형, 가능한 한 적은 가상 머신 구조,

  • 결과는 명확합니다. VM 사양에는 모호성이 있을 여지가 없으며 결과는 완전히 결정적이어야 합니다. 또한 가스 소모량을 측정할 수 있도록 계산 단계가 정확해야 합니다.

  • 공간 절약: EVM 구성 요소는 가능한 한 컴팩트해야 합니다.

  • 의도된 용도에 특화됨: VM에 구축된 애플리케이션은 20바이트 주소 및 32비트 사용자 지정 암호화 값을 처리할 수 있어야 하며 사용자 지정 암호화를 위한 모듈로 작업, 읽기 블록 및 트랜잭션 데이터 및 상태 상호 작용과 같은 기능이 있어야 합니다.

  • 간단하고 안전함: VM이 악용되는 것을 방지하려면 일련의 가스 소비 비용 모델을 쉽게 설정할 수 있어야 합니다.

  • 최적화 친화적: VM의 JIT(Just-In-Time Compilation) 및 가속 버전을 구축할 수 있도록 최적화하기 쉬워야 합니다.

  • 동시에 EVM에는 다음과 같은 특별한 디자인도 있습니다.

  • 임시/영구 저장소의 차이점: 먼저 임시 저장소와 영구 저장소가 무엇인지 살펴보겠습니다. 임시 저장소: VM의 모든 인스턴스에 존재하며 VM 실행이 끝나면 사라집니다. 영구 저장소: 블록체인 상태 계층에 존재합니다. 다음 트리가 실행된다고 가정합니다(S는 영구 저장소, M은 임시 저장소).

  • A가 B를 호출합니다.

  • B는 BS[0]=5, BM[0]=9로 설정하고;

  • B는 C를 호출합니다.

  • C가 B에게 전화를 겁니다.

    이때 B가 BS[0]을 읽으려고 하면 이전에 B에 저장된 데이터인 5를 가져오지만 B가 BM[0]을 읽으려고 하면 BM은 임시 저장소이므로 0이 됩니다. , 그리고 읽기 When it is a fetched, it is a new instance of the virtual machine. 내부 호출(inner call)에서 BM[0] = 13, BS[0] = 17로 설정하면 내부 호출과 C의 호출이 모두 종료되고 B의 외부 호출(outer call)로 복귀한다. , 이때 Take M을 읽으면 BM[0] = 9(이 값은 동일한 VM 실행의 마지막 인스턴스에서 설정됨), BS[0] = 17을 볼 수 있습니다. B의 외부 호출이 종료되고 A가 B를 다시 호출하면 BM[0] = 0, BS[0] = 17이 됩니다. 이 차이점의 목적은 다음과 같습니다. 1. 각 실행 인스턴스에는 메모리 공간이 할당되며 루프 호출로 성능이 저하되지 않으므로 안전한 프로그래밍이 더 쉬워집니다. 2. 빠르게 작동할 수 있는 인메모리 형식 제공: 트리를 수정해야 하므로 스토리지 업데이트가 필연적으로 느립니다.

  • 스택/메모리 모드: 초기에는 세 가지 유형의 컴퓨팅 상태가 있었습니다(다음 명령어를 가리키는 프로그램 카운터 제외). 스택(스택, 32바이트 표준 LIFO 스택), 메모리(메모리, 임시 바이트 배열 무기한 연장 가능), 보관 항목(보관, 영구 보관). 임시 저장 측면에서 스택과 메모리에 대한 대안은 메모리 전용 패러다임 또는 레지스터와 메모리의 하이브리드입니다(둘 사이에는 큰 차이가 없으며 레지스터는 본질적으로 일종의 메모리입니다). 이 경우 각 명령어에는 세 개의 인수가 있습니다(예: ADD R1 R2 R3: M[R1] = M[R2] + M[R3] ). 스택 패러다임을 선택한 이유는 명백합니다. 코드를 4배 더 작게 만듭니다.

  • 워드 크기 32바이트: 비트코인과 같은 대부분의 구조에서 워드 크기는 4바이트 또는 8바이트입니다. 4바이트 또는 8바이트는 메모리 주소 및 암호화 계산에 너무 제한적입니다. 크기를 제한하지 않고 그에 상응하는 안전한 가스 모델을 설정하는 것은 어렵습니다. 32바이트는 너무 커서 비효율을 일으키지 않으면서 많은 암호화 알고리즘에서 요구하는 큰 값과 주소를 저장하기에 충분하기 때문에 이상적인 크기입니다.

    우리에게는 자체 가상 머신이 있습니다. 가상 머신은 Java, Lisp 및 Lua와 같은 언어로 개발되었습니다. 우리는 다음과 같은 이유로 전문 가상 머신을 개발하는 것이 가치가 있다고 생각합니다: 1) 다른 가상 머신은 복잡성에 대한 비용이 적기 때문에, 즉 변경하기가 더 쉽기 때문에 우리의 VM 사양은 다른 많은 가상 머신보다 훨씬 간단합니다. 우리 계획의 복잡성은 개발 강화에 장벽을 만들고 합의 오류와 같은 잠재적인 보안 결함을 도입하여 복잡성 비용을 높입니다. 설치 실패를 유발하는 종속성 4) 완전한 검토 메커니즘은 특수한 보안 요구 사항에 따라 다를 수 있음 외부 VM을 사용해도 많은 작업이 절약되지 않습니다.

    가변적이고 확장 가능한 메모리 크기가 사용됩니다. 고정 메모리 크기는 너무 작거나 너무 큰 불필요한 제약 조건입니다. 메모리 크기가 고정되어 있으면 메모리에 액세스할 때마다 액세스가 경계를 초과하는지 여부를 확인해야 하므로 분명히 효율적이지 않습니다.

    1024 호출 깊이 제한: 많은 프로그래밍 언어는 메모리가 오버플로되기 전에 호출 깊이가 너무 깊기 때문에 충돌합니다. 따라서 블록 가스 한도를 한도로 사용하는 것만으로는 충분하지 않습니다.

    Untyped: 간결함을 위해. 그러나 DIV, SDIV, MOD, SMOD는 부호가 있거나 없는 opcode를 사용합니다(부호가 있는 opcode와 unsigned는 opcode ADD 및 MUL과 동일함). 사례는 간단합니다(예: a * b -> (a * b) / 2^32 a / b -> a * 2^32 / b 32비트 길이, 정수 상수의 +, - 및 *.

    교정 참고: 원본 번역에도 다음 단락이 있지만 해당 단락은 원본 텍스트의 현재 버전에서 삭제되었습니다. 스택 크기에는 제한이 없습니다. 특별한 이유가 없습니다! 대부분의 경우 이 디자인은 반드시 필요한 것은 아닙니다. 가스 오버헤드와 블록 가스 캡이 항상 각 리소스 소비에 대한 캡 역할을 하기 때문입니다.

  • 이 VM에 있는 일부 opcode의 기능과 목적은 이해하기 쉽지만 일부는 그렇지 않습니다. 여기에 몇 가지 특별한 이유가 있습니다.

  • ADDMOD,MULMOD: 대부분의 경우 mulmod(a, b, c) = a * b % c이지만 타원곡선 알고리즘에서는 32바이트 모듈러스 연산을 사용하며 a * b % c의 직접 실행은 실제로 ((a * b) % 2^256) % c 를 실행하면 완전히 다른 결과가 나옵니다. 32바이트 공간에서 32바이트 값의 a * b % c 계산을 수행하는 합의는 어렵고 지루합니다.

  • SIGNEXTEND: SIGNEXTEND opcode의 목적은 큰 부호 정수에서 작은 부호 정수로 유형 변환을 용이하게 하는 것입니다. 미래의 Just-In-Time 가상 머신은 주로 32바이트 정수를 처리하는 장기 실행 코드 블록을 감지할 수 있고 작은 부호 정수는 처리 속도를 높일 수 있기 때문에 작은 부호 정수는 유용합니다.

  • SHA3: 이더리움 코드에서 SHA3는 안전하고 강도가 높은 가변 길이 데이터 해시 매핑 방법으로 널리 사용됩니다. 일반적으로 메모리를 사용할 때 악의적인 충돌을 방지하기 위해 Hash 함수를 사용해야 하며, Merkle 트리 및 유사한 이더리움 데이터 구조를 확인할 때 Hash 함수를 사용해야 합니다. 중요한 것은 SHA256, ECRECVOR, RIPEM160과 같은 SHA3와 유사한 해시 함수가 opcode의 형태로 포함되지 않고 의사 계약의 형태로 포함된다는 것입니다. 이것의 목적은 그것들을 별도의 범주에 넣는 것이며, 나중에 적절한 "네이티브 플러그인" 시스템이 나오면 확장 opcode 없이도 더 많은 계약을 추가할 수 있습니다.

  • ORIGIN: ORIGIN opcode는 트랜잭션 발신자에 의해 제공되며 주요 기능은 컨트랙트가 지불된 가스를 반환할 수 있도록 하는 것입니다.

  • COINBASE: COINBASE의 주요 역할은 1) 하위 코인이 네트워크 보안에 기여하도록 허용하고, 2) 채굴자가 Schellingcoin과 같은 하위 합의 기반 애플리케이션을 설정하기 위한 분산 경제 역할을 할 수 있도록 하는 것입니다.

  • PREVHASH: PREVHASH는 준보안 임의성 소스로 사용할 수 있습니다. 또한 계약에서 매우 복잡한 "Ethereum 라이트 클라이언트" 재귀 구조를 요구하지 않고 이전 블록의 Merkle 트리 상태 증명을 평가할 수 있습니다.

  • EXTCODESIZE,EXTCODECOPY: 주요 기능은 계약이 템플릿에 따라 다른 계약의 코드를 확인하고 다른 계약과 상호 작용하기 전에 시뮬레이션하는 것입니다. 참조: https://lesswrong.com/lw/aq9/decision_theories_a_less_wrong_primer/

  • JUMPDEST: 점프 대상이 몇 개의 인덱스로 제한되는 경우(특히 동적 대상 점프의 계산 복잡성은 O(로그(유효한 도전 대상 수))인 반면 정적 점프는 항상 일정함) JIT 가상 머신은 구현하다. 따라서 1) 유효한 변수 점프 대상을 제한하고 2) 동적 점프가 아닌 정적 점프를 사용하도록 장려해야 합니다. 이 두 가지 목표를 달성하기 위해 다음과 같은 규칙을 설정했습니다. 코드의 이전 연산을 보고 현재 점프가 정적 점프인지 동적 점프인지 판단할 수 있도록 점프에 대한 제한이 필요합니다. 정적 점프가 필요하지 않기 때문에 사용 동기가 부여됩니다. 푸시 데이터로 점프를 비활성화하면 JIT VM 컴파일 및 실행 속도도 빨라집니다.

  • LOG: LOG는 이벤트 로그입니다.

  • CALLCODE: 이 opcode를 사용하면 계약이 자체 저장 항목을 사용하여 별도의 스택 공간과 메모리에 있는 다른 계약의 "기능"을 호출할 수 있습니다. 이를 통해 블록체인에서 표준 라이브러리 코드를 유연하게 구현할 수 있습니다.

  • SELFDESTRUCT: 계약이 더 이상 존재할 필요가 없는 경우 계약 자체를 삭제할 수 있습니다. SELFDESTRUCT는 즉시 실행되지 않고 트랜잭션이 실행된 후에 실행됩니다. 실행 후 SELFDESTRUCT가 롤백하도록 허용하면 캐싱의 복잡성이 크게 증가하여 효율적인 VM 구현에 도움이 되지 않기 때문입니다.

  • 원본 링크:

(위에)

원본 링크:

https://eth.wiki/en/fundamentals/design-rationale

저자: 비탈릭

번역 및 교정: 김앤아지안

ETH
개발자
스마트 계약
Odaily 공식 커뮤니티에 가입하세요