Skip to content

比特币中P2SH(pay-to-script-hash)多重签名的锁定脚本和解锁脚本 #17

@itlgl

Description

@itlgl

P2SH(pay-to-script-hash)多重签名的脚本

P2SH是多重签名的一种应用形式。在P2SH的交易中,多了一个Redeem Script的概念,称为赎回脚本。当向P2SH脚本的地址转账时,锁定脚本中填写的不是公钥地址的列表,而是Redeem Script的hash值,这样锁定脚本变的非常短。只有在P2SH向外转账时的解锁脚本才会很长。这样就避免了多重签交易中锁定脚本过长导致交易费也骤增的问题。

一个M-N的P2SH交易,赎回脚本Redeem Script的一般形式是:

OP_M <PublicKey 1> <PublicKey 2> ... <PublicKey N> OP_N OP_CHECKMULTISIG

锁定脚本的一般形式是:

OP_HASH160 PUSHDATA(<20-byte hash of Redeem Script>) OP_EQUAL

解锁脚本的一般形式是:

OP_0 PUSHDATA(<Signature 1>) PUSHDATA(<Signature2>) ... PUSHDATA(<Signature M>) <Redeem Script>

如果是一个2-3的P2SH多重签名交易,参与者为A,B,C,那么上面的三个脚本就具体成了下面的格式
赎回脚本Redeem Script:

OP_2 PUSHDATA(<PublicKey A> <PublicKey B> <PublicKey C>) OP_3 OP_CHECKMULTISIG

锁定脚本:

OP_HASH160 PUSHDATA(<20-byte hash of Redeem Script>) OP_EQUAL

解锁脚本(B和C发起交易):

OP_0 PUSHDATA(<Signature B>) PUSHDATA(<Signature C>) <Redeem Script>

为什么解锁脚本前面有一个空的签名OP_0?

这是由于CHECKMULTISIG执行的bug,P2SH的解锁脚本是以OP_0开始的,这里贴上《精通比特币》书中的描述:

bug01
bug02 png

脚本参数解释

脚本中的常量值

脚本中的OP_M和OP_N对应的是常量OP_1(0x51) ~ OP_16(0x60)

OP_CHECKMULTISIG=0xAE
OP_HASH160=0xA9
OP_EQUAL=0x88

OP_16常量值就到头了,也就是说现在多重签名最多可以有16个人参与!

PUSHDATA

这个在#16里面写过,这里再写一次:

如果0 < data.length < 76(0x4C),则结果为:1个字节data.length + data数据
如果76(0x4C) <= data.length < 2^8,则结果为:0x4C + 1个字节data.length + data数据
如果2^8 <= data.length < 2^16,则结果为:0x4D + 2个字节data.length + data数据
如果2^16 <= data.length < 2^32,则结果为:0x4E + 4个字节data.length + data数据

PublicKey

赎回脚本中的<PublicKey 1>是没有封装格式的,比如以41开头的非压缩格式公钥和以21开头的压缩格式公钥。

// 压缩格式公钥
21 03 0b461bf0f1253c9dacde9992594042d77798c5f0e7c76a1c587518606fb35478

// 非压缩格式公钥
41 04
0bf69616981e5970c992a0762f441abcadfed9fc4630fa5e1b82ab00e81d1690 // X
5d3820e073e1bd4a9dcfed336f4bf25edc634c2e174989767d299748359c2daf // Y

Signature的格式

有关Signature的签名格式,参见#16里面有关Signature的格式的描述。

示例

锁定脚本的例子解析

附录中的示例1中有P2SH多重签名(2-3的P2SH)的锁定脚本数据:

a9144bb8b35e3c41be76d8c0c16a3a5a398a7688e40187

按照锁定脚本解析一下(2-3的P2SH):

// OP_HASH160 PUSHDATA(<20-byte hash of Redeem Script>) OP_EQUAL

