def list_addresses(self, filterName=''): balance = {} for i in range(len(self.addresses)): person = self.addresses[i] name = person.items()[0][0] if '' != filterName and name != filterName: continue balance[name] = {} for j in range(len(person.items()[0][1])): addr = person.items()[0][1][j].items()[0][1] desc = person.items()[0][1][j].items()[0][0] if len(addr) == 3: # multisig deterministic hierarchical wallet kk0 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[0]) kk1 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[1]) kk2 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[2]) for k in range( 4 ): # device (0), web (1) or exchange (2) for case hardware wallet. idx (3) used for non-case for j in range( 2): # receive (0) and change (1) addresses gap = 0 found = False for i in range(99999): if k == 3: # regular keypath = "%d/%d.pub" % (j, i) else: # case keypath = "%d/%d/%d.pub" % (k, j, i) #print(keypath) sub0 = kk0.subkey_for_path(keypath).sec() sub1 = kk1.subkey_for_path(keypath).sec() sub2 = kk2.subkey_for_path(keypath).sec() if k == 3: # regular sub = sorted([sub0, sub1, sub2]) else: # case sub = [sub0, sub1, sub2] underlying_script = ScriptMultisig( n=2, sec_keys=[sub[0], sub[1], sub[2]]).script() addr = address_for_pay_to_script( underlying_script, netcode="BTC") ledger = blockchain_info.blockchain( addr, False) bal = ledger.balance() if ledger.tx_count != 0: found = True if found: print desc, i, j, k, addr, bal if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 20: break
def test_sign_pay_to_script_multisig(self): N, M = 3, 3 keys = [Key(secret_exponent=i) for i in range(1, M+2)] tx_in = TxIn.coinbase_tx_in(script=b'') underlying_script = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script() address = address_for_pay_to_script(underlying_script) self.assertEqual(address, "39qEwuwyb2cAX38MFtrNzvq3KV9hSNov3q") script = standard_tx_out_script(address) tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [address]) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[:M]) p2sh_lookup = build_p2sh_lookup([underlying_script]) tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) self.assertEqual(tx2.bad_signature_count(), 0)
def post(self): logging.info("transaction coming in") hextx = self.get_argument('hextx', None) subkeys = self.get_argument('subkeys', None) payoutaddress = self.get_argument('payoutaddress', None) fees = self.get_argument('fees', None) print subkeys if not hextx or not subkeys or not payoutaddress or not fees: logging.error("Did not receive trans or tree argument") return fees = tornado.escape.json_decode(fees) subkeys = tornado.escape.json_decode(subkeys) seed = mnemonic.Mnemonic.to_seed(PHRASE) wallet = BIP32Node.from_master_secret(seed) wifs = [] keys = [] for subkey in subkeys: key = wallet.subkey_for_path(subkey) keys.append(key) wifs.append(key.wif()) underlying_script = ScriptMultisig( n=N, sec_keys=[key.sec() for key in keys[:M]]).script() address = address_for_pay_to_script(underlying_script) tx2 = Tx.tx_from_hex(hextx) # first tx out, need another for the 1% to our wallet script = standard_tx_out_script(payoutaddress) tx_out = TxOut(fees['seller'], script) # TODO: figure out final wallet. This is sending to my phone script = standard_tx_out_script("1LhkvTTxFXam672vjwbABtkp9td7dxCwyB") tx2_out = TxOut(fees['bestcrow'], script) txs_out = [tx_out, tx2_out] tx2.txs_out = txs_out hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys) p2sh_lookup = build_p2sh_lookup([underlying_script]) tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) print tx2.as_hex() self.write(tx2.as_hex())
def list_addresses(self, filterName = ''): balance = {} for i in range(len(self.addresses)): person = self.addresses[i] name = person.items()[0][0] if '' != filterName and name != filterName: continue balance[name] = {} for j in range(len(person.items()[0][1])): addr = person.items()[0][1][j].items()[0][1] desc = person.items()[0][1][j].items()[0][0] if len(addr) == 3: # multisig deterministic hierarchical wallet kk0 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[0]) kk1 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[1]) kk2 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[2]) for k in range(4): # device (0), web (1) or exchange (2) for case hardware wallet. idx (3) used for non-case for j in range(2): # receive (0) and change (1) addresses gap = 0 found = False for i in range(99999): if k == 3: # regular keypath = "%d/%d.pub" % (j, i) else: # case keypath = "%d/%d/%d.pub" % (k, j, i) #print(keypath) sub0 = kk0.subkey_for_path(keypath).sec() sub1 = kk1.subkey_for_path(keypath).sec() sub2 = kk2.subkey_for_path(keypath).sec() if k == 3: # regular sub = sorted([sub0, sub1, sub2]) else: # case sub = [sub0, sub1, sub2] underlying_script = ScriptMultisig(n=2, sec_keys=[sub[0], sub[1], sub[2]]).script() addr = address_for_pay_to_script(underlying_script, netcode="BTC") ledger = blockchain_info.blockchain(addr, False) bal = ledger.balance() if ledger.tx_count != 0: found = True if found: print desc, i, j, k, addr, bal if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 20: break
def test_sign_pay_to_script_multisig(self): N, M = 3, 3 keys = [Key(secret_exponent=i) for i in range(1, M + 2)] tx_in = TxIn.coinbase_tx_in(script=b'') underlying_script = ScriptMultisig( n=N, sec_keys=[key.sec() for key in keys[:M]]).script() address = address_for_pay_to_script(underlying_script) self.assertEqual(address, "39qEwuwyb2cAX38MFtrNzvq3KV9hSNov3q") script = standard_tx_out_script(address) tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [address]) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[:M]) p2sh_lookup = build_p2sh_lookup([underlying_script]) tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) self.assertEqual(tx2.bad_signature_count(), 0)
def main(): if len(sys.argv) != 2: print("usage: %s bip32_key_file" % sys.argv[0]) sys.exit(-1) with open(sys.argv[1], "r") as f: hwif = f.readline().strip() # turn the bip32 text into a BIP32Node object BIP32_KEY = BIP32Node.from_hwif(hwif) # create three sec_keys (these are public keys, streamed using the SEC format) SEC_0 = BIP32_KEY.subkey_for_path("0/0/0").sec() SEC_1 = BIP32_KEY.subkey_for_path("0/1/0").sec() SEC_2 = BIP32_KEY.subkey_for_path("0/2/0").sec() public_key_sec_list = [SEC_0, SEC_1, SEC_2] # create the 2-of-3 multisig script # any 2 signatures can release the funds pay_to_multisig_script = ScriptMultisig(2, public_key_sec_list).script() # create a "2-of-3" multisig address_for_multisig the_address = address_for_pay_to_script(pay_to_multisig_script) print("Here is your pay 2-of-3 address: %s" % the_address) print("Here is the pay 2-of-3 script: %s" % b2h(pay_to_multisig_script)) print("The hex script should go into p2sh_lookup.hex") base_dir = os.path.dirname(sys.argv[1]) print("The three WIFs are written into %s as wif0, wif1 and wif2" % base_dir) for i in range(3): wif = BIP32_KEY.subkey_for_path("0/%d/0" % i).wif() with open(os.path.join(base_dir, "wif%d" % i), "w") as f: f.write(wif)
spk2 = BIP32Node.subkey_for_path(hwif2, path) spk3 = BIP32Node.subkey_for_path(hmpk1, path) #list of the public keys in sec format (to display them) print("public keys in hex:") print (BIP32Node.subkey_for_path(hwif1, path).sec_as_hex()) print (BIP32Node.subkey_for_path(hwif2, path).sec_as_hex()) print (BIP32Node.subkey_for_path(hmpk1, path).sec_as_hex()) #public subkeys in sec binary format (because ScriptMultisig requires it) keys = [spk1, spk2, spk3] #just remember that the third has not the secret exponent print(keys) script = ScriptMultisig(n=2, sec_keys=[key.sec() for key in keys]).script() print("script:") print(b2h(script)) address = address_for_pay_to_script(script) print(address) # Everything's ok until here """ tx_in = TxIn.coinbase_tx_in(script=b'') tx_out = TxOut(10000, script) # 0.1 mBits tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) """ spendables = blockr_io.spendables_for_address(address) #grab the spendables from an address tx = tx_utils.create_tx(spendables, [spk1.address()], fee="standard") # tx with the amount to the destination address. I take one key of which I have the secret key. hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[0:2]) # only the first two are private keys # build_hash160_lookup(key.secret_exponent() for key in keys[0:1]) # I sign only with the first one.
def balances(self, filterName=''): balance = {} for i in range(len(self.addresses)): person = self.addresses[i] name = person.items()[0][0] if '' != filterName and name != filterName: continue balance[name] = {} for j in range(len(person.items()[0][1])): addr = person.items()[0][1][j].items()[0][1] desc = person.items()[0][1][j].items()[0][0] if len(addr) == 3: # multisig deterministic hierarchical wallet kk0 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[0]) kk1 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[1]) kk2 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[2]) for k in range( 5 ): # device (0), web (1) or exchange (2) for case hardware wallet. Regular non case: 2of3 (3), 3of3 (4) for j in range( 2): # receive (0) and change (1) addresses gap = 0 for i in range(99999): if k == 3 or k == 4: # regular keypath = "%d/%d.pub" % (j, i) else: # case keypath = "%d/%d/%d.pub" % (k, j, i) #print(keypath) sub0 = kk0.subkey_for_path(keypath).sec() sub1 = kk1.subkey_for_path(keypath).sec() sub2 = kk2.subkey_for_path(keypath).sec() if k == 3 or k == 4: # regular sub = sorted([sub0, sub1, sub2]) else: # case sub = [sub0, sub1, sub2] required_signatures = 3 if k == 4 else 2 underlying_script = ScriptMultisig( n=required_signatures, sec_keys=[sub[0], sub[1], sub[2]]).script() addr = address_for_pay_to_script( underlying_script, netcode="BTC") bal = self.get_balance(addr) #print desc, i, j, addr, bal balance[name][addr] = [ bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i) ] if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 10: break elif len(addr) < 40: # regular address bal = self.get_balance(addr) balance[name][addr] = [bal, desc] elif 'xpub' == addr[0:4]: # deterministic hierarchical public key kk = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr) for j in range(2): # receive and change addresses gap = 0 for i in range(99999): keypath = "%d/%d.pub" % (j, i) #print(keypath) addr = kk.subkey_for_path(keypath).address() #print i, j, addr bal = self.get_balance(addr) balance[name][addr] = [ bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i) ] if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 10: break else: kk = pycoin.key.electrum.ElectrumWallet(addr) for i in range(20): for j in range(2): keypath = "%d/%d" % (j, i) addr = kk.subkey(keypath).address() #print i, j, addr bal = self.get_balance(addr) balance[name][addr] = [ bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i) ] return balance
sub_bip32_nodes = [BIP32Node.subkey_for_path(Key.from_text(public_wallets[i]), chainPaths[i]) for i in range(len(chainPaths))] print("Sub BIP32 wallets:") for i in sub_bip32_nodes: print(i) print("") script_encoded = ScriptMultisig(n=2, sec_keys=[key.sec() for key in sub_bip32_nodes]).script() script = b2h(script_encoded) print("Script:") print(script) print("") address = address_for_pay_to_script(script_encoded) # 3Bi36w9RZHmibi1ip7ud9dvtpDt59ij7GC print("Address: %s" % address) print("") spendables = spendables_for_address(address) # UTXOs of address # The simplest transaction: all the UTXOs, less the fees, go to the address. tx = create_tx(spendables,["3977Lp7VNWY5L8hY5W2oaNjeR5r8FZ6ban"], fee="standard") # raw hex not-signed transaction tx.as_hex() # to sign the transaction I need the sub_private keys print("Transaction as Hex:")
def balances(self, filterName = ''): balance = {} for i in range(len(self.addresses)): person = self.addresses[i] name = person.items()[0][0] if '' != filterName and name != filterName: continue balance[name] = {} for j in range(len(person.items()[0][1])): addr = person.items()[0][1][j].items()[0][1] desc = person.items()[0][1][j].items()[0][0] if len(addr) == 3: # multisig deterministic hierarchical wallet kk0 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[0]) kk1 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[1]) kk2 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[2]) for j in range(2): # receive and change addresses gap = 0 for i in range(99999): keypath = "%d/%d.pub" % (j, i) #print(keypath) sub0 = kk0.subkey_for_path(keypath).sec() sub1 = kk1.subkey_for_path(keypath).sec() sub2 = kk2.subkey_for_path(keypath).sec() #print i, j, addr underlying_script = ScriptMultisig(n=2, sec_keys=[sub0, sub1, sub2]).script() addr = address_for_pay_to_script(underlying_script, netcode="BTC") ledger = blockchain_info.blockchain(addr, False) bal = ledger.balance() balance[name][addr] = [bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i)] if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 10: break elif len(addr) < 40: # regular address ledger = blockchain_info.blockchain(addr, False) bal = ledger.balance() balance[name][addr] = [bal, desc] elif 'xpub' == addr[0:4]: # deterministic hierarchical public key kk = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr) for j in range(2): # receive and change addresses gap = 0 for i in range(99999): keypath = "%d/%d.pub" % (j, i) #print(keypath) addr = kk.subkey_for_path(keypath).address() #print i, j, addr ledger = blockchain_info.blockchain(addr, False) bal = ledger.balance() balance[name][addr] = [bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i)] if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 10: break else: kk = pycoin.key.electrum.ElectrumWallet(addr) for i in range(20): for j in range(2): keypath = "%d/%d" % (j, i) addr = kk.subkey(keypath).address() #print i, j, addr ledger = blockchain_info.blockchain(addr, False) bal = ledger.balance() balance[name][addr] = [bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i)] return balance
def balances(self, filterName = ''): balance = {} for i in range(len(self.addresses)): person = self.addresses[i] name = person.items()[0][0] if '' != filterName and name != filterName: continue balance[name] = {} for j in range(len(person.items()[0][1])): addr = person.items()[0][1][j].items()[0][1] desc = person.items()[0][1][j].items()[0][0] if len(addr) == 3: # multisig deterministic hierarchical wallet kk0 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[0]) kk1 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[1]) kk2 = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr[2]) for k in range(5): # device (0), web (1) or exchange (2) for case hardware wallet. Regular non case: 2of3 (3), 3of3 (4) for j in range(2): # receive (0) and change (1) addresses gap = 0 for i in range(99999): if k == 3 or k == 4: # regular keypath = "%d/%d.pub" % (j, i) else: # case keypath = "%d/%d/%d.pub" % (k, j, i) #print(keypath) sub0 = kk0.subkey_for_path(keypath).sec() sub1 = kk1.subkey_for_path(keypath).sec() sub2 = kk2.subkey_for_path(keypath).sec() if k == 3 or k == 4: # regular sub = sorted([sub0, sub1, sub2]) else: # case sub = [sub0, sub1, sub2] required_signatures = 3 if k == 4 else 2 underlying_script = ScriptMultisig(n=required_signatures, sec_keys=[sub[0], sub[1], sub[2]]).script() addr = address_for_pay_to_script(underlying_script, netcode="BTC") bal = self.get_balance(addr) #print desc, i, j, addr, bal balance[name][addr] = [bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i)] if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 10: break elif len(addr) < 40: # regular address bal = self.get_balance(addr) balance[name][addr] = [bal, desc] elif 'xpub' == addr[0:4]: # deterministic hierarchical public key kk = pycoin.key.BIP32Node.BIP32Node.from_hwif(addr) for j in range(2): # receive and change addresses gap = 0 for i in range(99999): keypath = "%d/%d.pub" % (j, i) #print(keypath) addr = kk.subkey_for_path(keypath).address() #print i, j, addr bal = self.get_balance(addr) balance[name][addr] = [bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i)] if bal == 0: if 0 == ledger.tx_count(): gap += 1 if gap > 10: break else: kk = pycoin.key.electrum.ElectrumWallet(addr) for i in range(20): for j in range(2): keypath = "%d/%d" % (j, i) addr = kk.subkey(keypath).address() #print i, j, addr bal = self.get_balance(addr) balance[name][addr] = [bal, '%s_%s_%d' % (desc, 'P' if 0 == j else 'Chg', i)] return balance
wallet = BIP32Node.from_master_secret(seed) for subkey in subkeys: key = wallet.subkey_for_path(subkey) wifs.append(key.wif()) N, M = 2, 3 ## TODO: create private keys. This is using wifs. Need to use only pub keys keys = [Key.from_text(wifs[i]) for i in range(0, M)] # redeem script. Sets it as 2-of-3. The hash of this is the bitcoin address underlying_script = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script() # multisig address. Just hash the redeem script address = address_for_pay_to_script(underlying_script) ## going to create a spend from this address. This should be the code on the web server spendables = insight.spendables_for_address(address) txs_in = [] for s in spendables: print s txs_in.append(s.tx_in()) # make tx_out on web server script = standard_tx_out_script(address) tx_out = TxOut(100000, script) txs_out = [tx_out] tx1 = Tx(version=1, txs_in=txs_in, txs_out=txs_out) tx1.set_unspents(txs_out)
print(i) print("") print("list of 'keys' wifs:") print("") for i in keys: print("Secret exponent : %s " % i.secret_exponent()) print("WIF : %s " % i.wif()) print("SEC : %s " % i.sec_as_hex()) print("") # Building underlying script to redem the funds with N signatures out of M underlying_script = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script() # I hash the script and transform it into a p2sh address address = address_for_pay_to_script(underlying_script) print(address) # Filling up the new created address with the fake coinbase transaction. No signature rquired. # Very important part. When you move funds to a p2sh address you write a special scriptPubKey: # Instead of: OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG # your p2sh scriptPubKey will be: # OP_HASH160 <hash(redeemScript)> OP_EQUAL # standard_tx_out_script(address) gives the scriptPubKey for a given multisig address script = standard_tx_out_script(address) # Fake coinbase transaction to fill our p2sh address # It it is a coinbase transaction we put in a newly constructed block. tx_in = TxIn.coinbase_tx_in(script=b'') print("TxIn: %s" % tx_in.__str__()) tx_out = TxOut(1000000, script) print("TxOut: %s" % tx_out.__str__()) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
keys = [] subkeys = [] count = 0 while count < 300: subkey = "0/0/%s" % count key = wallet.subkey_for_path(subkey) keys.append(key) subkeys.append(subkey) if len(keys) == 3: redeemscript = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script() address = address_for_pay_to_script(redeemscript) formongo = { 'multisigaddress': address, 'used': False, 'subkeys': subkeys } MONGODB.insert(formongo) keys = [] subkeys = [] #if not is_hashed_base58_valid(key.address()): # print "Nope" # sys.exit() count += 1
def create_multisig(self, escrow): logging.info("starting creation of multisig address") N, M = 2, 3 subkeydb = MONGOSUBKEYS.find_one() # first time running and we don't have a subkey set in the database if not subkeydb: subkeydb = MONGOSUBKEYS.insert({'subkey': 1}) # TODO: this has to be moved to the private key server # create the first public key. Needed for signing up from the website or the native client. subkey = subkeydb['subkey'] phrase = "sample core fitness wrong unusual inch hurry chaos myself credit welcome margin" seed = mnemonic.Mnemonic.to_seed(phrase) wallet = BIP32Node.from_master_secret(seed) subkeys = [] keys = [] if not escrow.has_key('sellerpubky') or not escrow['sellerpubkey']: logging.info( 'seller public key was not provided. We re making and storing the key' ) subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key1 = wallet.subkey_for_path(subkeystring) else: logging.info( 'seller public key was provided from the native client') key1 = Key.from_sec(h2b(escrow['sellerpubkey'])) keys.append(key1) if not escrow.has_key('buyerpubkey') or not escrow['buyerpubkey']: logging.info( 'buyer public key was not provided. We re making and storing the key' ) subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key2 = wallet.subkey_for_path(subkeystring) else: logging.info( 'buyer public key was provided from the native client.') key2 = Key.from_sec(h2b(escrow['buyerpubkey'])) keys.append(key2) # this is our own, no matter what subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key3 = wallet.subkey_for_path(subkeystring) keys.append(key3) redeemscript = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script() multisigaddress = address_for_pay_to_script(redeemscript) logging.info('multi-sig address was made: %s' % multisigaddress) MONGOSUBKEYS.update({'_id': subkeydb['_id']}, {"$set": { 'subkey': subkey }}) if escrow.has_key('_id'): MONGODB.update({'_id': escrow['_id']}, { "$set": { 'multisigaddress': multisigaddress, 'subkeys': subkeys } }) return (multisigaddress, subkeys)