主页 > imtoken官网下载1.0 > 【北大肖震-区块链技术与应用笔记】第四课-BTC系统的实现

【北大肖震-区块链技术与应用笔记】第四课-BTC系统的实现

imtoken官网下载1.0 2023-03-06 06:36:09

文章目录

【北大肖震-区块链技术与应用笔记】第四课-BTC系统的实现

区块链是去中心化的账本,BTC采用基于交易的账本模型,只记录转账交易和铸币交易,不直接记录每个账户有多少钱。 如果你想知道一个BTC账户里有多少钱,你需要通过交易记录来计算。

除了像BTC系统这样的基于交易的账本模型(transaction-based ledger)之外,还有一些系统是基于账户模型(account-based ledger)的,比如后面要学习的以太坊。 在这种模式下,系统必须明确记录每个账户中有多少币。

这种模式的BTC系统隐私保护较好,但会带来一定的成本。 例如,转账交易必须注明货币的来源(该货币来自上一笔交易的输出)btc区块交易查询,以防止双花攻击。

1. UTXO

BTC中的全节点需要维护一个叫做UTXO(Unspent Transaction Output)的数据结构,UTXO是尚未花费的交易的输出。 一个交易可能有多个输出,那些被花费的输出不在 UTXO 中。

image-20220414225603560

UTXO 集合中的每个元素都应给出生成该输出的交易的哈希值,以及它在该交易中的输出。 有了这两条信息,就可以定位到某笔交易中的某个输出。

使用 UTXO 可用于快速检测双花攻击。 如果想知道一笔新发布的交易是否合法,需要查看全节点内存中存储的UTXO。 要花掉的币只有在这个 UTXO 集合中才是合法的,否则要么不存在btc区块交易查询,要么已经花掉了。

随着交易的发布,每笔交易都会消耗一些输出并生成一些新的输出。 例如,在上面的示例中,B 给 D 5 BTC,它消耗了之前 A 给 B 5 BTC 的输出,但是产生了 B 给 D 5 BTC 的新输出,这个输出将存储在 UTXO 中。

不花就留在UTXO里

所有投入量=所有产出量 总投入=总产出 total\inputs=total\outputs total inputs=total outputs

2.交易费用

某些交易的总输入可能略大于总输出。 例如,总产出可能是1 BTC,总产出可能是0.99 BTC。 差额将作为记账费给予获得记账权的节点。

这是因为它不足以产生区块奖励,给予交易费可以成为其他人记账的动力

火币区块链交易id查询_btc区块交易查询_btc区块链查询网址

这里0.01BTC的手续费已经很高了,一些简单的交易是免费的

目前的激励机制主要是区块奖励

3. 区块示例

img

区块的区块头结构如下:

class CBlockHeader
{
public:
	//header
	int32_t nVersion;//BTC版本号,没法改
    uint256 hashPrevBlock;//前一个区块块头哈希值(32字节):不能改
    uint256 hashMerkleRoot;//通过修改Merkle Tree中铸币交易的CoinBase域来调整其根哈希值
    uint32_t nTime;//区块产生时间,有一定的调整余地,BTC系统并不要求非常精确的时间,这个域可以在一定范围内调整
    uint32_t nBits;//挖矿目标阈值编码后的版本,只能按照协议中的要求定期进行调整,不能随便改

火币区块链交易id查询_btc区块链查询网址_btc区块交易查询

uint32_t nNonce; }

块中的nonce是一个4字节或32位的整数,只有2322^{32}232个值。 因为BTC这几年太火了,挖的人多,所以挖矿难度调的很高。 很可能无法简单地通过调整nonce(搜索空间不够大)得到满足难度要求的解。

btc区块交易查询_btc区块链查询网址_火币区块链交易id查询

铸币交易没有交易来源,可以在CoinBase域中随意写入内容。 铸币交易的变化会改变交易的哈希值,变化会沿着Merkle Tree一路向上传递,最终使整个Merkle Tree的根哈希发生变化,间接调整区块头的哈希值。 因此,这个字段可以看作是一个额外的nonce。 如果block header的nonce域不够用,我们可以调整这个域的一些bytes一起来增加搜索空间。 比如把这个字段的前8个字节作为extra nonce,那么搜索空间会一下子增加到2962^{96}296

在这里插入图片描述

在实际挖矿中,一般会为此设计一个两层循环。 外层循环调整铸币交易CoinBase域的extra nonce,然后计算出Merkle Tree的根哈希值; 内层循环调整区块头的nonce,计算出整个区块头的nonce。 散列值

四、交易示例

image-20220415223227223

BTC系统中交易的输入输出都是由脚本指定的。 验证交易的输入和输出的过程是成对执行输入脚本和输出脚本(不是将同一交易的输入和输出脚本配对,而是将交易的输入和输出脚本配对) 输入脚本被执行与提供硬币来源的交易的输出脚本配对)。 只要配对后能成功执行,则交易验证通过。

5.概率分析

挖矿的过程就是不断尝试nonce来解谜。 每次尝试都可以看作是一次伯努利试验(Bernoulli trial: a random experiment with binary outcome)。 抛硬币是最简单的伯努利实验。 要么抬头,要么抬头。 这两个概率不必相同。 对于挖矿来说,成功和失败的概率相差很大,成功的概率很小。

当进行大量的伯努利试验时,这些伯努利试验就构成了一个伯努利过程(Bernoulli process: a sequence of independent Bernoulli trails)。 伯努利过程的一个性质是无记忆(memoryless),即做大量的实验,前面的实验结果对后面的没有影响,比如多次抛硬币的概率是反面朝上,下次抛硬币时正面朝上也不会增加。

