北京大学肖臻老师区块链课程笔记

1.1BTC-密码学基础:哈希、签名

image-20250110112804874

image-20250110113039222

1、比特币中的密码学原理

比特币(Bitcoin)

crypto-currency加密货币

但其实加密货币是不加密的,区块链所有的交易内容都是公开的,包括账户的地址,转账的金额。

比特币中主要用到了密码学中的两个功能:哈希、签名

密码学中用的哈希函数:cryptographic hash function

一、哈希

性质:

1、collision resistance

(哈希碰撞:两个不同输入算出的哈希值相等)/collision free ,但是碰撞是客观存在的,这个resistance是说没有办法人为制造哈希碰撞(ps:这个性质,理论上证明不了。实践经验)

两个输入x和y,如果x != y,H(x)= H(y),这就叫哈希碰撞

不同的输入可能会被映射到哈希表中的同一个位置,一般来说哈希碰撞是不可避免的,因为输入空间远远大于输出空间

例如:256位的哈希值,输出函数的空间:所有哈希值的取值:2^256,但输入空间可以无限大->任意多种输入的可能性

戈农原理:必然两个输入被映射到同一个输出的情况

要求x和y,遍历所有取值可能,brute-force

m->H(m),message digest用来检测对这个message的篡改

比如:有人改message的内容,他的哈希值就会变化。

这个性质说的是你找不到m‘,求H(m’)跟原来的哈希值恰好相等

--》不可能篡改内容又不被检测出来

例:很大的文件,想把他存放到某个云存储服务上,将来用到的时候再把它下载回来,你怎么知道你下载的版本跟当初上传的版本是一样的呢,这就用到hash function collision resistance这个性质,在上传文件之前,算一个哈希值出来,这个哈希值存在本地,将来下载之后,再算一个哈希值,跟原来的比较,一样:上传的文件没有被篡改,下载的还是原来那个版本

2、hiding

哈希函数的计算过程是单向的,不可逆的,

给x算出H(x),但是给H(x)没办法反推x,

这个哈希值没有泄露有关输入x的任何信息,

hiding成立前提:输入空间足够大,使蛮力求解的方法不可行

输入分布比较均匀,各种取值的可能性都是差不多的

比如如果输入空间比较大,但是绝大多数情况下取值集中在少数几个值,也是比较容易被破解

两个性质结合在一起,实现digital commitment

digital equivalent of a sealed envelope

比如:一个人预测股票会涨停,验证预测准不准确的方法如,这个人提前一天在电视台上公布预测结果:我预测明天某某股票会涨停,第二天收盘后,看这个股票是否真的涨停,

问题:如果预测结果提前公布了,可能会影响股市,比如这个人很有名气(股神),本来大家认为这只股票不会涨停的,她公开预测,大家买,结果把他变成了涨停(或者反方向的情况也可能发生(砸盘))

--》预测结果不能提前公开

H(x || nonce)

nonce:选取的一个随机数保证

除了密码学中要求的两个性质外,比特币中用到的哈希函数还要求第三个性质,

3、puzzle friendly

(挖矿的过程没有捷径,只能靠不停地尝试大量的nonce才能找到符合要求的解,所以这个过程才可以用来作为工作量证明:proof of work。你挖到矿了,找到符合要求的nonce了,一定是因为你做了大量的工作,没有捷径。但是一旦有人找到这个nonce,别人要验证是否符合要求,是很容易的。(难找易验)挖矿很难,验证很容易-》

(difficult to solve, but easy to verify))

哈希值的计算,事先是不可预测的

你想求在某范围内的哈希值,只能一个一个输入,

image-20250110121358483