a9 // OP_HASH160
14 // PUSHDATA,length=20
4bb8b35e3c41be76d8c0c16a3a5a398a7688e401 // 赎回脚本的hash,20字节
87 // OP_EQUAL

赎回脚本怎么得来

其实和普通的地址相似,因为要向地址38bPsA6ZXfRuxFD7efVXTkQd69422uzD4B转账,所以还是从地址得到这个hash值:

将地址38bPsA6ZXfRuxFD7efVXTkQd69422uzD4B进行base58解码得到054bb8b35e3c41be76d8c0c16a3a5a398a7688e401470355f00x05表示是P2SH的地址,base58编码以后地址以3开头),将这个结果去掉头部一个字节type,去掉尾部四个字节checksum,即为赎回脚本的hash。

解锁脚本的例子解析

附录中的示例2中有P2SH多重签名(2-3的P2SH)的解锁脚本数据:

00483045022100bd16b2ffa112937856716909162c00a66e7c5e6cccd0093ec9aece127632f8dc02205a567c53161e5fb62ac8d202acf8f8cc2f5a6496f47a878555dae7ffde85a41d01483045022100ac3c0365e103d97d3cc935755d5177e8f383993a558998200f8537e64f6b520002202216716f7fa54adc69095c4127ff6f97d42e28517a103f7691808db3cde6ee5b014cc9524104a7ada7c84ae36e98735597ee770a7cfd2d5d9398154b088ee352d3a83b21bbf537c0b8e4ea0acc172285b37571a9b1e36c0da387d6d1f361f0b65cad5c3f659e4104fe411f77e5aa50b54e0f2be0204b26cd1d2bf77bf95f2108a6b012e34637289121cd351c696c8a519b4b58674a87e7907385b4a5e7c0cfa5019346c1b04040914104eeffa9bbfe6dd2c99a9747ca5d1c1ebd15fe0344f52ff2915e3c11b3be9be11236895e5514b085c1f8a1bd8ef9c3db0cf1095aaf442cae11d88c3af026fabd1653ae // 解锁脚本,变长

按照解锁脚本解析一下(已经不记得由哪两人发起的交易了,暂且认为是B和C发起的):

// OP_0 PUSHDATA() PUSHDATA()

00 // OP_0
48 // PUSHDATA,len=72
3045022100bd16b2ffa112937856716909162c00a66e7c5e6cccd0093ec9aece127632f8dc02205a567c53161e5fb62ac8d202acf8f8cc2f5a6496f47a878555dae7ffde85a41d01 // signature B
48 // PUSHDATA,len=72
3045022100ac3c0365e103d97d3cc935755d5177e8f383993a558998200f8537e64f6b520002202216716f7fa54adc69095c4127ff6f97d42e28517a103f7691808db3cde6ee5b01 // signature C
4cc9 // PUSHDATA,len=201
524104a7ada7c84ae36e98735597ee770a7cfd2d5d9398154b088ee352d3a83b21bbf537c0b8e4ea0acc172285b37571a9b1e36c0da387d6d1f361f0b65cad5c3f659e4104fe411f77e5aa50b54e0f2be0204b26cd1d2bf77bf95f2108a6b012e34637289121cd351c696c8a519b4b58674a87e7907385b4a5e7c0cfa5019346c1b04040914104eeffa9bbfe6dd2c99a9747ca5d1c1ebd15fe0344f52ff2915e3c11b3be9be11236895e5514b085c1f8a1bd8ef9c3db0cf1095aaf442cae11d88c3af026fabd1653ae // Redeem Script

再按照Redeem Script的脚本解析一下Redeem Script:

// OP_2 OP_3 OP_CHECKMULTISIG

