
AI에게 비트코인 제네시스 블록을 재현하게 했더니, "채굴하지 않았다"라고 말하기 시작했다
요약
AI에게 비트코인 제네시스 블록을 JavaScript로 재현하도록 요청했을 때 발생하는 기술적 한계와 특이점을 다룹니다. 제네시스 블록은 일반적인 채굴 방식과 달리 특정 값이 코드에 내장되어 조립된다는 점을 설명합니다.
핵심 포인트
- 제네시스 블록은 네트워크 수신이 아닌 코드 내장 값으로 조립됨
- 블록 헤더는 80바이트의 특정 값들을 연결하여 구성됨
- 비트코인 블록 헤더는 SHA-256을 두 번 적용하는 SHA-256d 방식을 사용함
- 제네시스 블록은 이전 블록이 없으므로 이전 해시 값이 32바이트의 0임

AI에게 "비트코인의 첫 번째 블록을 JavaScript로 재현해줘"라고 부탁한다.
그러면 AI는 먼저 마이닝 (Mining)에 대한 설명을 시작한다.
넌스 (Nonce)를 바꾼다. 해시 (Hash)를 계산한다. 조건을 만족할 때까지 반복한다.
네, 거기까지는 맞다.
하지만 비트코인의 제네시스 블록 (Genesis Block), 즉 블록 0의 기동 방법을 조사하면 AI는 도중에 조금 난처해한다.
블록 0은 일반적인 블록처럼 네트워크로부터 수신하지 않는다.
초기 소스 코드에서는 필요한 값이 코드에 내장되어 있으며, 노드 (Node)는 그것을 조립한다.
"채굴한 블록을 받는" 것이 아니라, "모두가 동일한 재료로 만든다".
처음부터 갑자기 이상한 일을 하고 있다.
AI에게 전달하는 첫 번째 지시
우선 블록 헤더 (Block Header)만 만든다.
블록 헤더는 다음 6개의 값을 연결한 80바이트 (Byte)다.
버전 (Version)
이전 블록의 해시 (Previous Block Hash)
머클 루트 (Merkle Root)
...
제네시스 블록의 값은 다음과 같다.
const header = Buffer.concat([
Buffer.from("01000000", "hex"),
Buffer.alloc(32),
...
갑자기 16진수가 대량으로 등장했다.
AI에게 "좀 더 초보자용으로"라고 말하면, 아마 한 번 전부 문자열로 만들었다가 나중에 암호학적으로 올바르지 않은 샘플을 만들 것이다. 코드 예시가 친절해지는 대신, 블록이 다른 것이 되어버린다.
이 부분은 친절함보다 먼저 바이트 열 (Byte sequence)을 지켜야 한다.
이중 SHA-256을 적용하기
비트코인의 블록 헤더는 SHA-256을 두 번 통과시킨다.
Node.js라면 표준 crypto 모듈로 작성할 수 있다.
import { createHash } from "node:crypto";
function sha256d(data) {
const once = createHash("sha256").update(data).digest();
...
출력은 이것이다.
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
나왔다.
저 긴 해시가 80바이트의 헤더와 두 번의 SHA-256으로부터 나온다.
여기서 AI에게 "그럼 이 블록을 네트워크에 보내줘"라고 부탁하면, 이야기가 다시 복잡해진다.
블록 0에는 "이전"이 없다
일반적인 블록에는 이전 블록의 해시가 들어간다.
하지만 블록 0에는 이전 블록이 없다. 그래서 이전 블록 해시는 32바이트의 제로 (Zero)가 된다.
0000000000000000000000000000000000000000000000000000000000000000
"이전 블록을 찾아주세요"라고 AI가 말해도, 없는 것을 찾을 수는 없다.
여기서 "제네시스 (Genesis)"라는 이름이 갑자기 종교적으로 느껴지기도 하지만, 구현상으로는 맨 앞에 제로를 배치했을 뿐이다. 이름은 거창하고, 필드는 침묵한다.
넌스는 정말로 채굴되었는가
제네시스 블록의 넌스 (Nonce)는 2083236893이며, 16진수로는 0x7c2b1dac이다.
이 값을 헤더에 넣으면 앞서 말한 해시가 된다.
그렇다면 이것은 일반적인 채굴을 통해 네트워크로 전송된 블록인가?
여기서 AI는 아마 "네"라고 대답하고 싶어질 것이다. 작업 증명 (Proof of Work)이 있고, 넌스가 있으며, 조건을 만족하는 해시가 있다. 겉보기에는 완전히 채굴된 상태다.
하지만 Bitcoin v0.1 소스에는 MineGenesisBlock()이 없다. 빈 블록 데이터베이스로 기동한 노드는 내장된 상수로부터 블록 0을 재구축하고, 기대하는 해시와 일치하는지 확인한다.
여기서 일어나고 있는 것은 일반적인 블록의 수신과는 다르다.
일반적인 블록:
마이너 (Miner)가 만든다 → 네트워크로 보낸다 → 노드가 검증한다
블록 0:
...
AI가 순간적으로 멈추는 포인트는 바로 여기다.
"채굴의 결과"와 "네트워크에 배포된 블록"을 같은 단어로 묶어버리면 구조가 보이지 않게 된다.
타임즈(Times)지의 헤드라인은 어디에 들어있는가
제네시스 블록에는 다음 문자열이 들어있다.
The Times 03/Jan/2009 Chancellor on brink of second bailout for banks
이것은 블록 헤더의 일부가 아니다. 코인베이스 트랜잭션 (Coinbase Transaction) 안에 들어있다.
여기서 "그럼 그 트랜잭션도 JavaScript로 만들어보자"라고 진행하면, 버전(Version), 입력(Input), 출력(Output), 스크립트(Script), 머클 루트(Merkle Root) 계산이 시작된다. 구현(Implementation) 기사로서는 최고지만, 기사의 독자들이 SHA-256 단계 이전에 이탈해 버릴 것이다.
이번에는 헤더(Header) 재현에 집중한다.
그렇더라도 머클 루트(Merkle Root)를 통해 블록 헤더(Block Header)의 해시(Hash)에 영향을 미치고 있다는 점은 짚고 넘어가고 싶다. 내용물을 1바이트만 바꿔도 머클 루트가 바뀌고, 헤더가 바뀌며, 해시도 바뀐다.
블록은 "문장"과 "계산"이 별개로 놓여 있는 듯하면서도, 결국에는 동일한 해시(Hash)로 묶여 있다.
AI에게 리뷰를 시키는 프롬프트 (Prompt)
지금까지의 코드를 AI에게 전달할 때는 질문을 조금 바꾼다.
이 코드를 현대적인 Node.js로서 리뷰해 주세요.
단, 다음 조건을 지켜주세요.
- 비트코인(Bitcoin) 제네시스 블록(Genesis Block)의 헤더 재현이 목적
...
이 조건을 벗어나면, AI는 깔끔한 코드를 반환하면서도 다른 블록을 만들어 버린다.
코드 리뷰에서의 "좋은 설계"와 사료를 정확하게 재현하는 "좋은 설계"는 때때로 상충한다.
5일간의 공백으로 돌아가기
블록 0의 시각은 2009년 1월 3일, 블록 1은 2009년 1월 9일이다.
이 차이를 보면, "5일 동안 제네시스 블록만 채굴되었던 것이 아닐까"라고 상상하게 된다.
하지만 블록 0은 소스에 하드코드(Hard-coded)되어 있으며, 빈 데이터베이스로부터 로컬(Local)에서 재구축된다. 따라서 이 5일을 라이브 체인(Live Chain)상의 경과 시간으로 그대로 읽을 수는 없다.
AI는 날짜를 발견하면 즉시 시계열을 이야기로 만들어 버린다.
2009년 1월 3일, 블록 0.
2009년 1월 9일, 블록 1.
그 사이 5일.
네, 미스터리가 완성되었다.
하지만 구현을 살펴보면, 미스터리의 일부는 "하드코드된 값이 정해진 날"과 "네트워크가 공개적으로 가동된 날"의 차이로 보인다. 남은 의문은 있다. 하지만 날짜 간격만으로 사토시(Satoshi)의 5일을 채울 수는 없다.
요약: AI에게 만들게 하면, 블록 0이 조금 이상해 보인다
이번 코드는 짧다.
- 80바이트의 헤더를 만든다
- SHA-256을 두 번 적용한다
- 표시를 위해 바이트 순서(Byte Order)를 반전시킨다
- 기지의 제네시스 해시(Genesis Hash)와 비교한다
이것만으로 비트코인의 첫 번째 블록을 재현할 수 있다.
다만, 재현할 수 있다는 것과 일반적인 블록과 동일한 방식으로 태어났다는 것은 별개의 문제다.
AI에게 구현을 시키면 코드는 금방 작성할 수 있다. 오히려 무서운 것은 코드가 동작한 뒤에 "이것은 채굴된 블록입니다"라는 설명까지 완성되어 버린다는 점이다.
동작하는 코드가 역사의 설명까지 자동으로 올바르게 해주지는 않는다.
블록 0은 처음부터 그곳에 놓여 있다.
AI에게 코드를 작성하게 한 뒤, 블록 0이 어떻게 구동되는 설계였는지를 읽는다. 그때서야 비로소 "재현할 수 있는 것"과 "네트워크로부터 전달된 것"이 별개의 이야기임을 알게 된다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기