本文主要讲解比特币进行交易其中的技术原理, 交易包含的元素,交易验证。
基于UTXO的余额管理
比特币没有账户的概念,每个用户账号没有对应的账户记录,那么比特币系统是怎样确认用户账号是否有足够的余额进行交易,这是通过他们区块链上的UTXO计算出来。 这不是区块链的必要技术,不同区块链系统可以不同,以太坊就有账户为每个用户记录余额。
UTXO:UTXO 是 Unspent Transaction Output 的缩写,Transaction act发音简写为X
UTXO的管理余额
看概念太玄, 其实UTXO主要解决一个问题, 用户A有多少钱(比特币), UTXO的方式就是看,一共有多少交易是指向用户A,而且这些交易还没被使用,这些交易的总额就是A的可用余额。举个栗子,假如有1交易(tx1_A)是指向A(向A转账),转给A 100块, A就能拿着这笔交易证明自己有100块, 当A转账给B时候拿它为新转账交易(tx1_B),证明A拥有100, 这笔指向A交易即被标记为已经使用。
UTXO找零
那么还存存在一个问题,如果A要转B是10块钱,怎样解决? Tx1_A能标记为部分被使用?这是不可以的,交易要不就未消费要不就已消费, UTXO的解决方法一笔交易作为输入可以产生多笔输出交易。 这好比A拥有100块,可以同时转给 B 30块, C 70块,这样tx1_A就作为 tx1_B, tx1_C两笔交易的输入交易。 找零的方法就出来了, A给B转10块同时给自己转90块, tx1_A -> tx1_B, tx2_A 这样。
程序员都喜欢看图,上图:
具体看比特币的交易字段:
字段 | 类型 | 长度 | 说明 |
---|---|---|---|
Version | Unit32 | 4 | 交易数据格式的版本 |
tx_in_count | Var_int | 1+ | 输入交易数量 |
tx_in | tx_in[] | 41+ | 输入交易或者比特币来源列表 |
Tx_out_count | Var_int | 1+ | 输出交易数量 |
Tx_out | Tx_out[] | 8+ | 输出交易列表 |
Lock_time | Uint32_t | 4 | 锁定交易的期限 |
再看看上面两个结构类型tx_in, tx_out:
tx_in:
字段 | 类型 | 长度 | 说明 |
---|---|---|---|
Previous_tx_output | OutPoint | 36 | 对前面输出交易的引用 |
Sript length | Var_int | 1 | 对前面输出交易的引用 |
Script signature | Uchar[] | 变长 | 用于确认这个交易授权的脚本签名 |
Sequence | Uint32_t | 4 |
tx_out:
字段 | 类型 | 长度 | 说明 |
---|---|---|---|
value | Uint64_t | 64 | 转多少 |
Pk Sript length | Var_int | 1 | 签名脚本的长度 |
PK Script | Uchar[] | 变长 | 用于确认这个交易授权的脚本签名 |
比特币的交易验证
UTXO解决了余额, 还有解决怎样确定交易就是指向B,就是A要发起转账给B而不是别人。在比特币系统,用户身份都是一对秘钥,交易也是依赖这来证明身份。公钥是用户的账户,转账都是通过转账到用户的公钥,而私钥则用于签名自己发起的交易,确认交易是自己发起的而且交易数据没有变更,变更后签名必然验证不过。
交易结构简要图示
1、 证明B确实输入交易(tx1_B txid:001)的拥有者,这就要回到A转账给B时候,
A会把B的公钥(比特币里账户其实就是用户的公钥)放入签名脚本,并做签名放入脚本。
具体脚本
<PubK(X)> // 将放入的公钥X
OP_DUP // 取栈第一个,即公钥X
OP_HASH160 // 做hash160处理
<PubKHash(B)> // 放入B公钥的Hash值
OP_EQUALVERIFY // 两个值做比较是否相同
OP_CHECKSIG // 校验签名
所以这里X只有放入B的公钥,才能通过,能证明这个交易是转给B的。
2、 证明B确实发起了交易tx1_C,最后一OP_CHECKSIG则证明确实B发起tx1_C, 在交易里面的tx_in结构,有singure字段,是B用私钥对交易信息签名产生,通过B的公钥才能验证签名正确,这就保证交易确实B发起的并没被修改过。
这其中的OP_CHECKSIG算法 运用了椭圆曲线数字签名算法(ECDSA:The Elliptic Curve Digital Signature Algorithm ),一种利用椭圆曲线进行数字签名和验证的算法。具体数学原理我也没搞懂,不是本主题的重点不能展开,后续搞懂了可以另写一篇。
所以:
收到这笔交易时候,将B的公钥,A的公钥放入交易tx1_B验证交易确实A给B转账,同样对tx1_C(txid:002)验证放入C公钥和B的公钥验证确实是转账给C和确实B发起。
总结:
比特币的交易基于UTXO解决了用户余额问题,基于脚本签名解决交易合法性问题,
唯一性就是就是通过一个交易记录只能被作为一次输入, 多节点的唯一性就是区块链工作量证明来判决。
历史
区块链二:比特币的区块数据结构
区块链一 :区块链应用介绍和展望
时光隧道
区块链四:共识机制——PBFT算法深入讲解