比特币机制

比特币机制

https://zhuanlan.zhihu.com/p/45207775

https://zhuanlan.zhihu.com/p/46072343

https://zhuanlan.zhihu.com/p/46152836

https://zhuanlan.zhihu.com/p/46731633

交易

    交易由三部分构成:元数据、输入(多个)和输出(多个)

  • metadata: hash, ver, in_sz, out_sz, lock_time, size

  • inputs: prev_out{hash, n(index)}, scriptSig

  • outputs: values, scriptPubKey

记账方式

    account-base → UTXO-base

UTXO

    UTXO集被每个节点长期保存,保存在chainstate中,每当有新的区块被接受是,更新。

  • 优点:

        可扩展,能并行处理

        私密性,只要每次都使用新地址

  • 缺点: 反直觉、不高效

    

比特币脚本

    scriptSig相当于是一把锁(lock)

    scriptPubKey 是锁的钥匙

    比特币脚本是基于栈的语言。栈允许两类操作:入栈和出栈。使用后缀表达式。

    交易的执行结果要么就是成功的,也即交易是合法的,可以被包括在区块链中;要么就是失败,也即交易是无效的,不能被包括在区块链中。

交易类型

  P2PK

       验证scriptPubKey 提供的公钥确实是前序交易中scriptSig指定的公钥

       但是存在公钥泄露的风险,因为交易被打包后会全网广播

  P2PKH

       相比于P2PK,在你花钱之前你的公钥不会被暴露

       给支付者的地址是pkhash,只有在要花钱的时候才提供自己的pk

       分为两个部分,一部分验证pk确实是所指定的pk(通过检查pkhash),另一部分验证花钱者确实拥有pk(通过检查签名)

  P2SH

       顾名思义,pay-to-script-hash就是把币发到一个脚本的哈希,而不是公钥或者公钥哈希。

   OP_CHECKMULSIG

       和OP_CHECKSIG相比,OP_CHECKMULSIG多了个MUL,也即它需要检查多个签名。

       栈底需要补充一个OP_0

  •     提出该指令的目的是使能安全钱包、托管交易、以及其他需要多于一个签名的使用情况。

  •     使用WPS(wallet protection service)保护的钱包。譬如需要2-of-2的签名的交易,其中一个签名来自于安装了钱包的(可能不安全的)电脑,另一个签名来自WPS。当发送受保护的比特币时,用户的比特币客户端会将交易发给WPS,WPS会向用户请求确认,譬如用户确实发起了这个交易,以及交易的细节是正确的。

  •     组织资金使用:2-of-3的情况,由三名董事组成的董事会,为他们的组织维护资金-除非其中两名董事同意,否则不得动用这些资金。 较大的组织可以进行更大的多重签名交易,例如3-of-5, 5-of-9等。

  •     第三方托管服务(买方、卖方、以及信任第三方 Escrow transaction)。适用于需要2-of-3签名的交易。买方、卖方和第三方没人都提供公钥,买方将创建交易,并使用2-of-3 CHECKMULTISIG,然后将交易ID发送给卖方和第三方。卖方履行自己的责任,然后要求买方共同签名,才能获得支付的币。如果买卖双方起了争执,则第三方会参与进来,譬如如果买方收到货却不肯签名,那么第三方将进行签名,这样满足条件,从而卖方可以获得应得的报酬。

            但是,n-of-m会让购买方的scriptSig变长,而比特币中的每一个bit都是需要花钱的(有开销),相当于无形中增加了买方的成本。故,使用P2SH,即脚本的哈希作为接收地址,固定长度,将burden转移给卖方。

                也即从output转移到input。output处于UTXO中,input只存储在链上,相比之下input的开销小。

                将存储压力从现在支付状态时延迟到未来花费状态。

            

            根据redeemScript生成P2SH地址

payload为redeemScript

            Tx中,在scriptPubkey中的 redeemScriptHash地址为base58编码之前的

            P2SHaddress为redeemScriptHash经过base58编码后的

            **Base58 **

                在Base64基础上去除了容易混淆的字符

                

