# P2W\* over P2SH

ビットコインの要求をスクリプト化するための **witness scriptPubKey** を使うことが魅力的だと思われてきている一方で、実際最近のウォレットのほとんどは、P2PKHあるいはP2SHしかサポートしていない。

古いソフトウェアが共存している間、segwitの利点を利用するために、P2SH上でP2Wを使うことができる。古いBitcoinCoreを使っているノードにとっては、それは普通のP2SHを利用した支払いと捉える。

どんな **P2W\*** でも **P2SH上のP2W\*** に変換できる。以下の手順を踏む。

1. **ScriptPubKey** を、同じ内容を示すP2SHで置き換える
2. 変換前の **ScriptPubKey** はトランザクションインプットの **scriptSig** の中に1つだけのプッシュとして記録される。
3. すべての他のデータはトランザクションインプットのwitnessに示される。

心配しないでほしいのだが、もしこれが複雑だと思われたとしても、TransactionBuilderによって効果的にトランザクションを生成できる。

P2SH上のP2WPKH、または略称では **P2SH(P2WPKH)** だが、例を見てみよう。

**ScriptPubKey** を表示する。

```csharp
var key = new Key();
Console.WriteLine(key.PubKey.WitHash.ScriptPubKey.Hash.ScriptPubKey);
```

> 注意：これはとても畏怖の念を感じさせるコードだ。

そうするとよく親しみのあるP2SHの **scriptPubKey** が表示される。

```
OP_HASH160 b19da5ca6e7243d4ec8eab07b713ff8768a44145 OP_EQUAL
```

そしてこのアウトプットを使う、署名されたトランザクションは以下のようになる。

```javascript
"in": [
    {
      "prev_out": {
        "hash": "674ece694e5e28956138efacab96fc0bffd7c6cc1af7bb2729943fedf8f0b8b9",
        "n": 0
      },
      "scriptSig": "001404100ab485c95701bf0f4d73e3fe7d69ecc4f0ea",
      "witness": "3045022100f4c14cf383c0c97bbdaf520ea06f7db6c61e0effbc4bd3dfea036a90272f6cce022055b0fc058759a7961e718d48a3dc4dd5580fffc310557925a0865dbe467a835901 0205b956a5afe8f34a01337f0949f5733b5e376caaea57c9624e40e739a0b1d16c"
    }
  ],
```

**scriptSig** は先ほど出てきたScriptPubKey（言い換えると、**key.PubKey.WitHash.ScriptPubKey**）のP2SH化されたredeem scriptのプッシュでしかない。witnessは完全に通常の **P2WPKH** による支払いと同じになっている。

NBitcoinでは、**P2SH(P2WPKH)** に署名することは、ScriptCoinを用いた通常のP2SHとほぼ同じようなものだ。

同じ原則に則って、**P2SH(P2WSH)** がどのように見えるかを見てみよう。この場合、2つの異なるredeem scriptを扱わなければならない。トランザクションインプットの **scriptSig** に入れる必要のある **P2SHのredeem script** と、witnessに入れる必要のある **P2WSHのredeem script** だ。

最初のルールにもとづいて、**scriptPubKey** を表示してみよう。

1. **ScriptPubKey** をP2SHと同等の情報で置き換える。

   ```csharp
   var key = new Key();
   Console.WriteLine(key.PubKey.ScriptPubKey.WitHash.ScriptPubKey.Hash.ScriptPubKey);
   ```

   ```
   OP_HASH160 d06c0058175952afecc56d26ed16558b1ed40e42 OP_EQUAL
   ```

   > **注意**：理解できるから、ここでキレて回線切断しないで！
2. 置き換え前の **ScriptPubKey** はトランザクションインプットの **scriptSig** にたった1つのプッシュとして記録される。
3. すべての他のデータはトランザクションインプットのwitnessにプッシュされる。

項番3の「**他のデータ**」というのは、P2WSHにおける支払いの文脈では、**P2WSHのredeem script** のプッシュに続く、**P2WSHのredeem script** のパラメータを意味する。

```javascript
"in": [
    {
      "prev_out": {
        "hash": "1d23fa744a26cf6433f0841e9de7e088cf95e6f953e584b98d0de6ef4216765f",
        "n": 0
      },
      "scriptSig": "0020c54eb79829b2e26b71d15fd3b490b6e95cbdab361a45eed2cdfe642497480a6c",
      "witness": "3045022100d7570c3bf87149a0be3ba2e8bfccbdd35c3da44f741695e9962014795fabc4fc02203183cfa55a85728520b0f1ac59ac3ffa1a8526634fe619f99fac0f76016f366e01 2103146e87d7fcc81f3e044f97c6b262c01826f40a9ab9acae0f689983a5890a1f4dac"
    }
  ],
```

要約すると、P2SHのRedeem Scriptがハッシュされて、通常のP2WSHによる支払いとしてP2WSHのscriptPubKeyが得られる。そして通常のP2SHの支払いとして、P2WSHのscriptPubKeyはハッシュされて置き換わり、まさにP2SHを作るために使われる。

もし、P2SH/P2WSH/P2SH(P2WSH)/P2SH(P2WPKH)が複雑に思えていても、怖がることはない。\
NBitcoinでは、**これらP2SHが関連するすべての支払い形式において**、**ScriptCoin** を作ることだけしか求めない。それは **P2SH** の章で説明したとおりで、P2WSHかP2SHのRedeem ScriptとScriptPubKeyを与えてやれば、作ることができる。

NBitcoinに関して言えば、使いたいと思っているトランザクションアウトプットを使い、正しいredeem scriptがあれば、前章の「**マルチシグ**」の章で説明されたように、そして次の「**TransactionBuilderを使ってみる**」の章でも説明するが、**TransactionBuilder** が正しい署名の仕方を把握してくれる。

![](https://1176427111-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LL8tJvxJArUEX_X8UyG%2F-LL8tOvxescL5rHe0Q4e%2F-LL8tTzXG9RLxRBFKdkx%2FScriptCoin.png?generation=1535616883043616\&alt=media)

**P2SH/P2WSH/P2SH(P2WSH)/P2SH(P2WPKH)それぞれに互換性があるのだ。**

P2WPKHまたはP2WSHの支払いの例をさらに見たい場合は、<http://n.bitcoin.ninja/checkscript>で見られる。
