결함은 암호학이나 발행 일정이 아니라 검증 규칙의 구현에 있었다. 각 출력은 양수였지만 합계에서 오버플로가 발생해 음수가 되었다. 입력과 이 음수 합계의 차이는 수수료로 처리됐다. 버전 0.3.10은 개별 출력과 누적 합계에 상한을 추가했고, 수정된 분기로 재구성된 뒤 잘못된 블록은 활성 기록에서 제외됐다.
2010년 8월 15일, 개발자 Jeff Garzik은 이상한 블록 74 638을 보고했다. 트랜잭션 1d5e512a9723cbef373b970eb52f1e9598ad67e7408077a82fdac194b65333c9는 0.50 BTC짜리 입력 하나를 사용하면서 거대한 출력 두 개를 만들었다. 당시 printblock 기록에 따르면 각 출력은 92 233 720 368.54275808 BTC였다. 취약점을 악용한 이 트랜잭션의 작성자가 누구인지는 확실하게 밝혀지지 않았다. 공개 기록으로 확인할 수 있는 것은 트랜잭션 데이터이지, 작성자의 신원이나 동기가 아니다. [1]
당시 Bitcoin은 금액을 사토시 단위의 부호 있는 64비트 정수로 처리했다. 각 출력의 정숫값은 양수였으며 int64 최댓값보다 조금 작았다. 16진수 기록인 0x7ffffffffff85ee0도 이 값을 뒷받침한다. 그러나 둘을 더한 18 446 744 073 708 551 616 사토시는 표현 가능한 범위를 넘어섰고, 오버플로가 발생해 −1 000 000 사토시가 되었다. 기존 검증 코드는 이 음수 합계를 입력과 비교한 뒤 허용했다. 서명이 깨진 것이 아니라 산술 처리에 결함이 있었던 것이다. 토론에 처음 올라온 JSON 기록은 소수점 이하 마지막 자릿수가 다르므로, 여기서는 printblock과 16진수 기록이 모두 확인해 주는 정숫값으로 정확하게 계산한다. [1]
출력 합계가 −0.01 BTC가 되자 입력 0.50 BTC와의 차이 때문에 0.51 BTC라는 허위 수수료가 생겼다. 이에 따라 채굴자는 기본 보상인 50 BTC 대신 coinbase에서 50.51 BTC를 가져갔다. 사용한 입력을 빼고 coinbase의 초과분까지 포함하면, 거대한 두 출력은 잘못된 분기의 공급량을 정확히 18 446 744 073 709 551 616 사토시 늘렸다. 이는 2^64 사토시, 곧 184 467 440 737.09551616 BTC다. 따라서 이 수치는 두 출력의 금액을 단순히 더한 값이 아니다. [2]
커뮤니티는 시간 압박 속에서 공개 대응했다. Lfm은 심각한 버그라고 했고 Gavin Andresen은 각 출력을 2100만 BTC와 비교하는 빠른 검사를 제안했다. Satoshi Nakamoto는 음수나 과도한 출력과 매번 더한 뒤의 과도한 누적 합계를 거부하는 더 넓은 수정을 공개했다. 새로운 유효 분기가 잘못된 분기를 더 빨리 따라잡고 대체할 수 있도록 채굴자에게 일시 중단도 요청했다. [2]
Satoshi는 Garzik의 보고 약 다섯 시간 사십 분 뒤인 2010년 8월 15일 포럼 시각 23:48에 버전 0.3.10을 발표했다. 업데이트 노드는 악용 거래와 블록 74 638을 무효로 보고 마지막 공통 유효 블록 위에 구축했다. 당시 발표는 좋은 분기가 나쁜 분기를 추월했다고 나중에 알렸고, 업데이트 클라이언트는 blockchain 파일을 수동 삭제하지 않고 자동 재구성할 수 있었다. [3]
중앙 데이터베이스에서 과거 블록을 편집한 것이 아니다. 두 경쟁 기록이 존재했다. 옛 노드는 원래 규칙으로 블록을 받아들였고 수정 노드는 거부하며 유효한 선행 블록을 잇는 작업만 인정했다. 수정 분기가 더 많은 Proof of Work를 쌓자 네트워크가 이를 따랐고 인플레이션 블록은 활성 기록에서 벗어났다. 결정적이었던 것은 사용자와 채굴자의 새 규칙 설치와 후속 작업이지 한 관리자의 명령이 아니었다. [3]
당시 도입한 보호는 오늘날 Bitcoin Core에도 보인다. CheckTransaction은 음수 출력, MAX_MONEY 초과 출력, MoneyRange 밖의 누적 합계를 거부한다. 각 덧셈 뒤 검사해 위험한 합계가 비교 전에 넘치는 것을 막는다. 소스 주석은 CVE-2010-5139를 명시하고 별도의 중복 입력 검사는 다른 사건 CVE-2018-17144를 떠올리게 한다. [4]
이 사건은 2100만 개 한도가 해시만으로 지켜지는 마법의 상수가 아니라 정밀한 검증 규칙과 올바른 구현으로 강제됨을 보여 준다. 감사는 개별 범위, 안전한 덧셈, coinbase와 수수료, 검사 순서, 경계 시험 벡터, 독립 구현의 일치를 다뤄야 한다. 역사는 초기 공동체의 빠른 수정 능력과 소수 개발자, 채굴자, 수동 조율에 대한 당시의 높은 의존도도 함께 보여 준다. [5]
더 정확히 이해하려면 이 항목과 함께 다음도 읽어 보세요 Bitcoin Core, 합의 규칙, 트랜잭션, UTXO, Reorg, Soft Fork.
01유효한 Bitcoin에 1840억 BTC가 존재한 적이 있는가?+
악용 블록의 결과로 당시 채굴된 오류 분기에는 잠시 존재했다. 수정 노드는 그 분기를 거부했고 유효 분기가 재구성했으므로 거대 출력은 오늘날 활성 blockchain이나 UTXO 집합에 없다. 다만 역사적 사건 자체는 블록과 당시 대응으로 문서화되어 있다.
02이 사건이 2100만 개 한도를 영구히 깨뜨렸는가?+
오늘날 받아들여지는 기록에서는 아니다. 수정된 합의 규칙이 오류 블록을 거부했고 출력은 재구성으로 사라졌다. 그러나 한도는 올바른 검증과 참여자가 실제 실행하는 소프트웨어에 의존하며 문서의 문장만으로 공급을 강제할 수 없음을 보여 줬다.