이더리움 시작 이전의 이야기
저자: Vitalik Buterin
원제목: 《이더리움 프로토콜의 선사시대》
발표 시간: 2017년 9월 14일
현재 이더리움 프로토콜 뒤에 있는 아이디어는 기본적으로 2년 동안 안정되었지만, 이더리움은 한 번에 나타나지 않았고 현재의 개념으로 완전히 형성되지 않았습니다. 블록체인이 시작되기 전에, 이 프로토콜은 많은 중요한 발전과 설계 결정을 거쳤습니다. 이 문서의 목적은 이 프로토콜이 처음 시작된 이후의 다양한 진화를 살펴보는 것입니다. Geth, Cppethereum, Pyethereum 및 Ethereumj와 같은 프로토콜 구현에 대한 수많은 작업과 이더리움 생태계 내의 응용 프로그램 및 비즈니스 역사에 대해서는 의도적으로 범위를 벗어났습니다.
Casper와 Sharding Research의 역사도 등장합니다. 물론 우리는 블로그 글을 더 많이 발표할 수 있으며, Vlad, Gavin, 저 자신 및 다른 사람들의 모든 아이디어를 논의할 수 있습니다. 여기에는 "작업 증명", "허브 체인", "하이퍼큐브", 섀도우 체인 (Plasma의 전신이라고 할 수 있음), 체인 섬유 및 Casper의 다양한 반복이 포함됩니다. Vlad는 한 게시물에서 이를 다루었지만, 우리는 지금 생략하겠습니다.
우리는 먼저 이더리움으로 발전하기 전의 가장 초기 버전부터 시작하겠습니다. 그 당시에는 이더리움이라는 이름조차 없었습니다. 2013년 10월 이스라엘을 방문했을 때, 저는 마스터코인 팀과 많은 시간을 보냈고, 그들에게 몇 가지 기능도 제공했습니다. 그들이 무엇을 하고 있는지 몇 번 생각한 후, 저는 팀에 프로토콜을 보다 일반화하고 더 많은 유형의 계약을 지원할 수 있도록 제안했습니다. 같은 크고 복잡한 기능을 추가하지 않고도 말이죠:
https://web.archive.org/web/20150627031414/http://vbuterin.com/ultimatescripting.html

이것은 이더리움의 나중에 더 넓은 비전과는 거리가 멉니다. 그것은 순전히 마스터코인이 두 당사자 간의 계약을 전문적으로 연구하려고 했던 것입니다. 당사자 A와 B가 자금을 투입하고, 그 후 계약에 명시된 특정 공식에 따라 자금을 받는 것입니다 (예: 한 내기에서 "X가 발생하면 모든 자금을 A에게 주고, 그렇지 않으면 B에게 준다"라고 말할 수 있습니다). 스크립트 언어는 완전하지 않았습니다.
마스터코인 팀은 인상 깊었지만, 그들이 하고 있는 모든 것을 포기하고 이 방향으로 나아가는 것에는 관심이 없었습니다. 그래서 저는 이것이 올바른 선택이라는 것을 점점 더 확신하게 되었습니다. 그래서 여기 12월 2일의 버전 2가 있습니다:
https://web.archive.org/web/20131219030753/http://vitalik.ca/ethereum.html

여기에서, 당신은 실질적인 재조사의 결과를 볼 수 있습니다. 이는 주로 제가 스마트 계약이 완전히 일반화될 가능성을 깨달은 샌프란시스코 장거리 여행의 결과입니다. 단순히 두 당사자 간의 관계 조건을 설명하는 스크립트 언어가 아니라, 계약 자체가 완전한 계정이며 자산을 보유하고, 송금하고, 수신할 수 있는 능력을 가지고 있으며, 심지어 영구 저장을 유지할 수 있습니다 (당시 영구 저장은 "메모리"라고 불렸고, 유일한 임시 "메모리"는 256개의 레지스터였습니다). 이 언어는 스택 기반 컴퓨터에서 제 의지에 기반한 레지스터 기반 컴퓨터로 전환되었습니다; 복잡해 보이는 경우를 제외하고는 이에 대해 거의 논쟁이 없었습니다.
또한, 이제 내장된 수수료 메커니즘이 있다는 점에 유의하십시오:

