ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 비트코인 트랜잭션 데이터 구조
    Cryptography 2021. 10. 15. 17:09
    반응형

    트랜잭션은 비트코인 에코시스템의 핵심입니다. 트랜잭션은 요구사항에 따라 간단하게 비트코인을 특정 주소로 보내는 것일 수도 있고, 조금 더 복잡한 형태일 수도 있습니다. 

     

    각 트랜잭션은 최소한 한 개 이상의 인풋과 아웃풋으로 구성되어 있습니다. 인풋은 이전 트랜잭션에서 생성되어 '보내지는' 코인이고, 아웃풋 생성되는 코인이라고 볼 수 있습니다. 만약 한 트랜잭션이 새로운 코인을 만든다면, 인풋이 존재하지 않고, 서명(signature)도 필요 없습니다. 만약 트랜잭션이 코인을 다른 비트코인 주소로 보내려면, 송신자는 트랜잭션에 송신사의 비밀키(private key)로 서명을 하여야 합니다. 이러한 경우 코인의 기원을 보여주기 위해서 이전 트랜잭션에 대한 레퍼런스도 필요합니다.

     

    그렇기에 코인은 '지불되지 않은(unspent)' 트랜잭션 아웃풋이며 사토시(Satoshis) 단위로 표현됩니다. 

     

    이번 글에서는 트랜잭션의 데이터 구조를 자세하게 살펴보겠습니다:

     

    • Overview

    Overview

    트랜잭션의 데이터 구조는 아래 테이블과 같습니다:

     

    필드 크기 설명
    Version Number 4 bytes 트랜잭션 처리를 위해 채굴자와 노드들이 사용할 규칙을 명시합니다. 2가지 버젼(1, 2)의 트랜잭션이 존재합니다.
    Input counter 1-9 bytes 트랜잭션에 포함된 인풋의 갯수(양수)
    List of inputs 변동 각 인풋은 몇 개의 필드로 구성되어 있습니다:

    - 이전 트랜잭션 해시값
    - 이전 트랜잭션의 인덱스 값
    - 트랜잭션 스크립트 길이
    - 트랜잭션 스크립트
    - 시퀀스 넘버

    한 개의 블록(block) 안에 있는 첫 트랜잭션은 코인베이스(coinbase)라고 불립니다. 이 부분에 한 개 이상의 인풋이 명시되며, 어떤 비트코인이 지불에 사용될지 나타냅니다.
    Output counter 1-9 bytes 트랜잭션에 포함된 아웃풋의 갯수(양수)
    List of outputs 변동 해당 트랜잭션에 포함된 아웃풋들입니다. 비트코인의 수신자(들)을 나타냅니다.
    Lock time 4 bytes 트랜잭션이 유효한 최소 일시를 기록합니다. Unix 타임스탬프(5,000,000 보다 클 때), 블록 높이(5,000,000 보다 작을 때)를 나타냅니다.

     

    샘플 트랜잭션은 아래와 같습니다 [2]:

     

    {
        "txid" : "c80b343d2ce2b5d829c2de9854c7c8d423c0e33bda264c4013\
                  8d834aab4c0638",
        "hash" : "c80b343d2ce2b5d829c2de9854c7c8d423c0e33bda264c40138d834aab4c0638",
        "size" : 85,
        "vsize" : 85,
        "version" : 1,
        "locktime" : 0,
        "vin" : [
            {
                "txid" : "3f4fa19803dec4d6a84fae3821da7ac7577080ef75\
                          451294e71f9b20e0ab1e7b",
                "vout" : 0,
                "scriptSig" : {
                    "asm" : "",
                    "hex" : ""
                },
                "sequence" : 4294967295
            }
        ],
        "vout" : [
            {
                "value" : 49.99990000,
                "n" : 0,
                "scriptPubKey" : {
                    "asm" : "OP_DUP OP_HASH160 cbc20a7664f2f69e5355a\
                             a427045bc15e7c6c772 OP_EQUALVERIFY OP_CHECKSIG",
                    "hex" : "76a914cbc20a7664f2f69e5355aa427045bc15e\
                             7c6c77288ac",
                    "reqSigs" : 1,
                    "type" : "pubkeyhash",
                    "addresses" : [
                        "mz6KvC4aoUeo6wSxtiVQTo7FDwPnkp6URG"
                    ]
                }
            }
        ]
    }

     

    메타데이터

    트랜잭션의 이 부분에는 트랜잭션 크기, 인풋 갯수, 아웃풋 갯수, 트랜잭션 해시값, locktime 필드 등이 포함됩니다. 모든 트랜잭션은 버젼 넘버를 나타내는 접두사를 가집니다. 위 예시에서 size, version, locktime으로 표현되어 있습니다.

     

    인풋

    일반적으로 각 인풋은 이전 트랜잭션의 아웃풋을 지불합니다. 각 아웃풋은 소비되기 전까지 '미지불 트랜잭션 아웃풋 - UTXO(Unspent Transaction Output)'입니다. UTXO는 그렇기에 새로운 트랜잭션에 인풋으로 지불될 수 있습니다.

     

    트랜잭션 인풋 데이터 구조는 아래와 같습니다:

     

    필드 크기 설명
    Transaction hash 32 bytes UTXO가 있는 이전 트랜잭션의 해시값
    Output index 4 bytes 이전 트랜잭션 아웃풋(UTXO 등)의 인덱스 
    Script length 1-9 bytes unlocking 스크립트의 크기
    Unlocking script 변동 locking  스크립트의 요구사항을 만족하는 인풋 스크립트(ScriptSig)
    Sequence number 4 bytes 보통 Disabled되어 있거나 lock time을 포함하고 있음. Disbled는 0xFFFFFFFF로 표기.

     

    아웃풋

    아웃풋은 3개의 필드를 가지며, 비트코인 송신을 위한 로직(instruction)을 포함합니다. 

     

    아웃풋 구조는 아래와 같습니다:

    필드 크기 설명
    Value 8 bytes 전송될 사토시 갯수(양수)
    Script size 1-9 bytes locking 스크립트 크기
    Locking script 변동 아웃풋 스크립트(ScriptPubKey)

     

    검증(Verification)

    검증은 비트코인의 (아래에서 설명할) 스크립팅 언어를 사용해 수행됩니다. 

     

    스크립트 언어

    비트코인은 'Script'라고 불리는 간단한 스택 기반의 언어를 사용하여 어떻게 비트코인이 지불되고 전송될지 기술합니다. Script 언어는 Turing complete하지 않으며 비트코인 네트워크 상에서 장시간 실행되거나 행이 걸리는 것을 방지하기 위해 loop이 존재하지 않습니다.

    이 언어는 4세대 프로그래밍 언어와 같은 문법을 가지고 있으며 모든 피연산자 뒤에 연산자가 존재하는 reverse polish 노테이션을 사용합니다. LIFO 스택을 사용해, 왼쪽부터 오른쪽으로 수행되게 됩니다. 

     

    Script는 요소(element)와 연산(operation)이라는 2개의 컴포넌트로 구성되어 있습니다. Script는 다양한 연산(opcodes) 또는 지시를 사용하여 연산을 정의합니다. 요소들은 단순히 디지털 서명과 같은 데이터를 나타냅니다. Opcodes는 words, commands, functions으로도 알려져 있는데요. 비트코인 노드 소프트웨어의 초기 버젼은 이후 발견된 버그로 인해 사용되지 않은 몇 가지 opcodes들을 포함하고 있습니다. 

     

    scripting opcodes의 몇 가지 카테고리로는 상수들, flow control, 스택, bitwise logic, splice, arithmetic, cryptography, 그리고 lock time이 존재합니다. 

     

    트랜잭션 스크립트는 ScriptSig와 ScriptPubKey를 통해 검증 및 수행됩니다. ScriptSig는 unlocking 스크립트인 반면, ScriptPubKey는 locking 스크립트입니다:

     

    • ScriptSig: 트랜잭션을 unlock하고자 하는 사용자가 제공합니다
    • ScriptPubKey: 트랜잭션 아웃풋의 일부로 아웃풋을 지불하기 위해 이행되어야 할 조건을 명시합니다

     

    흔하게 쓰이는 Opcodes

    컴퓨터 내에서, opcode는 특정 연산을 수행하기 위한 지시어입니다. 예로, ADD는 opcode로 Intel CPU와 다양한 아키텍쳐에서 정수 더하기 연산을 위해 사용됩니다. 유사하게, 비트코인의 디자인에 있어서 opcodes는 비트코인 트랜잭션 검증을 위해 몇 가지 연산을 수행하는 기 위해 도입되었습니다. 

     

     

    비트코인에서 많이 사용되는 opcodes는 아래와 같습니다:

     

    Opcode 설명
    OP_CHECKSIG 공개키와 서명을 받아서 트랜잭션의 해시의 서명을 검증합니다. 맞는다면 TRUE가 스택에 push되고, 아니라면 FALSE가 push됩니다.
    OP_EQUAL 인풋들이 정확히 같으면 1 아니면 0을 리턴
    OP_DUP 스택의 최상위 아이템을 복사하여 만듬
    OP_HASH160 인풋을 처음에는 SHA-256으로, 그 다음 RIPEMD-160으로 2번 해시
    OP_VERIFY 스택의 최상위 값이 true가 아니면 트랜잭션을 유효하지 않은 것으로 마킹
    OP_EQUALVERIFY OP_EQUAL과 동일하나, 이후 OP_VERIFY를 수행함
    OP_CHECKMULTISIG 첫 서명을 받아서 매칭되는 키가 발견될 때까지 각 공개키와 비교를 진행합니다. 모든 서명들이 체크될 때까지 반복하는데요. 만약 모든 서명들이 유효한 것으로 판명되면 결과로 1을 리턴하고 아니라면 0을 리턴합니다.
    OP_HASH256 인풋은 SHA-256으로 2번 해시됩니다.
    OP_MAX 2개 인풋 중 큰 값을 리턴합니다.

     

     

     

    Reference

    [1] Mastering Blockchain

    [2] https://developer.bitcoin.org/examples/transactions.html

    반응형
Kaden Sungbin Cho