Clarification of BIP32 hierarchical deterministic multisig scripts As everyone is aware, I'm a huge proponent of Vitalik Buterin's pybitcointools Python 2.7/3.x library. I am having a some trouble understanding the BIP32 concepts, which are coded in the deterministic/composite modules.

In particular, this 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


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)?
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.

&gt;&gt;&gt; bip32_hdm_addr(redeemscript)
5221029057ffd5c48f95c46c5e12b837cd0e4a7538dfa8ab9eb3479593724a6109ffb4210316776496822873767c6a91efe85a55871fc4a944c1d1ccab52cebd386cef29d4210318ae5429f67dbf61f54ae947f38637f4bffa1e252922b431eeed397cac49a22953ae

Note, FWIW, 
&gt;&gt;&gt; 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!