이 시점에서, 이더는 실제로 가스입니다. 각 계산 단계 후에, 거래소가 요구하는 계약의 잔액이 감소하며, 계약이 통화 실행을 다 소진하면 중단됩니다. 이 "수신자 지불" 메커니즘은 계약 자체가 발신자에게 계약에 대한 수수료를 지불하도록 요구해야 하며, 이 수수료가 없을 경우 즉시 종료되어야 함을 의미합니다. 이 프로토콜은 계약이 비지불 거래를 거부할 수 있도록 16개의 무료 실행 단계의 할당을 제공합니다.
이것은 이더리움 프로토콜이 완전히 제 자신의 창작물일 때였습니다. 그러나 여기서부터 새로운 참여자들이 합류하기 시작했습니다. 지금까지 프로토콜 측면에서 가장 두드러진 인물은 Gavin Wood로, 그는 2013년 12월 저에게 연락을 주었습니다.

GO 클라이언트의 수석 개발자 Jeffrey Wilcke(당시 "Ethereal"이라고 불림)도 대략 같은 시기에 손을 내밀었지만, 그의 기여는 프로토콜 연구보다는 클라이언트 개발에 더 많았습니다.

"안녕하세요, Jeffrey, 이더리움에 관심을 가져주셔서 기쁩니다…"
Gavin의 초기 기여는 두 가지입니다. 첫째, 초기 설계에서 계약 호출 모델이 비동기적이라는 점을 주목할 수 있습니다. 계약 A는 계약 B에 대해 "내부 거래"를 생성할 수 있지만 ("내부 거래"는 Etherscan의 용어입니다; 처음에는 단순히 "거래"라고 불렸고, 나중에 "메시지 호출" 또는 "호출"이라고 불렸습니다), 첫 번째 거래의 실행이 완전히 완료된 후에야 내부 거래의 실행이 시작됩니다. 이는 거래가 내부 거래를 사용하여 다른 계약에서 정보를 얻는 방법이 없음을 의미합니다. 유일한 방법은 Extro OpCode(다른 계약의 저장소를 읽는 데 사용할 수 있는 Sload와 비슷함)였으며, 이후 Gavin과 다른 사람들의 지원으로 삭제되었습니다.
제 초기 사양을 구현하는 과정에서, Gavin은 자연스럽게 내부 거래를 동기화하여 구현했으며, 의도가 다르다는 것을 인식하지 못했습니다. 즉, Gavin의 구현에서는 계약이 다른 계약을 호출할 때 내부 거래가 즉시 실행되며, 실행이 완료되면 VM이 내부 거래를 생성한 계약으로 돌아가 다음 OPCODE를 계속 진행합니다. 우리 둘 모두에게 이 방법은 우수해 보였고, 그래서 우리는 이를 사양의 일부로 포함시키기로 결정했습니다.
둘째, 저와 Gavin 간의 논의(샌프란시스코에서 산책하는 동안, 정확한 세부 사항은 역사적 바람에 의해 영원히 잃어버릴 것이며, NSA의 깊은 아카이브에서 한두 개의 복사본이 사라질 수 있습니다)에서 거래 수수료 모델이 "계약 지불" 방법에서 "발신자 지불" 방법으로 전환되었고, "가스" 아키텍처로 전환되었습니다. 거래 발신자는 각 개별 거래 단계에서 즉시 차감되지 않고, 대신 일부 "가스"를 할당받아 (대략 계산 단계의 반격) 계산 단계는 이 가스의 할당에서 가져옵니다. 만약 거래가 가스를 다 소진하면, 가스는 여전히 압수되지만 전체 실행은 복구됩니다; 이는 전체 과정을 제거하기 때문에 가장 안전한 것으로 보입니다.
Gavin은 이더리움을 프로그래머블 자금 플랫폼으로 건설하는 비전에서 큰 공을 세웠으며, 블록체인 기반 계약이 디지털 자산을 보유하고 미리 설정된 규칙에 따라 이를 전송할 수 있도록 하여 일반 계산 플랫폼으로 발전하게 되었습니다. 이는 초점과 용어의 미세한 변화에서 시작되었으며, 이후 "Web 3" 합창에 대한 관심이 높아짐에 따라 이 영향은 더욱 강력해졌습니다. 이 합창은 이더리움을 분산된 기술의 집합으로 보고, 다른 두 가지는 귀찮음과 혼잡함입니다.

다른 사람들은 2014년 초에 변경을 제안하기도 했습니다. Andrew Miller와 다른 사람들이 이 아이디어를 제안한 후, 우리는 결국 스택 기반 아키텍처로 돌아갔습니다.