挖矿实际上就是找一个nonce(跟区块的块头里的其他信息合在一起作为输入,取出一个哈希来,哈希值要小于等于某个指定的目标阈值

image-20250110121610029

区块链,一个一个区块组成的链表,每一个区块有块头,块头有很多个阈,其中有一个阈是我们可以设置的随机数nonce

挖矿的过程:不停地尝试各种随机数,使得整个block header取哈希后,落在指定的范围之内(target)

image-20250110122020639

比特币中用的哈希函数SHA-256

secure hash algorithm

二、签名

比特币系统中的账户管理

日常生活要开账户:带证件去银行办理开户手续

(中心化系统的账户管理方式)

比特币:去中心化,没有银行之类的机构。

怎么开户?每个用户自己决定开户,不需要任何人批准,开户的过程:创立一个公钥和私钥的对。在本地创立一个公私钥对,就是一个账户

image-20250110122845695

公私钥这个概念,来源于非对称的加密体系,asymmetric encryption algorithm

最早的加密体系是对称的,最早叫做symmetric encryption algorithm

两个人通信,通讯的网络有可能被窃听,于是两个人事先商量好一个密钥(encryption key),我把这个信息加密之后发给你,你收到之后用这个密钥解密,因为加密和解密用同一个密钥,所以叫做对称的加密体系,前提是假设有某种安全的渠道能够把这个密钥分发给通讯的双方,因为密钥不能以明文的形式在网络上传输,(假设网络本身不安全),对称加密体系的弱点:密钥的分发不是很方便

加密用公钥,解密用私钥。

比如要把一个信息传给你,我用你的公钥给这个信息加密,你收到之后,用你的私钥解密得到原来的信息,(加密和解密用的是同一个人的公钥和私钥,都是接收方的公钥和私钥。

好处:解决了对称加密体系中密钥分发不方便的问题(加密的公钥不用保密,私钥要保密,但是私钥只要保存在本地就行,不需传给对方。给你通讯的人不需要知道你的私钥。你要回复他,相同的做法,你变成发出方,他变成接受方)

(用他的锁,只有他有钥匙能打开)

比特币是加密货币,但其实是不加密的,信息是公开的。

公私钥是用来实现签名功能的

比如我要发10个比特币给你,我把这个交易发布到区块链上,别人怎么知道这个交易是由我发起的呢

(会不会有人冒名顶替,把我账户的钱转走了(公钥=银行账户,私钥=账户密码))

需要我在发布这个交易的时候,用我自己的私钥对这个交易签名,其他人收到交易后,用我的公钥验证这个签名的正确性。

(签名用发出方的私钥,验证签名用发出方的公钥(都是同一个人的))

如果两人生成的公私钥对恰好相同怎么办?

比如有人要偷比特币,可以大量产生公私钥,对比我产生的公钥跟区块链上已有的某个公钥是否相同,一样:用对应的私钥把账上钱偷走。理论上可以,但实际上很难,2^256的公私钥,产生相同的公私钥的可能性很小,

比地球爆炸的概率还小,到目前为止,还没有这种方法攻击成功的先例

假设生成公私钥的过程有一个好的随机源

a sood source of randomness

如果选取的随机源不好,前面的分析就不成立了(比如有可能两个人的公私钥对一样),

比特币中用的签名算法,不光是生成公私钥的时候要有好的随机源,之后每一次签名的时候也要有好的随机源,只要有一次随机源选取不好,就有可能泄露私钥-》全完了

比特币系统,一般先对一个message取一个哈希,然后再对这个哈希值签名

1.2BTC-数据结构

1、区块链

区块链表和普通链表的区别:

1、用哈希指针代替普通指针

image-20250111131855283

最前面的区块是系统中产生的第一个区块-->创世纪块

最后的区块是最近产生的区块

image-20250111132226759

这种数据结构的好处?我只需要记住最后这个哈希值H()就可以检测出对区块链中任何部位的修改(无论哪个部分改动,最后都会导致保存的哈希值变化)-->多米诺骨牌效应

取哈希:把整个区块的内容合在一起取哈希。图中粉色全部(包括哈希值H())

image-20250111132401178

image-20250111132321988

比如我修改粉色部分,会导致后面的哈希值变化,再导致后后面的哈希值变化,最终影响到最后一个H(),所以要检测是否被篡改,只需要将最后一个H()保留在系统中,他变了,就说明前面有人变了

怎么知道别人给的区块是否正确?(哈希指针的性质)

只保存后面的区块,前面不保存,用到了再问别人要。

算他的哈希值,跟保存的哈希值对比一下就知道了

image-20250111133040212

2、Merkle tree

与binary tree的区别:

1、用哈希指针代替普通的指针

image-20250111133427814

一个数据块,他的哈希值存在上面那个节点,旁边的数据块也存在上面这个节点旁边

image-20250111133534693

两个哈希值拼在一起,再取哈希,存在上层节点

最上面的哈希值H()叫root hash

image-20250111133646079

只要记住根哈希值,就能检测出对树中任何部位的修改(整棵树都得到了保护)

image-20250111133921217

底下每一个数据块实际上是一个交易transaction

image-20250111134023445

每个区块分为两部分:块头和块身

block header

block body

在block header里有root hash

包含的所有交易组成的Merkle tree的根哈希值存在这个区块的block header里面,但是block header里没有交易的具体内容,只有一个根哈希值,block body里有交易列表

Merkle tree的作用:提供Merkle proof

比特币节点是比特币网络的支柱。它们确保和验证交易,并将它们广播给其他节点。主要有三种类型的节点:全节点、轻节点和挖矿节点。full nodes、miner nodes、light nodes

比特币中的节点分为两类:全节点、轻节点

全节点:保存整个区块的内容(block header、block body)交易的具体信息

轻节点:(如手机中的比特币钱包的应用)只保存一个block header。(轻量级节点)

问题:如果需要向一个轻节点证明某个交易是写入到区块链

比如:你向我买一些东西,需要转给我一笔钱。你跟我说你转给我的交易已经写到区块链里了,支付已经完成了。我是轻节点(比如只能在手机上查,怎么知道这个交易已经被写到区块链里了???

找到这个交易所在的位置,从这个交易往上一直到根节点的路径,这条路径就是Merkle proof

image-20250111192439435

image-20250111192502620

怎么知道黄色交易是否包含在Merkle tree里?

轻节点没有交易列表,没有这棵Merkle tree的具体内容,只有一个根哈希值(因为根哈希值是保存在block header里的)这个轻节点有block header。

轻节点向某个全节点发出请求,请求能够证明黄色交易包含在Merkle tree里的Merkle proof,收到请求之后,只要把图中标为红色的这三个哈希值发送给这个轻节点就行,有了这些红色哈希值,轻节点可以在本地算出图中标为绿色的三个哈希值

image-20250111232725712

首先算出黄色部分的哈希值,然后跟右边这个红色哈希值拼接起来,算出上一层节点的绿色哈希值,再跟左边这个红色哈希值拼接起来,再算出上一层节点的绿色哈希值,然后再跟右边这个红色哈希值拼接起来,算出整棵树的根哈希值,轻节点把这个哈希值跟block header里的根哈希值比较,就能知道黄色交易是否包含在Merkle tree里

image-20250111232837951

image-20250111232921268

全节点在Merkle proof里提供的这几个哈希值,就是从黄色交易所在的叶节点的位置到根节点的路径上用到的所有哈希值。

轻节点收到merkle proof之后,只要从下往上验证这些哈希值是否正确即可

只能查自己所在路径的那支,旁边的哈希值是查不了的(红色值算不出来,只能全节点给出)。

那旁边的哈希值你查不到不就给篡改哈希值制造一定的自由度了吗?

能不能两个哈希值(绿色和红色交易)都改了,这样上一层哈希值不就不变了吗?

-->人为制造哈希碰撞

实际中不可行,collision resistance这个性质

image-20250112004013870

Merkle proof可以证明Merkle tree包含了某个交易,所以这个证明也叫proof of membership/proof of inclusion

我是轻节点,你发给我一个Merkle proof,验证的复杂度是多少?时间、空间?

对地下这一层有n个交易,复杂度是对数级别,O(log(n)),较高效

能不能证明不包含某个交易?proof of non-membership?复杂度O(n)

最简单的证明方法(暴力遍历):把整棵树传给轻节点,验证树的构造都是对的,每一层用到的哈希值都正确,说明这些树里只有这些叶节点,没有别的,找的交易不在这里面,就证明了。。。

答案是没有更高效的方法,但是对叶节点的排列顺序要求,对交易的内容取哈希,按照哈希值从小到大排序,我要查的那个交易,算出一个哈希,看他在哪里。比如说在图中黄色部分中间(箭头指向),提供的proof包含这两个节点往上的路径到根节点,最后算出root hash都正确。

(除了左边那个交易,右边也得算进去)说明这两个节点在原来的Merkle tree里是相邻的节点,我要找的交易如果存在,应该在这两个之间,但是他没有出现,所以不存在。复杂度O(log(n)),但是要排序。

image-20250112005652797

image-20250112005444375

排好序的叫sort Merkle tree。

但是比特币里不需要排序,因为不需要证明不存在

区块链和Merkle tree都是用哈希指针(hash pointers)来构造。

那哈希指针还能用在哪里?只要这个数据结构是无环的都可以用哈希指针代替普通指针

例如:循环链表。如果用哈希链表的话,第一个hash pointer要依赖第二个hash pointer,所以得把第二个区块内容定下来,才能定第一个区块内容,第二个区块依赖第三个区块内容,而第三个区块依赖第一个区块内容。最后所有区块都未定-->循环依赖

image-20250112010313063

1.3BTC共识协议

double spending attack

引导

image-20250112140616416

CB(center bank)发行100元和50元,发行的数字货币都有CB的私钥签名,CB的公钥大家都知道,

我收到数字货币可验证真伪,买东西的时候,把数字货币发给你,你验证确实是CB发行的。这就完成了支付的过程。但是这个方案有很大的问题。

应用:密码学中公私钥体系、非对称加密算法,但是没有用到区块链。

(假设CB的私钥不会泄露,因为如果CB都会泄露,那普通人的就更会了,那比特币就没用了)

如果CB无限制发行货币-->通货膨胀。例如美联储量化宽松,影响市场的金融秩序。

更大的问题:这是一个文件,文件的内容不可伪造,但是文件可以复制,买一个东西给一个文件,与纸质货币不一样,给了就没了

数字货币和纸质货币的区别:double spending attack花两次攻击/双花攻击

改动:(还是CB发行数字货币)每个数字货币上有一个编号。央行要维护一个大的数据库(表),上面记录每个编号的数字货币在谁手里

image-20250112141637178

记录内容:以前在我这,现在给你了,在张三手里,张三支付是合法的。例如下图,现在在xz手里,改动后,现在在zjc手里,

image-20250112141850103

image-20250112141839238

央行核实后,人不对,这个数字货币已经花出去了-->double spending attack

缺点:太麻烦了,且是中心化方案(货币发行是央行控制、交易需要央行确认才能证明合法)

比特币中,谁来发行货币?挖矿。如何防范double spending attack?与上述类似,也是需要维护一个数据结构来检测是否发生交易。区别在于这个结构由所有用户共同维护,这个数据结构就是区块链

交易分为输入和输出

输入部分要说明币的来源和A的公钥;输出部分要给出收款人的公钥的哈希

铸币交易coinbase tx

image-20250112144837127

image-20250112144928045

两种哈希指针

1、连接各个区块(串起来)构成一个链表

2、指向前面某个交易,为了说明币的来源(记录,防伪和DSA)

image-20250112145455181

最后一个区块显示,B给F五个币,这里的B指向来源(A-》B),别的节点收到这个交易后,从这个区块往B的来源回溯,查到B-》C那里发现不对,,A-》B的钱已经被花出去了,说明最后这个交易(B-》E)不合法,就不会把他接受到区块链里

image-20250112145411026

image-20250112145554438

A-》B这个交易需要什么信息?

A的签名、B的地址。

在比特币系统中,收款的地址是通过公钥推算出来的,如B的地址,通过B的公钥取哈希得到

银行本身没有提供查询的功能(指定某个人,可以查到他的账户),都是你要告诉我(接收方告诉发起方),比特币系统类似,也没有提供查询功能。

A需要知道B的地址,B需要A的信息吗?必须知道A的公钥。(我得知道钱从哪来的)

思考,如何证明这个交易已经写进去?先要证明交易要写到区块链之前,需要符合什么条件?A有无足够的币的来源,指向铸币的交易,币的来源是A要证明的,与B无关。

每个节点必须知道A的公钥。因为私钥签名公钥验证(更重要的原因),每个节点都得独立验证(有可能有恶意节点),不能依靠别人,我收到这个交易,验证是否合法。假设A转给C,B作为旁观者也需要验证。

这与现在网上购物不同,现在:A、B、C访问电商平台x.com,这个网站公布公钥方便B和C交易,与A无关,因为这是B和C在做交易。

问题:

B‘ 伪造A-》B 的转账交易,B'用自己的公钥在输入中说是A 的公钥,用自己B’的私钥签名。别的节点收到后,用假造的公钥验证签名,肯定对以为交易合法。(A的公钥要和币的来源里说明的A的公钥的哈希要一致才合法)

公钥是A宣称的,如何防范安全漏洞?防范措施:需要与币的来源一致,否则非法。

(A给B发送信息,非对称加密体系,用B公开的的公钥加密,B收到之后用自己B的私钥解密。B需要传给A的时候,B变成A,此时需要用A的公钥加密,A用A的私钥解密)

验证过程是通过执行脚本完成的,每个交易的输入是一段脚本,公钥也是在输入的脚本里指定的,输出也是脚本,如何验证?输入脚本和前面交易(提供币的来源的交易)的输出脚本拼接在一起,能否顺利执行

比特币脚本BitCoin Script

Block header

(放的是宏观的信息),如

1、比特币哪个版本的协议version、

2、区块里指向前一个区块的指针hash of previous block header(只算前一个区块的块头)、

3、整棵Merkle tree的哈希值Merkle root hash、

4、(与挖矿相关)挖矿的难度目标阈值target(H(block header) <= target,整个块头的哈希小于目标阈值,block header里存的就是目标阈值的一个编码nBits,挖矿求的puzzle)、

5、随机数nonce

指针画在上面,原因:只有block header才有哈希指针。也可以把每个区块看成两部分(上面是block header,下面是block body)

image-20250112194438203

Block body

包含:transaction list交易列表

取哈希,把块头的所有部分取哈希。

Merkle root hash已经保证block body所包含的transaction list无法被篡改

image-20250112194656931

full node全节点,保留区块链所有信息,验证每一个交易,所以也叫fully validating node

light node轻节点(light weight node)只保存block header的信息,无法独立验证交易的合法性(比如是否双花攻击,没存以前的交易信息,无法查询)

大多数节点是轻节点,但是轻节点没有参与区块链的构造和维护,他只是利用区块链的信息,做查询操作

这些内容如何写入区块链?

区块链是一个去中心化的账本

账本的内容要取得分布式的共识distributed consensus

例子:

分布式的哈希表distributed hash table

很多台服务器共同维护一个分布式哈希表

需要取得共识的内容:哈希表中的内容:key-value pair键值对

image-20250112205646673

结论1:FLP impossibility result不可能结论

FLP(三个作者名字首字母)

在一个异步的系统asynchronous里,网络传输时延没有上限,即使只有一个成员有问题faulty ,也不可能取得共识

结论2:CAP Theorem

CAP:分布式系统的三个性质

consistency一致性

availability分布可用性

partition tolerance容忍性

任何一个分布式系统,比如分布式哈希表,这三个性质最多满足两个

协议:Paxos

这个协议可以保持一致性

如果协议达成了共识,这个共识一定是一致的(不会出现两个成员共识不一样)

这个协议有可能无法达成共识(虽然在实际中概率小,但是存在)

拜占庭将军问题 (The Byzantine Generals Problem)

拜占庭将军问题 (The Byzantine Generals Problem) - Liebing's Blog

byz.pdf

Consensus in BitCoin

假设大多数节点是好的,小部分是恶意的,这种情况下如何设计共识协议?

想法:

1、既然大多数节点都是好的,那直接投票吧。超过半数赞成则通过

问题:

(1)哪一个节点提出是个问题,如恶意节点不断发布候选区块,把时间都浪费在投票上

(没有办法强迫每个节点投票,都不投票区块链就陷入瘫痪状态)

(2)投票的网络延迟问题

(3)更大的问题:membership(任何基于投票的方案首先要确定谁有投票权)

如membership有严格定义,不是谁都可以加入的,如联盟链hyperledger,只有某些符合条件的大公司才能加入

如hyperledge fabric,一个联盟链的协议,这种情况下投票方案可行-->假设大多数成员是好的

但是比特币系统不是这样的。

女巫攻击(Sybil Attack)

比特币系统创建账户很容易,在本地产生一个公钥私钥对,就是一个账户,不需要任何人批准。(别人也不知道)光产生公私钥对被人是不知道的,只有跟外部产生交易的时候,别人才知道有这个账户的存在。

那现在搞一台超级计算机,什么事都不干,就干投票,产生超过半数的节点就有控制权了

这就叫女巫攻击

什么是女巫攻击 – 比特币行情

女巫攻击及其防范 - 知乎

如何防范?

挖矿mining,数字黄金digital gold

矿工miner:争夺记账权的节点

比特币的特殊投票,不是按照节点数目,而是计算力来投票

每个节点都可以在本地组装出一个候选区块,把他认为合法的交易放到这个区块里,然后尝试各种nonce值,

computational puzzle。

image-20250112220312085

block header里有个域,是个随机数nonce(4 byte),组装好区块后,就开始试各种各样的随机数。

节点获得了记账权:某个节点找到了某个区块的nonce

记账权:往比特币去中心化账本里写入下一个区块的权利

只有找到nonce获得记账权的节点,才有权利发布下一个区块。其他节点收到区块后,验证区块的合法性。如验证block header的内容,如nBits(目标阈值的一个编码),检查nBits域设置是否符合比特币协议中规定的难度要求

这里的合法:只是说区块的内容不包含非法的交易(每个交易都是有合法的签名,签名用的币以前都没有被花过、block header域里都合法)

但是是插在中间

image-20250112221335489

收到一个区块后,怎么知道插在哪里?

根据前一个区块的指针(hash of previous block),就知道他是插在这个位置

image-20250112221607058

A转给B,

A又转给自己A‘(这个交易本身也合法,但是不在最长合法链上)

判断一个交易是否double spending?看这个区块所在的分支,在这个分支上,币有没有被花过两次

image-20250112221903765

image-20250112222025367

比特币协议规定:

接受的区块应该是扩展最长合法链,接在后面才是合法区块

上图是分叉攻击forking attack的例子(通过往中间位置插入一个区块,来回滚某个已经发生了的交易)

但是也有可能发生,如两个节点同时获得记账权,会出现两个等长的分叉

image-20250112222313994

什么叫接收一个区块?如恶意节点不接收,那怎么区分他是否接收?

implicit concern。如果沿着这个区块往下继续扩展,就算是认可你发布的区块

image-20250112222623222

两个分叉会临时维持一段时间,直到其中某一个分叉最后胜出

假设上面这个分叉抢先一步找到了下一个区块,上面的分叉就变成了最长合法链,下面那个就叫做orphan block

算力竞争

获得记账权的节点的权利:可以决定哪些交易被写到下一个区块里,但是设计协议的时候,不应该让这个成为争夺记账权的主要动力

比特币的解决机制:出块奖励block reward

获得记账权的节点,在发布的区块里可以有一个特殊的交易(铸币交易coinbase transaction)在这个交易里可以发布一定数量的比特币

一个去中心化的货币要解决两个问题:

1、谁有发币权

2、怎么验证交易的合法性

下面解决谁有发行货币的权利的问题:

coinbase transaction

是比特币系统中发行新的比特币的唯一方法,其他所有的交易,都只不过是把已有的比特币从一个账户转移到另一个账户。

(如:用美元购买比特币,也没有产生新的比特币)

这个不用指明币的来源(因为币是凭空造出来的)

能产生多少个BTC呢?

每21w个区块,奖励减半

出块奖励50BTC-->-25BTC->12.5BTC--》6.25--》3.125(每个区块)

(比特币的区块奖励在 2020 年至 2024 年期间为 6.25 枚比特币 / 区块,根据其每四年减半一次的机制,预计 2024 年至 2028 年奖励将降至 3.125 枚比特币 / 区块。每四年一次减半)

We are tillvery,very early.

(根据 CoinMarketCap 2025 年 1 月 12 日的数据,比特币的流通供应量为 19,790,000 枚,总供应量也为 19,790,000 枚,占最大供应量 21,000,000 枚的 94.27%。)

问:orphan block在竞争中失败了,那是不是出块奖励没用了?是的。

如果上面有一个很长的区块链变成了主链(最长合法链),下面的分叉点记多少BTC,但是验证交易的时候,是验证区块所在的分叉是否正确(BTC协议要求接受最长合法链),如果你的交易接在一个很短的分叉后面,这个分叉上得到的BTC没用,因为大多数诚实的节点不会接受。

比特币系统需要取得的共识:去中心化的账本

只有获得记账权的节点才能往里面写东西,

那怎么获得记账权呢?解block header的随机数

如果A节点的算力是B节点的十倍,那A获得记账权的概率是B的十倍

不是普通的投票,而是看每秒钟能产生多少个nonce--》hash rate(决定投票的权重)

1.4BTC账本系统的实现

1、transaction-based ledger

没有记录账户上有多少钱,需要通过交易记录来推算

全节点要维护UTXO(Unspent Transaction Output)的数据结构

假设B花掉了5个BTC,C没花掉,所以B不在UTXO里,C在

image-20250113140843397

UTXO,每个元素要给出产生这个输出的交易的哈希值,以及他在这个交易里是第几个输出

为了防范double spending

想要花的钱在UTXO里才合法

image-20250113141148042

total inputs = total outputs

1 BTC 0.99BTC

第二个激励机制:transaction fee差额BTC作为交易费给获得记账权发布区块的节点

21w * 10min/(60min24h365d)约等于4年

2、account-based ledge

系统要记录每个账户有多少个币

image-20250113142413906

计算哈希值的时候,都是只算block header,不包含block body里具体交易列表

image-20250113142524824

H(block header)<= target

16进制

相同点:凡是符合难度要求的区块,块头的哈希值算出来都要有一长串的0

image-20250113142714466

uint32_t:32位无符号整数

就算把2^32可能的取值都遍历一遍,都有可能仍然找不到符合难度要求的。

原因:价格上涨(有利可图)-》挖矿的人多了-》竞争激烈-》挖矿难度调高-》单纯调整block header里nonce域,大概率找不到符合要求的(搜索空间不够大)

image-20250113143104235

version:当前使用BTC协议版本号(无法改)

previous block header hash:前一个区块的块头的哈希值(无法改)

merkle root hash根哈希值?(改这个把)

time:这个区块产生的时间,BTC系统不要求非常精确的时间,可在一定范围内调整(无法改)

nBits:挖矿时的目标阈值,这里是目标阈值编码后的版本。只能按照协议要求定期调整(无法改)

nonce:随机数。(光改这个不够)

image-20250113143521414

image-20250113143618652

image-20250113143652421

把coinbase域的前八个字节当做extra nonce来用,搜索空间--》2^96

真正挖矿的时候只有两层循环,外层循环调整coinbase域的extra nonce算出block header里的根哈希值之后,内层循环再调整header里的nonce

image-20250113143953068

验证交易合法性:将input scripts和output scripts配对后执行,不出错

不是把图中两个input scripts和output scripts配对,这两个脚本是同一个交易的脚本,不是把同一个交易里的输入和输出脚本配对而是把这个交易里的输入脚本跟前面提供币的来源的交易里的输出脚本配对

image-20250113144325001

tx产生的误解需注意

block header里没有交易的具体信息,只有一个Merkle tree 的根哈希值,这就足以保证整个区块包含的交易无法被篡改

分析挖矿过程的概率

挖矿:不断尝试各种nonce来求解puzzle

每次尝试nonce可看做一个Bernoulli trial(a random experiment with binary outcome)

(最简单的二分实验:掷硬币)

Bernoulli trial:a random experiment with binary outcome

Bernoulli process:a sequence of independent Bernoulli trials

Bernoulli process的性质: memoryless无记忆性:做大量实验,前面的实验结果对后面的实验没有影响

Poisson process

exponential distribution

出块时间服从指数分布(也是无记忆的)

整个系统的出块时间,并不是每个具体矿工的出块时间

Probability density概率密度

time to next block下一个出块时间

image-20250113171906511

曲线分析:从任何部分截断,剩下的曲线跟原来一样(服从指数分布)

与直觉相悖:现在还需挖多长时间,跟过去已经挖了多少时间没关系

progress free:过去的progress是没有用的

如果没有这种无记忆性,算力强的矿工会有不成比例的优势

(因为算力强的在过去的工作量大)

比如:系统中有两个矿工,A的算力是B的十倍,那么理想状况下,算力强的A,找到puzzle nonce的概率应该是B的十倍,这才叫公平。因为算力强的矿工能够尝试的nonce的数目是另一个的十倍,(memoryless保证)

如果没有这种无记忆性,算力强的矿工会有不成比例的优势:算力强的矿工获得记账权的概率会超过十倍,因为他过去尝试的不成功的nonce,下次nonce成功的概率就会增大

分析BTC的总量

出块奖励是系统产生新的BTC的唯一途径,而出块奖励是每隔四年要减半的,这样产生的BTC数量构成几何序列geometric series

image-20250113173043555

BTC求解puzzle除了比拼算力外,没有其他实际意义

BTC越来越难被挖到,是因为出块奖励被人为地减少了

BTC的稀缺性是人为造成的

挖矿求解puzzle本身是没有什么实际意义的,但是挖矿的过程对于维护比特币系统的安全性是至关重要的

BitCoin is secured by mining.

对于一个去中心化的,没有membership控制的系统来说,挖矿提供了一种凭借算力投票的有效手段,只要大部分算力是掌握在诚实的节点手里,系统的安全性就能够得到保证

出块奖励减半,但是挖矿的动力丝毫不减,过去几年,挖矿竞争激烈,BTC价格飙升

奖励减到0是不是大家就没动力挖矿了?不是,还有第二种激励机制:交易费

分析BTC的安全性

假设大部分算力掌握在诚实的节点手里,可以得到什么样的安全保证?

不能保证记账权不会落到恶意节点手里,因为挖矿得到区块大概率会落到诚实节点手里,但是恶意节点成功也是有可能的

1、不能偷币(不能伪造签名)

不能把别人账上的钱转到自己账户里,因为他没办法伪造别人的签名

image-20250113174522142

硬往里写,诚实的节点不会接受这个区块

image-20250113174552052

诚实的节点会继续沿着上一个区块挖

恶意节点的攻击是否成功的标志:能不能让诚实节点接受这个交易。(如果仅仅是恶意节点之间互相认账,诚实节点不认账,那是没用的)

image-20250113174755330

2、能不能把已经花了的币再花一遍?double spending attack

分叉攻击Forking attack

image-20250113174934185

区块插在哪个位置,是要在刚开始挖矿的时候就要决定的。因为设置的block header里要填上前一个区块的哈希,M节点想插入这个位置的话,一开始就要把这个区块设置成前一个区块(而不是等获得记账权之后再说)

image-20250113175119924

如果M-》A的钱产生了某种不可逆的外部效果,下面交易把这个交易回滚了,M就可以从中不当获利

例子:网上购物,M购买商品,网站接受BTC支付,他发起交易,把账转给这个网站,网站监听(电商委托某个全节点,监听区块链上的交易)到这个交易写到区块链里,以为支付成功了,所以把商品给了M,M拿到商品后又发起交易,把钱转给自己,然后把下面(转给自己那个分支)扩展成最长合法链,这样上面的区块就作废了

image-20250113175555788

如何防范?多等几个区块/确认confirmation

如果M-》A不是最后一个区块,而是连了好几个,那要回滚这个交易的难度就大大增加。因为还得在原来那个区块中间插入(而不是上图的最后一个区块)

image-20250113175641119

image-20250113175737097

有恶意的节点获得一次记账权是不够的。

image-20250113175908209

一直到6个确认,才认为前面那个是不可篡改的,需要等6*10=1h。

irrevocable ledger不可篡改的账本

不可篡改性只是一种概率上的保证,刚写入区块链的内容相对来说比较容易被改掉,经过好几个确认之后,被篡改的可能性大幅下降,呈指数级别的下降

zero confirmation零的确认:转账交易发布出去,但是还没被写入区块链里

image-20250113180257836

电商委托某个全节点,监听区块链上的交易。收到转账交易后,验证交易的合法性(合法签名、没花过),不用等到交易被写到区块链里

零确认应用普遍的原因:

1、比特币协议缺省的设置是节点接收最先听到的的那个交易,两个交易有冲突,你最先收到哪个就接受哪个(比如M-》A,M再转给自己,诚实的节点不接收)

2、很多购物网站,从支付成功到收到货物,有时间间隔(天然有一定的处理时间),比如买个笔记本电脑,在网上支付成功,电商第二天才会把电脑发货。所以如果发现转账交易最后没有被写到最长合法链上,电商可以选择取消发货

分析恶意节点获得记账权后可以做什么

如故意不包含某些交易,BTC协议没有规定获得记账权的节点一定要把某些节点包含在区块链里,但是这些合法的交易终究会被写到下一个区块里(总有诚实的节点愿意发布这些交易)

但其实在正常工作情况下,也会出现合法的交易没被包含的情况,可能就是这段时间交易的数目过多

BTC协议规定每个区块的大小有限制

selfish mining:得到区块后不发布隐藏起来

正常情况下,挖到区块马上发布,因为比人也会发布,你就得不到出块奖励了,

但是这种为了分叉攻击隐藏区块的做法,成功的概率很小,除非恶意节点超过50%的算力

selfish mining的好处:减少竞争

image-20250113182146276

建立在恶意节点算力强,运气好的情况下:

B区块挖出来后,不发布,挖到C也不发布,这时候别人还以为那个是最后一个区块,在挖A,等到别人发布A的时候,马上把C发布----》A白挖了,恶意节点获得两个出块奖励

但是风险很大:你没发布,以为你能在别人前面挖到下一个,如果你还没挖到C别人已经挖到A了,那你得赶紧发布,跟A抢,有可能抢赢

1.5BTC网络

新发布的区块在BTC网络上怎么传播?BTC网络的工作原理

The BitCoin Netwotk

1、BTC工作在应用层application layer :BitCoin Block chain

底层是网络层network layer:P2P Overlay Network

BTC的P2P网络很简单,所有节点是对等的,没有超级节点Super node和主节点master node

2、你要加入网络,你得和种子节点(seed node)联系,他会告诉你他所知道的网络中的其他节点

节点之间通过tcp通信,有利于穿透防火墙,离开不需要做操作。

3、特点:simple,robust,but not efficient

每个节点维护一个邻居节点的集合,消息传播在网络中采取flooding的方式,节点第一次听到消息后,把他传播给其他所有邻居节点,同时记录自己收到消息,下次再收到的时候,不需要再转给邻居节点(避免交易在网络上无限传播)

邻居节点的选取随机,没有考虑底层的拓扑结构

4、每个节点要维护一个等待上面交易的集合

交易的合法性(签名、双花)

每个节点根据在网络中的位置不同,收到交易的顺序不同,先收到交易的写入集合,另外一个就非法

image-20250113224741420

已经写入到区块链的交易在集合中就得删掉

如果听到的新发布的区块是A-》C(已经写入区块里,另一个就非法),那集合中A-》B的交易也得删除

image-20250113225044660

新发布的区块在网络上的传播方式与新发布的交易类似

每个节点要检查

1、区块内容的合法性

2、是否在最长合法链上

越大的区块在网络上的传播速度越慢

BTC传输限制:1M

BTC网络的传播属于best effort:一个交易发布到BTC网络上,不一定所有节点都能收到,不同节点收到交易的顺序不一定一样,网络传播延迟(可长可短),有的节点不一定按照BTC协议的要求进行转发(合法的不发,不合法的使劲发)

如果同时发布A-》B和A-》C,需要同时判断是否写过和有无冲突?

看节点是否恶意,正常不应该转发非法交易,但有节点不按规则来

双花攻击:花过的钱重新花,想办法把第二个重复花的交易转发到各个节点上,诚实的节点可能会拒绝

但是算力足够强,有可能把下面分叉链变成最长合法链

上面讲过一种正方:消费者攻击商家:分叉攻击,让交易回滚,拿回花出去的钱

还有反方:商家攻击消费者:钱支付给商家了,商家不发货或者发有问题的货,普通百姓不可能把交易回滚(回滚成本大于购买的金额)这是线下问题(线上系统都解决不了线下问题)这属于支付系统之外的事情。

支付宝这种中心化机构,出问题找平台投诉,但是BTC去中心化系统内部没办法受理投诉。

如何解决?电商有一定的信任,老这样别人就不买了

区块链回滚很麻烦,银行转账这种支付方式的投诉不是通过回滚的方法,而是产生一个新的交易,A转给B,有纠纷,B如果承认错误,把钱回转给A。BTC也是,商家退钱给你,不需要回滚(人理解的后一个交易是对前一个交易的退款)。

1.6BTC挖矿难度调整

target越小,挖矿难度越大

调整挖矿难度:调整目标空间在整个输出空间中所占的比例

BTC用的哈希算法:SHA-256(Secure Hash Algorithm 256-bit)

产生256位的哈希值,整个输出空间为2^256个可能取值

image-20250114174407429

通俗的说就是哈希值前面有多少个零

如:256位哈希值,合法的区块按要求算出来的哈希前面至少有70个零

挖矿难度和目标阈值成反比

difficulty = difficulty_1_target / target

difficulty_1_target:挖矿难度等于1的时候对应的目标阈值

挖矿难度最小是1

算力越强难度不变出块时间越短

出块时间短的问题:分叉成为常态,甚至多分叉

如果不到1秒钟就出块,区块在网络上传播的时间可能需要几十秒,底层的BTC网络需要几十秒的时间才能让其他节点收到。其他节点没有收到区块时,还是沿着已有的区块链往下扩展。

如果两个节点同时收到,同时发布了一个区块---》分叉

image-20250114175254861

image-20250114175503375

分叉过多,不易达成共识,危害系统安全

BTC协议假设大部分算力掌握在诚实的矿工手里,系统总算力越强,安全性越好,因为要发动51%攻击(51% attack),所需要的算力越大

image-20250114175643808

如果出块时间短,分叉攻击很容易成为最长合法链

以太坊的出块时间是15秒,这时候需要设计新的共识协议:ghost

多个分叉叫orphan block,不能简单地丢弃掉,给奖励(uncle reward)

以太坊同样需要调整出块难度,使得出块时间保持稳定

BTC规定每隔2016个区块重新调整目标阈值(2 weeks)

image-20250114180323555

如果实际时间超过2 weeks,说明平均出块间隔超过10min,所以应该降低挖矿难度,让出块更容易,反之亦然。

目标阈值增大最多增大四倍,不会一次性超过四倍,为了避免系统意外发生,导致目标阈值大波动

以上都是写在代码里的(开源),如果恶意节点不调怎么办?

(nBits是target编码的版本)该调不调,检查区块的合法性就不通过

历史上20年很多BTC都失败了,BTC的成功不是因为它更实用,是因为它更不实用,以前的加密货币设计成现实货币的电子支付,BTC没有任何真正的法币背书的。

中本聪设计的很多参数都有争议: 1、每个出块时间10min

2、每个块最多一兆字节1 M

3、每2016个区块调整出块难度(以太坊每个区块都可以调)

总的来说是比较保守的,出块时间、区块大小、支持的脚本语言

BTC系统的实际情况

图示BTC总算力的变化情况

image-20250114181657369

BTC没有流行起来之前,很长一段时间算力没有明显的增长,前面几年的hash rate几乎是0。其实前几年都是有增长的,只不过后面几年增长过快,算力呈现指数级增长

算力不是单调递增的,中间也有波动

图示挖矿难度,不是目标阈值(与算力增长同步,也符合难度调整的设计目标:通过调整挖矿难度,使得出块时间保持稳定)

image-20250114181734750

图示近半年的挖矿难度

image-20250114181844811

每个2 weeks难度上一台阶,说明:挖矿的人越来越多,用的设备越来越先进,反映出大家对BTC的热情越高,如果出现相反的情况,如某个加密货币的挖矿难度越调越小,说明挖矿变得越来越容易了--》大众对币的热情逐渐减少。如果持续出现这种情况,一般来说这个币慢慢不行了

图示每天出块时间

image-20250114182239090

出块时间稳定在10min上下震动---》难度调整达到了预期目的

图示近半年出块时间,按天作平均

image-20250114182345458

图示调整挖矿难度的公式:

image-20250114182421205

与上面公式一致,一个算难度,一个算目标阈值(实际BTC代码用目标阈值)(成反比)

1.7BTC挖矿

课程内容:总结相关内容,分析BTC挖矿趋势

全节点

职责:

1、一直在线

2、在本地硬盘上维护完整的区块链信息

3、在内存里维护UTXO集合,以便快速检验交易的正确性

4、监听比特币网络上的交易信息,验证每个交易的合法性

5、决定哪些交易会被打包到区块里

6、监听别人的矿工挖出来的区块,验证其合法性

7、挖矿

  • 决定沿着哪条链挖下去?

  • 当出现等长的分叉的时候,选择哪一个分叉?

4、(是否双花)

5、(缺省情况下,只要是合法的交易,并且交易费符合要求,就会被打包进区块里)

6、(1)区块每个交易都合法,包括铸币coinbase transaction(如有无篡改block reward出块奖励)

(2)发布的区块是否符合难度要求(通俗的说,检查block header取哈希后,前面有无足够的零,同时检查block header里难度目标阈值是否正确),全节点每2 weeks 按照BTC协议要求调整挖矿难度

(3)检查区块是否在延伸最长合法链

7、(* 1-6都在为7挖矿做准备)

(缺省情况下,应沿最长合法链)

(缺省情况下,选最先听到的分叉)

(真正能带来收益)(缺省就是default“默认”)

轻节点

职责:

1、非一直在线

2、不用保存整个区块链,只要保存每个区块的块头

3、不用保存全部交易,只保存与自己相关的交易

4、无法检验大多数交易的合法性,只能检验与自己相关的那些交易的合法性

5、无法检测网上发布的区块的正确性

6、可验证挖矿难度

7、只能检测哪个是最长链,不知道哪个是最长合法链

2、(存整个区块和只存block header差1k倍)

4、无法检测double spending

6、可验证是否符合难度要求,挖矿计算哈希值,只用块头信息block header(轻节点有),所以虽然无法检测交易是否合法,但是可检查发布区块难度要求。

轻节点假设发布区块的全节点不会发布非法的交易(无利全)

7、因为轻节点没办法检验链上包含交易都合法,但可检测链上的区块都符合挖矿难度要求。轻节点假设矿工是理性的

挖矿的注意事项

1、如果你监听到别人发布合法区块,也在最长合法链,你应该做什么?

停止已有的挖矿,重新在本地组装候选区块,重头开始挖矿。

因为如果沿着新区块往下挖,本地组装的区块中包含的交易就会发生变化(有些交易可能已经被包含到新区块里)、block header的内容也会变(block header里有(1)交易 tx 所组成的Merkle tree组成的Merkle root hash、(2)指向前一个区块的指针hash pointer)

可惜吗?挖了这么久,没用了?错,挖矿的性质:

无记忆性memoryless/process free

重新挖和继续挖,成功的概率一样

2、你挖到了合法的区块发布完就万事大吉了吗?错

有可能你发布的区块最终没成为最长合法链,可能存在race condition

或存在未知的double spending,使区块的某些交易有冲突

BTC如何保证安全性?

1、Merkle tree牵一发而动全身

2、有效防范双花攻击、女巫攻击、分叉攻击

3、协议,合法的交易、区块,最长合法链

1、密码学

别人没你的私钥,无法伪造签名,不能把你账上的钱转走。(前提:系统中拥有大多数算力的矿工是好的,遵守协议,不会接受非法签名的交易(如果没有,那密码学也白瞎)

如:去银行取钱,你需要出示合法的证件(相当于密码学的签名)(保证1),然后银行工作人员把钱给你,银行工作人员还需遵守规定不会把钱给没有合法证件的人(保证2)。

(密码学的性质保证别人无法伪造签名-》无法伪造身份)(产生私钥、签名的时候都需要好的随机源(够随机),就是为了密码学的性质)

2、共识机制

挖矿的趋势

1、设备改进(通用->专用,性价比逐渐提高)

2、大型矿池的出现

一、设备改进

1、CPU:通用计算

随着挖矿难度指数增加,性价比低

(家里的通用计算机、笔记本电脑。但其实内存大部分都是闲置的)

2、GPU:通用并行计算

主要用于大规模并行计算,如深度学习(矩阵乘法)

GPU是为了通用并行计算而设计的,用来挖矿,里面很多部件处于闲置状态(如用于浮点数计算的部件(深度学习计算梯度))

BTC挖矿只用到整数操作

2018年GPU火热,一部分由于深度学习火热,但更大一部分是挖矿火热

如今挖矿难度提升,超过了GPU 的算力范围,可以剩下GPU给深度学习和打游戏的行业服务

猜想这也是为什么英伟达市值暴涨后回跌

AI、自动驾驶、元宇宙、机器人、游戏、挖矿

3、ASIC芯片:挖矿专用

性价比之王

Application Specific Integrated Circuit

没有多余短路逻辑,专门为BTC挖矿计算哈希值设计的芯片。

除了挖矿,啥都干不了,。

  • 为某一种加密货币设计的ASIC芯片只能挖这种加密货币

除非两个加密货币用同一个mining puzzle,有些加密货币为解决能启动问题,故意用一个已有的货币的mining puzzle,如BTC,这样可以吸引更多人来挖矿---》merge mining。除了这种情况,其他都是一对一

加密货币cryptocurrency /ˈkrɪptəʊkʌrənsi/

1、BTC的ASIC芯片研发周期:1年(设计、流片、生产)

BTC价格剧烈波动,前期的研发费高昂且风险很大

一个定制的ASIC芯片使用周期很短(很快过时),竞争激烈,犹如军备竞赛。

研究表明,一款Asic芯片上市后,盈利在前两个月(算力在同类中最强),头两个月获得整个生命周期一半以上利润,然后就被淘汰了

购买矿机的时机很重要(先交钱,产商做完发给你要很久)

奸商:用客户的钱生产矿机,等矿机生产出来后,自己挖矿,赚取黄金时间头两个月的利润后,再把矿机交给用户。和用户说矿机还在生产测试中。(当BTC系统算力突然有明显的提高,这时候就是某个大厂商新矿机生产出来了)

--》在BTC浪潮中,真正赚钱的不一定是挖矿的,可能是卖矿机的。

2、舆论:ASIC芯片专门挖矿,与BTC去中心化设计理念相悖

如果用GPU人人都有,但是时代过了,用普通家里计算机的GPU已经很难挖到矿了,而且噪音大(4快),人无法在房间里呆下去

有些新的加密货币设计Alternative puzzle(目的:抗ASIC芯片化,resistance,让通用计算机也能参与计算过程)

二、大型矿池的出现

单个矿工挖矿,平均收益有,但是很不稳定

每10min出一个区块,这是对于BTC系统所有矿工作为一个整体而言

但是具体到某一矿工,出矿周期长,(如1台ASIC,1-2年出矿,6.25BTC奖励。相当于买彩票,买好多彩票,中了就是大奖,没中就是打水漂(电费))

单个矿工:

1、挖矿

2、承担全节点的其他责任

一、矿池出现的目的:

1、把矿工组织起来,作为一个整体。

2、解决收入不稳定的问题(单个矿工收入不稳定,合着干,成了一起分)

矿池架构:一个全节点驱动多个矿机

一个矿池一个矿主pool manager

(负责全节点除了以外的职责:

(1)监听网上交易,把交易打包成候选区块,

(2)看有无其他节点抢先发布区块,有,需调整重新挖矿)。

下连很多矿工miner(只负责挖矿计算哈希值)

ASIC芯片只能计算哈希值,不能做全节点其他职责

image-20250115140338035

矿池的好处:减轻矿工负担

(一个人买彩票,很少概率中大奖(挖不到什么都得不到,挖到就中大奖),现在变成中奖概率提高了,每天都有大概率比较容易得到小奖励almost valid block)

坏处:发动51%攻击变得容易

不一定攻击者本身有51%算力,只需有动员召集算力的能力

类似于云计算的

called computing 的优势on demand computing

平时不需要维护很大的计算机群,需要用的时候随时召唤

这里是on demand mining

二、收益如何分配?

矿池有两种组织形式:

1、大型数据中心(矿机属于同一个机构)

physically

大的矿机属于同一个机构

如大的互联网公司有成千上万的服务器-》大的矿池里有成千上万的矿机

收入分配不是问题

2、分布式(矿机属于不同机构)

如何分配收入?

矿工和矿主不在一起,矿工要加入矿池,要按照矿池规定的通讯协议和矿主联系,矿主分配计算哈希值的任务,矿工计算完后,把结果返回给矿主,将来有出块奖励的时候,一起分红

如果平均分配则是大锅饭,干好干坏一个样

按劳分配,按矿工贡献大小分配(工作量证明)

为什么挖矿收入不稳定?挖矿太难了

降低挖矿难度,收入就稳定了

如何降低难度?

如一个矿工算出nonce,前面70个0才合法,降低难度后,只需60个0,这样挖到的叫一个share(almost valid block)

挖到区块,差不多是符合要求即可

矿主拿到的区块除了证明矿工的工作量之外没有用处。区块不合法无法发布。

等将来某个矿工挖到区块后,按照提交的share数目分配收入

每个矿工挖到矿的概率取决去尝试的nonce数目,尝试的越多,share越多,(almost valid block)越多,所以可作为工作量衡量

不可能出现的问题:

1、可以偷出块奖励吗?不可以。

(1)如果矿工挖到区块后,不提交给矿主,自己偷偷发得到出块奖励呢?

平时挖到share时,提交给矿主,等到真正挖到合法区块后,自己发布?不可能。每个矿工的任务是矿主分配的。矿主组装好一个区块,,交给矿工尝试nonce(需要调整nonce域、coinbase parameter域)。

矿主把不同coinbase parameter所对应的nonce的范围交给不同矿工尝试

区块包含什么?

coinbase transaction里有收款人地址,这个地址填矿主pool manager的地址,矿工挖到区块自己发布没有。

(2)一开始不管矿主的任务,自己组装区块,偷偷把收款地址改成自己的地址如何?

这样提交的share不被认可。因为交易列表coinbase transaction已变化,算出的Merkle root根哈希值不一样。相当于矿工一开始就是单干

2、可以捣乱吗?

平时挖到share给矿工作为工作量证明,挖到真正的合法的区块后扔掉。(好像是损人不利己,但是矿池之间是存在竞争关系的,有可能为了打击竞争对手,故意派一些矿工加入到竞争对手的矿池里挖矿,采用这种方法起到破坏的作用(这些捣蛋矿工参与竞争对手的分红,别的矿工挖出来的出块奖励))

什么是比特币矿池?

矿池是比特币(数字货币)等P2P密码学虚拟货币开采所必须的基础设施,一般是对外开放的团队开采服务器,其存在意义为提升比特币开采稳定性,使矿工薪酬趋于稳定。目前全球算力较大的矿池有鱼池(F2Pool)、蚁池(AntPool)、币网(BW Pool)、国池(BTCC Pool)、BitFury。除了BitFury,其余都来自中国。

随着参与挖矿的人数越来越多,比特币全网的算力不断上涨,单个设备或少量的算力都很难再挖到比特币。这时候,矿池诞生了。

比特币矿池的运作原理

假设100万人参与比特币挖矿,全网400P算力,其中90%的矿工为1P(1000T)以下的算力,如果投入一台1T矿机,将占全网算力的40万分之1,理论上平均每40万个10分钟能挖到一个区块,也就是7.6年才能挖到一个区块然后一次性拿到50个比特币。

矿池突破地理位置的限制,将分散在全球的矿工及矿场的算力进行联结,一起挖矿。矿池负责信息打包,接入进来的矿场负责竞争记账权。由于集合了很多矿工的算力,所以矿池的算力占比大,挖到比特币的概率更高。

那么,假如我再找9个拥有1T算力矿机的矿工,达成协定,我们总共10个人,其中任何一个人挖到区块,都按照每人的算力占比来进行平分,那么我们就是一个整体,总共10T算力,那么平均0.76年即可挖到一个区块,然后算下来到我们手上的就是0.76年开采到5个比特币,如果组织100人、1000人、1万人甚至10万人呢?

如果是10万人,那么平均100分钟就能挖到1个区块,作为团队的一份子,收入将会趋于稳定。这就是矿池的基本原理,即大家组队进行比特币开采,可以参考彩票中的合买。当然,以上只是对矿池的基本原理和性质进行简单的描述,实际情况会非常复杂。

矿池是一个全自动的开采平台,即矿机接入矿池——提供算力——获得收益。矿池挖矿所产生的比特币奖励会按照每个矿工贡献算力的占比进行分配。相较单独挖矿,加入矿池可以获得更加稳定的收益。

关于矿池的统计数据

图示矿池在各个国家的比例

image-20250115142249616

引起恐慌:一个矿池算力超过51%,足以发动51%攻击

image-20250115142315005

图示公开后,GHash主动把算力占比大幅减少,以免动摇大家对BTC的信心

image-20250115142530984

image-20250115142701403

根据 Bankless Times 发布的比特币挖矿报告,目前全球 BTC 算力分布情况如下m.528btc.comm.528btc.com:

  1. 美国:拥有比特币网络 38% 的算力,是目前领先的比特币挖矿国家,美国上市比特币矿企在 2024 年 12 月占全球算力的 25.3%m.528btc.com。

  2. 中国:以 21% 的份额位居第二。但中国政府于 2021 年全面禁止比特币挖矿和交易,不过有消息称中国矿池仍运营着一定比例的网络算力m.528btc.com。

  3. 哈萨克斯坦:占比 13%,曾经在 2021 年中国打击比特币挖矿行动后,接收了部分从中国迁出的矿工腾讯网。

  4. 加拿大:拥有 7% 的算力,其因丰富的水力发电资源,在比特币挖矿方面具有一定优势m.528btc.com。

  5. 俄罗斯:以 5% 的份额位列第五,该国于 2024 年 11 月通过法案允许经政府批准的加密货币挖矿公司公开合法地发展挖矿产业m.528btc.com。

  6. 欧盟:其 28 个成员国的算力共计占比特币网络算力的 6%,其中爱尔兰占比特币网络算力的 2%m.528btc.com。

此外,德国占 3%、马来西亚占 3%腾讯网。需要注意的是,比特币算力分布情况可能会随着时间的推移、各国政策的变化以及挖矿技术的发展而发生改变。

根据目前可获取的部分信息,全球矿池算力分布大致如下:

美国

  • 占比情况:截至 2024 年底,美国矿池算力占全球的 40% 以上,如 Foundry USA 已成为全球最大的单一矿池,控制着约 36.5% 的比特币网络算力,MARA Pool 算力约为 32EH/s,贡献了总哈希算力的 4.35%区块链网。

  • 优势原因:美国一些地区对加密货币挖矿的政策相对包容,并且部分地区拥有丰富的能源供应,电力成本在一定程度上具有优势,能支撑大规模的挖矿活动,吸引了不少挖矿企业和机构投资者。

中国

  • 占比情况:有数据称截至 2024 年 9 月中国矿池运营着 55% 的网络算力,但由于中国对虚拟货币挖矿进行了严格的监管限制,大量矿场关闭,矿工出海,目前中国矿池的算力占比与过去相比有所下降网易手机网。

  • 相关矿池:以 AntPool(蚁池)、F2Pool(鱼池)为代表的中国矿池,在过去几年里一直占据着较大市场份额,并且不断通过技术创新来提高自身竞争力多特软件站。

其他国家和地区

  • 哈萨克斯坦:曾经在 2021 年中国打击比特币挖矿行动后,接收了部分从中国迁出的矿工,目前拥有一定的算力占比。

  • 加拿大:因丰富的水力发电资源,在比特币挖矿方面具有一定优势,拥有 7% 的算力。

  • 俄罗斯:2024 年 11 月通过法案允许经政府批准的加密货币挖矿公司公开合法地发展挖矿产业,该国拥有 5% 的算力。

  • 北欧国家:因其寒冷气候有助于降低散热成本而备受青睐,有部分矿池在此地区运营多特软件站。

  • 欧盟:其 28 个成员国的算力共计占比特币网络算力的 6%,其中爱尔兰占比特币网络算力的 2%。

  • 马来西亚:占 3%。

没有矿池超过半数的占比,可能是表面现象

如果一个机构有51%算力,可以放在多个矿池里,平时隐藏,真正发动攻击的时候集中。矿工转换矿池很容易(加入矿池就是按照协议和矿主联系,矿工把组装好的区块信息发给矿工,矿工尝试nonce值)

这是矿池的危害!!!

没矿池,攻击者要发动51%attack,自己要投入大量的硬件成本才能买到足够的矿机,系统半数以上算力。

他自己可能只占很少比例的算力,其余招募足够多的不明真相的群众加入矿池。

矿池的矿主收取一定的出块奖励作为管理费

(来源:1、出块奖励;2、交易费)

恶意矿池发动攻击前,故意把管理费降得很低,甚至赔本,吸引足够多的矿工,然后就可以攻击了。

假设有矿池达到51%算力,可以发动哪些攻击?

1、分叉攻击(为了回滚)

要等6个区块发布后再攻击,让B以为6个确认,这事成了。

虽然有6个确认,但是下面的分叉有51%算力,平均增长速度远大于上面分叉,最终会成为最长合法链。

image-20250115144154480

为什么说矿工不明真相呢?

原因:矿工只负责计算哈希值,不知道网上交易情况如何,发布什么区块,会不会double spending,分叉攻击

51%不是门槛(达到可攻,不达不能攻),不是绝对的,都是概率,只是相对容易。每个矿池所占的算力比重本身也是一个估计,而且是变化的。

2、Boycott

封锁禁欲

如:攻击者不喜欢某个账户,怀疑A账户参与非法交易,所有和A相关的交易都不上链。如果有人把A的交易发布到区块上,马上分叉,产生一个不包含A交易的区块(交易一上链马上分叉)越早越好,因为你是希望别人沿着你这链往下挖

image-20250115144526778

前面将BTC共识协议时讲过,虽然大部分算力掌握在诚实的好节点手里(前提),但是记账权也有可能被坏人获得(概率问题),如果坏节点获得记账权,他可以故意不把某些交易写入区块里,但是不影响后面诚实的好节点仍然可以把这些交易打包到区块里。

但是如果坏节点掌握51%算力的话,仗着自己算力强,公开地址某个交易,(只要出现这个交易,马上分叉,然后把分叉链变成最长合法链)

这样别的矿工不敢随便打包上面的交易进区块,因为一打包就分叉,这样他挖出来的区块作废了

3、有没有可能攻击者掌握51%算力后,把别人账上的钱转走?

不可能。无账户私钥,无法伪造签名。

那如果仗着算力强,强行把非法交易发到区块里,有什么后果?分叉,诚实的矿工会沿着另一条分叉去挖。

1.8BTC脚本

The BitCoin Scripting Language

image-20250115225742486

分析:

一个输入两个输出,一个没花unspent,一个花了spent

23个确认confirmations,回滚的可能性很小

输入脚本:分别把两个很长的数压入栈

唯一能访问的内存空间:堆栈(不像高级语言有全局变量、局部变量、动态分配内存空间等)基于栈的语言stock base language

输出脚本:两行,分别对应上面两个输出,每个输出有单独脚本

image-20250115230246999

宏观信息:metadata

txid:transaction ID

hash:交易的哈希值

version:使用的比特币协议的版本号

size:交易的大小

locktime:用来设定交易的生效时间(0表示立即生效,绝大多数情况下都是立即生效locktime=0)

vin,vout输入输出

blockhash:交易所在区块的哈希值

confirmation:多少个确认信息

time:交易从某个时间点到现在过了多少秒

blocktime:区块从某个时间点到现在过了多少秒

image-20250115232317022

交易的输入结构:

数组,一个交易可以有多个输入,这个例子只有一个输入,每个输入都要说明这个输入花的币是来自之前哪个交易的输出,并且要给出签名(多个输入对应多个签名)

代码前两行给出币的来源

txid:之前交易的哈希值

vout:交易的第几个输出

scriptSig-》input script:输入脚本(证明你有权利花这个钱)

image-20250115232655175

value:输出的金额(转多少钱),单位:BTC

一聪stoshi(中本聪Satoshi Nakamoto)

1BTC = e8聪

n:序号表示这是这个交易的第几个输出

scriptPubKey-》output script:输出脚本

为什么是pubkey?因为输出脚本最简单的形式就是给出一个public key

asm:输出脚本内容(操作)

reqSigs:输出需要多少个签名才能兑现。(multiSigs输出需要多个签名)

type:输出类型,pubkeyhash公钥哈希

address:输出地址

image-20250116121936823

如何验证合法?B-》C的输入脚本和A-》B的输出脚本拼接一起执行

早期:拼接在一起,从头到尾执行一遍。后来出于安全因素考虑,两个脚本改为分别执行。首先执行输出脚本,没出错再执行输出脚本,顺利执行,最后栈顶的结果为非零值true,即合法。

有任何错误则非法。

多个输入对应多个输出脚本匹配验证,全通过才合法

1、pay to public key hash

image-20250116122043462

image-20250116122054472

image-20250116122123232

image-20250116122216124

image-20250116122330088

1、pushdata(Sig):把输入脚本提供的签名压入栈

2、pushdata(PubKey):把输出提供的公钥压入栈

3、checksig:把栈顶两个元素弹出来,用公钥检查签名是否正确。正确返回true,否则执行出错,交易非法

下图pay to public key的实例

image-20250116122634139

image-20250116123003367

区别:输出脚本里没有直接给出收款人的公钥,给出公钥的哈希,公钥和签名在输入脚本给出。

dup、hash160:为了验证交易的正确性

image-20250116123137081

image-20250116123210709

image-20250116123237528

image-20250116123312442

image-20250116123415797

DUP:把栈顶元素复制一遍

HASH160:弹出栈顶元素,取哈希,得到哈希值再入栈(所以栈顶变成了公钥的哈希值

PUSHDATA(PubKeyHash):把输出脚本提供的公钥的哈希值入栈

equalverify:弹出栈顶两个元素,比较是否相等(目的:防止有人冒名顶替(用他自己的公钥冒充收款人的公钥))

相等,则两个哈希值消失

checksig:弹出栈顶两个元素,用公钥检查签名

任何一个环节错误:如

输入公钥和输出哈希对不上、输入签名和公钥对不上---》非法

image-20250116124223395

2、pay to script hash

最初没有,后来通过软分叉的形式加入

常见应用场景:对多重签名的支持

image-20250116124404969

输出脚本给出的不是收款人的公钥的哈希,而是收款人提供的脚本的哈希(脚本名称:redeemScript赎回脚本(将来花这个钱的时候,输入脚本要给出redeemScript的具体内容、能让redeemScript正确运行所需签名))

image-20250116124902939

验证分两步:

1、输入脚本给出的赎回脚本是否跟输出脚本里给出的哈希值匹配,不匹配说明赎回脚本错误(类似于pay to public key hash里给出的错误公钥)

2、(赎回脚本正确)把赎回脚本内容当做操作指令执行一遍

两步验证交易都通过才合法

image-20250116125200362

输出脚本用来验证输入脚本给出的赎回脚本是否正确

image-20250116125353425

两个hash不相等就game over了

第二阶段:

首先把输入脚本提供的序列化的赎回脚本反序列化(每个节点自己完成)

publickey入栈、checksig验证signature的正确性

验证通过后整个pay to script hash 才算执行完成

image-20250116125547521

多重签名

image-20250116125854746

BTC系统一个输出可能对应多个签名,

如公司账户要求5个合伙人中任意三人的签名才能把公司账户上的钱取走,为私钥的泄露提供安全保护,为私钥丢失提供冗余

(一个丢了没事还得两个,两个丢了没事三个也可以取钱,然后转到安全账户)

image-20250116130152713

输出脚本:n个公钥和一个阈值M

输入脚本:只需n个公钥对应签名中任意m个合法签名就能通过验证

红叉子:BTC中checkmultisig的实现有一个bug,执行的时候会从堆栈上多弹出一个元素。(bug无法改,去中心化系统,软件升级修复bug代价很大,需要硬分叉)

实际解决方案:在输入脚本里往栈上多压进一个没用的元素

红叉子:代表这个多余的元素

PS:M个签名的相对顺序要和他们在N个公钥中的相对顺序一致

image-20250116141129850

(图示checkmultisig的执行过程)

该例子假设三个签名给出两个就行,注意:签名给出的相对顺序与在公钥中的顺序一致

image-20250116141306176

输入脚本执行

image-20250116141327573

image-20250116141452971

该过程没有用到pay to script hash,而是用BTC脚本中原生的checkmultisig实现的

问题:网上购物,电商冒充签名,要求5个合伙人中任意三个人的签名才能把钱取出来,这就要求用户在支付的时候生成的转账交易里输出脚本给出这5个人的公钥、M和N的值(上述例子N=5, M=3)。

商家需要在购物网站公布。(不同电商要求不同,5给3,5给4,6给3)

---》转账不方便

如何解决呢?用pay to script hash

image-20250116142013851

本质:把复杂度从输出脚本转移到了输入脚本里的赎回脚本里(收款人提供)

输出脚本只需给出赎回脚本的哈希值即可

赎回脚本要给出:n个公钥、M和N的值

商家需要在购物网站公布赎回脚本的哈希值,

用户在生成转账交易的时候,把这个哈希值包含在输出脚本里即可

商家需要签名5选几对用户是不可见的,用户不需要知道

对用户来说,这种pay to script hash 和pay to public key hash没啥区别,只不过把公钥的哈希值换成了赎回脚本的哈希值(输出脚本写法有区别,问题不大)

输入脚本:电商花掉这笔输出时提供(包含:赎回脚本的序列化版本、让赎回脚本验证通过所需的M个签名)

假如电商改变签名规则,你只需改变输入脚本和赎回脚本的内容,公布新哈希值

image-20250116142725432

image-20250116142805786

第一、第二阶段的验证

image-20250116142851727

3、proof of burn

image-20250116142916634

return:无条件返回错误

包含这个脚本的交易永远不可能通过验证。被证明为销毁比特币的方法

应用场景: 1、小币种要求销毁一定数量的比特币,才能的到这个币种(AltCoin,alternative coin)

除了比特币之外的你都可以这么叫

1换1000个小币种

2、往区块链里写入内容

区块链是个不可篡改的账本,利用这些特性往里面添加需要永久保存的内容(如digital commitment)

你要知道某一时间某个事情,如涉及到知识产权保护的,把某项知识产权内容取哈希后,把哈希值放在return语句后面

image-20250116143650462

没占空间也没泄露,将来有纠纷,再公布知识产权输入的哈希值,证明在某个时间点知道某个知识。

coinbase transaction里coinbase域写内容没人管

这种方法只有获得记账权的节点才能用,全节点挖到矿了,发布区块,可以往coinbase transaction里的coinbase域写内容

coinbase范围:全节点

proof of burn适用范围:所有节点、用户。(可销毁比特币换小的币)

发布交易不需记账权,发布区块才需记账权

image-20250116230219823

image-20250116230251843

图二没有销毁比特币,只不过把输入里的比特币作为交易费转给挖到矿的矿工了

矿工看到这种脚本时,知道输出永不兑现,所以没存在UTXO里(对全节点友好)

图片为了简化,没加OP_前缀。

CHECKSIG其实是OP_CHECKSIG

CHECKMULTISIG也是OP_CHECKMULTISIG

DUP也是OP_DUP

就叫比特币脚本语言bitcoin script language

比特币脚本语言不支持循环(不支持循环就不会死循环,不用担心停机问题Halting Problem)

Halting Problem: given the description of an arbitrary program and a finite input, decidewhether the program finishes running or will run forever.

以太坊的智能合约语言是图灵完备的,表达能力很强

048A65a97

H65+8=72

e97+4=101

l97+11=108

l97+11=108

o97+14=111

blank32

W65+22=87

o111

r114

l108

d100

!33

8【右4【右2右3右3右1左左左左-1】右1右1右-1右右1【左】左-1】右右输出右-3输出7输出输出3输出右右输出左-1输出左输出3输出-6输出-8输出右右1输出右2输出

cell 0,cell0右边的格子命名为cell 1.

第一句将其递增8次变为8,然后循环执行

将其递增4次,然后循环执行

”右2右3右3右1左左左左-1“

右1右1右-1右右1【左】左-1

8

12

image-20250117005131330

1.9分叉fork

一、是什么?一条链变成两条链

二、产生原因?

1、挖矿。

两个节点差不多同时挖到矿,两节点都可发布区块,出现临时性的分叉,这样的分叉叫state fork(由于对比特币当前状态有分歧而导致的分叉)

2、分叉攻击forking attack

也是state fork,但是是人为造成的,所以也叫deliberate fork

3、协议更改。

软件升级-》修改比特币协议

去中心化系统,无法保证所有节点同时升级软件

假设大部分升级,少部分没升(不同意或者来不及)

这种分叉叫protocol fork(因为对比特币协议产生分歧,用不同版本的协议造成分叉)

三、根据对协议修改的内容的不同,可分为硬分叉hard fork和软分叉soft fork

1、什么是硬分叉?(旧不认新)(向后兼容)

如果对比特币协议增加新特性new feature,扩展新功能,这时候没有升级软件的旧节点不认可新特性,认为其非法

例子:比特币区块大小限制block size limit

比特币规定每个区块最多是1M=e6byte,一个交易250个byte

有人认为:太小,限制比特币的throughout,增加延迟

100,000/250=4000

4000/60/10 = 7 tx/sec --》每秒钟7比交易

(信用卡公司交易能够处理的数目比这多很多个数量级)

如果交易数目过多,有些交易需等到下一个区块才能被写进去,平均等10min

block size limit:1M->4M

假设有人发布软件更新,把block size limit从1M增加到4M(假设大多数节点都升级了,不是按账户数目算的,是按算力计算,即系统中拥有大多数哈希算力的节点都更新了软件)

image-20250117145626793

小区块新旧节点都认可,但大区块旧节点不认可

大多数新节点认可大区块,会沿着大区块的链继续挖

image-20250117145910596

是不是越大越好呢?不是。

比特币系统底层:P2P over the network,传播采用flooding的方式,消耗很大带宽,带宽是瓶颈

出现hard fork后,变成两条平行运行的链,平行运行的链,彼此之间有各自的加密货币,下面的区块在下面的链上有挖块奖励

--》社区分裂,社区中有一部分人为下面链正统(无篡改,更正描红),

image-20250117150513392

--》分家,各有各的规则。

分叉之前的币,按道理应该变成上下两条链都认可,一个币拆成两个币

ETH(ethereum)经典例子:我们现在的ETH已经不是原来的ETH了,分叉了,

ETH(ethereum):有人攻击ETH上的智能合约(Smart contract )The DAO(众筹,投资基金),以太坊社区决定用硬分叉的方法重新记账。

整个The DAO的钱都重新分到另一个智能合约上

ETC(ethereum classic)真正原来的协议

如果分叉后不采取措施有什么影响?

协议不同其他相同(私钥相同),账户余额也不一样,

A只想在上面那条链把币转给B,实现(ETH)A-》B的交易,结果在下面那条链也实现(ETC)A-》B了(这叫回放)

image-20250117155207376

解决:加chain ID

2、什么是软分叉?(新不认旧)(向前兼容)

新协议导致部分非法

block size limit:1M->0.5M(不仅仅是参数,至关重要,一个去中心化系统,改这个就可能会分叉)

小区块新旧都认, 大区块新节点不认

旧节点在看到新节点扩展的小区块链变成最长合法链,他就放弃他当前所在的分叉,切换到另外一条链上(旧节点不更新,他挖的区块可能作废)

软分叉:分叉是临时性的

image-20250117162639532

什么时候出现软分叉?给当前协议中没有规定的域增加新含义,赋予新规则

例:coinbase域(每个发布的区块可有一个铸币交易coinbase transaction)

把coinbse前8个字节作为extra nonce

block nonce只有4字节

2^32--》2^96

coinbase后面的空间开没用

提出:把UTXO集合当中的内容也组织成一棵Merkle tree,把Merkle roof hash根哈希值写在coinbase域里(改这个域的内容,block header里的根哈希值也会改)--》这样就可以用Merkle proof证明回复结果是否正确

目前UTXO集合:每个全节点自己在内存中维护(目的:快速查找,判断 是否双花)没有被写入区块链里

与Merkle proof不同

证明某个交易是否在某个区块里(全节点可以返回一个Merkle proof作为证明,轻节点可验证是否为真,全节点回复结果的正确性)

大部分轻节点如果不自己维护UTXO集合,无法证明全节点回复结果的正确性

著名软分叉例子:P2SH:Pay to Script Hash

支付时,不是付public hash,而是付赎回脚本redeemScript的哈希

执行时两步验证:

1、验证输入脚本的redeemScript与输出脚本的script的哈希值一样

(证明输入脚本提供的sctipt是正确的)

2、验证执行redeemScript,验证输入脚本的签名是否合法

旧节点不知道P2SH的特性,旧节点只会做第一阶段的验证

3、区别?

hard fork:必须所有节点都升级,才不会出现永久性的分叉。有旧节点不升级就会分叉

soft fork:只需半数以上算力的节点升级了,就不会出现

1.10问答

1、转账交易时,如果接收者不在线(没有连到比特币网络)该怎么办?

不需要接收者在线,转账交易只是一个记录,把我账户上的比特币转到他的账户上

2、假设某个全节点收到了一个转账交易,有无可能收款地址是节点没听说过的?

比特币账户创建不需要通知其他人,只需在本地产生一个公私钥对。只有转账地址收到钱后,其他节点才知道这个账户的存在

3、如果账户私钥丢失?

私钥丢失和泄露不一样。私钥丢失后,账上的钱变成了死钱。银行账户的密码丢了可以验证身份后重置密码。比特币系统没有人可以重置密码。

有些加密货币的交易所是中心化的机构,在交易所开账户,一般是需要提供身份证明的,你把比特币保存在交易所里,私钥是由交易所来保管的

加密货币交易所被黑例子:Mt.Gox

4、如果私钥泄露了?

比如你发现你的账户上出现可疑的交易。你需要尽快把账上的钱转到另外一个安全的账户上

5、如果转账时写错了地址?

无法取消已经发布的交易。如果你知道是谁的地址,跟对方联系看他愿不愿意转回来(无法强迫)。如果是一个不存在的地址(地址是公钥的哈希得到的),但有些地址不是由公钥哈希得到的,如digital commitment(你想把某项内容的哈希值发布到区块链上,证明你曾经在某个时间知道某个事情)

image-20250117193257832

标准做法:把内容放到OP_RETURN后面(没人管)

奇葩:用哈希值生成一个看上去很像比特币地址的东西

A-》B(B应该是某个比特币账户公钥取哈希后的地址),把需要保存的哈希值生成一个地址,作为收款人的地址-》这个地址没有对应的私钥

-》死钱

做法的目的:牺牲比特币换取往区块链里写东西的机会

转账交易的输出会永久保存在UTXO里,全节点收到转账交易后,不知道地址真假,对全节点不友好。

6、proof of burn和OP_RETURN 在实际当中如何操作?

当一个全节点收到一个转账交易的时候,首先检验交易的合法性,而OP_RETURN无条件返回错误,那怎么写入区块链里?

什么叫验证通过?

如何验证?把当前交易的输入脚本跟前面交易的币的来源的输出脚本拼在一起,看能否顺利执行,执行过程中不可抛出错误。

而OP_RETURN 是写在当前交易的输出脚本里的,所以验证当前交易的合法性时,不会执行该语句。有人想花这笔钱的时候才会执行

7、矿工可以偷答案吗?看到别人发布的合法nonce,作为自己的nonce发布--》如何知道是哪个矿工最先找到的nonce?

比特币挖矿就是在尝试大量的nonce看哪个符合难度要求

发布的区块里有coinbase tx,里面有收款地址,就是挖到矿的矿工的地址。偷答案需要把收款地址换成自己的地址。收款地址一变,coinbase的内容也变--》Merkle roof hash根哈希值变化(因为这个交易是和其他交易合在一起构成Merkle tree)nonce和根哈希值都在块头block header里,block header的内容变,原来的nonce作废

8、如何知道交易费该给哪个矿工?

交易费:发布交易时给矿工的小费。

实现不需要知道哪个矿工会挖到矿而得到交易费,

只要total inputs > total outputs

差额就是交易费=总输入-总输出

统计数据:

blockchain size

image-20250117195347879

UTXO集合的大小

image-20250117195423722

1、交易多-》UTXO变大

2、私钥丢失-》账户输出在UTXO里永久保存

比特币矿池挖矿情况:挖矿集中化趋势严重mining centralization

image-20250117195605886

比特币价格变化情况:

image-20250117195720771

比特币市值变化:与价格变化一致(绝对市值,不是加密货币整体中占的百分比)

image-20250117195809057

比特币的交易量:(按美元价格计算,波动与比特币本身价格波动有关)

image-20250117195904826

每天交易数目:与区块数目相关

image-20250117195958991

交易数目的变化,主要是因为每个区块里包含的交易数目发生变化

1.11匿名性

如何破坏匿名性?

Bitcoin and anonymity

privacy?做事不想让别人知道

有一定的匿名性:不需要真名,本地产生公钥作为地址,可以产生无数地址,可以用不同地址干不同事情。

但不是完全没名,是化名preudonymity

未名湖unnamed lake

以前银行存款可以用化名,谁有存折谁就可以取钱

网上交易最终要和实体世界联系

1、银行和比特币哪个匿名性好?

从某种意义上,如果银行允许用化名,他的匿名性比比特币好

比特币区块链账本公开,所有人可查,而银行的账本受控制,工作人员可查。

2、比特币什么情况下破坏匿名?

可以把不同地址关联在一起

为什么有时候输入输出有两个地址?用来找零,输入:一个不够用两个;输出:找零钱

不会告诉你哪个是找零的地址,但是可以分析出

如4,5-》3,6那3就是找零地址,因为如果3是商家的地址那就不用两个输入了。(通过这样把输入输出地址关联)

如何加强匿名?人为产生没必要输出。转账交易基本是由钱包软件生成。

比特币钱包数量不多,如果清楚钱包生成交易的方式,即可分析大部分区块链转账交易(常用钱包不会生成不必要地址)

image-20250117210209118

(1)生成很多地址账户,但是地址账户有可能被关联起来(一个账户地址关联)

(2)地址账户与你再社会现实世界的真实身份可能产生关联

任何让比特币虚拟世界与现实世界发生联系的时候都有可能泄露身份。

最明显:资金的转入和转出

场内交易:我想拥有比特币,我用钱转到对方账户里(资金的转入转出)

场外交易:私下交易

反洗钱法常用手段:关注资金的转入转出链

(3)大额资金转入转出

(4)用比特币支付时(用于支付的账户和真实身份有联系,这个比特币账户又和你其他比特币账户有联系)

缺点:延迟大、交易费贵

谁会知道你的身份?商家、其他人

例子:信用卡公司为了支持学术科研,公开收集到的信用卡交易记录

信用卡号码取哈希(无法反推),抹掉个人信息(姓名、性别、年龄。),信用卡号码不能完全抹掉(为了科研:研究不同社会群体消费习惯;根据个人过去消费推出将来消费)。

奇葩科研:研究怎么通过公开的数据推出的实际身份

如你今天去菜市场买菜,我可以记录你在某时间某地点有消费记录

之后你去买处方药,记录某时间某地点有消费记录。查哪些号码在这个时间点和地点有消费记录,过滤几次后很快能够精准定位哪个哈希值对应的是你。--》告诉我们:信用卡记录不能公开

比特币交易记录是公开的,所以你买个咖啡,除了商家知道你的账户,你周围的人,知道你在这个时间点地点在比特币网上做一笔消费,然后在区块链上查

--》比特币的匿名性没有想象中的完美

谁的匿名性保持最好?没有发生交易的账户。但是这算一个比特币用户吗?

中本聪!!!

他宁愿不变现,也要隐藏身份--》不是为了钱--》为了信念!!!

有个Silk road的非法网站,也叫eBay for illegal drugs

像eBay一样有网上交易平台、一套reputation system(网上交易后,可对商家信誉打分)

卖违禁品,为了逃避司法制裁,用比特币做支付手段,底层网络层用洋葱路由TOR,在美国用匿名邮寄的服务anonymous mail

运行了2-3年就被查封了,老板在旧金山被捕,更重要的是,他靠经营网站赚的十几万的比特币一个都没花(花了就暴露身份),没有公开如何抓到的(据说是这个人有几次不小心用同一台电脑登录它在真实世界的某个账户和他这个非法网站上的某个账号)

第二版Silk road 2运行没几年就被查封了

过去经验表明:比特币的匿名性没有想象中的美好(凡是用比特币从事违法活动的最后都被抓了)

中本聪能够长时间保持匿名性,属于个例,而且没干坏事。

为什么中本聪能保持匿名?当比特币这个项目走上正轨后,中本聪就消失了

hire your identity from whom?

技术性问题:假设你是一个比特币用户,你能做什么来尽量提高你的匿名性?

image-20250117213212160

如何提高匿名性?

比特币作用在应用层,底层是P2P-network,提高匿名性从两层入手

应用层?

(解决问题,看这个问题为什么会产生逆向思维,要保护什么就看什么东西可以破坏它)

破坏匿名性的原因:同一个人的各个不同的比特币账户之间会被关联起来(区块链是公开的账本,每一笔交易都可溯源)

(1)coin mixing

把各个不同人的币混在一起(在其他需要匿名性的领域的常用做法)

把你的身份跟周围人的身份混在一起,让人分不清楚谁是谁。

有专门做coin mixing 的网站提供服务,收取服务费,老板把币发给这个网站,网站内部进行一些重组,再把币取回来,这个币就不是当初发到网站上的币,随机抽取币给你

如果设计不好,也可能推算出当初哪些币是你存进去的

在现在区块链世界里,没有信誉非常高的coin mixing服务,网站本身也需要保持匿名,他匿名的结果:如果投进去的币被他捐款跑路了,你只能哭。

应用本身带有coin mixing的效果,但没有义务履行coin mixing的功能:比特币在线钱包

可能把数量很多的币混淆,取出来的不是当初存进去的币

(2)交易所

加密货币的交易所有天然的coin mixing的性质

例:我有一些比特币,上传到比特币交易所里,(我觉得过一段时间比特币价格会跌)卖出去换成美元/uddt,过一段时间,买入以太币,然后又换成莱特币,经过几次操作后,又买回比特币,然后提币把币提出来存在本地,这时候存在本地的比特币,一般来说就不是当初存进去的比特币了。(我A原来的比特币已经卖掉了,转到别人账户B里去了,再转回来不是B,大概率是账户C)

前提:交易所不会泄露相关记录。

为什么保护隐私匿名性难度大?区块链本身是公开的,不可篡改的。(不可篡改性对于隐私保护是灾难性的)

因为一旦你某个交易不小心把你的身份暴露出去,这个交易永久地写在区块链里,无法抹掉

网络层?

很多节点如果发现交易都是从同一个节点发出来的,从节点的ip地址推算出在物理世界中的真实身份。区块链是新生事物,但网络层的匿名性学术界已经有很好的解决方案(方法:多路径转发)(TOR基本思想:中间的每一个节点只知道他的上一个节点是谁,但不知道最早发出消息的是谁,只要有一个节点是诚实的,就可隐藏最初发线人的身份。)

(以前去网吧用网名发帖,去网吧有身份证,登记查ip(ip地址与真实身份强关联))

零知识证明

是什么?zero--knowlegde proof

零知识证明是指一方(证明者)向另一方(验证者)证明一个陈述是正确的,而无需透露除该陈述是正确的外的任何信息。

1、这个账户是我的。(这个例子不完全算零知识证明,因为透露签名给你了)

实际上是要证明我知道账户的私钥,但是我不能把私钥告诉你,--》签名

既要证明又不能让你知道-》产生私钥的签名,假设你知道账户的公钥,你可以验证签名的正确性

透露的额外信息有无问题要看应用场景

零知识证明的数学基础:同态隐藏

同态隐藏

  • 如果x,y不同,那么它们的加密函数值E(x)和E(y)也不相同。

  • 给定E(x)的值,很难反推出x的值。

  • 给定E(x)和E(y)的值,我们可以很容易地计算出某些关于x,y的加密函数值。

    • 同态加法:通过E(x)和E(y)计算出E(x+y)的值

    • 同态乘法:通过E(x)和E(y)计算出E(xy)的值

    • 扩展到多项式

三个性质分析:

1、这个不会碰撞,哈希函数有可能会碰撞-》如果两个加密函数值相等,那他输入也相等(逆否命题)

2、加密函数不可逆(与密码学性质类似:hiding property从哈希值无法知道输入值)

3、对加密后的函数值进行代数运算等价于对输入直接进行代数运算然后再加密

image-20250117221547326

image-20250117221745973

1、bob有E(X)和E(y)无法知道x和y--》满足不知道x和y的条件

2、同态加法的性质

3、性质一:E(X+Y)=E(7)说明无碰撞,加密值相等,则输入值相等

Bob可以用蛮力算法拆除原始的x和y是多少。

--》x和y随机化处理,保证x+y不变(如没限制整数)

image-20250117222236824

需求:让央行做中心化的记账交易,又不让他知道-》虚拟货币的编号不能是央行产生的,改成我产生的,但是不告诉央行编号有啥问题?如何保证真的不会被篡改?--》盲签

银行要记录这个序号的币是否双花(维护的数据库)

第三步设计目的:银行不知道B的币的编号哪来的(crypto magic)

比特币在很大程度上提供了匿名性,但不能完全消除,叫limit

能不能设计一种加密货币,一开始的体系结构就用密码学原理保证匿名性?

image-20250117223146714

把基础币搞得不能花unspentable来换取一个零币

零币在花的时候只需用零知识证明花掉的币是系统中存在的某一个合法的币就行,但不用透露你花的是系统中哪一个币(和比特币的本质区别:

比特币的每一笔转账交易都要说明币的来源-》保证花掉的币的真实性)

成为不了主流加密货币的原因:

1、为了匿名性付出了性能损失的代价,在数学原理上对初始化有严格的要求,初始的时候用的随机源要能够销毁掉,没销毁-》安全漏洞

2、需要强匿名性的用户占少数

3、不是100%安全,影响匿名性的因素还没解决:与实体发生交互的时候

1.12思考

1、哈希指针

区块的块头包含指向前一个区块的指针

指针保存的是本地内存的地址,只在本地计算机才有意义

发布区块的时候,哈希指针如何通过网络传输呢?

所谓的哈希指针只是一种一种形象的说法,实际系统中用的时候只有哈希,没有指针。

image-20250118133029685

image-20250118133049064

怎么找到前一个区块的内容?

全节点一般把区块存储在(key,value)数据库levelDB里

哈希的内容保证整个区块链的内容不可篡改

2、区块恋

情侣两个人合在一起买比特币,然后把私钥从中间截断,分成两部分,没惹你保留其中的一段,将来如果两个人继续好下去的话,那么两段私钥合在一起就能够把钱取出来。如果两个人分手了,那么当初买的币就被永久地锁在区块链上,谁也取不出来。

用blockchain 的不可篡改性,来作为两个人的爱情见证

如果推广下去,n个账户,这种截断私钥的做法会降低账户的安全性,

比特币系统每个账户的的安全性和所用的私钥长度相关256位私钥,用暴力破解不可行,就算把全世界的计算机用来计算256位的私钥也是不成功的。

一个人128位,只需把另一个人的128位猜出来即可

2^256>>>2^128>>2^64

多重签名MULTISIG

3、分布式共识

理论不可能(对特定模型) vs 实际应用

远程数据中心计算机是否死机,打电话解决

atnt实验室 vs 贝尔实验室

在异步的环境中,不可能区分远程的计算机是否死机或者延迟

延迟没上线

知识改变命运,这句话本身没错,但是对知识的一知半解,有可能使你的命运变得更差。

不要被学术界的思维限制了头脑

不要被程序员的思维限制了想象力

4、比特币的稀缺性

总量固定的东西,稀缺的东西不适合用来作为货币

一个好的货币,需有通货膨胀的功能

如果一个人早期拥有大量黄金,后来人怎么努力也赶不上

房地产亦是如此

5、量子计算

加密 vs 取哈希

加密:是为了解密,信息不丢失

取哈希:不可逆,信息丢失