はじめに
2016-12-24
仮想通貨・ブロックチェーン Advent Calendar 2016 が空いていたので、最近調べた P2SH についてのまとめを書いておく。
P2SH
Pay to Script Hash の略。 Bitcoin の支払いスクリプトの一種。
scriptPubKey
P2SH の scriptPubKey は次のようになる。
1 |
|
この判定は厳しく、OP_EQUAL の後に任意のコードを置いたり、20byte データを積むのに 0x14 以外のオペコードを使ったりしたら P2SH とは解釈されない。
bitcoin-core 0.13.1 のソースコードでは、script/script.cpp に IsPayToScriptHash という関数が定義されている。 コードを読めば厳密にチェックされているのが分かるかと。
```cpp:script/script.cpp bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: return (this->size() == 23 && (this)[0] == OP_HASH160 && (this)[1] == 0x14 && (*this)[22] == OP_EQUAL); }
1 2 3 4 5 6 7 |
|
bool CScript::IsPushOnly(const_iterator pc) const { while (pc < end()) { opcodetype opcode; if (!GetOp(pc, opcode)) return false; // Note that IsPushOnly() does consider OP_RESERVED to be a // push-type opcode, however execution of OP_RESERVED fails, so // it's not relevant to P2SH/BIP62 as the scriptSig would fail prior to // the P2SH special validation code being executed. if (opcode > OP_16) return false; } return true; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
OP_HASH160 [20-byte-hash-value] OP_EQUAL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
scriptSig: [sign] [redeem script] redeemScr: [pubkey] CHECKSIG
1 2 3 4 5 6 7 8 9 10 |
|
scriptSig: OP_0 [sign1] [sign2] [redeem script] redeemScr: OP_2 [pubkey1] [pubkey2] [pubkey3] OP_3 CHECKMULTISIG
1 |
|
<0>
となっている。 これは正しい CHECKMULTISIG の並びになっている。 // 最初の 0 は CHECKMULTISIG のバグにより必要なダミーの値
P2PKH で multisig を行うと、公開鍵がすべて scriptPubKey に入るので長くなってしまう。マルチシグ用のアドレスもそれに伴って長くなる。
P2SH の場合、redeem script の長さに関わらず、scriptPubKey の長さは 23byte で固定になる。
P2SH アドレス
P2SH のアドレスは、通常のアドレスと同様に base58check で作成する。 ただし以下の違いがある:
- P2PKH アドレスでは公開鍵の hash160 に対して base58check をかけるが、P2SH アドレスでは redeem script の hash160 を使う。
(scriptPubKey の 20byte hash と同じ値) - version byte は、main-net では 5, testnet では 196.
base58 後の先頭文字は、それぞれ '3' と '2'
トランザクションの署名対象
トランザクションの署名を作る際には、対応する UTXO の scriptPubKey で scriptSig を置き換えるが、 P2SH の場合は redeem script で置き換える。