主页 > imtoken钱包app安卓版 > 比特币源码学习——交易

比特币源码学习——交易

imtoken钱包app安卓版 2023-05-29 06:18:13

0x00 废话

距离上一篇文章已经半个多月了。 平时晚上回家比较懒,周末回家还得带娃。 研究代码的进度很慢。 趁着今天出差整理了一下代码,趁热开车出去了。 本文。 热情还在,但我在降低自己的要求,从出精品到不出错(我最怕误导孩子)。 调试环境从linux上的gdb降级为windows上的visual gdb; 为了一窥作者最初的设计思路,版本号也从0.14降到了0.8,隔离见证和闪电网络的研究暂时不在范围之内。 废话不多说,今天我们就来研究一下比特币的核心部分——交易。

0x01 UTXO

比特币交易中有一个非常重要的概念UTXO(Unspent Transaction Output),意思是比特币用UTXO替代了传统的账户体系。 这句话怎么理解,我们对比一下就知道了。 假设2个矿工A和B分别挖出区块,获得25个BTC的coinbase奖励,然后将两者都转给C,C转15个BTC给D。那么传统的账户体系,如下图:

UTXO的流通方式如下:

做过数据运维的朋友可能会说,UTXO不就是数据库中的日志表吗? 这是真的。 我们知道,银行或其他类似系统不仅需要存储数据结果,还需要对交易记录进行严格管理。 一旦发现异常数据,就要对交易记录进行逐一分析。 所以严格来说,数据结果表是多余的,因为可以通过流程计算出结果,记录更容易发现作弊者。 当然,记录计算结果是要付出代价的。 例如,它消耗大量的计算。 同时,对记录的完整性也有很高的要求。 一条记录不能出错,否则整个系统都会出错。 比特币通过去中心化的分布式存储和共识机制的完善,将UTXO的思想发挥到了极致。

我们看一下比特币大师书中对UTXO的描述:

比特币交易的基本单位是未使用的交易输出,简称UTXO。 UTXO是一定数量的比特币货币,不能被分割,不能被所有者锁定,也不能记录在区块链中,被全网认可为一个货币单位。 比特币网络以数百万计监控所有可用(未花费)的 UTXO。 当用户收到比特币时,金额将作为 UTXO 记录在区块链中。 这样,用户的比特币将作为 UTXO 分散到数百个交易和数百个区块中。 事实上,没有地方可以存储比特币地址或账户余额,只有被其所有者锁定的去中心化 UTXO。 “用户的比特币余额”的概念是通过比特币钱包应用程序创建的衍生产品。 比特币钱包通过扫描区块链并汇总属于该用户的所有 UTXO 来计算用户的余额。

0x02 交易

接下来我们来分析一下UTXO中的TX,TX是transaction的缩写。 CTransaction有两个重要的成员变量std::vectorvin和std::vectorvout,交易输入和交易输出。 看下面的类图就更一目了然了。

(上图有错字,CTxOut中的scriptPubKey应该是锁定脚本)对应的数据库序列化如下:

普通交易输入(CTxIn)

普通交易输出(CTxOut)

事务(CTransaction)

创世币库

CTx类代码,不难,不做太多注释

CTxOut类代码,不难,不做过多注释

CTransaction 类代码,一些注释

关于锁定时间的解释如下:

交易锁定时间 锁定时间定义了最早可以加入区块链的交易时间。 在大多数事务中,它被设置为 0 以指示立即执行。 如果锁定时间不为0且小于5亿,则视为区块高度,即在指定的区块高度之前,该交易还没有进入区块链。 如果锁定时间大于 5 亿,则将其视为 Unix 纪元时间戳(自 1970 年 1 月 1 日以来的秒数),并且在该指定时间之前交易未包含在区块链中。 使用锁定时间,就相当于延迟了一张纸质支票的生效时间。

0x03 交易流程

熟悉了交易的数据结构之后,我们来看看交易流程:

具体步骤如下: 1. 构造交易钱包类CWallet的CreateTransaction函数,创建交易。 主要分为3步: 1.填写交易的输出交易(vout)。 创建交易时,指定输出交易的信息,主要是输出脚本(地址构造为CScript)和要输出的币量(nValue)。

2、填写交易的输出交易(vin),首先从钱包中的交易信息中选择合适的比特币(SelectCoins函数)比特币交易代码,填写到交易的输入交易中。 3. 签名(CTxIn.scriptSig) 对输入交易的scriptSig进行签名(SignSignature函数)。 将新的交易信息和私钥计算出哈希值(SignatureHash函数),填入输入交易的scriptSig中(Solver函数)。 构建交易后,提交交易并发送出去。

2.发送交易当交易构造完成后,提交交易(钱包类CWallet的CommitTransaction函数)并发送出去。 提交交易时,首先将交易添加到钱包,然后将旧比特币标记为已花费,将其添加到交易内存池,最后传播交易。

在传播交易时(RelayTransaction函数)比特币交易代码,CInv由交易信息的哈希值构造,类型为MSG_TX,加入到各节点的发送列表(vInventoryToSend)中。 在发送消息(SendMessages)时,节点中发送列表中的交易信息是用“inv”命令发送出去的。

3.接收交易 当节点收到交易命令(“tx”)时,将交易信息添加到交易内存池中并向下传播。 有关详细信息,请参阅 ProcessMessage 函数。

由于本人水平有限,文中难免有看不懂的地方。 请给我你的建议!