精通比特幣(二)

交易

{
"version": 1,
"locktime": 0,
"vin": [
  {
    "txid":"7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
    "vout": 0,
    "scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
    "sequence": 4294967295
  }
],
"vout": [
  {
    "value": 0.01500000,
    "scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG"
  },
  {
    "value": 0.08450000,
    "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
  }
]
}

// - 7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18交易的vout
"vout": [
 {
   "value": 0.10000000,
   "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG"
 }
]
  • 交易截圖(代碼中的正在進行的交易)


    iShot2022-04-06 18.04.52.png
  • 交易截圖(代碼中的 7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18指定的交易)


    iShot2022-04-06 18.05.26.png

    上邊的input中的address 表示的是input中的交易中付款方的地址, output中的address 表示的是output中的交易中收款方的地址

  • 交易的輸入輸出

    • UTXO(unspent transaction outputs, 未花費的交易輸出) : 所有UTXO的集合被稱為UTXO集钢颂,目前有數(shù)百萬個UTXO甘改。 當(dāng)新的UTXO被創(chuàng)建主胧,UTXO集就會變大煞烫,當(dāng)UTXO被消耗時,UTXO集會隨著縮小国撵。每一個交易都代表UTXO集的變化(狀態(tài)轉(zhuǎn)換)
    • 用戶收到比特幣是指的錢包檢測到可用的UTXO, 通過錢包所控制的密鑰我們可以花費這些UTXO, 所以余額指的是所有UTXO的總和(可能分布在數(shù)百個交易和區(qū)塊中).
    • 一個用戶的比特幣余額: 比特幣錢包掃描區(qū)塊鏈并聚集所有屬于該用戶的UTXO來計算用戶的余額, 大多數(shù)錢包維護一個數(shù)據(jù)庫或使用數(shù)據(jù)庫服務(wù)來存儲所有UTXO的快速參考集妈嘹,這些UTXO由用戶所有的密鑰來控制花費行為。
    • 一個UTXO只能在一次交易中作為一個整體被消耗凡恍。這樣的話,由于UTXO(或交易輸出)的不可分割特性怔球,大部分比特幣交易都會產(chǎn)生找零.
    • 每一筆交易都會消耗之前被記錄的UTXO, 并創(chuàng)建新的UTXO以備未來的交易的消耗, 比特幣的交易就是在交易鏈中消耗和創(chuàng)建UTXO, 一筆比特幣的交易通過使用所有者的簽名來解鎖UTXO, 通過使用新的所有者的比特幣地址來鎖定并創(chuàng)建UTXO;
  • 交易輸出

    • 每一筆比特幣交易都會創(chuàng)建輸出,并被比特幣賬簿記錄下來(OP_RETURN除外), 幾乎所有的輸出都能創(chuàng)造一定數(shù)量的可用于支付的比特幣.
    • 交易的輸出包含
      • 一定數(shù)量的比特幣(value)
      • 確定花費這些輸出所需的條件(scriptPubKey)
    • 序列化和反序列化
      • 序列化
        • 將對象類型轉(zhuǎn)換成字節(jié)流的過程
      • 反序列化
        • 將字節(jié)流轉(zhuǎn)換成對象類型的過程
  • 交易輸入

    • 將UTXO標(biāo)記為被消費并通過解鎖腳本提供所有權(quán)證明.
    • 當(dāng)構(gòu)建一個交易的時候, 錢包通過控制地址對應(yīng)的UTXO中選擇足夠的價值來執(zhí)行被請求的付款(有時一個UTXO就足夠, 有時需要很多個), 對于將用于進行此次付款的每個UTXO, 錢包都會創(chuàng)建一個指向UTXO的輸入, 并使用解鎖腳本解鎖它.
    • 交易的輸出包含
      • UTXO指針: 一個交易ID嚼酝,引用包含正在使用的UTXO的交易(通過指向UTXO被記錄在區(qū)塊鏈中所在的交易的哈希值和序列號來實現(xiàn))
      • 索引: 用于標(biāo)識來自該交易vout的索引(從0開始)
      • 解鎖腳本: 用于解鎖支出
      • 序列號:
    • 序列化和反序列化
      • 序列化
        • 將對象類型轉(zhuǎn)換成字節(jié)流的過程
      • 反序列化
        • 將字節(jié)流轉(zhuǎn)換成對象類型的過程
    • 交易費
      • 大多數(shù)交易包含交易費(礦工費). 礦工會根據(jù)不同的標(biāo)準(zhǔn)(包括交易費)對交易進行優(yōu)先級排序, 交易費會影響處理優(yōu)先級. 交易費不足或者沒有交易費的交易可能會被推遲甚至可能會不被處理. 盡管交易費不是強制的, 而且沒有交易費最終也有可能會被處理, 但是交易費將提高處理的優(yōu)先級.
      • 現(xiàn)在任何創(chuàng)建交易的比特幣服務(wù)都必須動態(tài)實現(xiàn)收費, 動態(tài)費用通過費用估算服務(wù)/費用估算算法實現(xiàn). 費用化估算包括簡單的(計算最后一個塊中礦工費的平均值的中位數(shù)) / 復(fù)雜的(統(tǒng)計分析), 估計必要費用(以字節(jié)為單位), 是交易具有很高的可能性被選擇并打包進一定數(shù)量的塊內(nèi).
    • 交易的數(shù)據(jù)結(jié)構(gòu)沒有交易費的字段。相替代地竟坛,交易費是指輸入和輸出之間的差值闽巩。從所有輸入中扣掉所有輸出之后的多余的量會被礦工作為礦工費收集走(交易費即輸入總和減輸出總和的余量:交易費 = 求和(所有輸入) - 求和(所有輸出);
  • 比特幣交易腳本

    • 鎖定腳本
      • 一個放置在輸出上面的花費條件:它指定了今后花費這筆輸出必須要滿足的條件。
    • 解鎖腳本
      • 一個滿足鎖定腳本設(shè)定的花費條件的腳本, 通過解鎖腳本可以允許一個vout被消費, 解鎖腳本是每一筆比特幣交易輸入的一部分, 往往含有一個用戶的比特幣錢包(用戶的私鑰)生成的數(shù)字簽名, 由于解鎖腳本通常包含一個數(shù)字簽名, 所以也被稱為ScriptSig.
    • 流程
      • 每個比特幣節(jié)點都會通過同時執(zhí)行鎖定和解鎖腳本來驗證一筆交易, 每個輸入都包含一個解鎖腳本, 并引用之前的UTXO, 驗證軟件將復(fù)制解鎖腳本, 檢索輸入所引用的UTXO, 并復(fù)制鎖定腳本, 然后依次執(zhí)行鎖定腳本和解鎖腳本, 如果解鎖腳本滿足鎖定腳本條件, 則輸入有效.
      • P2PK(Pay-to-Public-Key)付款至公鑰
        • 腳本
          1. 鎖定腳本
            PUSHDATA(PubKey)
            CHECKSIG
          2. 解鎖腳本
            PUSHDATA(Sig)
        • 拼接
          PUSHDATA(Sig)
          PUSHDATA(PubKey)
          CHECKSIG
      • P2PKH(Pay-to-Public-Key-Hash)付款至公鑰hash
        • A->B : scriptPubKey: OP_DUP OP_HASH160 <B pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG B->C :scriptSig: <B 私鑰對交易的簽名> <B 公鑰>
        • 將輸入鎖定為一個公鑰哈希值担汤,即我們常說的比特幣地址.
        • 腳本
          1. 鎖定腳本
            OP_DUP
            OP_HASH160
            PUSHDATA(PubKey)
            OP_EQUALVERIFY
            OP_CHECKSIG
          2. 解鎖腳本
            PUSHDATA(Sig)
            PUSHDATA(PubKey)
        • 拼接
          PUSHDATA(Sig)
          PUSHDATA(PubKey)
          OP_DUP
          OP_HASH160
          PUSHDATA(PubKey)
          OP_EQUALVERIFY
          OP_CHECKSIG
        • 上述交易的腳本執(zhí)行流程(先執(zhí)行解鎖腳本,在執(zhí)行鎖定腳本, 因為是個棧結(jié)構(gòu),所以會先鎖定然后再解鎖).
        • 上述的<Cafe Public Key>地址是長度為520位(65字節(jié))的全公鑰(04前綴 || x坐標(biāo) || y坐標(biāo));


          iShot2022-04-06 18.18.28.png
      • 多重簽名
        • 其中N個公鑰被記錄在腳本中涎跨,并且至少有M個必須提供簽名來解鎖資金
        • 鎖定腳本
          M <Public Key 1> <Public Key 2> ... <Public Key N> N CHECKMULTISIG
        • 解鎖腳本, 解鎖腳本中有個0的原因是因為 CHECKMULTISIG的執(zhí)行中有一個bug, CHECKMULTISIG彈出最上面的項目,這是N(在這個例子中N是“3”)崭歧。然后它彈出N個項目隅很,這是可以簽名的公鑰。在這個例子中率碾,公鑰A叔营,B和C.然后,它彈出一個項目播掷,即M审编,仲裁(需要多少個簽名)。這里M = 2歧匈。此時垒酬,CHECKMULTISIG應(yīng)彈出最終的M個項目,這些是簽名件炉,并查看它們是否有效勘究。然而,不幸的是斟冕,實施中的錯誤導(dǎo)致CHECKMULTISIG再彈出一個項目(總共M + 1個)口糕。檢查簽名時,不考慮額外的項目磕蛇,因此它對CHECKMULTISIG本身沒有直接影響景描。但是,必須存在額外的值秀撇,因為如果不存在超棺,則當(dāng)CHECKMULTISIG嘗試彈出空堆棧時,會導(dǎo)致堆棧錯誤和腳本失敽茄唷(將交易標(biāo)記為無效)棠绘。因為額外的項目被忽略,它可以是任何東西,但通常使用0氧苍。所以正確的解鎖腳本中前邊多了個0;
          0 <Signature B> <Signature C>
        • 拼接
          0
          <Signature B>
          <Signature C>
          2
          <Public Key A>
          <Public Key B>
          <Public Key C>
          3
          CHECKMULTISIG
      • P2SH(Pay-to-Script-Hash)付款至腳本hash
        • scriptPubKey: OP_HASH 6fe28c0ab6f1b372c1a6 OP_EQUAL 這個腳本, hash(x) = 6fe28c0ab6f1b372c1a6 我們只是提供?一個x滿?足這個條件夜矗,就可以證明我可以花費這筆錢了了。scriptPubKey: OP_HASH 6fe28c0ab6f1b372c1a6 OPEQUAL 這?6fe28c0ab6f1b372c1a6不不是簡單的?一個數(shù)字的hash让虐,?而是?一段script的hash(簡稱redeemScript)紊撕。 OP_HASH hash(redeemScript) OPEQUAL 我們可以理理解成只要你提供了了?段script,它的二進制hash和目標(biāo)匹配澄干,那么你就可以花費這筆錢了.

        • 解決多重簽名中使用不方便的問題(花費這筆UTXO時: 在客戶付款前將該腳本發(fā)送給每一位客戶逛揩,而每一位顧客也必須使用特制的能產(chǎn)生客戶交易腳本的比特幣錢包軟件,每位顧客還得學(xué)會如何利用腳本來完成交易麸俘。).


          image.png
        • 可以看到贖回腳本不是在鎖定腳本中顯示, 并且贖回腳本值是展示在解鎖腳本中,也就是復(fù)雜的計算工作從(企業(yè)收款的那筆交易中的)發(fā)送方轉(zhuǎn)移到收款方. 同時礦工的交易費用從發(fā)送方轉(zhuǎn)移到收款方.

        • 當(dāng)有人試圖花費這筆UTXO時,附上原始贖回腳本(與UTXO鎖定的哈希)和必要的解鎖簽名即可, 即:

        • redeemScript

          • 非多重支付類型
            PUSHDATA(PubKey)
            CHECKSIG

          • 多重支付類型
            2
            PUSHDATA(PubKey_1)
            PUSHDATA(PubKey_2)
            PUSHDATA(PubKey_3)
            3
            CHECKMULTISIG

        • 解鎖腳本就是:

          • 非多重支付類型
            PUSHDATA(Sig)
            PUSHDATA(序列化的redeemScript)

          • 多重支付類型
            0
            PUSHDATA(Sig_1)
            PUSHDATA(Sig_2)
            PUSHDATA(序列化的redeemScript)

        • 鎖定腳本變成:
          HASH160
          PUSHDATA(redeemScriptHash)
          EQUAL

        • 驗證

          1. 驗證序列化的redeemScript是否與output script中的hash值是否匹配

            • 非多重支付
              PUSHDATA(Sig)
              PUSHDATA(序列化的redeemScript)
              HASH160
              PUSHDATA(redeemScriptHash)
              EQUAL

            • 多重支付
              0
              PUSHDATA(Sig_1)
              PUSHDATA(Sig_2)
              PUSHDATA(序列化的redeemScript)
              HASH160
              PUSHDATA(redeemScriptHash)
              EQUAL

          2. 反序列化執(zhí)行redeemScript, 驗證input script中給出的簽名是否正確

            • 非多重支付
              PUSHDATA(Sig) // - 這行是執(zhí)行完第一步驗證后棧中剩余的
              PUSHDATA(PubKey) // - redeemScript中的代碼
              CHECKSIG // - redeemScript中的代碼
            • 多重支付
              0 // - 這行是執(zhí)行完第一步驗證后棧中剩余的
              PUSHDATA(Sig_1) // - 這行是執(zhí)行完第一步驗證后棧中剩余的
              PUSHDATA(Sig_2) // - 這行是執(zhí)行完第一步驗證后棧中剩余的
              2 // - redeemScript中的代碼
              PUSHDATA(PubKey_1) // - redeemScript中的代碼
              PUSHDATA(PubKey_2) // - redeemScript中的代碼
              PUSHDATA(PubKey_3) // - redeemScript中的代碼
              3 // - redeemScript中的代碼
              CHECKMULTISIG // - redeemScript中的代碼
        • 同時可以將腳本哈希編譯為一個地址, 即P2SH地址是基于Base58編碼的一 個含有20個字節(jié)哈希的腳本(像比特幣地址是基于Base58編碼的一個含有20個字節(jié)的公鑰辩稽。由于P2SH地址采用5作為前綴,這導(dǎo)致基于Base58編碼的地址以“3”開頭);

  • 數(shù)字簽名

    • 比特幣中使用的數(shù)字簽名算法是ECDSA(Elliptic Curve Digital Signature Algorithm, 橢圓曲線數(shù)字簽名算法), 用于基于橢圓曲線私鑰/公鑰數(shù)字簽名的算法, 該簽名算法用于 OP_CHECKSIG从媚,OP_CHECKSIGVERIFY逞泄,OP_CHECKMULTISIG和OP_CHECKMULTISIGVERIFY, 當(dāng)鎖定腳本看到這些操作時候, 解鎖腳本必須包含一個 ECDSA簽名.
    • 用途
      1. 資金所有者已經(jīng)授權(quán)了支出這些資金.
      2. 授權(quán)不可否認(rèn).
      3. 交易在簽名之后沒有任何人篡改.
    • 創(chuàng)建數(shù)字簽名
      • ((Sig = F{sig}(F{hash}(m), dA))) : 使用私鑰對交易的hash做簽名運算,得到簽名結(jié)果

        1. dA 是簽名私鑰
        2. m : 交易
        3. F{hash} : hash 函數(shù)
          4.F{sig} : 簽名算法;
        4. Sig: 結(jié)果簽名
      • Sig是有兩個值組成的 即:Sig = (R, S), 得到R和S之后序列化為字節(jié)流,使用一種稱為DER(Distinguished Encoding Rules, 分辨編碼規(guī)則)的國際標(biāo)準(zhǔn)編碼方案.

        例如 : 3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301

        • 0x30表示DER序列的開始
        • 0x45 - 序列的長度(69字節(jié))
        • 0x02 - 接下來是一個整數(shù)
        • 0x21 - 整數(shù)的長度(33字節(jié))
        • R-00884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb
        • 0x02 - 接下來是一個整數(shù)
        • 0x20 - 整數(shù)的長度(32字節(jié))
        • S-4b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813
        • 后綴(0x01)指示使用的哈希的類型(SIGHASH_ALL)
  • 驗證簽名

    • 要驗證簽名, 必須有簽名(R和S), 序列化交易和公鑰.
    • 簽名可以指示交易數(shù)據(jù)的哪一部分包含在私鑰簽名的hash中(使用后綴表示), input中的不同的交易可以使用不同后綴類型,使每個交易擁有自己的后綴類型.


      image.png

      image.png
  • ECDSA算法

    • 簽名


      image.png
    1. k是臨時私鑰, K = k*G, 得到公鑰K, 其中Kx記作點的x坐標(biāo), Ky 記作點的y坐標(biāo).
    2. R = Kx
    3. dA是簽名私鑰
    4. m是交易數(shù)據(jù), Hash(m)是對交易做hash運算.
    5. p是橢圓曲線的素數(shù)階, 在 secp256k1 曲線中, p = 2^256 – 2^32 – 2^9 – 2^8 – 2^7 – 2^6 – 2^4 – 1
    6. 計算的到S, 如果, s==0, 重新執(zhí)行第一步. 從而得到 R和S;
    • 驗證簽名


      image.png
      1. R和S是簽名值
      2. Qa是公鑰
      3. m是簽署的交易數(shù)據(jù)
      4. G是橢圓曲線發(fā)生器點
        當(dāng)且僅當(dāng) 計算的點Px == R, 驗證簽名通過
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拜效,一起剝皮案震驚了整個濱河市喷众,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌紧憾,老刑警劉巖到千,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赴穗,居然都是意外死亡憔四,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門般眉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來了赵,“玉大人,你說我怎么就攤上這事甸赃∈裂矗” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵埠对,是天一觀的道長络断。 經(jīng)常有香客問我,道長项玛,這世上最難降的妖魔是什么妓羊? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮稍计,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘裕循。我一直安慰自己臣嚣,他們只是感情好净刮,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著硅则,像睡著了一般淹父。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上怎虫,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天暑认,我揣著相機與錄音,去河邊找鬼大审。 笑死蘸际,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徒扶。 我是一名探鬼主播粮彤,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼姜骡!你這毒婦竟也來了导坟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤圈澈,失蹤者是張志新(化名)和其女友劉穎惫周,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體康栈,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡递递,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谅将。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漾狼。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饥臂,靈堂內(nèi)的尸體忽然破棺而出逊躁,到底是詐尸還是另有隱情,我是刑警寧澤隅熙,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布稽煤,位于F島的核電站,受9級特大地震影響囚戚,放射性物質(zhì)發(fā)生泄漏酵熙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一驰坊、第九天 我趴在偏房一處隱蔽的房頂上張望匾二。 院中可真熱鬧,春花似錦、人聲如沸察藐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽分飞。三九已至悴务,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間譬猫,已是汗流浹背讯檐。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留染服,地道東北人别洪。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像肌索,于是被迫代替她去往敵國和親蕉拢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容