区块链是一个去中心化的账本,比特币采用了基于交易的账本模式 。然而,系统中并无显示记录账户包含比特币数,实际上其需要通过交易记录进行推算。在比特币系统中,全节点需要维护一个名为 UTXO(Unspent Transaction Output尚未被花掉的交易输出) 的数据结构。
如图,A转给B五个BTC,转给C 3个BTC,B将5个BTC花掉,则该交易记录不保存在UTXO中,C没有花掉,则该交易记录保存在UTXO中
UTXO集合中每个元素要给出产生这个输出的交易的哈希值(接收者的公钥),以及其在交易中是第几个输出。通过这两个信息,便可以定位到UTXO中的输出。
那么为什么要维护这样一个数据结构?为了防范“双花攻击”,判断一个交易是否合法,要查一下想要花掉的BTC是否在该集合中,只有在集合中才是合法的。如果想要花掉的BTC不在UTXO中,那么说明这个BTC要么根本不存在,要么已经被花过。所以,全节点需要在内存中维护一个UTXO,从而便于快速检测double spending(双花攻击)。
如图,A转给B5个BTC,之后B将其转给D,则UTXO中会删掉A->B这一交易记录,同时会添加B->D这一交易记录。
每个交易可以有多个输入,也可以有多个输出,但输入之和要等于输出之和(total inputs = total outputs)。
存在一些交易的total inputs 略大于 total outputs,这部分差额便作为交易费,给了获得记账权的节点。在公开课笔记4中最后提及到“区块中保存交易记录,如果仅仅设置出块奖励,那么,会不会存在节点只想发布区块获得出块奖励而不想打包交易?因此,BTC系统设计了Tranction fee(交易费),对于获得记账权节点来说,除了出块奖励之外,还可以得到打包交易的交易费。但目前来说,交易费远远小于出块奖励。等到未来出块奖励变少,可能区块链的维护便主要依赖于交易费了。
比特币是基于交易的模式,与之对应,还有一种基于账户的模式(如:以太坊)。基于账户的模式要求,系统中显示记录账户余额。也就是说,可以直接查询当前账户余额是多少货币。可以看到,比特币这种模式,隐私性较好,但其也付出一定代价。在进行交易时,因为没有账户这一概念,无法知道账户剩余多少BTC,所以必须说明币的来源(防止双花攻击)。而基于账户的模式,则天然地避免了这种缺陷,转账交易就是对一个(多个)账户余额的数字减和另一个(多个)账户余额的数字加和。
挖矿过程的概率分析挖矿本质上是不断尝试各种nonce,来求解这样一个puzzle。每次尝试nonce,可以视为一次伯努利试验。最典型的伯努利试验就是投掷硬币,正面和反面朝上概率为p和1-p。在挖矿过程中,一次伯努利试验,成功的概率极小,失败的概率极大。挖矿便是多次进行伯努利试验,且每次随机。这些伯努利试验便构成了a sequence of independent Bernoulli trials(一系列独立的伯努利试验)。根据概率论相关知识知道,伯努利试验本身具有无记忆性。也就是说,无论之前做多少大量试验,对后续继续试验没有任何影响。
对于挖矿来说,便是多次伯努利试验尝试nonce,最终找到一个符合要求的nonce。在这种情况下,可以采用泊松分布进行近似,由此通过概率论可以推断出,系统出块时间服从指数分布。(需要注意的是,出块时间指的是整个系统出块时间,并非挖矿的个人)
指数分布本身也具有无记忆性。也就是说,对整个系统而言,已经过去10min,仍然没有人挖到区块,那么平均仍然还需要等10min(很不符合人的直觉)。也就是说,将来要挖多久和已经挖多久无关。
实际上,挖矿这一 *** 作并非在解决数学难题,而是单纯的算力比拼。也就是说,挖矿这一过程并没有实际意义,但挖矿这一过程,却是对比特币系统的稳定起到重要维护作用。所以,只要大多数算力掌握在好的节点手中,便能够保障比特币系统的稳定。
比特币系统安全性分析1、可否"偷币"?(恶意节点能不能将其他账户上比特币转给自己?)
答案:不能。因为转账交易需要签名,恶意节点无法伪造他人签名。加入其获得记账权并硬往区块中写入该交易,大多数用户会认为其是一个非法区块,大多数算力将不认可该区块,从而沿着其他路径挖矿,随着时间推移,拥有大多数算力的诚实的节点将会仍然沿着原来区块挖矿,从而形成一条“最长合法链”,该区块变成孤儿区块。对于攻击者来说,不仅不能偷到其他人的比特币,而且得不到出块奖励,还浪费了挖矿花费的电费等成本。
2、可否将已经话过的币再花一遍?
如下图1,若M已经将钱转给B,现在想再转给自己,假设其获得记账权,若按照图1方式,很明显为一个非法区块,不会被其他节点承认。
所以,M只能选择图2方式,将M转账给B的记录回滚掉。这样就有了两条等长合法链,取决于哪一个会胜出。(如果上面交易产生不可逆的外部效果,下面交易回滚便又拿回钱,从而不当获益)需要注意的是,再挖矿之初便要选择上一个区块是谁。也就是说,并不是获得记账权之后才选择插入到哪一个区块之后。
如何防范这种攻击?如果再M->B这个交易之后还延续有几个区块,如下图所示,则大多数诚实节点不会承认下面的链。所以,便变成了恶意节点挖下面的链,其他节点挖上面的链的算力比拼。由于区块链中大多数节点为善意节点,则最终上面链会胜出,而恶意节点的链会不被认可,从而导致投入成本白费。
所以,一种简单防范防范便是多等几个确认区块。比特币协议中,缺省需要等6个确认区块,此时才认为该记录是不可篡改的。平均出块时间10min,六个确认区块便需要1小时,可见等待时间还是相对较长的。
3、可否故意不包含合法交易?
可以,但是可以等待后续区块包含,所以问题不大。实际运行中,可能由于某段时间实际交易数太多,而一个区块包含交易数存在最大值,导致某些合法交易并未被写入区块链(等待后续区块写入)。
4、selfish mining
提前挖到但不发布,继续挖下去,等到想要攻击的交易等了6次确认认为安全之后将整条链发布出去,试图回滚原来记录。这种情况,需要恶意节点掌握系统中半数以上算力才行,否则无法成为最长合法链。
需要注意的是,比特币系统中,假如发生以下情况,各个节点以自己先收到的区块所在链为主链,对后收到的合法区块会不予认可(但会先保存起来)。此时便变成了两批算力分布挖1和2,具体哪一个成为主链,取决于哪一条链先挖到下一个区块,使得两个等长合法链出现长短不一致,最终胜者成为最长合法链。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)