btc区块交易查询_btc区块链查询网址_火币区块链交易id查询

img

当伯努利分布(即二项分布)的n很大而p很小(试验次数多,每次试验成功的概率小)时,可以近似为泊松分布。 这里的挖矿是一个伯努利过程,n大,p小,所以可以近似为泊松过程。

img

6. 公平保障——无进展

出块时间服从指数分布,整个系统的出块时间根据BTC协议调整为10分钟左右

image-20220415224652426

出块时间服从的指数分布也是无记忆的,也就是说,如果从任意位置截去,剩下的部分仍然服从指数分布。 “未来开采了多少时间”与“过去开采了多少时间”没有任何关系。 不管挖了多久,系统平均出块时间仍然在10分钟左右。

无进展 - 过去完成的工作量不会改变后续成功的可能性。 这个属性是必要的。 假设一个加密货币系统不满足progress free,即过去做的工作越多,未来成功的概率就越大,那么算力强的矿工就会有不成比例的优势,这无法按比例计算到计算能力优势的比例。

7. BTC 总量分析

区块奖励是系统产生新BTC的唯一途径,区块奖励每210,000个区块(约每4年)减半,因此新产生的BTC总量形成一个几何序列(geometric series)。

KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ 21\times(50+25...

解决BTC挖矿难题,除了比较算力外,没有实际意义。 虽然挖矿过程没有实际意义,但对维护BTC系统的安全至关重要。 比特币是挖矿的安全。 挖矿提供了一种有效的算力投票方式。

八、安全分析

大部分计算能力掌握在诚实节点手中。 只能说下一个区块由诚实矿工出块的概率比较大,但不能保证记账权不会落入恶意节点手中。 .

火币区块链交易id查询_btc区块交易查询_btc区块链查询网址

将比特币转给他人

假设恶意节点M获得了记账权,想要转账节点A的钱,但是由于无法伪造A的签名(没有A的私钥),写任何错误的签名,都会导致诚实节点不接受这个候选块,而是继续沿着前一个块扩展。因为这个块是非法的,不管它有多长,都不是最长的合法链,这样的攻击是无效的

image-20220415230055513

交易是否成功取决于诚实节点是否接受

分叉攻击

M 将 BTC 转给 A,然后挖矿后立即挖出一个区块。 在这里,他填写了M给自己转BTC的交易,希望成为这个区块沿线最长的合法链,这样才能转账。 为A挤出,回滚消耗的BTC。 这也是一种双花攻击。

image-20220415230640136

假设A是一个允许BTC支付的购物网站。 交易M->A写入区块链后,A认为M支付成功。 花攻击。

如果这个M->A块后面还有一些其他的块,那么这次攻击的难度就会大大增加,因为它最好的方式还是在M->A的前一个块位置插入,但是要让它最长合法链很难,因为它不再是最长的合法链,诚实的节点只会扩展最长的合法链。

image-20220415231305649

如果大部分节点都在诚实节点手中,那么攻击就非常困难,而恶意节点必须连续多次获得记账权,才能改变最长的合法链。 所以最简单的预防方法之一就是多等几个区块,也叫多等几个确认。

image-20220415231416229

默认是等待 6 次确认(约 1 小时)后,才认为一次确认区块中的交易是防篡改的。

零确认:当交易刚刚发布,还没有写入区块链时,认为交易没有被篡改

btc区块链查询网址_火币区块链交易id查询_btc区块交易查询

零确认实际上被广泛使用有两个原因:

1️⃣ 如果两个交易之间有冲突,节点接收最先听到的交易。 在上面的分叉攻击的例子中,M->A 之后的 M->M' 大部分被诚实节点拒绝。

2️⃣ 购物网站委托全节点监控区块链。 从付款成功到发货实际上有一个比较长的处理时间。 如果发现交易最后没有写入最长合法链,购物网站可以选择取消发货。

image-20220415231557539

自私挖矿

一般情况下,节点会在挖到一个区块后立即发布。 这是为了获得区块奖励并收取交易费用。 自私挖矿就是保留所有挖出的区块。 其动机是,比如在之前的分叉攻击中,等到6次确认通过,然后一口气释放计算出的长分叉,替换掉最长的合法链。

其实做起来还是很困难的,因为这个恶意节点的算力必须要超过诚实的算力,才可能在一定时间后比它长。 另外,大多数诚实节点已经扩展了M->A交易所在的区块,这个恶意节点肯定有很多同谋节点。

还有一个好处就是减少了竞争者:比如下图,大家都在从A挖一个区块,然后一个节点挖出B,先把它藏起来。 这个时候其他人还在从A挖出一个区块,然后这个节点再挖出C,把B和C一起放出来,这样就少了一个对C节点的竞争。还是继续往下挖。 听到有人放D,就把B和C一起放,这样最长的合法链就是沿着ABC,别人挖出来的D就失效了。

image-20220415232505946

但这会带来很多风险。 假设有人在挖出C之前先挖出D并发布,这时候你只能快速发布B,很可能连这个记账权都竞争不过。这种自私挖矿的回报不高

参考

1. 比特币和加密货币技术:综合介绍

2. 以太坊白皮书、黄皮书、源代码

3. Solidity 文档

4. 北京大学肖震老师《区块链技术与应用》公开课系列笔记

5.【区块链学习笔记】4:BTC系统的实现