52 // OP_2
4104a7ada7c84ae36e98735597ee770a7cfd2d5d9398154b088ee352d3a83b21bbf537c0b8e4ea0acc172285b37571a9b1e36c0da387d6d1f361f0b65cad5c3f659e // PublicKey A
4104fe411f77e5aa50b54e0f2be0204b26cd1d2bf77bf95f2108a6b012e34637289121cd351c696c8a519b4b58674a87e7907385b4a5e7c0cfa5019346c1b0404091 // PublicKey B
4104eeffa9bbfe6dd2c99a9747ca5d1c1ebd15fe0344f52ff2915e3c11b3be9be11236895e5514b085c1f8a1bd8ef9c3db0cf1095aaf442cae11d88c3af026fabd16 // PublicKey C
53 // OP_3
ae // OP_CHECKMULTISIG

附录

示例1:有多重签名锁定脚本的交易

交易的hash为4373f6566e7f8095d3102485e540c948ca6932b34c8a4c38cf336cddc7be44f7,网页展示api JSON数据

网页截图:
tx4373

JSON数据:

{
  "block_hash": "00000000000000000176b5e7c2b2d51308b34dda208df6f2459edbba05ec1b75",
  "block_height": 423147,
  "block_index": 1027,
  "hash": "4373f6566e7f8095d3102485e540c948ca6932b34c8a4c38cf336cddc7be44f7",
  "hex": "01000000010b15b9b578e600fdd71d07efaafeaaab10250f903374922bfe1e0f5389f5bd87010000006a4730440220008f0c0678854d2649448380adb02a7438ba8dfccfe0a85cd0bd353e08d068a4022075e6254f16d7943657127ebb6655dbd3d4fa30395b46d7a57f36ef59617b56b20121026c40b52e1bb5f301925adb124b1573b4297c234dd2c601bfaef46d40bceca70cffffffff02d8469800000000001976a914921a4c141746bbd7beb8e81b05ba93d84b076a0088ac001200000000000017a9144bb8b35e3c41be76d8c0c16a3a5a398a7688e4018700000000",
  "addresses": [
    "1EKXAAiJDntbEK3WSVW3vTcwYJ5ciJ5kSL",
    "38bPsA6ZXfRuxFD7efVXTkQd69422uzD4B"
  ],
  "total": 9984216,
  "fees": 784,
  "size": 223,
  "preference": "low",
  "relayed_by": "124.205.119.164",
  "confirmed": "2016-08-01T11:09:18Z",
  "received": "2016-08-01T06:36:38.935Z",
  "ver": 1,
  "double_spend": false,
  "vin_sz": 1,
  "vout_sz": 2,
  "confirmations": 100786,
  "confidence": 1,
  "inputs": [
    {
      "prev_hash": "87bdf589530f1efe2b927433900f2510abaafeaaef071dd7fd00e678b5b9150b",
      "output_index": 1,
      "script": "4730440220008f0c0678854d2649448380adb02a7438ba8dfccfe0a85cd0bd353e08d068a4022075e6254f16d7943657127ebb6655dbd3d4fa30395b46d7a57f36ef59617b56b20121026c40b52e1bb5f301925adb124b1573b4297c234dd2c601bfaef46d40bceca70c",
      "output_value": 9985000,
      "sequence": 4294967295,
      "addresses": [
        "1EKXAAiJDntbEK3WSVW3vTcwYJ5ciJ5kSL"
      ],
      "script_type": "pay-to-pubkey-hash",
      "age": 422655
    }
  ],
  "outputs": [
    {
      "value": 9979608,
      "script": "76a914921a4c141746bbd7beb8e81b05ba93d84b076a0088ac",
      "spent_by": "50ca192a04c92030bb08d2f67e1ec4618ebb9c8131661fc9d6efbed2966513ba",
      "addresses": [
        "1EKXAAiJDntbEK3WSVW3vTcwYJ5ciJ5kSL"
      ],
      "script_type": "pay-to-pubkey-hash"
    },
    {
      "value": 4608,
      "script": "a9144bb8b35e3c41be76d8c0c16a3a5a398a7688e40187",
      "spent_by": "ac89b280cc21854b82b4cc111a0e6c0d10315117b6001e3f4f3af3d2f7b2fd53",
      "addresses": [
        "38bPsA6ZXfRuxFD7efVXTkQd69422uzD4B"
      ],
      "script_type": "pay-to-script-hash"
    }
  ]
}

