乐趣区

关于比特币:区块链入门-③-交易

区块链入门 ③ – 交易

交易

概述

比特币交易实质上蕴含交易参与者价值转移的相干信息数据结构。比特币区块链是一本寰球复式记账总账簿,每笔交易都是在比特币区块链上的一个公开记录。

本章中应用术语“钱包”时,咱们指的是构建交易的软件,而不仅仅是蕴含密钥的数据库。

前置常识

UTXO

UTXO,即“未破费的交易输入”(unspent transaction outputs)。所有 UTXO 的汇合被称为 UTXO 集。UTXO 集大小在新的 UTXO 减少时而增长,并在 UTXO 被耗费时而放大。每一个交易都代表 UTXO 集中的变动(状态转换)。

  • UTXO 的最小单位是八位小数的“聪”。
  • UTXO 是面值为“聪”的离散且不可分割的价值单位,一个 UTXO 只能在一次交易中 作为一个整体 被耗费。如果一个 UTXO 面值大于一笔交易所需,它依然必须作为整体全副应用,但同时会在交易中生成零头。比特币利用能够应用一些策略来满足付款需要:组合若干小额 UTXO,并算出精确的找零;或者应用一个比交易额大的 UTXO 而后进行找零。
  • 交易会耗费先前记录的未应用的 UTXO,并创立可供将来交易应用的新的 UTXO。通过这种形式,大量的比特币在生产和创立 UTXO 的交易链中在所有者之间进行转移。
  • “币基交易”(Coinbase Transaction):每个区块中的第一笔交易,这笔交易由“获胜”矿工设置,创立全新比特币并领取给该矿工作为采矿处分。币基交易并不生产 UTXO,相同,它有一种称为“coinbase”的非凡类型的输出。
余额

用户的比特币“余额”是指用户钱包中可用的 UTXO总和,它们可能扩散在数百个交易和区块中。比特币钱包通过扫描区块链并汇聚所有属于该钱包管制的私钥的 UTXO 来计算该用户的余额。

比特币脚本语言

比特币的脚本语言是一种基于栈的语言。脚本语言通过从左到右解决每个我的项目来执行脚本。

  • 数字(数据常量)被推到栈上。操作码(Operators)从栈中推送或弹出一个或多个参数,对其执行操作,并可能将后果推送到栈上。例如,操作码 OP_ADD 将从栈中弹出两个我的项目,增加它们,并将后果的总和推送到栈上。
  • 条件操作码(Conditional operators)对一个条件进行计算,产生一个 TRUE 或 FALSE 的布尔后果(boolean result)。例如,OP_EQUAL 从栈中弹出两个我的项目,如果它们相等,则推送为 TRUE(由数字 1 示意),否则推送为 FALSE(由数字 0 示意)。
比特币数字签名

数字签名是一种由两局部组成的数学计划:第一局部是应用私钥对数据创立签名的算法;第二局部是容许在给定数据和公钥时验证签名合法性的算法。比特币中应用的数字签名算法是椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm,ECDSA)

  • 创立签名

在比特币的 ECDSA 算法的实现中,被签名的“音讯”是交易,或更确切地说是交易中特定数据子集的哈希值。签名密钥是用户的私钥,后果就是签名,签名 Sig 由两个值组成,称为 R 和 S:Sig = (R, S)。

具体流程如下:

  1. 签名算法首先生成一个长期密钥对。长期密钥对基于随机数 k,用作长期私钥。如果应用雷同的值 k 在不同的音讯(交易)上生成两个签名,那么任何人都能够计算出签名私钥!!!
  2. 利用 k,咱们生成相应的长期公钥 P(以 P=k*G 计算,与派生比特币公钥雷同)。
  3. 数字签名的 R 值则是长期公钥 P 的 x 轴坐标。
  4. 数字签名的 S 值:

    $$
    S = k^{-1}(Hash(m) + dA * R) mod n
    $$

