미리 알아야 할 내용들
트랜잭션 기본 규칙
이번 글에서는 비트코인 트랜잭션의 기본 규칙에 대해 알아보겠습니다. 이를 위해 가장 먼저 비트코인 피자 거래로 유명한 거래의 이어지는 트랜잭션의 데이터를 불러오겠습니다.
위 사이트는 비트코인 트랜잭션 기록을 볼 수 있는 사이트로, 위 페이지에 공개되어 있는 비트코인의 피자 거래에서 이어지는 다음 트랜잭션에 대한 정보는 다음과 같습니다.
트랜잭션 해시: cca7507897abc89628f450e8b1e0c6fca4ec3f7b34cccf55f3f531c659ff4d79
트랜잭션 데이터: 01000000018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1000000008b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabbffffffff0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac00000000
위 트랜잭션 데이터에는 트랜잭션 버전과 잠금 스크립트, 해제 스크립트 등 이전에 알아봤던 내용들이 포함되어 있습니다. 지금부터는 본격적으로 위 트랜잭션이 어떤 방식으로 구성되어 있는지에 대해 알아보겠습니다.
트랜잭션 전체 구성
비트코인의 기본 트랜잭션은 크게 네 부분으로 구성되어 있습니다. 먼저 비트코인 트랜잭션의 첫 4바이트(16진수 8자리)는 비트코인 트랜잭션의 버전입니다.
트랜잭션 버전: 01000000
두 번째 등장하는 것은 트랜잭션의 입력입니다.
트랜잭션 입력: 018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1000000008b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabbffffffff
세 번째로 오는 것은 출력입니다.
트랜잭션 출력: 0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac
마지막으로 오는 것은 록 타임입니다. 록 타임은 생성된 비트코인 트랜잭션이 블록에 포함되지 않도록 정한 시간입니다. 즉, 록 타임이 지난 이후에 트랜잭션이 블록에 포함되도록 설정할 수 있습니다. 트랜잭션 맨 뒤 4바이트가 록 타임입니다.
록 타임: 00000000
위 내용을 정리하면 다음과 같습니다.
버전: 01000000
입력: 018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1000000008b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabbffffffff
출력: 0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac
록 타임: 00000000
트랜잭션 입력
전체 입력: 018dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1000000008b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabbffffffff
비트코인 트랜잭션 입력은 크게 다음과 같이 구성되어 있습니다.
입력 개수(가변 길이 정수): 01
이전 트랜잭션 해시(32바이트, 64자리, 리틀 엔디안): 8dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1
이전 트랜잭션의 출력 번호(4바이트, 8자리, 리틀 엔디안): 00000000
해제 스크립트: 8b4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb
시퀀스: ffffffff
가장 먼저 등장하는 입력 개수는 가변 길이 정수 형식으로 된 값으로, 들어온 입력의 총개수를 표시합니다. 여기서 가변 길이 정수란 정수의 길이에 따라 변하는 값으로, 252까지의 값은 1바이트의 16 진수로, 그 이상의 값은 범위마다 다른 크기의 리틀 엔디안으로 표시합니다.
두 번째로 등장하는 값인 이전 트랜잭션의 해시 값은 이번 트랜잭션에서 입력으로 사용될 이전 출력 값이 포함된 트랜잭션의 해시값입니다.
세 번째로 등장하는 값인 이전 트랜잭션의 출력 번호는 이 트랜잭션에서 입력으로 사용하고자 하는 이전 트랜잭션의 출력 번호를 말합니다. 예를 들어 이전 트랜잭션에 두 개의 출력인 출력0과 출력1가 존재하며, 이 중 출력1을 이번 트랜잭션의 입력으로 사용하고자 한다면 이 번호를 트랜잭션에 포함시킵니다.
네 번째로 등장하는 값인 해제 스크립트는 지금까지 알아봤던 해제 스크립트입니다.
마지막으로 등장하는 시퀀스는 트랜잭션의 록 타임을 위해 존재하는 값으로, 록 타임에 해당하는 시간이 지날 때까지의 트랜잭션을 정산하기 위해 존재하는 값입니다. 'ffffffff'로 설정하면 록타임 값이 무시됩니다.
정리하면 위 트랜잭션의 입력은 한 개이며(01), 이전 트랜잭션 해시(8dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1)에서 출력 0(00000000)을 이용하고, 록 타임은 사용하지 않는(ffffffff) 입력입니다.
해제 스크립트
트랜잭션의 입력은 이전 트랜잭션 출력의 잠금 스크립트에 해당하는 해제 스크립트를 가지고 있습니다. 이러한 해제 스크립트는 크게 다음과 같이 구성되어있습니다.
해제 스크립트 길이(가변 길이 정수): 8b
해제 스크립트: 4830450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e0141042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb
해제 스크립트 길이는 해제 스크립트의 총길이입니다. 입력 개수처럼 가변 길이 정수를 사용합니다. 여기에서는 8b이므로 10진수로 변환하여 139(바이트)입니다. 해제 스크립트의 전체 길이를 알게 되었으므로 본격적으로 139바이트(16진수 278자리)의 해제 스크립트를 하나씩 읽어오겠습니다.
가장 먼저 1바이트를 읽어오겠습니다. 그 결괏값은 16진수 '48'입니다. 10진수로는 72입니다. 비트코인 opcode의 OP_0을 제외한 모든 값은 16진수 '4c'(OP_PUSHDATA1) 부터 시작합니다. 따라서 16진수 48은 opcode가 아닌 이후에 읽어 들여야 할 데이터의 길이임을 알 수 있습니다. 주어진 값대로 72바이트를 읽어오겠습니다.
읽어온 값: 30450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e01
이후 다시 1바이트를 읽습니다. 읽어 들인 값은 16진수 '41', 10진수 65입니다. 이전과 마찬가지로 16진수 값이 '51'보다 작으므로 이어지는 65바이트 데이터를 읽어 들입니다.
읽어온 값: 042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb
모든 해제 스크립트의 값을 읽어 들였습니다. 이제 읽어온 값들을 살펴보겠습니다. 먼저 어떤 방식의 해제 스크립트가 사용되었는지 알기 위해서는 이전 트랜잭션의 잠금 스크립트가 필요합니다. 이미 이전 트랜잭션의 해시값을 알고 있으므로 이전 트랜잭션의 잠금 스크립트도 알 수 있습니다. 이전 트랜잭션의 해시값은 리틀 엔디안 값이므로 뒤에서부터 1바이트(2자리)씩 불러옵니다.
이전 트랜잭션 해시(리틀 엔디안): 8dd4f5fbd5e980fc02f35c6ce145935b11e284605bf599a13c6d415db55d07a1
이전 트랜잭션 해시(빅 엔디안): a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d
이전 트랜잭션에 대한 정보는 아래 페이지에서 확인할 수 있습니다.
해당 트랜잭션의 잠금 스크립트를 확인해보면 다음과 같습니다.
[OP_DUP] [OP_HASH160] <46af3fb481837fadbb421727f9959c2d32a36829> [OP_EQUALVERIFY] [OP_CHECKSIG]
결론적으로 해당 잠금 스크립트는 P2PKH 스크립트임을 알 수 있습니다. 즉 해제 스크립트는 공개키와 서명으로 구성되어 있음을 알 수 있습니다.
읽어온 데이터 1(서명, 30으로 시작하는 DER 형식 서명임을 알 수 있습니다): 30450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e01
읽어온 데이터 2(공개키, 04로 시작하는 비압축 형식 공개키임을 알 수 있습니다): 042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb
트랜잭션 출력
이어서 트랜잭션의 출력을 살펴보겠습니다. 트랜잭션의 출력은 트랜잭션 입력과 비슷하게 구성되어 있습니다.
전체 출력: 0200719a81860000001976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac009f0a5362000000434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac
출력 개수(가변 길이 정수): 02
출력0 비트코인 개수(리틀 엔디안, 8바이트, 16자리): 00719a8186000000
출력0 잠금 스크립트: 1976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac
출력1 비트코인 개수(리틀 엔디안, 8바이트, 16자리): 009f0a5362000000
출력1 잠금 스크립트: 434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac
가장 먼저 전체 출력 개수가 온 뒤, 각 출력마다의 전송할 비트코인 개수와 해제 스크립트가 이어지는 구조로 되어있습니다. 전체 출력 개수는 가변 길이 정수형이며, 전송할 비트코인 개수의 경우 리틀 엔디안 값이기 때문에 뒤에서부터 1바이트씩 읽어와 10진수로 변환해야 합니다.
잠금 스크립트
트랜잭션 출력은 잠금 스크립트를 포함하고 있습니다. 예제의 피자 거래의 경우 두 개의 출력이 존재하기 때문에 두 개의 잠금 스크립트가 존재합니다.
출력0의 잠금 스크립트를 먼저 분석해보겠습니다. 해제 스크립트와 마찬가지로 가장 먼저 오는 값은 전체 잠금 스크립트의 길이입니다.
출력0 전체 잠금 스크립트: 1976a914df1bd49a6c9e34dfa8631f2c54cf39986027501b88ac
출력0 잠금 스크립트 길이(가변 길이 정수): 19
그다음 이어지는 한 바이트(16진수 2자리)를 불러옵니다.
읽어온 값: 76
해당 값은 16진수 4b보다 큰 값이기 때문에 opcode입니다. 읽어온 값에 해당하는 opcode는 다음과 같습니다.
opcode: [OP_DUP]
같은 방식으로 다음 값을 읽습니다.
읽어온 값: a9
opcode: [OP_HASH160]
읽어온 값: 14
위 값은 opcode가 아니기 때문에 이어지는 0x14바이트(20바이트)의 값을 읽어옵니다.
읽어온 값: df1bd49a6c9e34dfa8631f2c54cf39986027501b
이어서 다음 값을 읽습니다.
읽어온 값: 88
opcode: [OP_EQUALVERIFY]
읽어온 값: ac
opcode: [OP_CHECKSIG]
읽어온 값을 모두 정리하면 다음과 같습니다.
[OP_DUP] [OP_HASH160] <df1bd49a6c9e34dfa8631f2c54cf39986027501b88> [OP_EQUALVERIFY] [OP_CHECKSIG]
결론적으로 출력0의 잠금 스크립트는 P2PKH 스크립트임을 알 수 있습니다.
이어서 출력1의 잠금 스크립트를 분석해보겠습니다. 출력 0과 같은 방식으로 값을 불러오겠습니다.
출력1 전체 잠금 스크립트: 434104cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455dac
출력1 잠금 스크립트 길이(가변 길이 정수): 43
읽어온 값: 41
읽어온 값: 04cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455d
읽어온 값: ac
opcode: [OP_CHECKSIG]
읽어온 값을 모두 정리하면 다음과 같습니다.
<04cd5e9726e6afeae357b1806be25a4c3d3811775835d235417ea746b7db9eeab33cf01674b944c64561ce3388fa1abd0fa88b06c44ce81e2234aa70fe578d455d> [OP_CHECKSIG]
결론적으로 출력1의 잠금 스크립트는 P2PK 스크립트임을 알 수 있습니다.
지금까지 비트코인 트랜잭션의 기본 규칙에 대해 알아봤습니다. 감사합니다.
이어지는 글들
'비트코인 > 비트코인 구조' 카테고리의 다른 글
[비트코인 구조] 비트코인 테스트넷 Faucet (0) | 2022.10.24 |
---|---|
[비트코인 구조] 가변 길이 정수(VarInt) (0) | 2022.10.21 |
[비트코인 구조] 세그윗(Segwit), Bech32 주소 (0) | 2022.09.23 |
[비트코인 구조] P2SH (0) | 2022.09.16 |
[비트코인 구조] P2PKH (0) | 2022.09.12 |