資料結構

Block Structure (區塊結構)

Block Structure Overview

在Block (btcutil/block.go)

// Block defines a bitcoin block that provides easier and more efficient
// manipulation of raw blocks.  It also memoizes hashes for the block and its
// transactions on their first access so subsequent accesses don't have to
// repeat the relatively expensive hashing operations.

type Block struct {
    msgBlock        \*wire.MsgBlock  // Underlying MsgBlock

    serializedBlock \[\]byte          // Serialized bytes for the block

    blockHash       \*chainhash.Hash // Cached block hash

    blockHeight     int32           // Height in the main block chain

    transactions    \[\]\*Tx           // Transactions

    txnsGenerated   bool            // ALL wrapped transactions generated
}

裡面的MsgBlock,

// MsgBlock implements the Message interface and represents a bitcoin
// block message.  It is used to deliver block and transaction information in
// response to a getdata message (MsgGetData) for a given block hash.

type MsgBlock struct {
    Header       BlockHeader
    Transactions \[\]\*MsgTx
}

Block Header

type BlockHeader struct {

    // Version of the block.  This is not the same as the protocol version.
    Version int32

    // Hash of the previous block in the block chain.
    PrevBlock chainhash.Hash

    // Merkle tree reference to hash of all transactions for the block.
    MerkleRoot chainhash.Hash

    // Time the block was created.  This is, unfortunately, encoded as a
    // uint32 on the wire and therefore is limited to 2106.
    Timestamp time.Time

    // Difficulty target for the block.
    Bits uint32        

    // Nonce used to generate the block.
    Nonce uint32

}

<pre><code>

02000000 ........................... Block version: 2

b6ff0b1b1680a2862a30ca44d346d9e8

910d334beb48ca0c0000000000000000 ... Hash of previous block's header

9d10aa52ee949386ca9385695f04ede2

70dda20810decd12bc9b048aaab31471 ... Merkle root

24d95a54 ........................... Unix time: 1415239972

30c31b18 ........................... Target: 0x1bc330 * 256**(0x18-3)

fe9f0864 ........................... Nonce

</code></pre>

裡面有methods:

BlockHash() : 傳回該 block之 double SHA256 (含header) Encode the header and double sha256 everything prior to the number of
transactions.

Transaction Format

結構解說

整體結構如圖:

交易由三個部分組成:

.● Metadata​.

There’s some housekeeping information — the size of the transaction, the number of inputs, and the number of outputs. There’s the hash of the entire transaction which serves as a unique ID for the transaction. That’s what allows us to use hash pointers to reference transactions. Finally there’s a “lock_time” field, which we’ll come back to later.

● Inputs (可能多組)

指向上一個output (區塊hash值+index)

script signature 解鎖

​The transaction inputs form an array, and each input has the same form. An input specifies a previous transaction, so it contains a hash of that transaction, which acts as a hash pointer to it. The input also contains the index of the previous transaction’s outputs that’s being claimed. And then there’s a signature. Remember that we have to sign to show that we actually have the ability to claim those previous transaction outputs.

● Outputs (可能多組)

金額跟script

​The outputs are again an array. Each output has just two fields. They each have a value, and the sum of all the output values has to be less than or equal to the sum of all the input values. If the sum of the output values is less than the sum of the input values, the difference is a transaction fee to the miner who publishes this transaction. And then there’s a funny line that looks like what we want to be the recipient address. Each output is supposed to go to a specific public key, and indeed there is something in that field that looks like it’s the hash of a public key. But there’s also some other stuff that looks like a set of commands. Indeed, this field is a script, and we’ll discuss this presently.

前述Block裡面之MsgBlock,

// MsgBlock implements the Message interface and represents a bitcoin
// block message.  It is used to deliver block and transaction information in
// response to a getdata message (MsgGetData) for a given block hash.

type MsgBlock struct {
    Header       BlockHeader
    Transactions \[\]\*MsgTx
}

從中取得交易資料

<pre><code>

transactions := block.Transactions\(\)

for \_, tx := range transactions {

    err := XXXX...\(tx\)

    if err != nil {
        return err
    }
}

</code></pre>

tx是交易的基本結構

tx (交易結構)

Raw Transaction Format

https://github.com/btcsuite/btcutil/blob/master/tx.go