其中:

  • k是长期私钥
  • R是长期公钥的 x 坐标
  • dA是签名私钥
  • m是交易数据(或其局部)
  • n是椭圆曲线的阶
  • 验证签名

验证应用数据(交易或其局部的哈希值),签名者的公钥和签名(R 和 S 值)来计算值 P,该值是椭圆曲线上的一个点,如果计算出的点 Px坐标等于R,则签名无效。

$$
P = S^{-1} Hash(m)*G + S^{-1}*R*Qa
$$

其中:

  • RS 是签名值
  • Qa是签名者的公钥
  • m是交易数据(或其局部)
  • G是椭圆曲线生成点
  • 数字签名的用处:

    • 身份认证性 : 签名证实私钥的所有者,即资金所有者,曾经受权收入这些资金。
    • 不可否认性 : 受权证实是不可否认的(不可否认性)。
    • 完整性 : 签名证实交易(或交易的特定局部)在签名之后没有也不能被任何人批改。

交易输入

每一笔比特币交易都会发明输入,并被比特币账簿(区块链)记录下来。除特例之外,简直所有的输入都能发明 UTXO。

交易输入蕴含两局部:

  • “value”:一定量的比特币,面值为“聪”(satoshis)。
  • “scriptPubKey”:作为破费输入所需条件的加密难题(cryptographic puzzle),也被称为锁定脚本(locking script)、见证脚本(witness script),或脚本公钥(scriptPubKey)。
{
    ...
    "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"
        }
    ]
}

交易输出

交易输出将 UTXO(通过被援用)标记为将被生产,并通过解锁脚本提供所有权证实。

交易输出蕴含四局部:

  • “txid”:一个交易 ID,援用蕴含正在应用的 UTXO 的 交易(不是 UTXO)
  • “vout”:一个输入索引,用于标识来自该 交易中的第几个 UTXO被援用(一个交易可能存在多个输入,第一个为零)。
  • “scriptSig”:一个解锁脚本,钱包构建它是为了满足 UTXO 中设置的生产条件,满足搁置在 UTXO 上的领取条件,解锁收入。
  • “scriptSig”:一个序列号,与工夫锁无关。
{
    ...
    "vin": [
        {
            "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
            "vout": 0,
            "scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL]0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
            "sequence": 4294967295
        }
    ]
}
  • 留神:交易输出中仅蕴含了“txid”,须要首先从区块链中检索援用的 UTXO,来获取该 UTXO 的面值和锁定条件。

交易脚本

比特币网络解决的大多数交易破费的是由“付款至公钥散列”(Pay-to-Public-Key-Hash,P2PKH)脚本锁定的输入。

相应的锁定脚本和解锁脚本如下:

  • 锁定脚本(scriptPubKey):锁定脚本是一个搁置在输入上的破费条件:它指定了今后破费这笔输入必须要满足的条件。其蕴含一个公钥散列(hash)值,即咱们常说的比特币地址。
  • 解锁脚本(scriptSig):解锁脚本是“解决”或满足输入上锁定脚本设定的破费条件并容许破费输入的脚本。解锁脚本是交易输出的一部分,其蕴含散列值对应的公钥和由相应私钥创立的数字签名。

每个比特币验证节点将通过一起执行锁定和解锁脚本来验证交易。

  1. 每个输出都蕴含一个解锁脚本,并援用先前存在的 UTXO。
  2. 验证软件将复制解锁脚本,检索输出援用的 UTXO,并从该 UTXO 复制锁定脚本。
  3. 而后按程序执行解锁和锁定脚本。如果解锁脚本满足锁定脚本条件,则输出无效。所有输出都是独立验证的,作为交易整体验证的一部分。

例子:

  • 锁定脚本
OP_DUP OP_HASH160 <Cafe Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG
  • 解锁脚本
<Cafe Signature> <Cafe Public Key>
  • 组合验证脚本
