chain-btc-script

259 阅读4分钟

bitcoin

脚本简介

比特币在交易中使用脚本系统,与FORTH(一种编译语言)一样,脚本是简单的、基于堆栈的、并且从左向右处理,它特意设计成非图灵完整,没有LOOP语句。

脚本语言是基于栈的,从左向右执行,无状态的,非图灵完备的语言;

  • 无状态确保交易一旦被放到区块链上,就不会出现输出永远不能被花费的情况
  • 非图灵完备(缺少循环和goto语句)让脚本语言更加灵活(flexible)和可预见,简化了安全模型
  • 图灵完备 => 能够计算一切可计算问题

一个脚本本质上是众多指令的列表,这些指令记录在每个交易中,交易的接收者想花掉发送给他的比特币,这些指令就是描述接收者是如何获得这些比特币的。一个典型的发送比特币到目标地址D的脚本,要求接收者提供以下两个条件,才能花掉发给他的比特币:

(1)一个公钥,当进行HASH生成比特币地址时,生成的地址是嵌入在脚本中的目标地址D

(2)一个签名(私钥),证明接收者保存与上述公钥相对应的私钥。

脚本可以灵活改变花掉比特币的条件,举个例子,脚本系统可能会同时要求两个私钥、或几个私钥、或无需任何私钥等等。

如果联合脚本中未导致失败并且堆栈顶元素为真(非零),表明交易有效。

堆栈保存着字节向量,当用作数字时,字节向量被解释成小尾序的变长整数,最重要的位决定整数的正负号。这样0×81代表-1,0×80是0的另外一种表示方式(称之为负0)。正0用一个NULL长度向量表示。字节向量可以解析为布尔值,这里False表示为0,True表示为非0

交易标准

五种交易标准:P2PKH、P2PK、MS(限15个密钥)、P2SH和OP_Return。OP_Return将不会介绍,因为其存储的是信息(或者说只是字节),并非比特币货币。

交易的基本流程

  1. scriptPubKey => 发送方将自己的utxo使用锁定脚本锁定,锁定在接收方的地址上;
  2. scriptSig => 接收方使用解锁脚本进行解锁,才能提取BTC

P2PKH

Pay-to-Public-Key-Hash: 使用公钥hash锁定,现行主要的交易标准;

p2pkh.jpeg

// 完成拼接的脚本内容
<Sig> <PubKey> OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG
//// 解锁脚本 scriptSig => <Sig> <PubKey>
// sig: 使用secp256k1 生成的签名
// PubKey:原生公钥
//// 锁定脚本 scriptPubKey => OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG 

执行顺序

  1. 入栈:{ }
  2. OP_DUP => 复制栈顶: { }
  3. OP_HASH160 => 计算hash: { }
  4. 入栈 => 计算hash: { ,}
  5. OP_EQUALVERIFY 比较相等 => 计算hash: { }
  6. OP_CHECKSIG 校验签名=> { 0:失败,非0:成功}

sig签名是私钥与交易hash进行运算,验证签名OP_CHECKSIG是将公钥与签名进行运算,结果0则校验失败

P2PK

Pay-to-Public-Key: 使用公钥锁定脚本

<Signature from Private Key A> <Public Key A> OP_CHECKSIG
// 解锁脚本: <Signature from Private Key A>
// 锁定脚本: <Public Key A> OP_CHECKSIG

MS(限15个密钥)

Multiple Signatures:多重签名

// 锁定脚本,N是存档的公钥总数,M激活交易需要的最少公钥个数
M <Public Key 1> <Public Key 2> ... <Public Key N> N OP_CHECKMULTISIG
// 解锁脚本:op_0 占位符,无意义,是少M个,
// m=2
OP_0 <Signature 1> <Signature 2>

P2SH

pay-to-script-hash:是MS多重签名的简化版本:

// ms锁定脚本,m=2
2 <Public Key A> <Public Key B> <Public Key C> 5 OP_CHECKMULTISIG
// 对脚本依次进行SHA256,RIPEMD160 得到 hash: 8ac1d7a2fa204a16dc984fa81cfdf86a2a4e1731, 生成p2sh的锁定脚本
OP_HASH160 8ac1d7a2fa204a16dc984fa81cfdf86a2a4e1731 OP_EQUAL
// 解锁脚本(也叫回收脚本)
<Sig1> <Sig2> <2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG>
// 执行顺序,先判断相等,在校验签名

P2SH的特点是,将制作脚本的责任给了接收方,好处是可以暂缓节点存储的压力。

参考