Tx定義了一筆比特幣的交易,這個結構著重在簡單、運作有效率。同時也會在一開始將資料的 hash值記錄起來以避免額外的hash計算(耗資源)。

type Tx struct {

    msgTx   \*wire.MsgTx     // Underlying MsgTx, the bitcoin wire protocol 

    txHash  \*chainhash.Hash // Cached transaction hash

    txIndex int             // Position within a block or TxIndexUnknown

}

裡面有methods:

MsgTx() : 傳回下層的交易訊息

Hash() : 傳回交易的hash值,如果已有cache就回覆cache值

Index() : 傳回交易在這個區塊裡的index

SetIndex() : 設定交易在區塊裡的index值

NewTx() : 運用下層的 wires.msgTx,傳回一個新的Tx

NewTxFromBytes() : // NewTxFromBytes returns a new instance of a bitcoin transaction given the
serialized bytes. See Tx.

NewTxFromReader() : //NewTxFromReader returns a new instance of a bitcoin transaction given a
Reader to deserialize the transaction. See Tx.

tx 是一個包裝,真正內容在msgTx

<pre><code>

msgTx := tx.MsgTx\(\)

</code></pre>

msgTx

btcd/wire/msgtx.go

<pre><code>

// MsgTx implements the Message interface and represents a bitcoin tx message.

// It is used to deliver transaction information in response to a getdata

// message \(MsgGetData\) for a given transaction.

//

// Use the AddTxIn and AddTxOut functions to build up the list of transaction

// inputs and outputs.

type MsgTx struct {

Version  int32

TxIn     \[\]\*TxIn

TxOut    \[\]\*TxOut

LockTime uint32

}

</code></pre>

裡面很重要的是轉入項(TxIn) 與轉出項(TxOut)

TxIn 的結構

<pre><code>

// TxIn defines a bitcoin transaction input.

type TxIn struct {

    PreviousOutPoint OutPoint

    SignatureScript  \[\]byte

    Sequence         uint32

}

</code></pre>

用OutPoint結構來表示上一個轉出的點,因為上一筆交易的轉出會成為這一筆交易的轉入

<pre><code>

btcd/btcjson/chainsvrwscmds.go

type OutPoint struct {

Hash  string \`json:"hash"\`

Index uint32 \`json:"index"\`

}

是一個hash結構(上一筆交易的地址)加上一個32bit的index

至於SignatureScript是一個unlocking script,要拿來處理交易認證解鎖用的。跟TxOut的PublicKeyScript這個locking script是一對。這個P2PKH的驗證就容後解釋。

</code></pre>

TxOut 的結構

<pre><code>

// TxOut defines a bitcoin transaction output.
type TxOut struct {

    Value    int64

    PkScript \[\]byte

}

</code></pre>

範例

整體看起來像如此:

<pre><code>

btcd/blockchain/fullblocktests/params.go

    Transactions: \[\]\*wire.MsgTx{{

        Version: 1,

        TxIn: \[\]\*wire.TxIn{{

            PreviousOutPoint: wire.OutPoint{

                Hash:  chainhash.Hash{},

                Index: 0xffffffff,

            },

            SignatureScript: fromHex\("04ffff001d010445" +

                "5468652054696d65732030332f4a616e2f" +

                "32303039204368616e63656c6c6f72206f" +

                "6e206272696e6b206f66207365636f6e64" +

                "206261696c6f757420666f72206261686b73"\),

            Sequence: 0xffffffff,

        }},

        TxOut: \[\]\*wire.TxOut{{

            Value: 0,

            PkScript: fromHex\("4104678afdb0fe5548271967f1" +

                "a67130b7105cd6a828e03909a67962e0ea1f" +

                "61deb649f6bc3f4cef38c4f35504e51ec138" +

                "c4f35504e51ec112de5c384df7ba0b8d578a" +

                "4c702b6bf11d5fac"\),

        }},

        LockTime: 0,

    }},

</code></pre>

Message (Protocol Messages)

// messageHeader defines the header structure for all bitcoin protocol messages.

type messageHeader struct {

magic    BitcoinNet // 4 bytes

command  string     // 12 bytes

length   uint32     // 4 bytes

checksum \[4\]byte    // 4 bytes

}

results matching ""

    No results matching ""