<p>OK, I got it working with <em>pybitcointools</em>. </p>

<p>The command, <code>bip32_hdm_script</code>, as one can infer, returns hex of the P2SH redeemscript using the specified BIP32 master public/private keys (which is no different to using <code>mk_multisig_script(pubkey1 pubkey2 pubkey3 2)</code> for a 2-of-3 P2SH). Likewise, <code>bip32_hdm_addr</code> returns the P2SH address one gets from the redeemscript.</p>

<p>The catch is we're dealing with paths and such, and the function has issues with object types. </p>

<p>Let's use master private keys seeded with 0,1 and 2, respectively... </p>

<p><code>b32mprivkeys = [ bip32_master_key(str(x)) for x in range(3)]</code>
gives <code>['xprv9s21ZrQH143K2FsoUgfptxnkXbTjWSyu7oPKz2BtJm5yWC8pZMtxbx66FhZoY2e6Fwz2rZ4zPZrgpNJHRd68RtQNcFFVbwGf7Vapo4spoqL',
 'xprv9s21ZrQH143K2r9LvVthYjmsCLwZGpAc4uAAeovjhf7vaAbiunLgRdp8DAo4fSGUMuYQzzGfNGkdsR9xq6vcaKQSTa2VQx7o31N3kxcZi9k',
 'xprv9s21ZrQH143K2AV64RkNhLQEHTphnaGZqrGBhXTw9gBTMfvDAPiKFWpkBmt9otxA2X14bRS6mPdxohX4QCP3PMi8TG7KvCriGcsQHwDHVfT']</code></p>

<p><strong>Signing with master private keys won't work directly</strong>, let's get the master pubkeys:</p>

<p><code>b32mpubs = map(bip32_privtopub, b32mprivs)</code></p>

<p>Now, in this example, we want to descend to path <code>0/1</code>, in a 2-of-3 multisig. This is represented by an <em>int</em>, <code>2</code>, and a <strong>tuple</strong> (only!) of the path, so <code>(0, 1)</code>. </p>

<p><code>redeemscript = bip32_hdm_script(b32mpubss, 2, (0, 1)) = 5221029057ffd5c48f95c46c5e12b837cd0e4a7538dfa8ab9eb3479593724a6109ffb4210316776496822873767c6a91efe85a55871fc4a944c1d1ccab52cebd386cef29d4210318ae5429f67dbf61f54ae947f38637f4bffa1e252922b431eeed397cac49a22953ae</code></p>

<p>Now, we use <code>bip32_hdm_addr</code> to get the P2SH address.</p>

<p><code>&gt;&gt;&gt; bip32_hdm_addr(redeemscript)
5221029057ffd5c48f95c46c5e12b837cd0e4a7538dfa8ab9eb3479593724a6109ffb4210316776496822873767c6a91efe85a55871fc4a944c1d1ccab52cebd386cef29d4210318ae5429f67dbf61f54ae947f38637f4bffa1e252922b431eeed397cac49a22953ae</code></p>

<p>Note, FWIW, 
<code>&gt;&gt;&gt; bip32_hdm_addr(redeemscript) == scriptaddr(redeemscript)
     True</code></p>

<hr>

<p>AGAIN: <strong>Do not try signing with master private keys</strong> using <code>bip32_hdm_script</code>, lest you return a redeemscript, which when deserialised, gives:</p>

<p><code>slice(            # we want the privkeys only
       deserialize_script(bip32_hdm_script(b32mprivkeys, 2, (0, 1))), 
       1, 4)</code></p>

<p>See how the keys from the redeemscript are 33 bytes long? And don't start with 02/03/04? That'll make an <strong>unusable</strong> P2SH address, so beware this pitfall!</p>