SegWit 隔离见证

    https://zhuanlan.zhihu.com/p/139279297

    签名部分在矿工验证后就没有作用,故将签名部分移除

    - 解决ECDSA存在交易延展性问题 (malleability)

        在不知道私钥的情况下,可以更改交易中签名的几个位,却仍能通过矿工的验证(OpenSSL不是严格验证)

        结果: 会导致TxID的变化,即伪造了新的交易(仅签名变化,交易内容不变)

            e.g. mtgox attack 向交易所重复提款

        移除签名后,签名的改变不能影响到TxID

    - 减少交易所占空间,增加区块链的吞吐量

        签名部分占65%

Lightning Network:Micropayment Channel

    #### 简介

    使用特殊的智能合约解决同一买卖双方的小微高频交易(比特币的交易吞吐量太小)

    交易双方建立channel,在整个交易结束后才上联链。由于中间交易不上链,也不会产生过多手续费。

    甚至不一定需要建立专门的渠道来向某个人发送资金。相反,你可以使用与你已连接的人的频道向某人发送付款。系统将自动找到最短路径。

    - 交易双方分别向合约投入资金,生成两个合约:

        - 注资合约

        - 撤销合约

    每当部分交易完成,A会签署新合约跟进交易,之前的合约视为作废

    - 如果A想赖账

        - 恶意签署了Tx3

            - 在没有B签名的情况下,FundTx3不被认可,B可以签署Tx2并公布上链,获得应得收入

        - 直接签署Refund

            - 有一段TimeLock计时,在此期间内不会生效。B在发现后可以签署最新的Tx将钱拿走

    #### RSMC

        Revocable Sequence Maturity Contract

        

        - Fund 大致同上 Lock some money

        - Commit

            每次会产生两份合约,互相签署

            交易双方都可以签署Commit Tx,关闭本次channel

        - Delivery

        - Revocable delivery

            交易可撤回/退出,提出撤回/退出的人会被惩罚(等待n个block生成)

            C2a和C2b使用同一个input,属于双花,故最终只有一个会被确认

            - 对于C2a,Alice可以确保钱不会被Bob偷走

                AliceR2由Alice创建,只有在Alice同意的情况下才会转账给Bob

        - Breach remedy

            - Bob无法cheat

                在产生state2时,双方要相互交换withdrawKeys (AliceR1、BobR1),让state1失效,即给了对方拿走state1中所有钱的能力,但前提是对方先将state1的合约进行了广播(想要赖账)

                若Bob在state2时广播了C1b,想赖账,则根据C1b,Alice会立刻收到2btc,而Bob需要继续等待100个block,期间Alice发现后,可以提供自己的key,把剩下的钱都转到自己的地址

    #### HTLC

        Hashed Time Lock Contract

        RSMC缺点:需要交易双方之间建立支付通道channel

            开关channel都需要online,费时间又费钱

        HTLC提供了路由能力,可以通过已经建立连接的第三方进行可信 的交易,避免建立channel的开销

HTLC Script

        Alice通过Bob向Carol转账,Bob与交易双方各建立一个HTLC连接

        - Alice首先向Bob转账,并要求Bob返回Carol的pbKey,否则在locktime结束后,Alice通过提供自己的pbKey取回刚转的钱。Alice会将转账的钱锁在HTLC交易中,Bob不用担心

        - Bob向Carol要求Carol的pbKey,若没超时前完成,则Alice与Carol交易等价成功,Bob可以向Carol要求支付手续费。若与Alice的HTLC已经超时,Bob可以拒绝Carol的取款请求。

        - 注意与Alice(payer)的HTLC连接过期时间要早于与Carol(payee)

            否则,Bob可能会损失交易额(A,C各拿走一份)

