<p>First of all, what are you trying to do? Why do you need a P2WSH address?</p>

<p>A P2WSH address (and P2SH addresses earlier) send coins to a <em>script</em>, which requires satisfying that script to decode. A script of the form <code>&lt;key&gt; CHECKSIG</code> is wasteful - you should be using P2WPKH instead. In general, you use P2WSH when you have more complex spending requirements than a single key. This most often happens when you need multisig (multiple devices or people need to sign off on a spend).</p>

<p>Now, all of this is outside of the scope of BIP173, which only specifies how to encode segwit outputs into human-readable strings and back.</p>

<p>A segwit output is an output whose scriptPubKey starts with OP_0, OP_1, ..., OP_16, and is followed by a push of 2 to 40 bytes. That's it, and BIP173 can encode any of those.</p>

<p>Now, since the activation of BIP141 in Bitcoin, a small subset of segwit outputs have been given a meaning:</p>

<ul>
<li>OP_0 + 20-byte push of RIPEMD160(SHA256(pubkey)) is called a P2WPKH for that public key.</li>
<li>OP_0 + 32-byte push of SHA256(script) is called P2WSH for that script.</li>
</ul>

<p>All other kinds of segwit outputs are meaningless right now (non-standard and spendable by anyone), but that could change in the future. However, all of them can be encoded in Bech32 using BIP173. It doesn't care what the context or meaning is; it just encodes the version number (the OP_n opcode at the start) and the data bytes (what is being pushed afterwards).</p>

<p>Perhaps your confusion comes from the fact that the BIP173 test vectors use "key + OP_CHECKSIG" in its examples. That was just a simple way of constructing examples that are reproducible. They're not representative for how to actually use it.</p>

CC BY-SA 4.0
2018-11-19T08:15:34.907Z
I totally missed that the "key + OP_CHECKSIG" was meaningless in itself. What I wanted to do is add tests to make absolutely sure my implementation was correct: I've added those test now! (See: https://github.com/Kolibri-POS/bech32/blob/master/test/segwit_test.dart#L61-L71)
harm
CC BY-SA 4.0
2018-11-16T17:12:30.023Z
2018-11-16T17:12:30.023Z
Pieter Wuille
<p>When you push items on the stack you must use an opcode to state how long the item you are pushing is. In this case you want to push 33 bytes so OP_PUSH33</p>

<p>Your script would be: </p>

<p><code>OP_PUSH33 0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 OP_CHECKSIG</code> </p>

<p>or </p>

<p><code>210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac</code>. </p>

<p>Then your witness program becomes <code>witprog = sha256(script)</code> or <code>1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262</code></p>

<p>Then you bech32 encode and you get <code>bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3</code></p>

<blockquote>
  <p>Besides the CHECKSIG opcode requires two parameters.</p>
</blockquote>

<p>The other parameter will be the signature and it will be provided by the person spending the coins as part of their scriptSig. Your scriptPubkey is only the second half of the script, the first half comes from the input.</p>

CC BY-SA 4.0
2018-11-19T08:10:41.123Z
That `OP_PUSH33` wasn't evident for me at all when reading https://en.bitcoin.it/wiki/Script. Thanks!
harm
CC BY-SA 4.0
2018-11-16T13:42:15.427Z
2018-11-16T13:50:57.140Z
2018-11-16T13:50:57.140Z
Mike D
<p>The <a href="https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki" rel="nofollow noreferrer">BIP173</a> specification defines how to create Bech32 Segwit native addresses.</p>

<p>In the <a href="https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#examples" rel="nofollow noreferrer">examples</a> section a public key is given: <code>0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798</code>. </p>

<p>Based on that key it is somewhat easy to generate a P2WPKH address, one hashes the key with SHA256, then with RIPEMD160 and use the hex decoded result as the witness program (first two commands are simple CLI and the last is from the Dart <a href="https://pub.dartlang.org/documentation/bech32/latest/bech32/Segwit/Segwit.html" rel="nofollow noreferrer">bech32</a> library):</p>

<pre><code>$ echo 0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 | xxd -r -p | openssl sha256
(stdin)= 0f715baf5d4c2ed329785cef29e562f73488c8a2bb9dbc5700b361d54b9b0554                                                                                                                                                                                                                                      

$ echo 0f715baf5d4c2ed329785cef29e562f73488c8a2bb9dbc5700b361d54b9b0554 | xxd -r -p | openssl ripemd160                                                                                                                                                         
(stdin)= 751e76e8199196d454941c45d1b3a323f1433bd

Segwit('bc', 0, HEX.decode("751e76e8199196d454941c45d1b3a323f1433bd"))
// bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3
</code></pre>

