Exemple #1
0
 def test_multisig_one_at_a_time(self):
     N = 3
     M = 3
     keys = [Key(secret_exponent=i) for i in range(1, M + 2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(n=N, sec_keys=[key.sec()
                                            for key in keys[:M]]).script()
     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(),
                              [keys[-1].address()])
     ids = [
         "403e5bfc59e097bb197bf77a692d158dd3a4f7affb4a1fa41072dafe7bec7058",
         "5931d9995e83721243dca24772d7012afcd4378996a8b953c458175f15a544db",
         "9bb4421088190bbbb5b42a9eaa9baed7ec7574a407c25f71992ba56ca43d9c44",
         "03a1dc2a63f93a5cf5a7cb668658eb3fc2eda88c06dc287b85ba3e6aff751771"
     ]
     for i in range(1, M + 1):
         self.assertEqual(tx2.bad_signature_count(), 1)
         self.assertEqual(tx2.id(), ids[i - 1])
         hash160_lookup = build_hash160_lookup(key.secret_exponent()
                                               for key in keys[i - 1:i])
         tx2.sign(hash160_lookup=hash160_lookup)
         self.assertEqual(tx2.id(), ids[i])
     self.assertEqual(tx2.bad_signature_count(), 0)
    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
Exemple #3
0
 def multisig_M_of_N(self, M, N, unsigned_id, signed_id):
     keys = [Key(secret_exponent=i) for i in range(1, N+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script()
     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(), [keys[-1].address()])
     self.assertEqual(tx2.id(), unsigned_id)
     self.assertEqual(tx2.bad_signature_count(), 1)
     hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys)
     tx2.sign(hash160_lookup=hash160_lookup)
     self.assertEqual(tx2.id(), signed_id)
     self.assertEqual(tx2.bad_signature_count(), 0)
 def multisig_M_of_N_individually(self, M, N):
     keys = [Key(secret_exponent=i) for i in range(1, N + 2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     script = ScriptMultisig(m=M, sec_keys=[key.sec()
                                            for key in keys[:N]]).script()
     tx_out = TxOut(1000000, script)
     tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out])
     for partial_key_list in itertools.permutations(keys[:N], M):
         tx2 = create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()])
         for key in partial_key_list:
             self.assertEqual(tx2.bad_signature_count(), 1)
             hash160_lookup = build_hash160_lookup([key.secret_exponent()])
             tx2.sign(hash160_lookup=hash160_lookup)
         self.assertEqual(tx2.bad_signature_count(), 0)
Exemple #5
0
 def test_sign_pay_to_script_multisig(self):
     M, N = 3, 3
     keys = [Key(secret_exponent=i) for i in range(1, N+2)]
     tx_in = TxIn.coinbase_tx_in(script=b'')
     underlying_script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).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[:N])
     p2sh_lookup = build_p2sh_lookup([underlying_script])
     tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup)
     self.assertEqual(tx2.bad_signature_count(), 0)
Exemple #6
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())
Exemple #7
0
    def script_for_path(self, path):
        """Get the redeem script for the path.  The multisig format is (n-1) of n, but can be overridden.

        :param: path: the derivation path
        :type: path: str
        :return: the script
        :rtype: ScriptMultisig
        """
        if not self._complete:
            raise Exception("account not complete")
        if path not in self._cache['keys']:
            self._cache['keys'][path] =\
                [key.subkey_for_path(path + ".pub") for key in self.keys]

        subkeys = self._cache['keys'][path]
        secs = [key.sec() for key in subkeys]
        if self._sort:
            secs.sort()
        script = ScriptMultisig(self._num_sigs, secs)
        return script
    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
Exemple #9
0
def get_multisig_address(m, pub_keys):
    pay_to_multisig_script = ScriptMultisig(m, pub_keys).script()
    return address_for_pay_to_script(
        pay_to_multisig_script,
        netcode=NET_CODE), pay_to_multisig_script.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
Exemple #11
0
subkeys = ["0/0/138", "0/0/139", "0/0/140"]
wifs = []

seed = mnemonic.Mnemonic.to_seed(phrase)
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)
Exemple #12
0
from pycoin.key import Key
from pycoin.serialize import h2b
from pycoin.tx import Tx, TxIn, TxOut, SIGHASH_ALL, tx_utils
from pycoin.tx.TxOut import standard_tx_out_script

from pycoin.tx.pay_to import ScriptMultisig, ScriptPayToPublicKey
from pycoin.tx.pay_to import address_for_pay_to_script, build_hash160_lookup, build_p2sh_lookup
from pycoin.tx.pay_to import script_obj_from_address, script_obj_from_script

import pymongo

MONGOCONNECTION = pymongo.Connection('127.0.0.1', 27017)

keys = MONGOCONNECTION.escrow.keys.find_one({'used': False})

N = 2
M = 3
keys = [Key(secret_exponent=i) for i in range(1, M + 2)]
script = ScriptMultisig(2, [Key.from_text(k).sec() for k in sigs.values()])

print script.address()
#print script
# public key in binary
print key.sec()

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()
Exemple #14
0
    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)