区块

    区块是一种被包含在公开账簿(区块链)里的聚合了交易信息的容器数据结构。它由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易列表组成。区块头是80字节,而平均每个交易至少是250字节,而且平均每个区块至少包含超过500个交易。

    ### Hash Pointer

    【哈希指针是一种数据结构,是一个指向数据存储位置及其位置数据的哈希值的指针。这就使得正常的指针可用于取回信息,哈希指针用于验证信息是否发生改变。】

    - retrieve 获取数据

    - verify 验证数据,保证数据完整性(交易数据&区块数据)

    

    区块链中的区块主要依赖于两种基于Hash的数据结构

    - 一是区块的哈希链,通过哈希指针形成的链,可以跳转到之前或者之后的区块

        一旦一个区块有很多代以后,瀑布效应将保证该区块不会被改变,除非强制重新计算该区块所有后续的区块。正是这样的重新计算需要耗费巨大的计算量,所以一个长区块链的存在可以让区块链的历史不可改变,这也是比特币安全性 的一个关键特征。

    - 二是区块内的每个块内的交易组成的树状结构。

    

    每个区块的第一个交易是coinbase transaction,也即generation transaction,作为矿工打包交易生成区块的奖励。

    ### Merkle Tree

    除了区块链之外,Merkle可信树在其他领域应用也很多,如在分布式系统中用于数据一致性验证,git中的版本一致性验证也是基于Merkle树。大部分Merkle树是二叉哈希树,在比特币中,merkle树主要适用于组织正常的交易,使得交易易于验证并且使用较少的资源。

        为什么要用Merkle树

        使用分布式文件服务器做例子。如果两个服务器A和B都是对某个文件系统的冗余备份。现在希望A和B通信来确认一下,它们所保存的文件是一致的。

        - 如果不使用哈希,那么这个通信代价是整个的文件系统,需要把所有的文件都传递到一个进行比较的服务器上,然后进行字符串比较。

        - 如果A和B两个服务器上存储的文件系统都是一致的,也即两个的哈希值是一样的,那么自然是很好的。

        - 如果两个哈希值不一致,A服务器就可以向B服务器要两个子节点的哈希值;然后沿着不一样的路径一直走下去,从而可以确定导致根哈希值不同的文件。

    ### SPV

    在比特币中,使用Merkle树可以支持轻量级的节点SPV。SPV可以不需整个网络的数据而确认交易是否存在。

    需要验证时,向全节点请求,全节点返回对应的Merkle Path,SPV进行验证。

    安全性

        1. 若全节点返回的是一条恶意的路径?

            由于哈希的计算具有不可预测性,使得一个恶意的“全”节点想要为一条不存在的节点伪造一条“伪路径”使得最终计算的根哈希与轻节点所维护的根哈希相同是不可能的

        2. 为什么不直接向全节点请求该节点是否存在于区块链中?

            由于在公链 的环境中,无法判断请求的全节点是否为恶意节点 ,因此直接向某一个或者多个全节点请求得到的结果是无法得到保证的。但是轻节点本地维护的区块头信息,是经过工作量证明验证的 ,也就是经过共识一定正确的,若利用全节点提供的Merkle路径,与待验证的节点进行哈希计算,若最终结果与本地维护的区块头中根哈希一致,则能够证明该节点一定存在于默克尔树中。

        3. SPV容易受到什么攻击?

            SPV节点毫无疑问可以证实某个交易的存在性,它也能够证明某个区块中不存在某个交易,但它不能验证某个交易(譬如同一个UTXO的双重支付)在整个链中不存在,这是因为SPV节点没有一份关于所有交易的记录。这个漏洞会被针对SPV节点的拒绝服务攻击或双重支付型攻击 所利用。

            为了防御这些攻击,SPV节点需要随机连接到多个节点 ,以增加与至少一个可靠节点相连接的概率。这种随机连接的需求意味着SPV节点也容易受到网络分区攻击或Sybil攻击 。在后者情况中,SPV节点被连接到虚假节点或虚假网络中,没有通向可靠节点或真正的比特币网络的连接。

            > 完整的区块链节点是通过检查整个链中在它之下的数千个区块来保证这个UTXO没有被支付,从而验证交易。而SPV节点是通过检查在包含该交易的区块所收到的确认数目来验证交易

    ### Bloom Filter

    Q: SPV节点怎么样从网络中接收到与自己相关的交易,确定交易所在的区块呢?

    A:在比特币中,使用Bloom过滤器来加快钱包同步;以太坊使用Bloom过滤器用于快速查询以太坊区块链的日志。