Charles Hoskinson은 비트코인의 SHA256에서 새로운 SHA3(또는 더 정확하게는 Keccak256)으로 전환할 것을 제안했습니다. 논란이 있었지만, Gavin, Andrew 및 다른 사람들과의 논의는 스택에서 값의 크기가 32바이트로 제한되어야 한다는 결론에 도달했습니다. 고려된 또 다른 대안은 무한 크기의 정수였지만, 이는 얼마나 많은 가스를 사용하는지, 더하기, 곱하기 및 기타 작업을 이해하기 어려운 문제가 있었습니다.
우리가 생각한 초기 채굴 알고리즘은 2014년 1월에 Dagger라는 장치였습니다:
https://github.com/ethereum/wiki/blob/master/Dagger.md

Dagger는 "방향성 비순환 그래프"(DAG)라는 알고리즘에서 사용되는 수학적 구조의 이름입니다. 이 아이디어는 매 n개의 블록마다 새로운 DAG가 시드에서 생성된 의사 랜덤으로 생성되며, DAG의 하부는 수십 기가바이트를 저장해야 하는 일련의 노드 집합이 될 것입니다. 그러나 DAG에서 개인 값을 생성하려면 수천 개의 항목을 계산해야 합니다. "Dagger 계산"은 이 하부 데이터 집합의 무작위 위치에서 일부 값을 얻고, 이를 결합하는 것을 포함합니다. 이는 Dagger 계산을 수행하는 빠른 방법이 있다는 것을 의미합니다 - 이미 메모리에 데이터를 저장했기 때문에 기억 집약적인 방법이 아니라, 처음부터 얻어야 하는 각 값을 얻는 것입니다.
이 알고리즘의 목적은 당시 유행하던 알고리즘과 동일한 "기억력" 속성을 가지면서도, 여전히 경량 클라이언트 친화적이도록 하는 것이었습니다. 채굴자는 빠른 방법을 사용하므로 그들의 채굴은 메모리 대역폭에 의해 제한됩니다(이론적으로 소비자급 RAM은 이미 매우 중요하므로 ASIC을 통해 추가 최적화하기가 어렵습니다). 그러나 경량 클라이언트는 메모리가 없지만 느린 버전을 사용하여 검증할 수 있습니다. 빠른 방법은 몇 마이크로초가 걸릴 수 있으며, 메모리가 없는 방법은 느리게 밀리초가 걸리므로 경량 클라이언트에게 여전히 매우 실행 가능했습니다.
여기서부터 이더리움 개발 과정에서 이 알고리즘은 여러 번 변경되었습니다. 우리가 경험한 다음 아이디어는 "적응형 작업 증명"이었습니다. 여기서 작업 증명은 무작위로 선택된 이더리움 계약을 실행하는 것을 포함하며, ASIC에 저항할 것이라는 똑똑한 이유가 있습니다: ASIC이 개발된다면, 경쟁하는 채굴자는 많은 계약을 생성하고 발표할 동기를 가지게 됩니다. 이러한 계약은 ASIC이 실행하기에 적합하지 않다는 것을 설명합니다. 이 이야기는 일반 계산을 위한 ASIC과 같은 것이 없기 때문에 CPU에 불과하므로, 우리는 이 저항적 인센티브 메커니즘을 사용하여 기본적으로 일반 계산을 실행하는 작업 증명을 만들 수 있습니다.
실패한 이유는 간단합니다: 원거리 공격. 공격자는 블록 1에서 시작하여 그들이 전용 하드웨어를 위해 만들 수 있는 간단한 계약으로 체인을 채우고, 주 체인을 빠르게 초과할 수 있습니다. 그래서… 다시 설계로 돌아갑니다.
다음 알고리즘은 "무작위 회로"라고 불리며, 이 Google 문서에서 설명되며, 저와 Vlad Zamfir이 제안하고 Matthew Wampler-Doty 등이 분석했습니다. 여기서의 아이디어는 채굴 알고리즘에서 일반 계산을 시뮬레이션하는 것이며, 이번에는 무작위로 생성된 회로를 실행하는 것입니다. 이러한 원칙에 기반하여 증명하는 것은 어렵지 않지만, 2014년에 우리가 접촉한 컴퓨터 하드웨어 전문가들은 대체로 매우 비관적이었습니다. Matthew Wampler-Doty 자신은 SAT 해결 기반의 작업 증명을 제안했지만, 결국 거부되었습니다.
마지막으로, 우리는 "Dagger Hashimoto"라는 알고리즘으로 회로를 완성했습니다. "dashimoto"는 때때로 "dashimoto"라고 불리며, hashimoto에서 많은 아이디어를 차용했습니다. Hashimoto는 Thaddeus Dryja의 작업 증명 알고리즘으로, "I/O의 작업 증명" 개념을 처음으로 제안했으며, 여기서 채굴 속도의 주요 제한 요소는 초당 해시가 아니라 초당 RAM 접근의 범위입니다. 그러나, 이는 Dagger의 경량 클라이언트 친화적인 DAG 생성 데이터 세트와 결합되었습니다. 제가 여러 조정을 한 후, Matthew, Tim 및 다른 사람들과 함께 이 아이디어는 우리가 현재 ethash라고 부르는 알고리즘으로 융합되었습니다.

