区块链-比特币笔记

密码学原理
哈希函数
collision resistance:H(x1)=y1,很难人为找到一个x2经过hash计算后的值也等于y1
所以可以hash函数的collision resistance的原理来验证信息是否被篡改
hiding:x->H(x),一个x对应一个H(x),通过只公布H(x),就能实现对x的保护,前提是x的要足够大,防止受到暴力攻击
挖矿:求解nouce(一个值)。nouce和区块块头里的其他信息合起来作为输入,计算出一个哈希值,该哈希值在难度目标阈值之内,即为挖矿成功
puzzle friendly:只看哈希值,并不能推断出什么数更可能计算出该哈希值
签名(asymmetric encryption algorithm):发布交易时用自己私钥签名,其他人用自己的公钥验证签名的正确性
比特币中一般是先对一个message取哈希,再对该哈希进行签名

hash pointers:指针指向前一个区块,并保存前一个区块的哈希值
merkle tree:为区块提供一个根哈希值(root hash);提供merkle proof

区块块头(block head):保存根哈希值,指向前一个结点的指针,协议(version),target(难度目标阈值),nouce(hash后满足难度目标阈值的值)
区块块身(block body):保存交易的具体内容(transaction list)
轻节点只保存根哈希值

区块链协议
遵循最长合法链
挖出区块(即计算出nouce值)的节点有记账权,且有铸币奖励(block reward)
如果两个区块同时被挖出,就看挖出的下一个区块认可(将自己挖出的区块记在该区块后面)这两个区块中的哪一个,被认可的区块胜出,不被认可的区块被抛弃(orphan block)
UTXO(Unspent Transaction Output):所有没被花出去的交易的输出都保存在这个数据类型中,在UTXO中的元素提供产生这个输出的交易的hash值,以及它在本交易中是第几个输出,就能够定位到在UTXO中的输出
挖矿的特性:memeryless(progress free):过去尝试过的所有失败的nouce值,不影响接下来要尝试的nouce值的成功概率,保障了挖矿的公平性
比特币网络(The Bitcoin Network)
应用层(application layer):区块链(Bitcoin block chain)
网络层(network layer):p2p覆盖网络(p2p overlay network)
设计原则:简单,鲁棒,而不是高效(simple, robust, but not efficient)
消息的传播方式:flooding,即一个结点收到消息后,将消息传播给其邻居结点(邻居结点的选取是随机的,增强了鲁棒性,牺牲了高效性),并标记自己已经收到过这个消息,再次接收到此消息就不再传播给邻居结点了

挖矿难度调整的目的:避免出块时间太短,造成区块链上有太多分叉,也是为了避免有恶意结点的攻击
怎样调整挖矿难度:new_target = target * actual time / expected time 或者 next_difficulty = previous_difficulty * expected time / actual time
注:target为区块要求的目标阈值(target越大,挖矿难度越小),actual time为挖出2016个区块花费的实际时间,expected time为想要调整的
时间(2016 * 10):每10分钟出一个区块

交易过程:假如A转账给B
输入(收款方B):指出货币的来源(即来自哪个交易的输出,具体是给出该交易的hash值),给出输出的序号(指明是第几个输出),输入脚本
输出(转帐方A):可能会有多个输出。给出输出金额,给出该次输出的序号(从0开始),输出脚本
比特币脚本语言:
输入输出的验证方式(用栈做存储):
一、P2PK(Pay to Public Key)
输入脚本:给出 签名
输出脚本:给出收款人公钥。并检查输入中的 签名 是否与公钥匹配
二、P2PKH(Pay to Public Key Hash):最常用的一种验证方式
输入:给出签名,公钥
输出:给出收款人公钥的hash。复制输入的公钥,并将复制的公钥算出hash值,算出的hash值与输出中给出的hash值比较,最后检验输入的签名和公钥是否匹配
三、P2SH(Pay to Script Hash)
输入:给出签名和序列化的赎回脚本(redeemScript赎回脚本给出公钥并验证签名和公钥是否匹配)
输出:收款人提供的赎回脚本的Hash值
执行过程:
1、签名进栈,序列化的赎回脚本进栈,赎回脚本算hash值,输出脚本的hash值进栈,检查两个hash值是否匹配
2、序列化赎回脚本反序列化,展开,脚本中的公钥进栈,检查公钥和签名是否匹配
四、多重签名
输入:第一个位置给出一个随机的元素(由于脚本bug,无法修复),给出多个签名(>=M且<=N)
输出:给出阈值M,即最少需要的签名数,给出收款人的多个公钥,及给出的公钥数目N
执行:输入脚本中的随机元素压入栈,多个签名压入栈。输出脚本的阈值M进栈,所有公钥及公钥数目进栈,最后进行检查,签名与所有公钥的匹配数目大于阈值M则验证通过
但这种方式的多重签名输出脚本即用户端需要给出M,N,及相应的公钥,加大的用户使用的难度,降低了体验感。
五、用P2SH实现多重签名
输入:给出随机元素,多个签名,序列化的赎回脚本(脚本中包含M,N,及多个公钥)
输出:给出收款人提供的赎回脚本的hash
执行:1、先验证脚本hash,输入脚本的随机元素,多个签名,序列化的脚本依次进栈,计算赎回脚本的Hash,输出脚本的hash进栈,比较这两个hash值,相同则将序列化的赎回脚本反序列化,进行下一步操作
2、执行CHECKMULTISIG,即比较给出的签名与赎回脚本中给出的公钥的匹配数目是否大于阈值M,如果满足阈值,则验证通过
这种多重签名方式将操作难度转移到了收款方,方便用户使用。

分叉
硬分叉:由于比特币协议变更(比如区块大小1M->4M),新结点认同变更后的协议,不认同老结点挖出的区块,新结点就会沿着新结点挖出的区块往下挖,而老结点不认同协议,认为新结点挖出的区块不合法,就会沿着协议变更之前的最后一个区块挖,最终产生永久存在的硬分叉,硬分叉存在后交易里要写明发布交易的区块链ID,防止交易在两条链上都发布出去,造成损失。需要所有结点都认同协议更新,才不会产生硬分叉。
软分叉:同样由于协议变更(比如区块大小1M->0.5M),新结点认同变更后的协议,老结点也认同变更后的协议,老结点认为新结点挖出的区块合法,但新结点认为老结点挖出的区块不合法。所以每当老结点挖出一个不符合变更后的协议的区块,新结点不认同该区块,就会产生软分叉。新结点会沿着合法的区块往下挖,老结点挖出的不合法的区块就会被抛弃,软分叉就是区块链上不会永久存在的分叉。

比特币的匿名性
潜在危险:
1、同一个人掌握的不同账户之间有关联
2、用比特币与现实进行交互时可能暴露身份
解决办法:
1、专门负责coin mixing的网站,不过这样的网站也是具有匿名性的,可能卷款跑路
2、交易所
3、在线钱包
零知识证明:一方向另一方证明一个陈述是正确的而无需透露除了该陈述是正确的外的任何信息
其数学基础是同态隐藏:E(x)该函数具有hiding property,且每一个x对应的E(x)不会有碰撞
具有同态加法(根据E(x)和E(y)可以计算出E(x+y)可以和同态乘法的性质

return(花费比特币获取向区块链上写入信息的机会)与coinbase域
都可以保存一些信息,比如可以用来证明自己在某个时间节点已经知道了某种信息。但coinbase域只有拥有记账权的节点能使用,发布交易不需要有记账权,发布区块需要有记账权

posted @ 2021-04-01 19:05  MasterBeyond  阅读(361)  评论(0)    收藏  举报