交易数据解析:

01000000 // Version
01 // 交易输入个数
0b15b9b578e600fdd71d07efaafeaaab10250f903374922bfe1e0f5389f5bd87 // UTXO
01000000 // UTXO index
6a // 解锁脚本长度
4730440220008f0c0678854d2649448380adb02a7438ba8dfccfe0a85cd0bd353e08d068a4022075e6254f16d7943657127ebb6655dbd3d4fa30395b46d7a57f36ef59617b56b20121026c40b52e1bb5f301925adb124b1573b4297c234dd2c601bfaef46d40bceca70c // 解锁脚本
ffffffff // sequence,序列号
02 // 交易输出个数
d846980000000000 // 金额
19 // 锁定脚本长度
76a914921a4c141746bbd7beb8e81b05ba93d84b076a0088ac // 锁定脚本1
0012000000000000 // 金额
17 // 锁定脚本长度
a9144bb8b35e3c41be76d8c0c16a3a5a398a7688e40187 // 锁定脚本2
00000000 // Time Lock

示例2:有多重签名解锁脚本的交易

交易的hash为ac89b280cc21854b82b4cc111a0e6c0d10315117b6001e3f4f3af3d2f7b2fd53,网页展示api JSON数据

网页截图:
txac89

JSON数据:

{
  "block_hash": "0000000000000000011edeab34b5145125efa596fbc2e6a88825acd9570aa4d8",
  "block_height": 423431,
  "block_index": 927,
  "hash": "ac89b280cc21854b82b4cc111a0e6c0d10315117b6001e3f4f3af3d2f7b2fd53",
  "hex": "0100000001f744bec7dd6c33cf384c8a4cb33269ca48c940e5852410d395807f6e56f6734301000000fd5e0100483045022100bd16b2ffa112937856716909162c00a66e7c5e6cccd0093ec9aece127632f8dc02205a567c53161e5fb62ac8d202acf8f8cc2f5a6496f47a878555dae7ffde85a41d01483045022100ac3c0365e103d97d3cc935755d5177e8f383993a558998200f8537e64f6b520002202216716f7fa54adc69095c4127ff6f97d42e28517a103f7691808db3cde6ee5b014cc9524104a7ada7c84ae36e98735597ee770a7cfd2d5d9398154b088ee352d3a83b21bbf537c0b8e4ea0acc172285b37571a9b1e36c0da387d6d1f361f0b65cad5c3f659e4104fe411f77e5aa50b54e0f2be0204b26cd1d2bf77bf95f2108a6b012e34637289121cd351c696c8a519b4b58674a87e7907385b4a5e7c0cfa5019346c1b04040914104eeffa9bbfe6dd2c99a9747ca5d1c1ebd15fe0344f52ff2915e3c11b3be9be11236895e5514b085c1f8a1bd8ef9c3db0cf1095aaf442cae11d88c3af026fabd1653aeffffffff0100090000000000001976a914921a4c141746bbd7beb8e81b05ba93d84b076a0088ac00000000",
  "addresses": [
    "1EKXAAiJDntbEK3WSVW3vTcwYJ5ciJ5kSL",
    "38bPsA6ZXfRuxFD7efVXTkQd69422uzD4B"
  ],
  "total": 2304,
  "fees": 2304,
  "size": 437,
  "preference": "low",
  "relayed_by": "124.205.119.164",
  "confirmed": "2016-08-03T06:18:06Z",
  "received": "2016-08-03T03:26:33.685Z",
  "ver": 1,
  "double_spend": false,
  "vin_sz": 1,
  "vout_sz": 1,
  "confirmations": 100499,
  "confidence": 1,
  "inputs": [
    {
      "prev_hash": "4373f6566e7f8095d3102485e540c948ca6932b34c8a4c38cf336cddc7be44f7",
      "output_index": 1,
      "script": "00483045022100bd16b2ffa112937856716909162c00a66e7c5e6cccd0093ec9aece127632f8dc02205a567c53161e5fb62ac8d202acf8f8cc2f5a6496f47a878555dae7ffde85a41d01483045022100ac3c0365e103d97d3cc935755d5177e8f383993a558998200f8537e64f6b520002202216716f7fa54adc69095c4127ff6f97d42e28517a103f7691808db3cde6ee5b014cc9524104a7ada7c84ae36e98735597ee770a7cfd2d5d9398154b088ee352d3a83b21bbf537c0b8e4ea0acc172285b37571a9b1e36c0da387d6d1f361f0b65cad5c3f659e4104fe411f77e5aa50b54e0f2be0204b26cd1d2bf77bf95f2108a6b012e34637289121cd351c696c8a519b4b58674a87e7907385b4a5e7c0cfa5019346c1b04040914104eeffa9bbfe6dd2c99a9747ca5d1c1ebd15fe0344f52ff2915e3c11b3be9be11236895e5514b085c1f8a1bd8ef9c3db0cf1095aaf442cae11d88c3af026fabd1653ae",
      "output_value": 4608,
      "sequence": 4294967295,
      "addresses": [
        "38bPsA6ZXfRuxFD7efVXTkQd69422uzD4B"
      ],
      "script_type": "pay-to-script-hash",
      "age": 423147
    }
  ],
  "outputs": [
    {
      "value": 2304,
      "script": "76a914921a4c141746bbd7beb8e81b05ba93d84b076a0088ac",
      "addresses": [
        "1EKXAAiJDntbEK3WSVW3vTcwYJ5ciJ5kSL"
      ],
      "script_type": "pay-to-pubkey-hash"
    }
  ]
}