<p>Generating a P2WSH involves the script <code>key OP_CHECKSIG</code> followed by once SHA256 hashing. I'm at a loss how to construct said script. The opcode <code>OP_CHECKSIG</code> is <a href="https://en.bitcoin.it/wiki/Script" rel="nofollow noreferrer">encoded</a> as <code>0xac</code>. But appending that to the key seems silly (and doesn't work). Besides the <code>CHECKSIG</code> opcode requires two parameters. What do I hash?</p>

<bech32-address><p2wsh>
Constructing a P2WSH address from the BIP173 spec
harm
# Constructing a P2WSH address from the BIP173 spec

(Asked by: username_0 on 2018-11-16)

The [BIP173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) specification defines how to create Bech32 Segwit native addresses.

In the [examples](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#examples) section a public key is given: `0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798`.

Based on that key it is somewhat easy to generate a P2WPKH address, one hashes the key with SHA256, then with RIPEMD160 and use the hex decoded result as the witness program (first two commands are simple CLI and the last is from the Dart [bech32](https://pub.dartlang.org/documentation/bech32/latest/bech32/Segwit/Segwit.html) library):

```
$ echo 0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 | xxd -r -p | openssl sha256
(stdin)= 0f715baf5d4c2ed329785cef29e562f73488c8a2bb9dbc5700b361d54b9b0554                                                                                                                                                                                                                                      

$ echo 0f715baf5d4c2ed329785cef29e562f73488c8a2bb9dbc5700b361d54b9b0554 | xxd -r -p | openssl ripemd160                                                                                                                                                         
(stdin)= 751e76e8199196d454941c45d1b3a323f1433bd

Segwit('bc', 0, HEX.decode("751e76e8199196d454941c45d1b3a323f1433bd"))
// bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3

```

Generating a P2WSH involves the script `key OP_CHECKSIG` followed by once SHA256 hashing. I'm at a loss how to construct said script. The opcode `OP_CHECKSIG` is [encoded](https://en.bitcoin.it/wiki/Script) as `0xac`. But appending that to the key seems silly (and doesn't work). Besides the `CHECKSIG` opcode requires two parameters. What do I hash?

**Tags:** bech32-address, p2wsh


---

## 2 answers

### Answer by username_2 on 2018-11-16. Score: 4 | Accepted answer

When you push items on the stack you must use an opcode to state how long the item you are pushing is. In this case you want to push 33 bytes so OP\_PUSH33

Your script would be:

`OP_PUSH33 0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 OP_CHECKSIG`

or

`210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac`.

Then your witness program becomes `witprog = sha256(script)` or `1863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262`

Then you bech32 encode and you get `bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3`

> Besides the CHECKSIG opcode requires two parameters.

The other parameter will be the signature and it will be provided by the person spending the coins as part of their scriptSig. Your scriptPubkey is only the second half of the script, the first half comes from the input.

> **Comments:**
> **username_0**: That `OP_PUSH33` wasn't evident for me at all when reading https://en.bitcoin.it/wiki/Script. Thanks!  

---

### Answer by username_1 on 2018-11-16. Score: 6

First of all, what are you trying to do? Why do you need a P2WSH address?

A P2WSH address (and P2SH addresses earlier) send coins to a *script*, which requires satisfying that script to decode. A script of the form `<key> CHECKSIG` is wasteful - you should be using P2WPKH instead. In general, you use P2WSH when you have more complex spending requirements than a single key. This most often happens when you need multisig (multiple devices or people need to sign off on a spend).

Now, all of this is outside of the scope of BIP173, which only specifies how to encode segwit outputs into human-readable strings and back.

A segwit output is an output whose scriptPubKey starts with OP\_0, OP\_1, ..., OP\_16, and is followed by a push of 2 to 40 bytes. That's it, and BIP173 can encode any of those.

Now, since the activation of BIP141 in Bitcoin, a small subset of segwit outputs have been given a meaning:

* OP\_0 + 20-byte push of RIPEMD160(SHA256(pubkey)) is called a P2WPKH for that public key.
* OP\_0 + 32-byte push of SHA256(script) is called P2WSH for that script.

All other kinds of segwit outputs are meaningless right now (non-standard and spendable by anyone), but that could change in the future. However, all of them can be encoded in Bech32 using BIP173. It doesn't care what the context or meaning is; it just encodes the version number (the OP\_n opcode at the start) and the data bytes (what is being pushed afterwards).

Perhaps your confusion comes from the fact that the BIP173 test vectors use "key + OP\_CHECKSIG" in its examples. That was just a simple way of constructing examples that are reproducible. They're not representative for how to actually use it.

> **Comments:**
> **username_0**: I totally missed that the "key + OP_CHECKSIG" was meaningless in itself. What I wanted to do is add tests to make absolutely sure my implementation was correct: I've added those test now! (See: https://github.com/Kolibri-POS/bech32/blob/master/test/segwit_test.dart#L61-L71)  

---