可以保护查询者的隐私

    布隆过滤器(Bloom Filter)是1970年由布隆提出的,用来判断某个元素是否在集合内,它具有运行速度快(时间效率),占用内存小的优点(空间效率),但是有一定的误识别率和删除困难 的问题。它能够判断某个元素一定不在 集合内或可能在 集合内,也即Bloom Filter会造成一定的False Positive,但是不会造成False Negative。

    Bloom过滤器的实现是由一个可变长度(N)的二进制数组(N位二进制数构成一个位域)和数量可变(M)的一组哈希函数组成。这些哈希函数的输出值始终在1和N之间,并且该函数为确定性函数,也即对特定输入总是得到同一个的结果。Bloom过滤器的准确性和私密性 能通过改变长度(N)和哈希函数的数量(M)来调节。

    - 传回的不一定对,但对的一定都被传回。

    - Bloom filter的优点包括:空间效率和查找时间复杂性;不需要存储元素本身,在保护隐私方面具有优势。

    Bloom filter被广泛应用于各种领域,比如拼写检查、字符串匹配算法、网络包分析工具、Web Cache、文件系统、存储系统等。

    ### SPV & Bloom Filter

        Process

        首先,SPV节点会初始化一个不会匹配任何关键词的“空白”Bloom过滤器。接下来,SPV节点会创建一个包含钱包中所有地址信息的列表,并创建一个与每个地址相对应的交易输出相匹配的搜索模式。通常,这种搜索模式是一个向公钥付款的哈希脚本,该脚本是一个会出现在每一个向公钥哈希地址(P2PKH)付款的交易中的锁定脚本。如果SPV节点需要追踪P2SH地址余额,搜索模式就会变成P2SH脚本。然后,SPV节点会把每一个搜索模式添加至Bloom过滤器里,这样只要关键词出现在交易中就能够被过滤器识别出来。最后,对等节点会用收到的Bloom过滤器来匹配传送至SPV节点的交易。

        使用以下算法,一旦发现了匹配,则算法停止。

        1. 测试交易本身的哈希。

        2. 对于每个输出,测试输出脚本中的每一个数据项。每一个哈希(密钥)都单独测试。

            更新BF

            如果在测试交易的时候发现了匹配的输出,那么节点也可以升级filter,将该输出的COutPoint结构也添加到filter中。也即,将该交易的输出中与SPV用户自己相关的部分(可用于其他交易的输入)添加到filter中。

        3. 对于每一个输入,测试COutPoint结构。

        4. 对于每一个输入,测试输入脚本ScriptSig的每一个数据项。

        5. 否则,没有匹配。

        分析

        1. 步骤1是因为用户有可能对某一个特定的交易感兴趣;

        2. 步骤2是因为用户可能在过滤器中加入了自己的公钥或地址;如果某一笔交易发钱给自己,那么用该COutpoint来更新过滤器;【检查自己的收入】

        3. 步骤3、4检查自己的花费;

        选项

        - Bloom_update_none

            不更新。主要是因为,随着加入项的增多,Bloom Filter的效率会变低。

        - Bloom_update_all

            将输出中的scriptpbk中的outpoint都加入进来。

        - Bloom_update_P2PUBKEY_ONLY

            仅在输出脚本是 pay-to-pubkey或者是pay to multisig形式的时候才将outpoint添加到filter中。

            【在P2PKH类型的交易中,如果要花费,则在scriptsig中一定会有用户的公钥提供,所以用户可以通过在filter中添加自己的公钥来查询;从而防止filter性能快速下降】

        

钱包

    有一个误解是,比特币钱包里含有比特币。事实上,钱包里只含有钥匙。 “钱币”被记录在比特币网络的区块链中。 用户通过钱包中的密钥签名交易,从而来控制网络上的钱币。 在某种意义上,比特币钱包是密钥链。每个用户有一个包含多个密钥的钱包。保管比特币,本质就是存储和管理私钥

    - 将密钥存在移动设备就像把钱带在身上,方便使用但是安全性不佳,这种方式叫做“Hot strorage

    - 另一种方式是将密钥锁起来,不上网,用起来不方便,但是很安全,这种叫做“cold storage

    ### 钱包类型

    - 早期的做法是一次性生成100个左右的公私钥对,从最开始就生成足够多的私钥并且每个密钥只使用一次。管理这种密钥的钱包称作,非确定性钱包 (nondeterministic wallet),这种钱包也被称为“Just a Bunch Of Keys(一堆密钥)”,简称JBOK钱包 。这种钱包的缺点很明显,因为很难管理 。如果生成多个密钥,必须保存所有的副本。而且一旦钱包不能访问,所有的资金就不能使用了。在建议每个比特币地址只使用一次的情况时,这种钱包不是好的选择,虽然比特币核心客户端包含了这种钱包,但是不鼓励大家使用。这种钱包现在正在被确定性钱包替换。

    - 第二种类型是确定性钱包(deterministic wallet) ,其中所有的密钥都是从一个主密钥派生出来,这个主密钥即为种子(seed)。该类型钱包中所有密钥都相互关联,如果有原始种子,则可以再次生成全部密钥。

        确定性钱包中使用了许多不同的密钥推导方法。最常用的推导方法是使用树状结构,称为分级确定性钱包或HD钱包 。确定性钱包由种子衍生创造。为了便于使用,种子被编码为英文单词,也称为助记词。

        - HD钱包有两个主要的优势

            - 第一,树状结构可以被用来表达额外的组织含义 。比如当一个特定分支的子密钥被用来接收交易收入并且有另一个分支的子密钥用来负责支付花费。不同分支的密钥都可以被用在企业环境中,这就可以支配不同的分支部门、子公司、具体功能以及会计类别。

            - 第二,用户可以在不需要访问相对应的私钥的前提下建立一个公钥的序列 。所以HD钱包在不安全的服务器中使用或者在每笔交易中发行不同的公钥。公钥不需要被预先加载或者提前衍生,而在服务器中不需要可用来支付的私钥。

            HD 钱包的确定性来源于种子,当种子确定后,钱包中的所有私钥就都是确定的,都可以从种子计算出来。

    ### *ECDSA

    https://zhuanlan.zhihu.com/p/425590941

    ### 密钥生成

        #### 扩展密钥

        

        扩展公钥,不同于公钥,公钥是理所当然应该公开的;而扩展公钥因为是公钥和链码的连接,为了保护链码,应该保护扩展公钥

        - 可以从私钥和链码,衍生出其所有的 子私钥及对应的子公钥(及之后每层所有的子私钥及对应的子公钥)

        - 可以从公钥和链码,衍生出其常规衍生 的子公钥(及之后每层常规衍生的子公钥)

        - 无法从某个密钥(公钥和私钥)计算出其父密钥,或同层的其他兄弟密钥

        安全性:

            扩展密钥使用方便,但要注意:

            - 虽然泄露某个扩展公钥不会丢币,但会导致以此为根节点衍生出的扩展公钥全部泄露,破坏了隐私性

            - 泄露扩展公钥和该公钥衍生出的之后任一代公钥对应的私钥,有被推导出该扩展公钥所有后代私钥的可能

            也即,如果攻击者获得了父链码和父公钥 ,那么就可以获得所有的子链码 。有了子链码,如果又获得了底层的某一个私钥(孙子密钥) ,那么可以根据这个链码生成所有的扩展私钥

        #### 强化子密钥

        强化的子密钥生成需要祖先链码、祖先私钥和索引值 生成子链码和子私钥 。这样的话,仅仅知道祖先扩展公钥不能用来生成强化的子公钥。(无法生成Left-hand-output,所以知道父公钥的情况下,也不能直接计算出子公钥;)

        HD钱包使用index来指示生成的是否位强化子密钥

posted @ 2021-12-13 22:21  紫羊  阅读(104)  评论(0)    收藏  举报