2014년 여름까지, 프로토콜은 크게 안정되었으며, 작업 증명 알고리즘을 제외하고는 2015년 초까지 Ethash 단계에 도달하지 못했습니다. Gavin의 황서 형태로 반공식적인 사양이 존재했습니다.

2014년 8월, 저는 삼촌 블록 메커니즘을 개발하고 소개했습니다. 이 메커니즘은 이더리움의 블록체인이 더 짧은 블록 시간과 더 높은 용량을 가지도록 하면서 중앙 집중화 위험을 줄였습니다. 이는 POC6의 일환으로 도입되었습니다.
Bitshares 팀과의 논의는 우리가 스택을 1급 데이터 구조로 추가하는 것을 고려하게 했지만, 시간 부족으로 인해 결국 그렇게 하지 못했습니다. 이후의 보안 감사와 DOS 공격은 실제로 우리가 생각했던 것보다 훨씬 더 어려운 것으로 나타났습니다. 당시 이를 안전하게 실행하는 방법을 생각했습니다.
9월, 저는 Gavin과 함께 프로토콜 설계의 다음 두 가지 주요 변경 사항을 계획했습니다. 첫째, 상태 트리와 거래 트리 옆에 각 블록은 "영수증 트리"도 포함합니다. 영수증 트리는 거래 생성의 로그 해시와 중간 상태 루트를 포함합니다. 로그는 거래 생성이 블록체인에 "출력"으로 저장될 수 있게 하며, 경량 클라이언트가 이를 접근할 수 있지만, 미래 상태 계산은 접근할 수 없습니다. 이는 분산 응용 프로그램이 이벤트를 쉽게 쿼리할 수 있도록 하는 데 사용될 수 있습니다. 예를 들어, 토큰 전송, 구매, 생성 및 채우기 거래 주문, 경매 시작 등이 있습니다.
또한 고려된 다른 아이디어는 전체 거래의 실행 흔적에서 머클 트리를 생성하여 어떤 것을 증명하는 것이었습니다. 로그를 선택한 이유는 단순성과 완전성 간의 타협이기 때문입니다.
두 번째는 "프리컴파일" 아이디어로, EVM에서 복잡한 암호 계산을 사용할 수 있도록 하면서 EVM 오버헤드를 처리하지 않는 문제를 해결했습니다. 우리는 또한 "로컬 계약"에 대한 더 야심찬 아이디어를 경험했습니다. "채굴자가 특정 계약의 구현을 최적화할 수 있다면, 그들은 이러한 계약의 패키징 비용에 대해 '투표'할 수 있으며, 따라서 대부분의 채굴자가 더 빠르게 실행할 수 있는 계약은 자연스럽게 가스 가격을 낮출 것입니다." 그러나 이러한 모든 아이디어는 우리가 그러한 것을 구현할 수 있는 암호 경제적으로 안전한 방법을 제시할 수 없었기 때문에 거부되었습니다. 공격자는 항상 특정 함정의 암호 작업을 실행하는 계약을 생성할 수 있으며, 함정 문을 자신과 친구에게 할당하여 그 계약을 더 빨리 실행할 수 있습니다. 그런 다음 그 계약을 실행하고 가스에 대한 투표를 하여 네트워크에 사용할 수 있습니다. 대신, 우리는 해시 및 서명 스킴과 같은 일반적인 작업을 위해 프로토콜에서 지정된 적은 수의 프리컴파일을 단순히 선택하는 야심찬 방법을 선택했습니다.
Gavin은 또한 "프로토콜 추상화" 개념을 개발하는 데 중요한 초기 목소리였습니다. 이더 잔액, 거래 서명 알고리즘, nonce 등을 계약 자체로 이동시키고, 이론적으로 최종 목표는 전체 이더리움 프로토콜을 특정 원시 상태를 가진 가상 머신에 함수 호출을 하는 상황으로 설명할 수 있도록 하는 것입니다. 이러한 아이디어는 초기 전선 버전으로 들어갈 충분한 시간이 없었지만, 원칙은 몇 가지 콘스탄티노플 변화, 카스퍼 계약 및 분할 규격을 통해 서서히 통합될 것으로 예상되었습니다.
이 모든 것은 POC7에서 구현되었습니다. POC7 이후, 프로토콜은 미성년자를 제외하고는 큰 변화가 없었습니다. 그러나 특정 경우에는 보안 감사에서 도출된 세부 사항이 중요했습니다…
2015년 초, Jutta Steiner 등은 소프트웨어 코드 감사 및 학술 감사를 포함한 사전 출시 보안 감사를 조직했습니다. 이 소프트웨어 감사는 주로 Gavin Wood와 Jeffrey Wilcke가 이끄는 C++ 및 GO 구현에 의해 수행되었으며, 제 Pyethereum 구현에서도 소규모 감사가 있었습니다. 두 가지 학술 감사 중 하나는 Ittay Eyal(“이기적인 채굴”으로 유명)에서 수행되었고, 다른 하나는 Andrew Miller와 다른 최소 권위자들에 의해 수행되었습니다. EYAL 감사는 작은 프로토콜 변경을 초래했습니다: 체인의 총 난이도는 삼촌을 포함하지 않습니다. 최소 권한 감사는 스마트 계약 및 가스 경제학과 패트리샤 트리에 더 집중했습니다. 이 감사는 여러 프로토콜 변경을 초래했습니다. 작은 변경 사항은 sha3(addr) 및 sha3(key)를 직접 주소 및 키 대신 트라이 키로 사용하는 것이었습니다. 이는 트라이에 대한 최악의 공격을 더 어렵게 만들 것입니다.

