비트코인 스크립트(Script)는 UTXO를 만든 출력의 scriptPubKey와, 그 UTXO를 쓰는 입력의 scriptSig 또는 증인(witness) 데이터를 정해진 규칙대로 평가해 최종 조건이 참인지 확인합니다. 전통적인 P2PKH에서는 서명과 공개키를 스택에 넣고, 공개키의 HASH160 값이 출력에 고정된 해시와 같은지 검사합니다. 그다음 OP_CHECKSIG가 현재 거래의 서명 해시와 공개키로 서명을 검증합니다. 마지막 스택 값만 참이면 된다는 흔한 설명에는 P2SH·세그윗·탭루트의 별도 검증 규칙과 정책 플래그라는 조건이 빠져 있습니다.
지출 조건은 이전 출력에 들어 있습니다
비트코인 거래의 입력은 아무 잔액이나 직접 가리키지 않습니다. 이전 거래의 txid와 출력 번호로 UTXO를 참조합니다. 그 출력의 scriptPubKey가 돈을 쓸 조건을 정하고, 새 입력은 scriptSig나 증인 영역에 조건을 채울 데이터와 서명을 담습니다. 검증 노드는 참조된 출력의 금액과 스크립트까지 불러와 거래 전체 맥락에서 평가합니다.
비트코인 개발자 가이드는 스크립트를 상태도 반복문도 없는 포스(Forth) 계열의 스택 언어로 설명합니다. 각 연산 코드(opcode)는 맨 위에서 값을 꺼내 계산하고 결과를 다시 올립니다. 네트워크 전체 상태를 마음대로 읽는 스마트 계약 가상머신과는 다릅니다. 실행의 핵심 맥락은 서명이 묶어 두는 거래 필드와 UTXO 데이터입니다.
비트코인 스크립트는 돈을 보내는 프로그램이 아닙니다. 특정 UTXO를 지금 이 입력이 써도 되는지 가려내는 조건식입니다.
JOBCOIN 해설

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.
- 지출 조건은 이전 출력에 들어 있습니다
비트코인 거래의 입력은 아무 잔액이나 직접 가리키지 않습니다.
- P2PKH 스택을 한 단계씩 따라갑니다
P2PKH 입력은 먼저 서명과 공개키를 스택에 올립니다.
- 서명은 현재 거래에서 고른 부분에 묶입니다
OP_CHECKSIG가 검증하는 메시지는 화면에 보이는 txid 문자열이 아닙니다.
설명을 위한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.
P2PKH 스택을 한 단계씩 따라갑니다
P2PKH 입력은 먼저 서명과 공개키를 스택에 올립니다. OP_DUP가 공개키를 복제하면 OP_HASH160이 복제본에 SHA-256을 적용한 뒤 다시 RIPEMD-160을 적용합니다. 이어서 출력에 적혀 있던 기대 공개키 해시가 올라가고, OP_EQUALVERIFY가 두 해시가 같은지 확인합니다. 다르면 그 자리에서 실패합니다.
해시가 같으면 스택에는 서명과 공개키가 남습니다. OP_CHECKSIG는 서명 끝에 붙은 서명 해시 유형과 거래 데이터로 서명 대상 요약값을 만들고, secp256k1 공개키로 검증합니다. 성공하면 참이, 실패하면 거짓이 남습니다. 서명 바이트가 올바른지만 보는 게 아니라 거래의 어느 부분에 서명했는지도 중요합니다.
| 단계 | 스택 동작 | 실패 조건 |
|---|---|---|
| 데이터 올리기 | 서명·공개키 추가 | 인코딩 규칙 위반 |
| OP_DUP | 공개키 복제 | 스택 부족 |
| OP_HASH160 | 공개키 해시 계산 | 유효한 데이터 필요 |
| OP_EQUALVERIFY | 기대 해시와 비교 | 해시 불일치 |
| OP_CHECKSIG | 거래 서명 검증 | 서명·요약값 불일치 |
서명은 현재 거래에서 고른 부분에 묶입니다
OP_CHECKSIG가 검증하는 메시지는 화면에 보이는 txid 문자열이 아닙니다. 입력별 scriptCode와 금액, 버전, 입력 목록, 출력 목록, 잠금 시간 가운데 서명 해시 규칙이 고른 부분을 직렬화해 해시한 값입니다. 레거시, 세그윗 v0, 탭루트는 서명 해시를 만드는 규칙이 서로 다릅니다.
그래서 같은 DER 서명을 다른 입력이나 금액에 그대로 붙이면 보통은 유효하지 않습니다. SIGHASH_NONE·SINGLE·ANYONECANPAY 같은 플래그는 서명이 묶는 범위를 바꿉니다. 지갑은 서명자가 어디까지 변경을 허용했는지 분명히 보여 줘야 합니다. OP_CHECKSIG가 통과했다고 해서 받는 주소에 대한 의도까지 안전했다는 뜻도 아닙니다.
- 참조 UTXO의 txid·vout을 확인합니다.
- scriptPubKey 유형과 증인 버전을 가려냅니다.
- 입력 스택 항목과 인코딩을 확인합니다.
- 서명 해시 유형과 서명 범위를 확인합니다.
- 합의 결과와 정책 결과를 따로 기록합니다.
P2SH와 세그윗은 검증 단계를 하나 더 둡니다
P2SH 출력은 redeemScript의 HASH160 값을 잠가 둡니다. 입력이 내놓은 redeemScript 전체가 약속된 해시와 같은지 먼저 검사하고, 그 스크립트를 실제 조건으로 다시 실행합니다. P2WPKH는 scriptSig 대신 증인 영역에 서명과 공개키를 두고, 20바이트 증인 프로그램을 P2PKH와 비슷한 scriptCode로 해석합니다.
탭루트의 키 경로는 슈노르(Schnorr) 서명 한 개를 출력 키로 검증합니다. 스크립트 경로는 탭스크립트와 제어 블록으로 약속된 머클 루트를 다시 만들어 냅니다. 모든 주소 형식을 ‘scriptSig와 scriptPubKey를 그냥 이어 붙인다’고 설명하면 최신 증인 규칙을 놓치게 됩니다. 출력 유형부터 가려내야 합니다.
유효하다고 해서 중계되는 것은 아닙니다
합의 규칙을 만족하면 블록 안에서는 유효할 수 있습니다. 하지만 노드마다 멤풀(mempool)이 IsStandard 검사와 수수료·크기 정책에 따라 그 거래를 중계하지 않을 수 있습니다. 개발자 가이드도 비표준 거래가 기본 설정 노드에서 전달되지 않더라도, 채굴자가 블록에 넣으면 합의 검증은 통과할 수 있다고 설명합니다.
디버깅할 때는 스크립트 오류, 합의 플래그, 멤풀 거부 사유를 나눠 봅니다. 회귀 테스트망(regtest)에서 통과한 맞춤 스크립트가 공개 네트워크에서도 저절로 퍼진다고 가정하면 안 됩니다. 실제로 배포하기 전에는 목표 Bitcoin Core 버전의 testmempoolaccept 결과와 원시 거래 해독 결과를 함께 보관하세요.
자주 묻는 질문
P2PKH는 scriptSig와 scriptPubKey를 항상 단순 연결하나요?
전통적인 P2PKH를 설명할 때는 쓸모 있는 그림입니다. 다만 P2SH·세그윗·탭루트에는 별도 평가 규칙이 있으니 출력 유형부터 확인해야 합니다.
OP_CHECKSIG는 txid에 서명하나요?
아닙니다. 해당 서명 해시 알고리즘이 고른 거래 필드를 직렬화해 만든 요약값을 검증합니다.
Script가 참이면 모든 노드가 mempool에 받아 주나요?
아닙니다. 합의상 유효한지와 표준 중계·멤풀 정책을 통과하는지는 별개 문제입니다.