CC BY-SA 3.0
2015-04-25T15:14:24.940Z
2015-04-25T15:14:24.940Z
Wizard Of Ozzie
<p>As everyone is aware, I'm a huge proponent of Vitalik Buterin's <a href="https://github.com/vbuterin/pybitcointools/" rel="nofollow">pybitcointools</a> Python 2.7/3.x library. I am having a some trouble understanding the BIP32 concepts, which are coded in the <em><a href="https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/deterministic.py" rel="nofollow">deterministic</a>/<a href="https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/composite.py" rel="nofollow">composite</a></em> modules.</p>

<p>In particular, <a href="https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/composite.py#L51" rel="nofollow">this code</a>:</p>

<pre><code># BIP32 hierarchical deterministic multisig script
def bip32_hdm_script(*args):
    if len(args) == 3:
        keys, req, path = args
    else:
        i, keys, path = 0, [], []
        while len(args[i]) &gt; 40:
            keys.append(args[i])
            i += 1
        req = int(args[i])
        path = map(int, args[i+1:])
    pubs = sorted(map(lambda x: bip32_descend(x, path), keys))  # 
    return mk_multisig_script(pubs, req)    # (req = required sigs) ... returns redeemScript hex


# BIP32 hierarchical deterministic multisig address
def bip32_hdm_addr(*args):
    return scriptaddr(bip32_hdm_script(*args))   # returns P2SH address
</code></pre>

<p>I've had issues signing 2-of-2 P2SH/HD Txs with Electrum which I could only successfully sign using <code>createrawtransaction</code> \ <code>signrawtransaction</code> in Bitcoin-CLI. </p>

<p>How exactly is P2SH in combination with HD wallets implemented (preferably in terms of the aforementioned Python code)?</p>

CC BY-SA 3.0
2015-04-15T02:11:06.403Z
Are you having trouble with creating these outputs, or signing a transaction spending them once you've created them?
Nick ODell
CC BY-SA 3.0
2015-04-15T02:16:24.407Z
@NickODell I'd like to be able to sign using the Python code. I don't want to confuse things too much, but Electrum 2.0.4 partially signs, returning this JSON data: https://gist.github.com/d6397e62bdb78f905cfa ... It makes no sense because it's substituted the extended public key in the script. (NB the data is safe to share, no worries about stolen keys or whatever)
Wizard Of Ozzie
CC BY-SA 3.0
2015-04-15T16:06:28.860Z
I'd be also interested to know how multisig can be implemented with the HD wallet. Does it automatically generates multisig addresses?
abeikverdi
<bip32-hd-wallets><python><p2sh>
Clarification of BIP32 hierarchical deterministic multisig scripts
Wizard Of Ozzie
# Clarification of BIP32 hierarchical deterministic multisig scripts

(Asked by: username_0 on 2015-04-15)

