去中心化账本结构
transaction-based ledger 基于交易的账本模式(比特币)
每个区块中记录交易信息,并不显示的记录每个账户中的钱,需要通过交易来推算
有利于隐私保护,但必须说明币的来源
比特币中的块和交易
交易的输入和输出都是用脚本的方式来指定的。比特币中验证交易的合法性,是将前一个提供币的来源的交易的输出脚本和当前交易的输入脚本拼接起来,不出现错误,则说明交易是合法的。
销毁比特币的方法
使用含有return方法的输出脚本,在执行到return语句后直接返回false,终止当前脚本进程,所以这个output无法再被花出去,其对应的UTXO可以被剪枝,无需保存。
应用场景:使用BTC交换一些小币种,或者往区块链中写入内容时使用(需要交付一些交易费)
数据结构 UTXO 集合:Unspent Transaction Output 没有被花掉的交易输出
由全节点在内存中来保存维护,所有交易的输入等于所有交易的输出+交易费。
例如A将5BTC转给了B,将3BTC转给了C,那么交易输出就有两个;当B将这5BTC花掉后,这个输出就不会再被保存,而只保存A转给C的输出。
集合中的每个元素,给出产生输出交易的哈希值,和它在交易中是第几个输出,就可以定位到UTXO中的输出
可以用来快速检测double spending
transaction fee 交易费
平均出块时间 10min (每隔10分钟产生一个区块,每隔2016个区块会调整difficulty来保持出块时间维持在10min),这样计算的话,每隔4年(产生21万块区块)后,出块奖励会减半,因此后期出块奖励将会变得非常小,交易费会变成主要收益
增加difficulty时,块头中4字节的nonce不够用,可以使用extra nonce。铸币交易中有一个域叫做coinbase,可以自行写入一些内容,当修改这个域中的内容时,merkle root根哈希值也会发生变化。可以将铸币交易中coinbase域的字节当作extra nonce,这样挖矿的时候会有两层循环,外层循环找出extra nonce算出根哈希值,内层循环再找nonce。
挖矿抢夺记账权
挖矿概率
Bernoulli trial : a random experiment with binary outcome(memoryless)
每次挖矿可以看作是一次伯努利尝试
Bernoulli process : a sequence of independent Bernoulli trials
由于实验次数多,每次实验成功概率都很小,因此可以用泊松分布来近似
出块时间服从指数分布,有 progress free的性质,可以来保证挖矿的公平性
系统中比特币的总量为2100万(21万×50×2)
Bitcoin is secured by mining
挖矿这个机制的设立对于维护比特币的安全性至关重要
能够保证大部分算力掌握在诚实的节点中
如果记账权落到坏人手中
不可能的恶意行为:(诚实的节点不接受)
- 把别人帐上的钱转走:无法伪造他人签名,这条交易是非法的,诚实的节点不会接受这个区块,会沿着上一个块继续挖
可能的恶意行为:(诚实的节点接受了)
双花攻击,把之前的交易回滚,下方链成为最长链,M->A作废,但该交易已经产生不可逆的行为(例如网购)
简单的防止方法:多等几个确认区块。比特币中需要等待六个确认区块,才能认为前面的交易是不可篡改的(对于交易M->A,M->A的块是one confirmation,之前的时间点是zero confirmation,即交易发布但未写入区块中)
故意不打包某些合法交易(基本没有危害)
selfish mining:挖出矿来后不直接发布区块,而是沿着这个块一直往下挖,直到分链长度大于主链,直接将主链的后半部分覆盖掉
恶意节点用于进行分叉攻击
一个普通的恶意矿工成功的概率很小,当恶意节点的算力占百分之五十以上,成功的概率才较大
诚实节点用于获得更多的挖矿时间
节点挖出块之后不立马发布,而是沿着自己的块继续挖;其他节点会沿着上一个块继续挖。如果该节点能够在其他节点挖出块之前再挖出一个,将会获得两个出块奖励。
这样做有可能会失去原来的出块奖励
account-based ledger 基于账户的账本模式(以太坊)
直接显示账户余额,不需要说明币的来源
见ETH-帐户一节