交易数据解析:

01000000 // Version,4字节
01 // 交易输入个数,1字节
f744bec7dd6c33cf384c8a4cb33269ca48c940e5852410d395807f6e56f67343 // UTXO(Unspent Transaction Output),32字节
01000000 // UTXO的index,4字节
fd5e01 // 解锁脚本长度,VarInt,变长
00483045022100bd16b2ffa112937856716909162c00a66e7c5e6cccd0093ec9aece127632f8dc02205a567c53161e5fb62ac8d202acf8f8cc2f5a6496f47a878555dae7ffde85a41d01483045022100ac3c0365e103d97d3cc935755d5177e8f383993a558998200f8537e64f6b520002202216716f7fa54adc69095c4127ff6f97d42e28517a103f7691808db3cde6ee5b014cc9524104a7ada7c84ae36e98735597ee770a7cfd2d5d9398154b088ee352d3a83b21bbf537c0b8e4ea0acc172285b37571a9b1e36c0da387d6d1f361f0b65cad5c3f659e4104fe411f77e5aa50b54e0f2be0204b26cd1d2bf77bf95f2108a6b012e34637289121cd351c696c8a519b4b58674a87e7907385b4a5e7c0cfa5019346c1b04040914104eeffa9bbfe6dd2c99a9747ca5d1c1ebd15fe0344f52ff2915e3c11b3be9be11236895e5514b085c1f8a1bd8ef9c3db0cf1095aaf442cae11d88c3af026fabd1653ae // 解锁脚本,变长
ffffffff // 交易序列号,4字节
01 // 交易输出个数,1字节
0009000000000000 // 输出金额,8字节
19 // 锁定脚本长度,VarInt,变长
76a914921a4c141746bbd7beb8e81b05ba93d84b076a0088ac // 锁定脚本,变长
00000000 // Time Lock,4字节

Metadata

Metadata

Assignees

No one assigned

    Labels

    wontfixThis will not be worked on比特币bitcoin

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions