交易脚本

    ⽐特币客⼾端通过执⾏⼀个⽤类Forth脚本语⾔编写的脚本验证⽐特币交易。锁定脚本被写⼊UTXO,同时它往往包含⼀个⽤
同种脚本语⾔编写的签名。当⼀笔⽐特币交易被验证时,每⼀个输⼊值中的解锁脚本被与其对应的锁定脚本同时(互不⼲扰
地)执⾏,从⽽查看这笔交易是否满⾜使⽤条件。
    ⽐特币交易验证并不基于⼀个不变的模式,⽽是通过运⾏脚本语⾔来实现。这种语⾔可以表达出多到数不尽的条件变种。这也是⽐特币作为⼀种“可编程的货币”所拥有的权力。
    ⽐特币脚本语⾔被称为基于栈语⾔,因为它使⽤的数据结构被称为栈。栈是⼀个⾮常简单的数据结构,它可以被理解成为⼀
堆卡⽚。栈允许两类操作:⼊栈和出栈。⼊栈是在栈顶部增加⼀个项⽬,出栈则是从栈顶部移除⼀个项⽬。

    脚本分类
    ⽐特币的交易验证引擎依赖于两类脚本来验证⽐特币交易:⼀个锁定脚本和⼀个解锁脚本。
    锁定脚本是⼀个放在⼀个输出值上的“障碍”,同时它明确了今后花费这笔输出的条件。由于锁定脚本往往含有⼀个公钥(即⽐特币地址)。
    解锁脚本是⼀个“解决”或满⾜被锁定脚本在⼀个输出上设定的花费条件的脚本,同时它将允许输出被消费。解锁脚本是每⼀笔⽐特币交易输出的⼀部分,⽽且往往含有⼀个被⽤⼾的⽐特币钱包(通过⽤⼾的私钥)⽣成的数字签名。由于解锁脚本常常包含⼀个数字签名,因此被称作 ScriptSig
    每⼀个⽐特币客⼾端会通过同时执⾏锁定和解锁脚本来验证⼀笔交易。对于⽐特币交易中的每⼀个输⼊,验证软件会先检索输⼊所指向的UTXO。这个UTXO包含⼀个定义了花费条件的锁定脚本。接下来,验证软件会读取试图花费这个UTXO的输⼊中所包含的解锁脚本,并执⾏这两个脚本。

    脚本特性
     1、图灵⾮完备性,这意味着脚本的复杂性有限,交易可执⾏的次数也可预⻅。施加的这些限制确保该语⾔不被⽤于创造⽆限循环或其它类型的逻辑炸弹,受限制的语⾔能防⽌交易激活机制被⼈当作薄弱环节⽽加以利⽤。
     2、⾮主权验证,⽐特币交易脚本语⾔是⽆国家主权的,没有国家能凌驾于脚本之上,也没有国家会在脚本被执⾏后对其进⾏保存。可以预⻅的是,⼀个脚本能在任何系统上以相同的⽅式执⾏。,这意味着⼀个有效的交易对每个⼈⽽⾔都是有效的,⽽且每⼀个⼈都明⽩这⼀点。这种对于结果的可预⻅性是⽐特币系统的⼀项重要良性特征。
     3、脚本语言,脚本是⼀种⾮常简单的语⾔,这种语⾔被设计为能在有限的硬件上执⾏,它仅需最少的处理即可,⽽且不能做许多现代编程语⾔可以做的事情。当涉及可编程的钱时,这是它的⼀个基于深思熟虑的安全特性。

    标准交易脚本

    五⼤标准脚本分别为P2PKH、P2PK、MS(限15个密钥)、P2SH和OP_Return.
     P2PKH(Pay-to-Public-Key-Hash)
    ⽐特币⽹络上的⼤多数交易都是P2PKH交易,此类交易都含有⼀个锁定脚本,该脚本由公钥哈希实现阻⽌输出功能,公钥哈
希即为⼴为⼈知的⽐特币地址。由P2PKH脚本锁定的输出可以通过键⼊公钥和由相应私钥创设的数字签名得以解锁。
    P2PK(Pay-to-Public-Key)
    与P2PKH相⽐,P2PK模式更为简单。与P2PKH模式含有公钥哈希的模式不同,在P2PK脚本模式中,公钥本⾝已经存储在
锁定脚本中,⽽且代码⻓度也更短。P2PKH是由Satoshi创建的,主要⽬的⼀⽅⾯为使⽐特币地址更简短,另⼀⽅⾯也使之
更⽅便使⽤。P2PK⽬前在Coinbase交易中最为常⻅,Coinbase交易由⽼的采矿软件产⽣,⽬前还没更新⾄P2PKH。
    锁定版脚本:<Public Key A> OP_CHECKSIG
    解锁的脚本<Signature from Private Key A>
    验证组合脚本:<Signature from Private Key A> <Public Key A> OP_CHECKSIG
     多重签名
    多重签名脚本设置了这样⼀个条件,假如记录在脚本中的公钥个数为N,则⾄少需提供其中的M个公钥才可以解锁。这也被称
为M-N组合,其中,N是记录在脚本中的公钥总个数,M是使得多重签名⽣效的公钥数阀值(最少数⽬)。
    M-N多重签名锁定脚本:   M <Public Key 1> <Public Key 2> ... <Public Key N> N OP_CHECKMULTISIG
    解锁脚本:OP_0 <Signature B> <Signature C>
    两个脚本组合将形成⼀个验证脚本:OP_0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 OP_CHECKMULTIS
      数据输出(OP_RETURN操作符)
     OP_Return 允许开发者在交易输出上增加40字节的⾮交易数据。然后,与伪交易型的UTXO不同, OP_Return 创造了⼀种明确的可复查的⾮交易型输出,此类数据⽆需存储于UTXO集。 OP_Return 输出被记录在区块链上,它们会消耗磁盘空间,也会导致区块链规模的增加,但它们不存储在UTXO集中,因此也不会使得UTXO内存膨胀,更不会以消耗代价⾼昂的内存为代价使全节点都不堪重负。
    OP_RETURN 脚本的样式:OP_RETURN <data>
     P2SH(Pay-to-Script-Hash)

    多重签名会有如下问题:

    1.交易臃肿,N个公钥都要包含在交易的输出中(锁定脚本中),增加了交易的大小同时增加了交易费用,另外还增加了矿工维护UTXO的负担。

    2.付款用户必须根据你提供的所有公钥信息对交易中的锁定脚本进行定制,给支付带来极大的不便利。

    

    P2SH的出现即是为了解决多重签名存在的这些问题,P2SH增加赎回脚本(Redeem Script)概念,P2SH脚本内容示例:

    赎回脚本 2 PubKey1 PubKey2 PubKey3 PubKey4 PubKey5 5 CHECKMULTISIG
    锁定脚本HASH160 <20-byte hash of redeem script> EQUAL

    解锁脚本Sig1 Sig2 <redeem script>

    从脚本内容可以看到,锁定脚本从原来的多重签名锁定脚本变成了原脚本的哈希,而赎回脚本内容即为原来的多重签名    锁定脚本内容,解锁脚本中增加了赎回脚本的内容。

    所以执行的情况变成如下:

    1.先对比解锁脚本中的赎回脚本内容哈希与锁定脚本中是否一致
    Sig1 Sig2 <redeem script> HASH160 <20-byte hash of redeem script> EQUAL

    2.如果上面的对比结果一致,则变成执行如下内容(回到了多重脚本验证的情况)

    Sig1 Sig2 2 PubKey1 PubKey2 PubKey3 PubKey4 PubKey5 5 CHECKMULTISIG

    
    优点:
     1.锁定脚本简化,减小了交易的空间占用
    2.P2SH地址使付款人无需关心复杂的操作,只需向地址支付即可
    3.P2SH使多重签名脚本的负担转移到收款人身上,而不是付款人
    (1)多重签名导致的交易大小扩大仍然存在,只是由锁定脚本转移到了解锁脚本上。
    (2)只有当需要解锁P2SH地址上的比特币进行付款时才会发生,延迟了占用较多空间交易发生的时间。
    (2)交易大小导致的交易速度减慢,交易费增加等负担转移到收款人承担。

比特币交易P2PKH(Pay-to-Public-Key-Hash)解锁过程示例
    
     解锁脚本 <Sig> <PubKey>
     锁定脚本:OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG

从上图可知,比特币将解锁脚本与锁定脚本拼接后,使用堆栈语言按 后进先出 的顺序执行,最后完成CHECK,如果返回结果为TRUE,代表解锁成功,用户可以使用该笔输出作为新交易的输入进行交易。如果返回为FALSE或者执行过程中出现问题,则花费这笔输出的请求被拒绝。

猜你喜欢

转载自blog.csdn.net/xq723310/article/details/80219843