BTC-实现
BTC-实现
-
Transaction-based ledger(比特币是基于交易的账本模式)
- Account-based ledger(以太坊是基于账户的账本模式)
-
UTXO Unspent Transaction Output(还未交易的输出)
比特币系统的全节点要维护一个叫UTXO(unspent transaction output)(还没有被花出去的交易的输出)的数据结构。例如:A转给B五个BTC,转给C3个BTC,B将5个BTC花掉,则该交易记录不保存在UTXO中,C没有花掉,则该交易记录保存在UTXO中
UTXO的作用
UTXO集合中每个元素要给出产生这个输出的交易的哈希值,以及其在交易中是第几个输出。通过这两个信息,就可以定位到UTXO的输出。
为了检测double spending。判断一个交易是否合法,要查一下想要花掉的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的情况
比特币系统设计了第二个激励机制:交易费(transaction fee)。矿工将信息放入区块中,会获得交易费
-
挖矿时只改随机数不够,还可以更改根哈希值。
-
比特币是基于交易的模式,与之对应,还有一种基于账户的模式(如:以太坊)。基于账户的模式要求,系统中显示记录账户余额。也就是说,可以直接查询当前账户余额是多少货币。可以看到,比特币这种模式,隐私性较好,但其也付出一定代价。在进行交易时,因为没有账户这一概念,无法知道账户剩余多少BTC,所以必须说明币的来源(防止双花攻击)。而基于账户的模式,则天然地避免了这种缺陷,转账交易就是对一个(多个)账户余额的数字减和另一个(多个)账户余额的数字加
-
比特币的发行总量及计算公式
Geometric serices
21wx50x(1+1/2+1/4+....)=21wx50x1/(1-1/2)=2100w
-
比特币系统设计的平均出块时间是10分钟,就是整个系统平均10分钟会产生一个新的区块,因比特币数量的上限以及人为的提高寻找区块链的难度,导致新区块的产生仅仅依靠nonce(随机数)很难维持出块奖时间的稳定,因此加入了coinbase的随机, 只有铸币交易没有输入,它有一个coinbase,可以写入任何的内容。因此通过改变这其中的内容来改变最后的哈希值。所以真正挖矿的时候只有两层循环,外层循环调整coinbase域的extra nonce。算出block header里的根哈希值之后,内层循环再调整header里的nonce。
- 每次求解nonce 是Bernoulli trial :a random experiment with binary outcome
- 比特币系统中验证交易的合法性,就是把input scripts和output script配对后执行来完成的。注意:不是把图中的input scripts和output scripts配对,因为这两个脚本是一个交易中的脚本。不是把同一个交易里的输入脚本和输出脚本配对,而是把这里的输入脚本和前面提供币来源的交易的输出脚本配对。如果输入输出脚本拼接在一起,能顺利执行不出现错误,那么该交易就是合法的。
- 挖矿过程每次尝试一个nonce可以看作是一个Bernoulli trial(伯努利实验)。每一个随机的伯努利实验就构成了一个伯努利过程。它的一个性质是:无记忆性
- 在区块链中,nonce(number only used once)是一个在工作量证明算法中中的变量,用于调整矿工进行哈希运算的输入,以满足特定的难题要求。nonce是一个32位的整数,矿工会将该数字与区块中的其他信息一起通过哈希函数进行哈希运算。矿工可以不断尝试不同的nonce值,指到找到一个满足特定条件的哈希值,即满足H(nonce|block header)<=target
- 指数分布也是无记忆性的。因为概率分布曲线的特点是:随便从一个地方截断,剩下一部分曲线跟原来是一样的。比如:已经等十分钟了,还没有人找到合法的区块,仍然参考概率密度函数分布 ,平均仍然要等十分钟。Prisson process(泊松过程)将来还要挖多长时间,跟过去已经挖了多长时间是没有关系的。这个过程也叫:progress free
BTC系统中具体的区块信息
比特币系统安全性分析(Bitcoin is secured by mining)
大多数算力掌握在好的用户手中,能否保障不良交易记录不会被写入区块链?
需要注意的是,算力低的用户并非完全不能获得记账权,仅仅是概率上较低的问题。但实际上,即使拥有少量算力的恶意节点,也有一定概率获得某个区块的记账权。
可否"偷币"?(恶意节点能不能将其他账户上比特币转给自己?)
答案:不能。因为转账交易需要签名,恶意节点无法伪造他人签名。假如其获得记账权并硬往区块中写入该交易,大多数用户会认为其是一个非法区块,大多数算力将不认可该区块,从而沿着其他路径挖矿,随着时间推移,拥有大多数算力的诚实的节点将会仍然沿着原来区块挖矿,从而形成一条“最长合法链”,该区块变成孤儿区块。对于攻击者来说,不仅不能偷到其他人的比特币,而且得不到出块奖励,还浪费了挖矿花费的电费等成本。
可否将已经花过的币再花一遍?
如下图1,若M已经将钱转给B,现在想再转给自己,假设其获得记账权,若按照图1方式,很明显为一个非法区块,不会被其他节点承认。
所以,M只能选择图2方式,将M转账给B的记录回滚掉。这样就有了两条等长合法链,取决于哪一个会胜出。(如果上面交易产生不可逆的外部效果,下面交易回滚便又拿回钱,从而不当获益)
注意
:区块插在哪个位置,在刚挖矿时就是要决定的,因为设置的block header里要填上前一个block header的哈希。所以他想插到那个区块的话,一开始就要认定,而不是等获得记账权以后再认定。irrevocable ledger(不可撤销的记账)
如何防范这种攻击?
如果再M->B这个交易之后还延续有几个区块,如下图所示,则大多数诚实节点不会承认下面的链。所以,便变成了恶意节点挖下面的链,其他节点挖上面的链的算力比拼。由于区块链中大多数节点为善意节点,则最终上面链会胜出,而恶意节点的链会不被认可,从而导致投入成本白费。
- 能不能把已经花了的币再花一遍(即double spending)
假如他把M→A的交易写在了一个区块里面,现在他获得了记账权,他又发布另一个交易,把这个钱转回给自己,即M→M'。同样,这很明显是double spending,只要是诚实的节点都不会接受这个区块。
注意
:区块插在哪个位置,在刚挖矿时就是要决定的,因为设置的block header里要填上前一个block header的哈希。所以他想插到那个区块的话,一开始就要认定,而不是等获得记账权以后再认定。irrevocable ledger(不可撤销的记账)
所以,一种简单防范便是多等几个确认区块。比特币协议中,缺省需要等6个确认区块,因此才认为该记录是不可篡改的。平均出块时间10min,6个确认区块需要1小时,可见等待时间还是相对较长的。
-
是否故意不包含合法交易?
可以,但是可以等待后续区块包含,所以并没有太大影响,可能由于某段时间实际交易数太多,而一个区块包含交易数存在最大值,导致某些合法交易未被写入区块链(等待后续区块的写入)。
selfish mining
M→M'的交易所在的区块所在的链条虽然短,但是先偷偷的生成比上面更多的区块,然后等上面的链条公布后再公布,就能够胜过上面的几个区块了
- 目的一:selfish mining是分叉攻击(fork attack)的一种手段。但这样成功的概率并不大,因为有恶意的节点本来算力占比就不高,还要生成更多的区块,就非常困难
- 目的二:假如A挖了两个区块都没有发布,而在B挖到一个区块公布后立马公布,这样B挖的区块就作废了。好处是减少竞争,因为A在挖第二个区块时,别人还在挖第一个区块(前提是A算力足够强)。
- 坏处是假如A挖出一个区块,A以为他能赶在别人前再挖一个区块,结果这时有人挖出了第一个区块,那这样的话A就要在别人发布之后立马发布,去争取区块奖励
热门相关:有个人爱你很久 不科学御兽 本法官萌萌哒 大妆 豪门情变,渣总裁滚远点!