開源 Bitcoin P2P電子貨幣系統背後的技術(二)

轉載:http://www.showmuch.com/article/article_117.html

Bitcoin 電子貨幣系統的核心功能是面對面(點對點)支付,就像真實貨幣一樣,無需中間人,幾乎不需要交易費。它背後的技術實現是很巧妙的通過將造幣(Mint),交易(transaction,這裏提到的交易都是特指的支付),交易驗證(transaction verifiction)交織在一起,形成一個完美的圓。所以要想把它的機理理解清楚,就必須同時理解bitcoin的電子貨幣,交易,造幣的確切含義。

首先從電子貨幣談起。

電子貨幣和交易單(Transaction)

Bitcoin電子貨幣解決的是:

  1. 任意造幣的問題:通過“挖礦”機制保證了不能任意造幣。
  2. 重複花錢的問題(Double-Spending):利用P2P網絡,通過HashCash的機制。

事實上Bitcoin系統中不存在獨立的電子貨幣,貨幣值是依附於交易單存在的,所以在bitcoin中的電子貨幣的實質就是交易單,確切的說是貨幣交易(Transactions)的 數字簽名鏈,它的數字簽名算法使用的是ECDSA(橢圓曲線數字簽名算法 secp256k1曲線)進行簽名的。
交易單的數據如下:

In:
Previous tx: f5d8ee39a430901c91a5917b9f2dc19d6d1a0e9cea205b009ca73dd0
4470b9a6
Index: 0
scriptSig: 304502206e21798a42fae0e854281abd38bacd1aeed3ee3738d9e1446
618c4571d1090db022100e2ac980643b0b82c0e88ffdfec6b64e3e6ba35e7ba5fd
d7d5d6cc8d25c6b241501

Out:
Value: 5000000000
scriptPubKey: OP_DUP OP_HASH160 404371705fa9bd789a2fcd52d2c580b65d35
549d OP_EQUALVERIFY OP_CHECKSIG

交易單記錄的是本次交易的收入來源(in)和支出(out)。當你支出(給)一筆錢的時候,首先在交易單中就要描述清楚你要支出(out)的錢的收入來源(in),然後在支出(out)項中,指明要支出的金額,以及通過腳本的形式寫明接收者的公鑰,然後用自己的私鑰簽名(scriptSig)認可該筆交易,最後將交易單廣播到網絡。

收入來源(in):

  • Previous tx: 爲收入來源交易單的散列值,也就是待支付的錢是誰給你的,經常會有多個收入來源被列在交易單中
  • index: 指明是收入來源交易單中具體哪一個out,也就是Previous tx交易單中的out索引值(因爲out也可以有多個)。
  • scriptSig: 擁有者對該交易的ECDSA簽名認可。

接收對象(out):

  • Value: 發送的幣值,以Satoshi 爲單位,1BTC = 100,000,000 Satoshi
  • scriptPubKey: 接收方的公鑰腳本。

in與out的關係:

  • 每一筆交易,out的總額應該等於in的總額。但是,在這個交易單裏,只會有out的Value,沒有in的Value,而是通過in的Pervious與index,追溯到上一個交易單的某一個out,獲得Value。
  • 一次send bitcoin,剩下的錢,應該out給自己,否則這個錢就丟了。

情況列舉:

  • 我有10個BTC,是某一次交易獲得的,我要送給朋友A,10個BTC。這時候,有一個in,一個out。
  • 我有10個BTC,是某一次交易獲得的,我要送給朋友A,5個BTC,這時候,有一個in,兩個out,一個指向朋友5個BTC,一個指向我自己,得到剩下的5個BTC。
  • 我有10個BTC,是以前的兩次交易獲得的,我要送給朋友A,10個BTC,這時候,有兩個in,一個out。
  • 我有10個BTC,是以前的兩次交易獲得的,其中一次獲得了6個BTC,另一次獲得了4個BTC,我要送給我的朋友7個BTC,這時候,有兩個in,兩個out。
  • // An input of a transaction.  It contains the location of the previous
    // transaction's output that it claims and a signature that matches the
    // output's public key.
    //
    class CTxIn
    {
    public:
        COutPoint prevout;
        CScript scriptSig;
        unsigned int nSequence;
        ....
    }
     
    //
    // An output of a transaction.  It contains the public key that the next input
    // must be able to sign with to claim it.
    //
    class CTxOut
    {
    public:
        int64 nValue;
        CScript scriptPubKey;
        ....
    }
     
    //
    // The basic transaction that is broadcasted on the network and contained in
    // blocks.  A transaction can contain multiple inputs and outputs.
    //
    class CTransaction
    {
    public:
        int nVersion;
        std::vector<CTxIn> vin;
        std::vector<CTxOut> vout;
        unsigned int nLockTime;
     
        ....
     
  • 每一筆交易單驗證追查到最後,第一筆總是“挖礦”所得,這被稱爲coinbase。
    如果是第一次“挖礦”所得,電子貨幣的內容用JSON格式表示如下:
  • {
      "hash":"b3141455cb397e42665b90b3726c4770fd36101715618718111403bc780ceaa2",
      "ver":1,
      "vin_sz":1,
      "vout_sz":1,
      "lock_time":0,
      "size":135,
      "in":[
        {
          "prev_out":{
            "hash":"0000000000000000000000000000000000000000000000000000000000000000",
            "n":4294967295
          },
          "coinbase":"042194261a02f200"
        }
      ],
      "out":[
        {
          "value":"50.01000000",
          "scriptPubKey":"0452d1a02ffeacfc0c78fcf2ceeaf04d5416c15af1c65da13d9cdaa56844c825c1aa2f540e9439bf38a43419002d8441eea627cb56d6ed51e7848da5c3f6eee6ec OP_CHECKSIG"
        }
      ]
    }
     每一筆交易都會向整個P2P網絡廣播該貨幣的交易記錄。通過投票機制,來決定該支付交易是否正常。如節點認爲該交易記錄是正常的那麼就通過CPU計算POW(Proof-of-Work),然後廣播,其它節點收到這個POW可以繼續投票,形成Block 鏈(見挖礦)。如果節點收到不一致的兩個交易記錄,那麼只信任鏈最長的。如果一筆Bitcoin被支出兩次的情況廣播出來,那麼某些節點將先看到它第一次發生的支付交易,其他節點則看到的是它第二次發生的支付交易。究竟是哪一個支付交易“贏”了,則是由恰好創建了下一個block的那個節點來決定 —— 無論是哪個節點找到了“小的散列值”, 它的block中包含的那個支付交易被判斷爲有效的,其他的支付交易被視爲無效。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章