As everyone is aware, I'm a huge proponent of Vitalik Buterin's [pybitcointools](https://github.com/vbuterin/pybitcointools/) Python 2.7/3.x library. I am having a some trouble understanding the BIP32 concepts, which are coded in the *[deterministic](https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/deterministic.py)/[composite](https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/composite.py)* modules.

In particular, [this code](https://github.com/vbuterin/pybitcointools/blob/master/bitcoin/composite.py#L51):

```
# BIP32 hierarchical deterministic multisig script
def bip32_hdm_script(*args):
    if len(args) == 3:
        keys, req, path = args
    else:
        i, keys, path = 0, [], []
        while len(args[i]) > 40:
            keys.append(args[i])
            i += 1
        req = int(args[i])
        path = map(int, args[i+1:])
    pubs = sorted(map(lambda x: bip32_descend(x, path), keys))  # 
    return mk_multisig_script(pubs, req)    # (req = required sigs) ... returns redeemScript hex

# BIP32 hierarchical deterministic multisig address
def bip32_hdm_addr(*args):
    return scriptaddr(bip32_hdm_script(*args))   # returns P2SH address

```

I've had issues signing 2-of-2 P2SH/HD Txs with Electrum which I could only successfully sign using `createrawtransaction` \ `signrawtransaction` in Bitcoin-CLI.

How exactly is P2SH in combination with HD wallets implemented (preferably in terms of the aforementioned Python code)?

**Tags:** bip32-hd-wallets, python, p2sh

> **Comments:**
> **username_1**: Are you having trouble with creating these outputs, or signing a transaction spending them once you've created them?  
> **username_0**: @username_1 I'd like to be able to sign using the Python code. I don't want to confuse things too much, but Electrum 2.0.4 partially signs, returning this JSON data: https://gist.github.com/d6397e62bdb78f905cfa ... It makes no sense because it's substituted the extended public key in the script. (NB the data is safe to share, no worries about stolen keys or whatever)  
> **username_2**: I'd be also interested to know how multisig can be implemented with the HD wallet. Does it automatically generates multisig addresses?  

---

## 1 answers

### Answer by username_0 on 2015-04-25. Score: 1

OK, I got it working with *pybitcointools*.

The command, `bip32_hdm_script`, as one can infer, returns hex of the P2SH redeemscript using the specified BIP32 master public/private keys (which is no different to using `mk_multisig_script(pubkey1 pubkey2 pubkey3 2)` for a 2-of-3 P2SH). Likewise, `bip32_hdm_addr` returns the P2SH address one gets from the redeemscript.

The catch is we're dealing with paths and such, and the function has issues with object types.

Let's use master private keys seeded with 0,1 and 2, respectively...

`b32mprivkeys = [ bip32_master_key(str(x)) for x in range(3)]`
gives `['xprv9s21ZrQH143K2FsoUgfptxnkXbTjWSyu7oPKz2BtJm5yWC8pZMtxbx66FhZoY2e6Fwz2rZ4zPZrgpNJHRd68RtQNcFFVbwGf7Vapo4spoqL',
'xprv9s21ZrQH143K2r9LvVthYjmsCLwZGpAc4uAAeovjhf7vaAbiunLgRdp8DAo4fSGUMuYQzzGfNGkdsR9xq6vcaKQSTa2VQx7o31N3kxcZi9k',
'xprv9s21ZrQH143K2AV64RkNhLQEHTphnaGZqrGBhXTw9gBTMfvDAPiKFWpkBmt9otxA2X14bRS6mPdxohX4QCP3PMi8TG7KvCriGcsQHwDHVfT']`

**Signing with master private keys won't work directly**, let's get the master pubkeys:

`b32mpubs = map(bip32_privtopub, b32mprivs)`

Now, in this example, we want to descend to path `0/1`, in a 2-of-3 multisig. This is represented by an *int*, `2`, and a **tuple** (only!) of the path, so `(0, 1)`.

`redeemscript = bip32_hdm_script(b32mpubss, 2, (0, 1)) = 5221029057ffd5c48f95c46c5e12b837cd0e4a7538dfa8ab9eb3479593724a6109ffb4210316776496822873767c6a91efe85a55871fc4a944c1d1ccab52cebd386cef29d4210318ae5429f67dbf61f54ae947f38637f4bffa1e252922b431eeed397cac49a22953ae`

Now, we use `bip32_hdm_addr` to get the P2SH address.

`>>> bip32_hdm_addr(redeemscript)
5221029057ffd5c48f95c46c5e12b837cd0e4a7538dfa8ab9eb3479593724a6109ffb4210316776496822873767c6a91efe85a55871fc4a944c1d1ccab52cebd386cef29d4210318ae5429f67dbf61f54ae947f38637f4bffa1e252922b431eeed397cac49a22953ae`

Note, FWIW,
`>>> bip32_hdm_addr(redeemscript) == scriptaddr(redeemscript)
True`

---

AGAIN: **Do not try signing with master private keys** using `bip32_hdm_script`, lest you return a redeemscript, which when deserialised, gives:

`slice( # we want the privkeys only
deserialize_script(bip32_hdm_script(b32mprivkeys, 2, (0, 1))),
1, 4)`

See how the keys from the redeemscript are 33 bytes long? And don't start with 02/03/04? That'll make an **unusable** P2SH address, so beware this pitfall!


---

