# 比特币和数字货币技术 第三周总结

By [markchern](https://paragraph.com/@markchern) · 2022-11-15

---

比特币机制
-----

### 3.1 比特币交易

比特币的交易的数据结构不是基于账号，而是基于账本。

![基于账号的交易记录](https://storage.googleapis.com/papyrus_images/b6afac31209fa6c66d0b73f154d830cff3cf83b466356473da04b0a3047461b5.png)

基于账号的交易记录

基于账号的交易记录的缺点是如果要验证某一笔交易是否合法，那么需要回溯之前与这个账号相关的交易。虽然通过一些数据结构可以高效解决，但是增加了账本的大小。

![基于账本的交易记录](https://storage.googleapis.com/papyrus_images/53ec8e6c4a82a59353bf2b92be09cdf2fbf10ecd21638148911e655be2530518.png)

基于账本的交易记录

基于账本的交易记录，每一笔交易有多个输入和输出。每个输入有之前的交易的的哈希，该交易其中某个输出的下标，还有之前交易的签名。输出则是输出的地址和交易金额。

地址变更，每一笔交易会将输入的金额全部转到指定的输出地址。例如艾丽丝有10个比特币，转8个给鲍勃，剩下的一般再转给自己。

高效验证：这样做的好处是每一交易的验证只需要核实之前一个交易，并且不需要额外的数据结构。

合并资金：如果想合并不同地址的资金，只要使用一个交易也就可以了。

合并输出:如果两个不同人想支付同一个人，只要使用一个交易就可以，然后附上两个不同签名。

![实际比特币交易数据](https://storage.googleapis.com/papyrus_images/1ad2fffeae9d9cbe30c781733701bcd25b8ba427df16f2725704e59f54c2afa1.png)

实际比特币交易数据

### 3.2 比特币脚本

比特币脚本语言

![支付给哈希过的地址的脚本](https://storage.googleapis.com/papyrus_images/b2f39543f1fdc70111b761c6dc5f6b1a7a4429576e9365cc93981131375b562a.png)

支付给哈希过的地址的脚本

![公钥脚本和签名脚本的拼接，检查是否合法兑现先前交易的输出](https://storage.googleapis.com/papyrus_images/d8cb0ba682faa9c90681e569f620781fb5ac4f967afd97ea405d53efff767b6b.png)

公钥脚本和签名脚本的拼接，检查是否合法兑现先前交易的输出

脚本语言的好处：基于栈，没有变量，线性执行。体积小，执行快。坏处是没有循环，图灵不完备，无法执行许多有用的程序。

执行要么出错，要么执行完。

![脚本执行](https://storage.googleapis.com/papyrus_images/d8c6bb6d6b68b1a337494a5e474df721f3894da170f95b784b54942f94454dfa.png)

脚本执行

燃烧证明

这是一类特殊的脚本，无论执行什么都提前返回。因此输入的钱相当于被销毁。

支付给脚本哈希

为了解决普通用户的使用问题，即如果商家使用多签，不需要顾客知道脚本如何使用，只需要提供脚本的哈希，用户即可完成支付。

### 3.3 脚本的应用

**第三方担保交易**

假设甲方想向乙方购买一批货物，但是甲方希望货到付款，乙方希望款到发货。如何解决这个问题？我们使用第三方担保交易。甲方不是付款给乙方，而是付款给第三方。第三方担保交易使用多签名机制，只要3方中有两方签名，那么交易生效。

如果甲方确认收货，那么就可以签名。如果乙方确认收款，也可以签名。这时交易成功。如果甲方认为没收到货或乙方认为没收到签等原因，那么此时第三方可以根据双方提供的证据选择令款项退回给甲方，或者将款型支付给乙方。

**绿色地址**

在现实世界，例如与小摊贩的交易中，通过共识网络确认一笔交易需要大量时间。因此我们可以引进第三方，将钱交由它们保管，就像银行。这样，钱只是在同一个控制人控制的地址转移钱，不需要共识网络参与。但是绿色地址需要再引入像政府等监管机构防止监守自盗。

高效微支付

假设甲方向乙方购买一项按分钟收费的服务。如果每分钟创建一个交易，那手续费和交易确认时间将耗费过多。甲方可以预先创建一个多签名的支付，附上签名。每过一分钟，甲方在原先交易交易的基础上，再创建一个交易，将截止目前需要支付的费用转给乙方，剩下退回，然后签名。每过一分钟，增加支付的的费用，剩下退回。

当服务完，乙方选择甲方最后一个签名过的交易再加上自己的签名，交易成功。如果甲不签名，那么乙方终止服务，签掉最后一笔交易。由于所有的交易的输入都是同一个地址，所以只有一个交易可以生效。

**锁时**

如果乙方选择不签名，让甲的保证金一直保存在多签地址。这时，甲方可以设置锁时，保证一段时间后如果乙方迟迟不肯签名，那么保证金将自动退还原地址。

**智能合约**

比特币的脚本语言限制了智能合约的使用范围，以太坊实现了图灵完全，所以它的智能合约功能更为强大。但是交易费用和速度时目前的瓶颈。

### 3.4 比特币区块

将交易打包成块可以使交易速率更快，区块链更短，更容易验证。

比特币区块包含两种哈希数据结构。第一种使区块链，每个区块的头是一个哈希指针，指向前一个区块。身体是包含当前区块所有交易的Merkle 树。树使得验证一个交易是否在特定区块的时间是O(logn)。

![区块链](https://storage.googleapis.com/papyrus_images/267ac15077c2f8e05c78b386741752abee2dbce137638bcee33792be887fba6c.png)

区块链

每个区块包含一个特殊的交易，用来创造比特币。它没有输入，只有输出。

![币基础交易](https://storage.googleapis.com/papyrus_images/c459b8255bd575dcfd2b3c8230dbd4be92336f143708ac8be5db571749163a31.png)

币基础交易

### 3.5 比特币网络

比特币网络所有的节点没有区别，例如没有主从之分。使用TCP协议发送消息。

网络结构随着时间变化而变化，节点可以自由加入或退出。如果有节点3小时没有活动，那么其它节点将遗忘它。

假设你想加入网络。首先我们需要知道一个在网络的节点，称为种子节点。然后发送消息给种子节点，让它发送它知道的其它节点。以此类推，直到加了足够多的节点。

如果我们想要发布一笔交易，那么我们通过自己节点将交易发送给自己相连接的节点。这些节点再发送交易给它们相连接的节点。这个过程称为洪水算法。

当一个节点听到一笔新交易，可以先验证交易是否合法。然后只传播合法交易给其它节点。

所有这些验证取决于节点自身，网络本身无法强制要求。

由于网络存在验证，所以甲用同一笔输入付给乙和丙有可能在不同的节点各自合法。至于最后谁合法，无法确定。但可以保证只有一笔交易合法。这种情况称为竞赛条件。

**网络大小**

![](https://storage.googleapis.com/papyrus_images/f5f88101569a280adfcc0cc61667393f8d035554d246215bc5bef4c9d2d3d8bc.png)

**存储需要**

![](https://storage.googleapis.com/papyrus_images/745f4745ea1e1bbc83576cd73dafda14ef0e2a5550ffad1ddbaf807bdf316fd9.png)

**轻节点**

不需要储存所有交易，只储存与自己相关的交易，加快验证。

### 3.6 限制和改进

限制一：每秒交易数太小

限制二：难以做出硬分叉，改进代码。

**硬分叉**

改进代码，发布新版本。但是节点是否使用取决于它们。

**软分叉**

改进规则，提高验证速度之类。

---

*Originally published on [markchern](https://paragraph.com/@markchern/xQ19ekdXQIv0Iw6GJ6kk)*