<Cafe Signature> <Cafe Public Key> OP_DUP OP_HASH160 <Cafe Public Key Hash> OP_EQUALVERIFY OP_CHECKSIG
  • 验证流程

签名散列类型

比特币签名有一种办法,用于通过应用 SIGHASH 标记来批示交易数据的 某一部分 蕴含在由私钥签名的散列中。

每个输出可能在其解锁脚本中蕴含一个签名。因而,蕴含多个输出的交易能够领有具备不同 SIGHASH 标记的多个签名,这些标记在每个输出中承诺交易的不同局部。

有三个 SIGHASH 标记:ALL,NONE 和 SINGLE。

SIGHASH flag Value Description
ALL 0x01 签名利用到所有输入输出
NONE 0x02 签名只利用到所有输出,不包含任何输入
SINGLE 0x03 签名利用到所有输出和与签名输出具备雷同索引号的那个输入

另外还有一个修饰符标记 SIGHASH_ANYONECANPAY,它能够与后面的每个标记组合应用。

当设置 ANYONECANPAY 时,只有以后输出被签名,其余的(及其序列号)放弃凋谢以进行批改。ANYONECANPAY 的值为 0x80,并通过按位 OR 运算,失去如下表所示组合标记:

SIGHASH flag Value Description
ALL ANYONECANPAY 0x81
NONE ANYONECANPAY 0x82
SINGLE ANYONECANPAY 0x83

利用 sighash 标记的形式:

  1. 依据应用的 SIGHASH 标记,生成交易的正本并截断其中的某些字段(设置为零长度并清空)。
  2. 序列化交易正本,将 SIGHASH 标记被增加到序列化交易的结尾。
  3. 将序列化交易正本 +SIGHASH 标记散列,失去的散列值即是被签名的“音讯”。
  4. 因为在散列化前,SIGHASH 作为最初一步被蕴含在内,签名也会对 SIGHASH 类型进行签订,因而不能被更改(例如,不能被矿工批改)。

利用:

  • ALL|ANYONECANPAY:这种标记能够用来做“众筹”交易,众筹发起人能够用单笔输入来构建一个交易,这笔输入将“指标”金额付给众筹发起人。这样的交易显然是有效的,因为它没有输出。然而当初其他人能够通过增加本人的输出作为捐献来批改它们,他们用 ALL|ANYONECANPAY 签订本人的输出,直到收集到足够的输出以达到输入的指标金额前,交易有效,每一笔捐款都是一种“承诺”,在募集够整个指标金额之前,筹款不能发出。
  • NONE:该构造可用于创立特定金额的“不记名支票”或“空白支票”。它对输出进行承诺,但容许输入锁定脚本被更改。任何人都能够将本人的比特币地址写入输入锁定脚本并兑换交易。
  • NONE|ANYONECANPAY:这种结构能够用来建造一个“吸尘器”。在钱包中领有渺小 UTXO 的用户无奈破费这些费用,因为手续费超过了这些渺小 UTXO 的价值。借助这种类型的签名,渺小 UTXO 能够捐献给任何违心募集的人并由他们随时破费。

交易费

交易费是指输出和输入之间的差值。从所有输出中扣掉所有输入之后的残余的金额是矿工收取的交易费。

  • 交易的数据结构自身没有交易费这个字段。
  • 交易费是以千字节为单位计算的,而不是比特币交易的金额,这意味着如果把大量小型 UTXO 作为输出可能须要领取更高的交易费。
  • 交易费作为矿工打包(挖矿)一笔交易到下一个区块中的一种激励;同时作为一种克制因素,通过对每一笔交易收取小额费用来避免对系统的滥用。胜利挖到某区块的矿工将失去该区内蕴含的交易费,并将该区块增加至区块链中。
  • 大多数状况下,交易费影响解决优先级,这意味着有足够费用的交易费更可能被打包进下一个挖出的区块中;任何创立交易的比特币服务,包含钱包、交易所、批发利用等,都必须实现交易费动静计算性能。
退出移动版