경고는 그 시대보다 약간 멀리 있을 수 있습니다…
우리가 논의한 또 다른 중요한 사항은 가스 제한 투표 메커니즘이었습니다. 그 당시 우리는 비트코인 크기 논쟁에서의 진전 부족에 대해 우려하고 있었고, 이더리움에서 더 유연한 설계를 갖고 싶었으며, 필요에 따라 시간이 지남에 따라 조정할 수 있기를 원했습니다. 그러나 도전 과제는: 최적의 제한은 무엇인가? 저의 초기 아이디어는 실제 사용 가스 사용의 장기 지수 이동 평균을 목표로 하는 동적 제한을 설정하는 것이었습니다. 따라서 장기적으로 평균 블록은 가득 차게 될 것입니다. 그러나 Andrew는 이 점에서 활용 가능성이 있었습니다 - 특히, 제한을 높이고자 하는 채굴자는 자신의 블록에 거래를 포함시키기만 하면 되며, 이러한 거래는 많은 가스를 소모하지만 처리하는 데는 적은 시간이 걸리므로 항상 전체 블록을 생성할 수 있습니다. 따라서 최소한 상승 방향에서, 안전 모델은 채굴자가 가스 제한에 대해 투표하도록 단순히 허용하는 것과 같습니다.
우리는 깨지기 어려운 가스 제한 전략을 생각해내지 못했기 때문에, Andrew가 추천한 해결책은 채굴자가 가스 제한에 대해 명시적으로 투표하도록 하고, 기본 투표 전략을 EMA 규칙으로 설정하는 것이었습니다. 그 이유는 우리가 최대 가스 제한을 설정하는 올바른 방법에 도달하기까지는 아직 멀었으며, 특정 방법이 실패할 위험이 채굴자가 투표권을 남용할 위험보다 더 큰 것처럼 보였기 때문입니다. 따라서 우리는 차라리 채굴자가 가스 제한에 대해 투표하도록 하고, 유연성의 이점을 위해 너무 높거나 낮은 한계를 수용하기로 결정했습니다. 또한 채굴자가 필요에 따라 매우 빠르게 상향 또는 하향으로 조정할 수 있는 능력을 갖추도록 하였습니다.

Gavin, Jeff와 저 사이의 소규모 해커톤(POC9) 이후, POC9는 3월에 출시되었으며, 개념 발표의 최종 증명이 될 예정이었습니다. Livenet에서 사용할 계획을 가지고, 이더리움의 장기 계획을 수립하였으며, 4개월 동안 테스트넷을 운영했습니다. Vinay Gupta는 "이더리움 출시 과정"이라는 블로그 글을 작성하여 이더리움 Livenet 개발의 네 가지 예상 단계를 설명하고, 현재 이름인 Frontier, Homestead, Mesropolis 및 Serenity를 부여했습니다.
해커톤은 4개월 동안 진행되었습니다. 처음 두 달 동안 다양한 구현에서 많은 버그가 발견되었고, 합의 실패가 발생하는 등 여러 문제가 있었지만, 6월경에는 네트워크가 눈에 띄게 안정되었습니다. 7월에는 코드 동결을 결정하고, 출시를 발표했으며, 7월 30일에 출시되었습니다.













