예제 #1
0
    def _generate_new_keypair(self):

        seed = str(random.randrange(2 ** 256))

        # Deprecated (pre-BIP32)
        # self.secret = hashlib.sha256(secret).hexdigest()
        # self.pubkey = privkey_to_pubkey(self.secret)
        # self.log.debug('Keys %s %s', self.secret, self.pubkey)

        # Move to BIP32 keys m/0/0/0
        wallet = bitcoin.bip32_ckd(bitcoin.bip32_master_key(seed), 0)
        wallet_chain = bitcoin.bip32_ckd(wallet, 0)
        bip32_identity_priv = bitcoin.bip32_ckd(wallet_chain, 0)
        identity_priv = bitcoin.bip32_extract_key(bip32_identity_priv)
        bip32_identity_pub = bitcoin.bip32_privtopub(bip32_identity_priv)
        identity_pub = bitcoin.encode_pubkey(bitcoin.bip32_extract_key(bip32_identity_pub), 'hex')

        self.pubkey = identity_pub
        self.secret = identity_priv

        new_settings = {
            "secret": self.secret,
            "pubkey": self.pubkey,
            "bip32_seed": seed
        }
        self.db_connection.update_entries("settings", new_settings, {"market_id": self.market_id})
        self.settings.update(new_settings)
def _derive_and_print(master_key: str,
                      *path: int,
                      derive_pub_key: bool = True,
                      magicbyte: int = 0):
    master_pub_key = bitcoin.bip32_privtopub(master_key)
    derived_key = _derived_key(master_key, *path)
    if derive_pub_key:
        derived_bip32_pub_key = _derived_key(master_pub_key, *path)
        derived_pub_key = bitcoin.bip32_extract_key(derived_bip32_pub_key)
    else:
        derived_bip32_pub_key = derived_pub_key = 'N.A.'
    derived_pub_key_from_key = bitcoin.bip32_privtopub(derived_key)
    print('''    Derivation path: ({}),
    Derived BIP32 key: {},
    Derived BIP32 public key: {},
    BIP32 public key from derived BIP32 private: {},
    Derived key: {},
    Derived public key: {},
    Public key from derived key: {},
    BTC address: {}
    '''.format(
        ', '.join(
            str(x) if x <= 2**31 else str(x - 2**31) + '\'' for x in path),
        derived_key, derived_bip32_pub_key, derived_pub_key_from_key,
        bitcoin.bip32_extract_key(derived_key), derived_pub_key,
        bitcoin.privtopub(bitcoin.bip32_extract_key(derived_key)),
        bitcoin.pubtoaddr(bitcoin.privtopub(
            bitcoin.bip32_extract_key(derived_key)),
                          magicbyte=magicbyte)))
예제 #3
0
    def _generate_new_keypair(self):

        seed = str(random.randrange(2**256))

        # Deprecated (pre-BIP32)
        # self.secret = hashlib.sha256(secret).hexdigest()
        # self.pubkey = privkey_to_pubkey(self.secret)
        # self.log.debug('Keys %s %s', self.secret, self.pubkey)

        # Move to BIP32 keys m/0/0/0
        wallet = bitcoin.bip32_ckd(bitcoin.bip32_master_key(seed), 0)
        wallet_chain = bitcoin.bip32_ckd(wallet, 0)
        bip32_identity_priv = bitcoin.bip32_ckd(wallet_chain, 0)
        identity_priv = bitcoin.bip32_extract_key(bip32_identity_priv)
        bip32_identity_pub = bitcoin.bip32_privtopub(bip32_identity_priv)
        identity_pub = bitcoin.encode_pubkey(
            bitcoin.bip32_extract_key(bip32_identity_pub), 'hex')

        self.pubkey = identity_pub
        self.secret = identity_priv

        new_settings = {
            "secret": self.secret,
            "pubkey": self.pubkey,
            "bip32_seed": seed
        }
        self.db_connection.update_entries("settings", new_settings,
                                          {"market_id": self.market_id})
        self.settings.update(new_settings)
예제 #4
0
def showDetails(mnemonic, passphrase="", i=1):

    myMnemonic = mnemonic
    passphrase = passphrase

    mnemo = Mnemonic('english')
    seed = hexlify(mnemo.to_seed(myMnemonic, passphrase=passphrase))
    print 'Seed:\t\t\t\t', seed

    priv = bitcoin.bip32_master_key(unhexlify(seed))
    print 'Xpriv:\t\t\t\t', priv

    key = bitcoin.encode_privkey(bitcoin.bip32_extract_key(priv),
                                 'wif_compressed')
    print 'Key:\t\t\t\t', key

    pub = bitcoin.bip32_privtopub(priv)
    print 'Derived public key:\t', pub
    pubHex = bitcoin.bip32_extract_key(pub)
    print 'public key (hex):\t', pubHex
    print 'Master Key address:\t', bitcoin.pubtoaddr(pubHex)

    print ""
    print "TREZOR Keys:"

    account = 0
    derivedPrivateKey = bitcoin.bip32_ckd(
        bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44 + HARDENED), HARDENED),
        HARDENED + account)
    print 'Derived private key:', derivedPrivateKey

    privateKey = bitcoin.encode_privkey(
        bitcoin.bip32_extract_key(derivedPrivateKey), 'wif_compressed')
    print 'private key (wif):\t', privateKey

    derivedPublicKey = bitcoin.bip32_privtopub(derivedPrivateKey)
    print 'Derived public key:', derivedPublicKey

    publicKeyHex = bitcoin.privtopub(privateKey)
    print 'public key (hex):\t', publicKeyHex

    address = bitcoin.pubtoaddr(publicKeyHex)
    print 'address:\t\t\t', address

    print ""
    print "Account public keys (XPUB)"
    xpubs = []
    for i in range(0, i):
        derivedPrivateKey = bitcoin.bip32_ckd(
            bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44 + HARDENED),
                              HARDENED), HARDENED + i)
        xpub = bitcoin.bip32_privtopub(derivedPrivateKey)
        print 'Account', i, 'xpub:', xpub
        xpubs.append(xpub)

    return xpubs
예제 #5
0
def showDetails(mnemonic, passphrase="", i=1):

    myMnemonic = mnemonic
    passphrase = passphrase


    mnemo = Mnemonic('english')
    seed = hexlify(mnemo.to_seed(myMnemonic, passphrase=passphrase))
    print 'Seed:\t\t\t\t', seed

    priv = bitcoin.bip32_master_key(unhexlify(seed))
    print 'Xpriv:\t\t\t\t', priv

    key = bitcoin.encode_privkey(bitcoin.bip32_extract_key(priv), 'wif_compressed')
    print 'Key:\t\t\t\t', key


    pub = bitcoin.bip32_privtopub(priv)
    print 'Derived public key:\t', pub
    pubHex = bitcoin.bip32_extract_key(pub)
    print 'public key (hex):\t', pubHex
    print 'Master Key address:\t', bitcoin.pubtoaddr(pubHex)


    print ""
    print "TREZOR Keys:"

    account = 0
    derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+account)
    print 'Derived private key:', derivedPrivateKey

    privateKey = bitcoin.encode_privkey(bitcoin.bip32_extract_key(derivedPrivateKey), 'wif_compressed')
    print 'private key (wif):\t', privateKey


    derivedPublicKey = bitcoin.bip32_privtopub(derivedPrivateKey)
    print 'Derived public key:', derivedPublicKey

    publicKeyHex = bitcoin.privtopub(privateKey)
    print 'public key (hex):\t', publicKeyHex

    address = bitcoin.pubtoaddr(publicKeyHex)
    print 'address:\t\t\t', address

    print ""
    print "Account public keys (XPUB)"
    xpubs = []
    for i in range(0, i):
        derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+i)
        xpub = bitcoin.bip32_privtopub(derivedPrivateKey)
        print 'Account', i, 'xpub:', xpub
        xpubs.append(xpub)

    return xpubs
예제 #6
0
파일: recovery.py 프로젝트: hatgit/granary
def cosign(master_xpriv, recovery_package):
    raw_txs = recovery_package['txs']
    print "Signing %d transactions" % len(raw_txs)
    for tx_index, tx_raw in enumerate(raw_txs):
        print "\nTransaction #", tx_index
        hex_tx = tx_raw['bytes']
        tx = bitcoin.transaction.deserialize(unhexlify(hex_tx))
        keypaths = tx_raw['input_paths']
        keypairs = {}
        for p in keypaths:
            xpriv = seedlib.bip32_child(master_xpriv, p)
            priv = bitcoin.bip32_extract_key(xpriv)
            pub = bitcoin.privtopub(priv)
            keypairs[pub] = priv
        for i, inp in enumerate(tx['ins']):
            (sigs, pubkeys, redeemScript, M,
             N) = multisig.decode_multisig_script(inp['script'])
            for p in pubkeys:
                if p in keypairs:
                    sig_new = bitcoin.multisign(hex_tx, i, redeemScript,
                                                keypairs[p])
                    sigs.append(sig_new)
                    tx_new = bitcoin.apply_multisignatures(
                        unhexlify(hex_tx), i, redeemScript, sigs)
                    print "Signed transaction %d input %d" % (tx_index, i)

                    # replace tx with newly signed transaction
                    hex_tx = hexlify(tx_new)
        recovery_package['txs'][tx_index]['bytes'] = hex_tx
    return recovery_package
예제 #7
0
 def get_private_for_chain(account, key_number, settings=None):
     if settings is None:
         settings = Settings.Instance().get_settings_json()
     account_key = settings['accounts'][account]['accountKey']
     return_key = bitcoin.bip32_ckd( account_key, key_number )
     return_key = bitcoin.bip32_extract_key( return_key )
     return return_key
예제 #8
0
def create_invoice_domain (domain, payer):
	cur = BMMySQL().conn().cursor(MySQLdb.cursors.DictCursor)
	filterwarnings('ignore', category = MySQLdb.Warning)
	cur.execute ("SELECT bm, masterpubkey_btc, offset_btc, feeamount, feecurrency FROM domain WHERE name = %s AND active = 1", (domain))
	result = False
	for row in cur.fetchall():
		result = row
	while result:
		if result['masterpubkey_btc'][0:4] == "xpub":
			# BIP44
			dpk1 = bitcoin.bip32_ckd(result['masterpubkey_btc'], 0)
			dpk2 = bitcoin.bip32_ckd(dpk1, result['offset_btc'])
			pubkey = bitcoin.bip32_extract_key(dpk2)
		else:
			# Electrum 1.x
			pubkey = bitcoin.electrum_pubkey(result['masterpubkey_btc'], result['offset_btc'])
		address = bitcoin.pubkey_to_address(pubkey)
		bitcoind_importaddress(address)
		cur.execute ("UPDATE domain SET offset_btc = offset_btc + 1 WHERE name = %s AND active = 1 AND masterpubkey_btc = %s", (domain, result['masterpubkey_btc']))
		if result['feecurrency'] in ("USD", "GBP", "EUR"):
			result['feeamount'] /= decimal.Decimal(get_bitcoin_price(result['feecurrency']))
		cur.execute ("INSERT IGNORE INTO invoice (issuer, payer, address, coin, amount, type, paid) VALUES (%s, %s, %s, 'BTC', %s, 0, 0)", (result['bm'], payer, address, result['feeamount']))

		# invoice already exists for that address, increment
		if cur.rowcount == 0:
			cur.execute ("SELECT bm, masterpubkey_btc, offset_btc, feeamount, feecurrency FROM domain WHERE name = %s AND active = 1", (domain))
			result = False
			for row in cur.fetchall():
				result = row
			continue
		
		cur.close()
		return address, result['feeamount'];
	cur.close()
	return False
예제 #9
0
    def get_bip32_key(public_keys):
        settings = Settings.Instance().get_settings_json()

        if (settings['bip32master'] is None):
            return None

        account_number, account_key, key_number = KeyHelper.get_account_number_and_chain(
            settings)

        #see if we already have this cached, and I can just get the key fast
        cached = set(settings['accounts'][account_number].get(keys, []))
        pub_set = set(public_keys)
        hits = cached & pub_set

        if len(hits) > 0:
            return KeyHelper.get_private_for_chain(account_number, hits[0][0],
                                                   settings)

        #drat, didn't find it! at least we can only need to test the ones that
        #we didn't already check
        missed = set(range(key_number)) - set([cache[0] for cache in cached])

        for i in missed:
            priv = bitcoin.bip32_ckd(account_key, i)
            priv = bitcoin.bip32_extract_key(priv)
            canidate = bitcoin.privtopub(priv)
            if (canidate in public_keys):
                return priv

        return None
예제 #10
0
    def get_next_public_key():
        settings = Settings.Instance().get_settings_json()

        if (settings['bip32master'] is None):
            raise RuntimeError("Master key has not been set up yet")

        account_number, account_key, key_number = KeyHelper.get_account_number_and_chain(
            settings)

        return_key = bitcoin.bip32_ckd(account_key, key_number)
        return_key = bitcoin.bip32_extract_key(return_key)
        return_key = bitcoin.privtopub(return_key)

        #save key for later
        if 'keys' not in settings['accounts'][account_number]:
            settings['accounts'][account_number]['keys'] = []
        settings['accounts'][account_number]['keys'].append(
            (key_number, return_key, False))

        #we increment the key counter after making the key
        #because the chain code is 0 indexed, making the 0th key
        #the first one we use
        key_number += 1

        #remember to save our new key
        settings['accounts'][account_number]['numKeys'] = key_number
        Settings.Instance().save_config_file(settings)

        return return_key
예제 #11
0
 def get_private_for_chain(account, key_number, settings=None):
     if settings is None:
         settings = Settings.Instance().get_settings_json()
     account_key = settings['accounts'][account]['accountKey']
     return_key = bitcoin.bip32_ckd(account_key, key_number)
     return_key = bitcoin.bip32_extract_key(return_key)
     return return_key
예제 #12
0
 def regenerate_keys(account_key, needed_keys, key_list):
     for key in needed_keys:
         return_key = bitcoin.bip32_ckd(account_key, key)
         return_key = bitcoin.bip32_extract_key(return_key)
         return_key = bitcoin.privtopub(return_key)
         key_list.append((key, return_key, False))
     return
예제 #13
0
    def get_bip32_key( public_keys ):
        settings = Settings.Instance().get_settings_json()

        if( settings['bip32master'] is None ):
            return None

        account_number, account_key, key_number = KeyHelper.get_account_number_and_chain( settings )

        #see if we already have this cached, and I can just get the key fast
        cached = set( settings['accounts'][account_number].get(keys,[]) )
        pub_set = set( public_keys )
        hits = cached & pub_set 

        if len(hits) > 0:
            return KeyHelper.get_private_for_chain( account_number, hits[0][0], settings )

        #drat, didn't find it! at least we can only need to test the ones that 
        #we didn't already check
        missed = set(range(key_number)) - set([cache[0] for cache in cached])
            
        for i in missed:
            priv = bitcoin.bip32_ckd( account_key, i )
            priv = bitcoin.bip32_extract_key( priv )
            canidate = bitcoin.privtopub( priv )
            if( canidate in public_keys ):
                return priv

        return None
예제 #14
0
    def get_next_public_key(  ):
        settings = Settings.Instance().get_settings_json()

        if( settings['bip32master'] is None ):
            raise RuntimeError( "Master key has not been set up yet" )

        account_number, account_key, key_number = KeyHelper.get_account_number_and_chain( settings )

        return_key = bitcoin.bip32_ckd( account_key, key_number )
        return_key = bitcoin.bip32_extract_key( return_key )
        return_key = bitcoin.privtopub( return_key )

        #save key for later
        if 'keys' not in settings['accounts'][account_number]:
            settings['accounts'][account_number]['keys'] = []
        settings['accounts'][account_number]['keys'].append( (key_number, return_key, False ) )
        
        #we increment the key counter after making the key
        #because the chain code is 0 indexed, making the 0th key 
        #the first one we use
        key_number += 1

        #remember to save our new key
        settings['accounts'][account_number]['numKeys'] = key_number
        Settings.Instance().save_config_file( settings )

        return return_key
예제 #15
0
 def _derive_address(self, change_or_deposit, index, master_key):
     xpriv = bip32_ckd(
         bip32_ckd(self.get_bip44_master(master_key), change_or_deposit),
         index)
     priv = bip32_extract_key(xpriv)
     address = privtoaddr(priv, self.get_address_byte())
     return address, priv
예제 #16
0
def create_invoice_user (email):
	cur = BMMySQL().conn().cursor(MySQLdb.cursors.DictCursor)
	cur.execute ("SELECT bm, masterpubkey_btc, offset_btc, feeamount, feecurrency FROM user WHERE email = %s AND active = 1", (email))
	result = False
	for row in cur.fetchall():
		result = row
	if result:
		if result['masterpubkey_btc'][0:4] == "xpub":
			# BIP44
			dpk1 = bitcoin.bip32_ckd(result['masterpubkey_btc'], 0)
			dpk2 = bitcoin.bip32_ckd(dpk1, result['offset_btc'])
			pubkey = bitcoin.bip32_extract_key(dpk2)
		else:
			# Electrum 1.x
			pubkey = bitcoin.electrum_pubkey(result['masterpubkey_btc'], result['offset_btc'])
		address = bitcoin.pubkey_to_address(pubkey)
		bitcoind_importaddress(address)
		cur.execute ("UPDATE user SET offset_btc = offset_btc + 1 WHERE email = %s AND active = 1 AND masterpubkey_btc = %s", (email, result['masterpubkey_btc']))
		if result['feecurrency'] in ("USD", "GBP", "EUR"):
			result['feeamount'] /= decimal.Decimal(get_bitcoin_price(result['feecurrency']))
		cur.execute ("INSERT INTO invoice (issuer, address, coin, amount, type, paid) VALUES (%s, %s, 'BTC', %s, 1, 0)", (result['bm'], address, result['feeamount']))
		cur.close()
		return address, result['feeamount'];
	cur.close()
	return False
예제 #17
0
 def regenerate_keys( account_key, needed_keys, key_list ):
     for key in needed_keys:
         return_key = bitcoin.bip32_ckd(account_key, key)
         return_key = bitcoin.bip32_extract_key(return_key)
         return_key = bitcoin.privtopub(return_key)
         key_list.append( ( key, return_key, False ) )
     return 
예제 #18
0
def derive_childkey(key, chaincode, prefix=bitcoin.MAINNET_PUBLIC):
    """
    Given a 33 byte public key and 32 byte chaincode (both in hex) derive the first child key.
    """

    master_key = bitcoin.bip32_serialize((prefix, 0, b"\x00" * 4, 0, unhexlify(chaincode), unhexlify(key)))
    child_key = bitcoin.bip32_ckd(master_key, 0)
    return bitcoin.bip32_extract_key(child_key)
예제 #19
0
def derive_childkey(key, chaincode, prefix=bitcoin.MAINNET_PUBLIC):
    """
    Given a 33 byte public key and 32 byte chaincode (both in hex) derive the first child key.
    """

    master_key = bitcoin.bip32_serialize((prefix, 0, b'\x00'*4, 0,
                                          unhexlify(chaincode), unhexlify(key)))
    child_key = bitcoin.bip32_ckd(master_key, 0)
    return bitcoin.bip32_extract_key(child_key)
예제 #20
0
def getPrivKey(xpriv, i):
    privkeys = {}
    priv0 = bitcoin.bip32_ckd(xpriv, 0)

    privateKey = bitcoin.bip32_ckd(priv0, i)
    wifKey = bitcoin.encode_privkey(bitcoin.bip32_extract_key(privateKey), 'wif_compressed')
    address_fromPriv =  bitcoin.privtoaddr(wifKey)
    privkeys[address_fromPriv] = wifKey

    return privkeys
예제 #21
0
def getAddressesFromXPUB(xpub, i=10):
    addressList = []
    pub0 = bitcoin.bip32_ckd(xpub, 0)

    for i in range (0, i):
        publicKey = bitcoin.bip32_ckd(pub0, i)
        hexKey = bitcoin.encode_pubkey(bitcoin.bip32_extract_key(publicKey), 'hex_compressed')
        address_fromPub =  bitcoin.pubtoaddr(hexKey)
        addressList.append(address_fromPub)

    return addressList
예제 #22
0
def key_address(masterkey, path):
    """Compute address and private key (hex) for path"""

    derived_key = descend(masterkey, path)
    priv_key = btc.bip32_deserialize(derived_key)[-1]
    pub_key = btc.bip32_extract_key(btc.bip32_privtopub(derived_key))
    priv_key_hex = btc.encode_privkey(
        btc.decode_privkey(priv_key, 'bin_compressed'), 'hex')
    address = btc.pubkey_to_address(pub_key)

    return priv_key_hex, address
예제 #23
0
def get_next_address(send_job):
    if 'addresses' in send_job:
        this_index = send_job['index']
        send_job['index'] = (send_job['index'] + 1) % len(send_job['addresses'])
        return send_job['addresses'][this_index]
    elif 'xpub' in send_job:
        send_job['index'] += 1
        return btc.pubtoaddr(btc.bip32_extract_key(btc.bip32_ckd(
            send_job['xpub'], send_job['index']-1)), get_p2pk_vbyte())
    else:
        assert False
예제 #24
0
    def _generate_new_keypair(self):

        seed = str(random.randrange(2**256))

        # Deprecated (pre-BIP32)
        # self.secret = hashlib.sha256(secret).hexdigest()
        # self.pubkey = privkey_to_pubkey(self.secret)
        # self.log.debug('Keys %s %s', self.secret, self.pubkey)

        # Move to BIP32 keys m/0/0/0
        wallet = bitcoin.bip32_ckd(bitcoin.bip32_master_key(seed), 0)
        wallet_chain = bitcoin.bip32_ckd(wallet, 0)
        bip32_identity_priv = bitcoin.bip32_ckd(wallet_chain, 0)
        identity_priv = bitcoin.bip32_extract_key(bip32_identity_priv)
        bip32_identity_pub = bitcoin.bip32_privtopub(bip32_identity_priv)
        identity_pub = bitcoin.encode_pubkey(
            bitcoin.bip32_extract_key(bip32_identity_pub), 'hex')

        self.pubkey = identity_pub
        self.secret = identity_priv

        # Generate SIN
        sha_hash = hashlib.sha256()
        sha_hash.update(self.pubkey)
        ripe_hash = hashlib.new('ripemd160')
        ripe_hash.update(sha_hash.digest())

        self.guid = ripe_hash.hexdigest()
        self.sin = obelisk.EncodeBase58Check('\x0F\x02%s' % ripe_hash.digest())

        newsettings = {
            "secret": self.secret,
            "pubkey": self.pubkey,
            "guid": self.guid,
            "sin": self.sin,
            "bip32_seed": seed
        }
        self.db_connection.update_entries("settings", newsettings,
                                          {"market_id": self.market_id})
        self.settings.update(newsettings)
예제 #25
0
    def _generate_new_keypair(self):

        seed = str(random.randrange(2 ** 256))

        # Deprecated (pre-BIP32)
        # self.secret = hashlib.sha256(secret).hexdigest()
        # self.pubkey = privkey_to_pubkey(self.secret)
        # self.log.debug('Keys %s %s', self.secret, self.pubkey)

        # Move to BIP32 keys m/0/0/0
        wallet = bitcoin.bip32_ckd(bitcoin.bip32_master_key(seed), 0)
        wallet_chain = bitcoin.bip32_ckd(wallet, 0)
        bip32_identity_priv = bitcoin.bip32_ckd(wallet_chain, 0)
        identity_priv = bitcoin.bip32_extract_key(bip32_identity_priv)
        bip32_identity_pub = bitcoin.bip32_privtopub(bip32_identity_priv)
        identity_pub = bitcoin.encode_pubkey(bitcoin.bip32_extract_key(bip32_identity_pub), 'hex')

        self.pubkey = identity_pub
        self.secret = identity_priv

        # Generate SIN
        sha_hash = hashlib.sha256()
        sha_hash.update(self.pubkey)
        ripe_hash = hashlib.new('ripemd160')
        ripe_hash.update(sha_hash.digest())

        self.guid = ripe_hash.hexdigest()
        self.sin = obelisk.EncodeBase58Check('\x0F\x02%s' % ripe_hash.digest())

        newsettings = {
            "secret": self.secret,
            "pubkey": self.pubkey,
            "guid": self.guid,
            "sin": self.sin,
            "bip32_seed": seed
        }
        self.db_connection.update_entries("settings", newsettings, {"market_id": self.market_id})
        self.settings.update(newsettings)
예제 #26
0
    def get_signing_key(self, contract_id):
        # Get BIP32 child signing key for this order id
        rows = self.db_connection.select_entries("keystore", {
            'contract_id': contract_id
        })

        if len(rows):
            key_id = rows[0]['id']

            settings = self.get_settings()

            wallet = bitcoin.bip32_ckd(bitcoin.bip32_master_key(settings.get('bip32_seed')), 1)
            wallet_chain = bitcoin.bip32_ckd(wallet, 0)
            bip32_identity_priv = bitcoin.bip32_ckd(wallet_chain, key_id)
            # bip32_identity_pub = bitcoin.bip32_privtopub(bip32_identity_priv)
            return bitcoin.encode_privkey(bitcoin.bip32_extract_key(bip32_identity_priv), 'wif')

        else:
            self.log.error('No keys found for that contract id: #%s', contract_id)
            return
예제 #27
0
 def get_scriptpubkeys(self, change, from_index, count):
     result = []
     for index in range(from_index, from_index + count):
         pubkeys = [
             btc.bip32_extract_key(btc.bip32_ckd(branch[change], index))
             for branch in self.pubkey_branches
         ]
         pubkeys = sorted(pubkeys)
         redeemScript = ""
         redeemScript += "%x" % (0x50 + self.m)  #op_m
         for p in pubkeys:
             redeemScript += "21"  #length
             redeemScript += p
         redeemScript += "%x" % (0x50 + len(pubkeys))  #op_n
         redeemScript += "ae"  # op_checkmultisig
         scriptpubkey = self.redeem_script_to_scriptpubkey(redeemScript)
         self.scriptpubkey_index[scriptpubkey] = (change, index)
         result.append(scriptpubkey)
     self.next_index[change] = max(self.next_index[change],
                                   from_index + count)
     return result
예제 #28
0
    def generate_new_pubkey(self, contract_id):
        self.log.debug('Generating new pubkey for contract')

        # Retrieve next key id from DB
        next_key_id = len(self.db_connection.select_entries("keystore", select_fields="id")) + 1

        # Store updated key in DB
        self.db_connection.insert_entry(
            "keystore",
            {
                'contract_id': contract_id
            }
        )

        # Generate new child key (m/1/0/n)
        wallet = bitcoin.bip32_ckd(bitcoin.bip32_master_key(self.settings.get('bip32_seed')), 1)
        wallet_chain = bitcoin.bip32_ckd(wallet, 0)
        bip32_identity_priv = bitcoin.bip32_ckd(wallet_chain, next_key_id)
        bip32_identity_pub = bitcoin.bip32_privtopub(bip32_identity_priv)
        pubkey = bitcoin.encode_pubkey(bitcoin.bip32_extract_key(bip32_identity_pub), 'hex')

        return pubkey
예제 #29
0
    def generate_new_pubkey(self, contract_id):
        self.log.debug('Generating new pubkey for contract')

        # Retrieve next key id from DB
        next_key_id = len(
            self.db_connection.select_entries("keystore",
                                              select_fields="id")) + 1

        # Store updated key in DB
        self.db_connection.insert_entry("keystore",
                                        {'contract_id': contract_id})

        # Generate new child key (m/1/0/n)
        wallet = bitcoin.bip32_ckd(
            bitcoin.bip32_master_key(self.settings.get('bip32_seed')), 1)
        wallet_chain = bitcoin.bip32_ckd(wallet, 0)
        bip32_identity_priv = bitcoin.bip32_ckd(wallet_chain, next_key_id)
        bip32_identity_pub = bitcoin.bip32_privtopub(bip32_identity_priv)
        pubkey = bitcoin.encode_pubkey(
            bitcoin.bip32_extract_key(bip32_identity_pub), 'hex')

        return pubkey
예제 #30
0
 def get_pubkey(self, change, index):
     return btc.bip32_extract_key(
         btc.bip32_ckd(self.branches[change], index))
예제 #31
0
파일: wallet.py 프로젝트: wozz/joinmarket
 def get_key(self, mixing_depth, forchange, i):
     return btc.bip32_extract_key(btc.bip32_ckd(
             self.keys[mixing_depth][forchange], i))
예제 #32
0
import bitcoin
from os import urandom

user = '******'
email = '*****@*****.**'
SECRET_KEY = urandom(32)

master_key = bitcoin.bip32_master_key((user + email).encode() + SECRET_KEY)
print(master_key)

for i in range(10):
    child = bitcoin.bip32_ckd(master_key, i)
    addr = bitcoin.bip32_extract_key(child)
    print(bitcoin.privtoaddr(addr, 0x58))
예제 #33
0
    def add_receipt(self,
                    received,
                    libbitcoin_client,
                    feedback=None,
                    quality=None,
                    description=None,
                    delivery_time=None,
                    customer_service=None,
                    review="",
                    dispute=False,
                    claim=None,
                    payout=True):

        """
        Add the final piece of the contract that appends the review and payout transaction.
        """
        self.blockchain = libbitcoin_client
        receipt_json = {
            "buyer_receipt": {
                "receipt": {
                    "ref_hash": digest(json.dumps(self.contract, indent=4)).encode("hex"),
                    "listing": {
                        "received": received,
                        "listing_hash": self.contract["buyer_order"]["order"]["ref_hash"]
                    },
                    "dispute": {
                        "dispute": dispute
                    }
                }
            }
        }
        if None not in (feedback, quality, description, delivery_time, customer_service):
            receipt_json["buyer_receipt"]["receipt"]["rating"] = {}
            receipt_json["buyer_receipt"]["receipt"]["rating"]["feedback"] = feedback
            receipt_json["buyer_receipt"]["receipt"]["rating"]["quality"] = quality
            receipt_json["buyer_receipt"]["receipt"]["rating"]["description"] = description
            receipt_json["buyer_receipt"]["receipt"]["rating"]["delivery_time"] = delivery_time
            receipt_json["buyer_receipt"]["receipt"]["rating"]["customer_service"] = customer_service
            receipt_json["buyer_receipt"]["receipt"]["rating"]["review"] = review
        if payout:
            order_id = self.contract["vendor_order_confirmation"]["invoice"]["ref_hash"]
            outpoints = pickle.loads(self.db.Purchases().get_outpoint(order_id))
            payout_address = self.contract["vendor_order_confirmation"]["invoice"]["payout"]["address"]
            redeem_script = str(self.contract["buyer_order"]["order"]["payment"]["redeem_script"])
            for output in outpoints:
                del output["value"]
            value = self.contract["vendor_order_confirmation"]["invoice"]["payout"]["value"]
            outs = [{'value': value, 'address': payout_address}]
            tx = bitcoin.mktx(outpoints, outs)
            signatures = []
            chaincode = self.contract["buyer_order"]["order"]["payment"]["chaincode"]
            masterkey_b = bitcoin.bip32_extract_key(self.keychain.bitcoin_master_privkey)
            buyer_priv = derive_childkey(masterkey_b, chaincode, bitcoin.MAINNET_PRIVATE)
            masterkey_v = self.contract["vendor_offer"]["listing"]["id"]["pubkeys"]["bitcoin"]
            vendor_key = derive_childkey(masterkey_v, chaincode)
            valid_inputs = 0
            for index in range(0, len(outpoints)):
                sig = bitcoin.multisign(tx, index, redeem_script, buyer_priv)
                signatures.append({"input_index": index, "signature": sig})
                for s in self.contract["vendor_order_confirmation"]["invoice"]["payout"]["signature(s)"]:
                    if s["input_index"] == index:
                        if bitcoin.verify_tx_input(tx, index, redeem_script, s["signature"], vendor_key):
                            tx = bitcoin.apply_multisignatures(tx, index, str(redeem_script),
                                                               sig, str(s["signature"]))
                            valid_inputs += 1
            receipt_json["buyer_receipt"]["receipt"]["payout"] = {}
            if valid_inputs == len(outpoints):
                self.log.info("Broadcasting payout tx %s to network" % bitcoin.txhash(tx))
                self.blockchain.broadcast(tx)
                receipt_json["buyer_receipt"]["receipt"]["payout"]["txid"] = bitcoin.txhash(tx)
            receipt_json["buyer_receipt"]["receipt"]["payout"]["signature(s)"] = signatures
            receipt_json["buyer_receipt"]["receipt"]["payout"]["value"] = value
        if claim:
            receipt_json["buyer_receipt"]["receipt"]["dispute"]["claim"] = claim
        receipt = json.dumps(receipt_json["buyer_receipt"]["receipt"], indent=4)
        receipt_json["buyer_receipt"]["signature"] = \
            self.keychain.signing_key.sign(receipt, encoder=nacl.encoding.HexEncoder)[:128]
        self.contract["buyer_receipt"] = receipt_json["buyer_receipt"]
예제 #34
0
    def create(self,
               expiration_date,
               metadata_category,
               title,
               description,
               currency_code,
               price,
               process_time,
               nsfw,
               shipping_origin=None,
               shipping_regions=None,
               est_delivery_domestic=None,
               est_delivery_international=None,
               terms_conditions=None,
               returns=None,
               keywords=None,
               category=None,
               condition=None,
               sku=None,
               images=None,
               free_shipping=None,
               shipping_currency_code=None,
               shipping_domestic=None,
               shipping_international=None,
               options=None,
               moderators=None):
        """
        All parameters are strings except:

        :param expiration_date: `string` (must be formatted UTC datetime)
        :param keywords: `list`
        :param nsfw: `boolean`
        :param images: a `list` of image files
        :param free_shipping: `boolean`
        :param shipping_origin: a 'string' formatted `CountryCode`
        :param shipping_regions: a 'list' of 'string' formatted `CountryCode`s
        :param options: a 'dict' containing options as keys and 'list' as option values.
        :param moderators: a 'list' of 'string' guids (hex encoded).
        """

        profile = Profile(self.db).get()
        self.contract = OrderedDict({
            "vendor_offer": {
                "listing": {
                    "metadata": {
                        "version": "0.1",
                        "category": metadata_category.lower(),
                        "category_sub": "fixed price"
                    },
                    "id": {
                        "guid": self.keychain.guid.encode("hex"),
                        "pubkeys": {
                            "guid":
                            self.keychain.guid_signed_pubkey[64:].encode(
                                "hex"),
                            "bitcoin":
                            bitcoin.bip32_extract_key(
                                self.keychain.bitcoin_master_pubkey),
                            "encryption":
                            self.keychain.encryption_pubkey.encode("hex")
                        }
                    },
                    "item": {
                        "title": title,
                        "description": description,
                        "process_time": process_time,
                        "price_per_unit": {},
                        "nsfw": nsfw
                    }
                }
            }
        })
        if expiration_date == "":
            self.contract["vendor_offer"]["listing"]["metadata"][
                "expiry"] = "never"
        else:
            self.contract["vendor_offer"]["listing"]["metadata"][
                "expiry"] = expiration_date + " UTC"
        if metadata_category == "physical good" and condition is not None:
            self.contract["vendor_offer"]["listing"]["item"][
                "condition"] = condition
        if currency_code.upper() == "BTC":
            item = self.contract["vendor_offer"]["listing"]["item"]
            item["price_per_unit"]["bitcoin"] = price
        else:
            item = self.contract["vendor_offer"]["listing"]["item"]
            item["price_per_unit"]["fiat"] = {}
            item["price_per_unit"]["fiat"]["price"] = price
            item["price_per_unit"]["fiat"]["currency_code"] = currency_code
        if keywords is not None:
            self.contract["vendor_offer"]["listing"]["item"]["keywords"] = []
            self.contract["vendor_offer"]["listing"]["item"][
                "keywords"].extend(keywords)
        if category is not None:
            self.contract["vendor_offer"]["listing"]["item"][
                "category"] = category
        if sku is not None:
            self.contract["vendor_offer"]["listing"]["item"]["sku"] = sku
        if options is not None:
            self.contract["vendor_offer"]["listing"]["item"][
                "options"] = options
        if metadata_category == "physical good":
            self.contract["vendor_offer"]["listing"]["shipping"] = {}
            shipping = self.contract["vendor_offer"]["listing"]["shipping"]
            shipping["shipping_origin"] = shipping_origin
            if free_shipping is False:
                self.contract["vendor_offer"]["listing"]["shipping"][
                    "free"] = False
                self.contract["vendor_offer"]["listing"]["shipping"][
                    "flat_fee"] = {}
                if shipping_currency_code == "BTC":
                    self.contract["vendor_offer"]["listing"]["shipping"][
                        "flat_fee"]["bitcoin"] = {}
                    self.contract["vendor_offer"]["listing"]["shipping"][
                        "flat_fee"]["bitcoin"]["domestic"] = shipping_domestic
                    self.contract["vendor_offer"]["listing"]["shipping"][
                        "flat_fee"]["bitcoin"][
                            "international"] = shipping_international
                else:
                    shipping = self.contract["vendor_offer"]["listing"][
                        "shipping"]
                    shipping["flat_fee"]["fiat"] = {}
                    shipping["flat_fee"]["fiat"]["price"] = {}
                    shipping["flat_fee"]["fiat"]["price"][
                        "domestic"] = shipping_domestic
                    shipping["flat_fee"]["fiat"]["price"][
                        "international"] = shipping_international
                    shipping["flat_fee"]["fiat"][
                        "currency_code"] = shipping_currency_code
            else:
                self.contract["vendor_offer"]["listing"]["shipping"][
                    "free"] = True
            self.contract["vendor_offer"]["listing"]["shipping"][
                "shipping_regions"] = []
            for region in shipping_regions:
                shipping = self.contract["vendor_offer"]["listing"]["shipping"]
                shipping["shipping_regions"].append(region)
            listing = self.contract["vendor_offer"]["listing"]
            listing["shipping"]["est_delivery"] = {}
            listing["shipping"]["est_delivery"][
                "domestic"] = est_delivery_domestic
            listing["shipping"]["est_delivery"][
                "international"] = est_delivery_international
        if profile.HasField("handle"):
            self.contract["vendor_offer"]["listing"]["id"][
                "blockchain_id"] = profile.handle
        if images is not None:
            self.contract["vendor_offer"]["listing"]["item"][
                "image_hashes"] = []
            for image_hash in images:
                if len(image_hash) != 40:
                    raise Exception("Invalid image hash")
                self.contract["vendor_offer"]["listing"]["item"][
                    "image_hashes"].append(image_hash)
        if terms_conditions is not None or returns is not None:
            self.contract["vendor_offer"]["listing"]["policy"] = {}
            if terms_conditions is not None:
                self.contract["vendor_offer"]["listing"]["policy"][
                    "terms_conditions"] = terms_conditions
            if returns is not None:
                self.contract["vendor_offer"]["listing"]["policy"][
                    "returns"] = returns
        if moderators is not None:
            self.contract["vendor_offer"]["listing"]["moderators"] = []
            for mod in moderators:
                mod_info = self.db.ModeratorStore().get_moderator(
                    unhexlify(mod))
                print mod_info
                if mod_info is not None:
                    moderator = {
                        "guid": mod,
                        "blockchain_id": mod_info[6],
                        "pubkeys": {
                            "signing": {
                                "key": mod_info[1][64:].encode("hex"),
                                "signature": mod_info[1][:64].encode("hex")
                            },
                            "encryption": {
                                "key": mod_info[2].encode("hex"),
                                "signature": mod_info[3].encode("hex")
                            },
                            "bitcoin": {
                                "key": mod_info[4].encode("hex"),
                                "signature": mod_info[5].encode("hex")
                            }
                        }
                    }
                    self.contract["vendor_offer"]["listing"][
                        "moderators"].append(moderator)

        listing = json.dumps(self.contract["vendor_offer"]["listing"],
                             indent=4)
        self.contract["vendor_offer"]["signature"] = \
            self.keychain.signing_key.sign(listing, encoder=nacl.encoding.HexEncoder)[:128]
        self.save()
예제 #35
0
    def verify(self, sender_key):
        """
        Validate that an order sent over by a buyer is filled out correctly.
        """

        try:
            contract_dict = json.loads(json.dumps(self.contract, indent=4),
                                       object_pairs_hook=OrderedDict)
            del contract_dict["buyer_order"]
            contract_hash = digest(json.dumps(contract_dict, indent=4))

            ref_hash = unhexlify(
                self.contract["buyer_order"]["order"]["ref_hash"])

            # verify that the reference hash matches the contract and that the contract actually exists
            if contract_hash != ref_hash or not self.db.HashMap().get_file(
                    ref_hash):
                raise Exception("Order for contract that doesn't exist")

            # verify the signature on the order
            verify_key = nacl.signing.VerifyKey(sender_key)
            verify_key.verify(
                json.dumps(self.contract["buyer_order"]["order"], indent=4),
                unhexlify(self.contract["buyer_order"]["signature"]))

            # TODO: verify the bitcoin signature after we add it

            # verify buyer included the correct bitcoin amount for payment
            price_json = self.contract["vendor_offer"]["listing"]["item"][
                "price_per_unit"]
            if "bitcoin" in price_json:
                asking_price = price_json["bitcoin"]
            else:
                currency_code = price_json["fiat"]["currency_code"]
                fiat_price = price_json["fiat"]["price"]
                request = Request('https://api.bitcoinaverage.com/ticker/' +
                                  currency_code.upper() + '/last')
                response = urlopen(request)
                conversion_rate = response.read()
                asking_price = float("{0:.8f}".format(
                    float(fiat_price) / float(conversion_rate)))
            if asking_price > self.contract["buyer_order"]["order"]["payment"][
                    "amount"]:
                raise Exception("Insuffient Payment")

            # verify a valid moderator was selected
            # TODO: handle direct payments
            valid_mod = False
            for mod in self.contract["vendor_offer"]["listing"]["moderators"]:
                if mod["guid"] == self.contract["buyer_order"]["order"][
                        "moderator"]:
                    valid_mod = True
            if not valid_mod:
                raise Exception("Invalid moderator")

            # verify all the shipping fields exist
            if self.contract["vendor_offer"]["listing"]["metadata"][
                    "category"] == "physical good":
                shipping = self.contract["buyer_order"]["order"]["shipping"]
                keys = [
                    "ship_to", "address", "postal_code", "city", "state",
                    "country"
                ]
                for value in map(shipping.get, keys):
                    if value is None:
                        raise Exception("Missing shipping field")

            # verify buyer ID
            pubkeys = self.contract["buyer_order"]["order"]["id"]["pubkeys"]
            keys = ["guid", "bitcoin", "encryption"]
            for value in map(pubkeys.get, keys):
                if value is None:
                    raise Exception("Missing pubkey field")

            # verify redeem script
            chaincode = self.contract["buyer_order"]["order"]["payment"][
                "chaincode"]
            for mod in self.contract["vendor_offer"]["listing"]["moderators"]:
                if mod["guid"] == self.contract["buyer_order"]["order"][
                        "moderator"]:
                    masterkey_m = mod["pubkeys"]["bitcoin"]["key"]

            masterkey_b = self.contract["buyer_order"]["order"]["id"][
                "pubkeys"]["bitcoin"]
            masterkey_v = bitcoin.bip32_extract_key(
                self.keychain.bitcoin_master_pubkey)
            buyer_key = derive_childkey(masterkey_b, chaincode)
            vendor_key = derive_childkey(masterkey_v, chaincode)
            moderator_key = derive_childkey(masterkey_m, chaincode)

            redeem_script = bitcoin.mk_multisig_script(
                [buyer_key, vendor_key, moderator_key], 2)
            if redeem_script != self.contract["buyer_order"]["order"][
                    "payment"]["redeem_script"]:
                raise Exception("Invalid redeem script")

            # verify the payment address
            if self.testnet:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script, 196)
            else:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script)
            if payment_address != self.contract["buyer_order"]["order"][
                    "payment"]["address"]:
                raise Exception("Incorrect payment address")

            return True

        except Exception:
            return False
예제 #36
0
 def _derive_address(self, change_or_deposit, index, master_key):
     xpriv = bip32_ckd(bip32_ckd(self.get_bip44_master(
         master_key), change_or_deposit), index)
     priv = bip32_extract_key(xpriv)
     address = privtoaddr(priv, self.get_address_byte())
     return address, priv
예제 #37
0
def nextWord(currSeed, nextPos):
    global seedCount
    global f
    if nextPos < len(sys.argv) - 1:
        if len(seedStruct[nextPos]) > 1:
            for x in range(seedStruct[nextPos]['min'],
                           seedStruct[nextPos]['max'] + 1):
                #print("WordLength: " + str(x) + "------------------------------")
                for theWord in words[x]:
                    currSeed += theWord + " "
                    nextWord(currSeed, nextPos + 1)
                    currSeed = currSeed.strip().rsplit(' ', 1)[0] + " "
        else:
            currSeed += seedStruct[nextPos]['word'] + " "
            nextWord(currSeed, nextPos + 1)
            currSeed = currSeed.strip().rsplit(' ', 1)[0] + " "

    else:
        if len(seedStruct[nextPos]) > 1:
            for x in range(seedStruct[nextPos]['min'],
                           seedStruct[nextPos]['max'] + 1):
                #print("WordLength: " + str(x) + "------------------------------")
                for theWord in words[x]:
                    currSeed += theWord
        else:
            currSeed += seedStruct[nextPos]['word']
            seedCount += 1
        #print("Seed:" + currSeed)
        try:
            entropy = binascii.hexlify(m.to_entropy(currSeed))
            hexSeed = binascii.hexlify(m.to_seed(currSeed))
            print("Found valid seed!")
            #print(hexSeed)
            print("Seed: " + currSeed)
            output = open('keys_' + str(seedCount) + '.txt', 'w')
            output.write('Seed: ' + currSeed + '\n')

            xprv = bitcoin.bip32_master_key(binascii.unhexlify(hexSeed))

            #xprvReceive = bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 2**31),0) #m/0'/0
            #xprvChange = bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 2**31),1) #m/0'/1
            #m/44'/0'/0'/0 - Receive
            xprvReceive = bitcoin.bip32_ckd(
                bitcoin.bip32_ckd(
                    bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 44 + 2**31),
                                      2**31), 2**31), 0)
            #m/44'/0'/0'/1 - Change
            xprvChange = bitcoin.bip32_ckd(
                bitcoin.bip32_ckd(
                    bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 44 + 2**31),
                                      2**31), 2**31), 1)

            rcvAddr = []
            chgAddr = []
            rcvPrivKey = []
            chgPrivKey = []

            sys.stdout.write("Generating Seed Keys/Addresses.")
            for x in range(0, 100):
                if x % 10 == 0:
                    sys.stdout.write(".")
                childprivReceive = bitcoin.bip32_ckd(xprvReceive, x)
                childprivChange = bitcoin.bip32_ckd(xprvChange, x)

                pkeyReceive = bitcoin.bip32_extract_key(childprivReceive)
                pkeyChange = bitcoin.bip32_extract_key(childprivChange)

                rcvAddr.append(bitcoin.privtoaddr(pkeyReceive))
                chgAddr.append(bitcoin.privtoaddr(pkeyChange))

                rcvPrivKey.append(
                    bitcoin.encode_privkey(pkeyReceive, 'wif_compressed'))
                chgPrivKey.append(
                    bitcoin.encode_privkey(pkeyChange, 'wif_compressed'))

            for x in range(0, 100):
                output.write(rcvPrivKey[x] + '\n')
                output.write(chgPrivKey[x] + '\n')

            output.write(
                '------ END KEYS ------------------------------------\n')

            for x in range(0, 100):
                output.write(rcvAddr[x] + '\n')
                output.write(chgAddr[x] + '\n')

            output.write(
                '------ END ADDRESSES -------------------------------\n')
            output.close()

            print("Dumped!")
        except ValueError:
            sys.stdout.write('.')

        if seedCount % 1000000 == 0:
            print(str(seedCount) + ' Seeds ' + str(datetime.now()))
            f.write((str(seedCount) + ' Seeds ' + str(datetime.now())) + '\n')
        currSeed = currSeed.strip().rsplit(' ', 1)[0] + " "
예제 #38
0
    def add_purchase_info(self,
                          quantity,
                          ship_to=None,
                          shipping_address=None,
                          city=None,
                          state=None,
                          postal_code=None,
                          country=None,
                          moderator=None,
                          options=None):
        """
        Update the contract with the buyer's purchase information.
        """

        profile = Profile(self.db).get()
        order_json = {
            "buyer_order": {
                "order": {
                    "ref_hash":
                    digest(json.dumps(self.contract, indent=4)).encode("hex"),
                    "quantity":
                    quantity,
                    "id": {
                        "guid": self.keychain.guid.encode("hex"),
                        "pubkeys": {
                            "guid":
                            self.keychain.guid_signed_pubkey[64:].encode(
                                "hex"),
                            "bitcoin":
                            bitcoin.bip32_extract_key(
                                self.keychain.bitcoin_master_pubkey),
                            "encryption":
                            self.keychain.encryption_pubkey.encode("hex")
                        }
                    },
                    "payment": {}
                }
            }
        }
        if profile.HasField("handle"):
            order_json["buyer_order"]["order"]["id"][
                "blockchain_id"] = profile.handle
        if self.contract["vendor_offer"]["listing"]["metadata"][
                "category"] == "physical good":
            order_json["buyer_order"]["order"]["shipping"] = {}
            order_json["buyer_order"]["order"]["shipping"]["ship_to"] = ship_to
            order_json["buyer_order"]["order"]["shipping"][
                "address"] = shipping_address
            order_json["buyer_order"]["order"]["shipping"]["city"] = city
            order_json["buyer_order"]["order"]["shipping"]["state"] = state
            order_json["buyer_order"]["order"]["shipping"][
                "postal_code"] = postal_code
            order_json["buyer_order"]["order"]["shipping"]["country"] = country
        if options is not None:
            order_json["buyer_order"]["order"]["options"] = options
        if moderator:  # TODO: Handle direct payments
            chaincode = sha256(str(
                random.getrandbits(256))).digest().encode("hex")
            order_json["buyer_order"]["order"]["payment"][
                "chaincode"] = chaincode
            valid_mod = False
            for mod in self.contract["vendor_offer"]["listing"]["moderators"]:
                if mod["guid"] == moderator:
                    order_json["buyer_order"]["order"]["moderator"] = moderator
                    masterkey_m = mod["pubkeys"]["bitcoin"]["key"]
                    valid_mod = True
            if not valid_mod:
                return False
            masterkey_b = bitcoin.bip32_extract_key(
                self.keychain.bitcoin_master_pubkey)
            masterkey_v = self.contract["vendor_offer"]["listing"]["id"][
                "pubkeys"]["bitcoin"]
            buyer_key = derive_childkey(masterkey_b, chaincode)
            vendor_key = derive_childkey(masterkey_v, chaincode)
            moderator_key = derive_childkey(masterkey_m, chaincode)

            redeem_script = bitcoin.mk_multisig_script(
                [buyer_key, vendor_key, moderator_key], 2)
            order_json["buyer_order"]["order"]["payment"][
                "redeem_script"] = redeem_script
            if self.testnet:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script, 196)
            else:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script)
            order_json["buyer_order"]["order"]["payment"][
                "address"] = payment_address

        price_json = self.contract["vendor_offer"]["listing"]["item"][
            "price_per_unit"]
        if "bitcoin" in price_json:
            order_json["buyer_order"]["order"]["payment"][
                "amount"] = price_json["bitcoin"]
        else:
            currency_code = price_json["fiat"]["currency_code"]
            fiat_price = price_json["fiat"]["price"]
            try:
                request = Request('https://api.bitcoinaverage.com/ticker/' +
                                  currency_code.upper() + '/last')
                response = urlopen(request)
                conversion_rate = response.read()
            except URLError:
                return False
            order_json["buyer_order"]["order"]["payment"]["amount"] = float(
                "{0:.8f}".format(float(fiat_price) / float(conversion_rate)))

        self.contract["buyer_order"] = order_json["buyer_order"]
        order = json.dumps(self.contract["buyer_order"]["order"], indent=4)
        # TODO: This should also be signed with the bitcoin key. It's the only way a moderator
        # will have to link this contract to a bitcoin transaction.
        self.contract["buyer_order"]["signature"] = \
            self.keychain.signing_key.sign(order, encoder=nacl.encoding.HexEncoder)[:128]
        return (self.contract["buyer_order"]["order"]["payment"]["address"],
                order_json["buyer_order"]["order"]["payment"]["amount"])
예제 #39
0
 def add_receipt(self,
                 received,
                 libbitcoin_client,
                 feedback=None,
                 quality=None,
                 description=None,
                 delivery_time=None,
                 customer_service=None,
                 review="",
                 dispute=False,
                 claim=None,
                 payout=True):
     """
     Add the final piece of the contract that appends the review and payout transaction.
     """
     self.blockchain = libbitcoin_client
     receipt_json = {
         "buyer_receipt": {
             "receipt": {
                 "ref_hash":
                 digest(json.dumps(self.contract, indent=4)).encode("hex"),
                 "listing": {
                     "received":
                     received,
                     "listing_hash":
                     self.contract["buyer_order"]["order"]["ref_hash"]
                 },
                 "dispute": {
                     "dispute": dispute
                 }
             }
         }
     }
     if None not in (feedback, quality, description, delivery_time,
                     customer_service):
         receipt_json["buyer_receipt"]["receipt"]["rating"] = {}
         receipt_json["buyer_receipt"]["receipt"]["rating"][
             "feedback"] = feedback
         receipt_json["buyer_receipt"]["receipt"]["rating"][
             "quality"] = quality
         receipt_json["buyer_receipt"]["receipt"]["rating"][
             "description"] = description
         receipt_json["buyer_receipt"]["receipt"]["rating"][
             "delivery_time"] = delivery_time
         receipt_json["buyer_receipt"]["receipt"]["rating"][
             "customer_service"] = customer_service
         receipt_json["buyer_receipt"]["receipt"]["rating"][
             "review"] = review
     if payout:
         order_id = self.contract["vendor_order_confirmation"]["invoice"][
             "ref_hash"]
         outpoints = pickle.loads(
             self.db.Purchases().get_outpoint(order_id))
         payout_address = self.contract["vendor_order_confirmation"][
             "invoice"]["payout"]["address"]
         redeem_script = str(self.contract["buyer_order"]["order"]
                             ["payment"]["redeem_script"])
         for output in outpoints:
             del output["value"]
         value = self.contract["vendor_order_confirmation"]["invoice"][
             "payout"]["value"]
         outs = [{'value': value, 'address': payout_address}]
         tx = bitcoin.mktx(outpoints, outs)
         signatures = []
         chaincode = self.contract["buyer_order"]["order"]["payment"][
             "chaincode"]
         masterkey_b = bitcoin.bip32_extract_key(
             self.keychain.bitcoin_master_privkey)
         buyer_priv = derive_childkey(masterkey_b, chaincode,
                                      bitcoin.MAINNET_PRIVATE)
         masterkey_v = self.contract["vendor_offer"]["listing"]["id"][
             "pubkeys"]["bitcoin"]
         vendor_key = derive_childkey(masterkey_v, chaincode)
         valid_inputs = 0
         for index in range(0, len(outpoints)):
             sig = bitcoin.multisign(tx, index, redeem_script, buyer_priv)
             signatures.append({"input_index": index, "signature": sig})
             for s in self.contract["vendor_order_confirmation"]["invoice"][
                     "payout"]["signature(s)"]:
                 if s["input_index"] == index:
                     if bitcoin.verify_tx_input(tx, index, redeem_script,
                                                s["signature"], vendor_key):
                         tx = bitcoin.apply_multisignatures(
                             tx, index, str(redeem_script), sig,
                             str(s["signature"]))
                         valid_inputs += 1
         receipt_json["buyer_receipt"]["receipt"]["payout"] = {}
         if valid_inputs == len(outpoints):
             self.log.info("Broadcasting payout tx %s to network" %
                           bitcoin.txhash(tx))
             self.blockchain.broadcast(tx)
             receipt_json["buyer_receipt"]["receipt"]["payout"][
                 "txid"] = bitcoin.txhash(tx)
         receipt_json["buyer_receipt"]["receipt"]["payout"][
             "signature(s)"] = signatures
         receipt_json["buyer_receipt"]["receipt"]["payout"]["value"] = value
     if claim:
         receipt_json["buyer_receipt"]["receipt"]["dispute"][
             "claim"] = claim
     receipt = json.dumps(receipt_json["buyer_receipt"]["receipt"],
                          indent=4)
     receipt_json["buyer_receipt"]["signature"] = \
         self.keychain.signing_key.sign(receipt, encoder=nacl.encoding.HexEncoder)[:128]
     self.contract["buyer_receipt"] = receipt_json["buyer_receipt"]
예제 #40
0
    def add_order_confirmation(self,
                               payout_address,
                               comments=None,
                               shipper=None,
                               tracking_number=None,
                               est_delivery=None,
                               url=None,
                               password=None):
        """
        Add the vendor's order confirmation to the contract.
        """

        if not self.testnet and not (payout_address[:1] == "1" or payout_address[:1] == "3"):
            raise Exception("Bitcoin address is not a mainnet address")
        elif self.testnet and not \
                (payout_address[:1] == "n" or payout_address[:1] == "m" or payout_address[:1] == "2"):
            raise Exception("Bitcoin address is not a testnet address")
        try:
            bitcoin.b58check_to_hex(payout_address)
        except AssertionError:
            raise Exception("Invalid Bitcoin address")
        conf_json = {
            "vendor_order_confirmation": {
                "invoice": {
                    "ref_hash": digest(json.dumps(self.contract, indent=4)).encode("hex")
                }
            }
        }
        if self.contract["vendor_offer"]["listing"]["metadata"]["category"] == "physical good":
            shipping = {"shipper": shipper, "tracking_number": tracking_number, "est_delivery": est_delivery}
            conf_json["vendor_order_confirmation"]["invoice"]["shipping"] = shipping
        elif self.contract["vendor_offer"]["listing"]["metadata"]["category"] == "digital good":
            content_source = {"url": url, "password": password}
            conf_json["vendor_order_confirmation"]["invoice"]["content_source"] = content_source
        if comments:
            conf_json["vendor_order_confirmation"]["invoice"]["comments"] = comments
        confirmation = json.dumps(conf_json["vendor_order_confirmation"]["invoice"], indent=4)
        conf_json["vendor_order_confirmation"]["signature"] = \
            self.keychain.signing_key.sign(confirmation, encoder=nacl.encoding.HexEncoder)[:128]
        order_id = digest(json.dumps(self.contract, indent=4)).encode("hex")
        # apply signatures
        outpoints = pickle.loads(self.db.Sales().get_outpoint(order_id))
        redeem_script = self.contract["buyer_order"]["order"]["payment"]["redeem_script"]
        value = 0
        for output in outpoints:
            value += output["value"]
            del output["value"]
        value -= TRANSACTION_FEE
        outs = [{'value': value, 'address': payout_address}]
        tx = bitcoin.mktx(outpoints, outs)
        signatures = []
        chaincode = self.contract["buyer_order"]["order"]["payment"]["chaincode"]
        masterkey_v = bitcoin.bip32_extract_key(self.keychain.bitcoin_master_privkey)
        vendor_priv = derive_childkey(masterkey_v, chaincode, bitcoin.MAINNET_PRIVATE)
        for index in range(0, len(outpoints)):
            sig = bitcoin.multisign(tx, index, redeem_script, vendor_priv)
            signatures.append({"input_index": index, "signature": sig})
        conf_json["vendor_order_confirmation"]["invoice"]["payout"] = {}
        conf_json["vendor_order_confirmation"]["invoice"]["payout"]["address"] = payout_address
        conf_json["vendor_order_confirmation"]["invoice"]["payout"]["value"] = value
        conf_json["vendor_order_confirmation"]["invoice"]["payout"]["signature(s)"] = signatures

        self.contract["vendor_order_confirmation"] = conf_json["vendor_order_confirmation"]
        self.db.Sales().update_status(order_id, 2)
        file_path = DATA_FOLDER + "store/listings/in progress/" + order_id + ".json"
        with open(file_path, 'w') as outfile:
            outfile.write(json.dumps(self.contract, indent=4))
예제 #41
0
    def add_order_confirmation(self,
                               payout_address,
                               comments=None,
                               shipper=None,
                               tracking_number=None,
                               est_delivery=None,
                               url=None,
                               password=None):
        """
        Add the vendor's order confirmation to the contract.
        """

        if not self.testnet and not (payout_address[:1] == "1"
                                     or payout_address[:1] == "3"):
            raise Exception("Bitcoin address is not a mainnet address")
        elif self.testnet and not \
                (payout_address[:1] == "n" or payout_address[:1] == "m" or payout_address[:1] == "2"):
            raise Exception("Bitcoin address is not a testnet address")
        try:
            bitcoin.b58check_to_hex(payout_address)
        except AssertionError:
            raise Exception("Invalid Bitcoin address")
        conf_json = {
            "vendor_order_confirmation": {
                "invoice": {
                    "ref_hash":
                    digest(json.dumps(self.contract, indent=4)).encode("hex")
                }
            }
        }
        if self.contract["vendor_offer"]["listing"]["metadata"][
                "category"] == "physical good":
            shipping = {
                "shipper": shipper,
                "tracking_number": tracking_number,
                "est_delivery": est_delivery
            }
            conf_json["vendor_order_confirmation"]["invoice"][
                "shipping"] = shipping
        elif self.contract["vendor_offer"]["listing"]["metadata"][
                "category"] == "digital good":
            content_source = {"url": url, "password": password}
            conf_json["vendor_order_confirmation"]["invoice"][
                "content_source"] = content_source
        if comments:
            conf_json["vendor_order_confirmation"]["invoice"][
                "comments"] = comments
        confirmation = json.dumps(
            conf_json["vendor_order_confirmation"]["invoice"], indent=4)
        conf_json["vendor_order_confirmation"]["signature"] = \
            self.keychain.signing_key.sign(confirmation, encoder=nacl.encoding.HexEncoder)[:128]
        order_id = digest(json.dumps(self.contract, indent=4)).encode("hex")
        # apply signatures
        outpoints = pickle.loads(self.db.Sales().get_outpoint(order_id))
        redeem_script = self.contract["buyer_order"]["order"]["payment"][
            "redeem_script"]
        value = 0
        for output in outpoints:
            value += output["value"]
            del output["value"]
        value -= TRANSACTION_FEE
        outs = [{'value': value, 'address': payout_address}]
        tx = bitcoin.mktx(outpoints, outs)
        signatures = []
        chaincode = self.contract["buyer_order"]["order"]["payment"][
            "chaincode"]
        masterkey_v = bitcoin.bip32_extract_key(
            self.keychain.bitcoin_master_privkey)
        vendor_priv = derive_childkey(masterkey_v, chaincode,
                                      bitcoin.MAINNET_PRIVATE)
        for index in range(0, len(outpoints)):
            sig = bitcoin.multisign(tx, index, redeem_script, vendor_priv)
            signatures.append({"input_index": index, "signature": sig})
        conf_json["vendor_order_confirmation"]["invoice"]["payout"] = {}
        conf_json["vendor_order_confirmation"]["invoice"]["payout"][
            "address"] = payout_address
        conf_json["vendor_order_confirmation"]["invoice"]["payout"][
            "value"] = value
        conf_json["vendor_order_confirmation"]["invoice"]["payout"][
            "signature(s)"] = signatures

        self.contract["vendor_order_confirmation"] = conf_json[
            "vendor_order_confirmation"]
        self.db.Sales().update_status(order_id, 2)
        file_path = DATA_FOLDER + "store/listings/in progress/" + order_id + ".json"
        with open(file_path, 'w') as outfile:
            outfile.write(json.dumps(self.contract, indent=4))
예제 #42
0
    def add_purchase_info(
        self,
        quantity,
        ship_to=None,
        shipping_address=None,
        city=None,
        state=None,
        postal_code=None,
        country=None,
        moderator=None,
        options=None,
    ):
        """
        Update the contract with the buyer's purchase information.
        """

        profile = Profile(self.db).get()
        order_json = {
            "buyer_order": {
                "order": {
                    "ref_hash": digest(json.dumps(self.contract, indent=4)).encode("hex"),
                    "quantity": quantity,
                    "id": {
                        "guid": self.keychain.guid.encode("hex"),
                        "pubkeys": {
                            "guid": self.keychain.guid_signed_pubkey[64:].encode("hex"),
                            "bitcoin": bitcoin.bip32_extract_key(self.keychain.bitcoin_master_pubkey),
                            "encryption": self.keychain.encryption_pubkey.encode("hex"),
                        },
                    },
                    "payment": {},
                }
            }
        }
        if profile.HasField("handle"):
            order_json["buyer_order"]["order"]["id"]["blockchain_id"] = profile.handle
        if self.contract["vendor_offer"]["listing"]["metadata"]["category"] == "physical good":
            order_json["buyer_order"]["order"]["shipping"] = {}
            order_json["buyer_order"]["order"]["shipping"]["ship_to"] = ship_to
            order_json["buyer_order"]["order"]["shipping"]["address"] = shipping_address
            order_json["buyer_order"]["order"]["shipping"]["city"] = city
            order_json["buyer_order"]["order"]["shipping"]["state"] = state
            order_json["buyer_order"]["order"]["shipping"]["postal_code"] = postal_code
            order_json["buyer_order"]["order"]["shipping"]["country"] = country
        if options is not None:
            order_json["buyer_order"]["order"]["options"] = options
        if moderator:  # TODO: Handle direct payments
            chaincode = sha256(str(random.getrandbits(256))).digest().encode("hex")
            order_json["buyer_order"]["order"]["payment"]["chaincode"] = chaincode
            valid_mod = False
            for mod in self.contract["vendor_offer"]["listing"]["moderators"]:
                if mod["guid"] == moderator:
                    order_json["buyer_order"]["order"]["moderator"] = moderator
                    masterkey_m = mod["pubkeys"]["bitcoin"]["key"]
                    valid_mod = True
            if not valid_mod:
                return False
            masterkey_b = bitcoin.bip32_extract_key(self.keychain.bitcoin_master_pubkey)
            masterkey_v = self.contract["vendor_offer"]["listing"]["id"]["pubkeys"]["bitcoin"]
            buyer_key = derive_childkey(masterkey_b, chaincode)
            vendor_key = derive_childkey(masterkey_v, chaincode)
            moderator_key = derive_childkey(masterkey_m, chaincode)

            redeem_script = "75" + bitcoin.mk_multisig_script([buyer_key, vendor_key, moderator_key], 2)
            order_json["buyer_order"]["order"]["payment"]["redeem_script"] = redeem_script
            if self.testnet:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script, 196)
            else:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script)
            order_json["buyer_order"]["order"]["payment"]["address"] = payment_address

        price_json = self.contract["vendor_offer"]["listing"]["item"]["price_per_unit"]
        if "bitcoin" in price_json:
            order_json["buyer_order"]["order"]["payment"]["amount"] = price_json["bitcoin"]
        else:
            currency_code = price_json["fiat"]["currency_code"]
            fiat_price = price_json["fiat"]["price"]
            try:
                request = Request("https://api.bitcoinaverage.com/ticker/" + currency_code.upper() + "/last")
                response = urlopen(request)
                conversion_rate = response.read()
            except URLError:
                return False
            order_json["buyer_order"]["order"]["payment"]["amount"] = float(
                "{0:.8f}".format(float(fiat_price) / float(conversion_rate))
            )

        self.contract["buyer_order"] = order_json["buyer_order"]
        order = json.dumps(self.contract["buyer_order"]["order"], indent=4)
        self.contract["buyer_order"]["signature"] = self.keychain.signing_key.sign(
            order, encoder=nacl.encoding.HexEncoder
        )[:128]

        return self.contract["buyer_order"]["order"]["payment"]["address"]
예제 #43
0
 def get_bip32_private_key(self, path_n, master_key):
     priv = self.bip32_descend(master_key, path_n)
     ret = bitcoin.bip32_extract_key(priv)
     return ret
예제 #44
0
	def get_key(self, mixing_depth, forchange, i):
		return btc.bip32_extract_key(btc.bip32_ckd(self.keys[mixing_depth][forchange], i))
예제 #45
0
    def verify(self, sender_key):
        """
        Validate that an order sent over by a buyer is filled out correctly.
        """

        try:
            contract_dict = json.loads(json.dumps(self.contract, indent=4), object_pairs_hook=OrderedDict)
            del contract_dict["buyer_order"]
            contract_hash = digest(json.dumps(contract_dict, indent=4))

            ref_hash = unhexlify(self.contract["buyer_order"]["order"]["ref_hash"])

            # verify that the reference hash matches the contract and that the contract actually exists
            if contract_hash != ref_hash or not self.db.HashMap().get_file(ref_hash):
                raise Exception("Order for contract that doesn't exist")

            # verify the signature on the order
            verify_key = nacl.signing.VerifyKey(sender_key)
            verify_key.verify(
                json.dumps(self.contract["buyer_order"]["order"], indent=4),
                unhexlify(self.contract["buyer_order"]["signature"]),
            )

            # verify buyer included the correct bitcoin amount for payment
            price_json = self.contract["vendor_offer"]["listing"]["item"]["price_per_unit"]
            if "bitcoin" in price_json:
                asking_price = price_json["bitcoin"]
            else:
                currency_code = price_json["fiat"]["currency_code"]
                fiat_price = price_json["fiat"]["price"]
                request = Request("https://api.bitcoinaverage.com/ticker/" + currency_code.upper() + "/last")
                response = urlopen(request)
                conversion_rate = response.read()
                asking_price = float("{0:.8f}".format(float(fiat_price) / float(conversion_rate)))
            if asking_price > self.contract["buyer_order"]["order"]["payment"]["amount"]:
                raise Exception("Insuffient Payment")

            # verify a valid moderator was selected
            # TODO: handle direct payments
            valid_mod = False
            for mod in self.contract["vendor_offer"]["listing"]["moderators"]:
                if mod["guid"] == self.contract["buyer_order"]["order"]["moderator"]:
                    valid_mod = True
            if not valid_mod:
                raise Exception("Invalid moderator")

            # verify all the shipping fields exist
            if self.contract["vendor_offer"]["listing"]["metadata"]["category"] == "physical good":
                shipping = self.contract["buyer_order"]["order"]["shipping"]
                keys = ["ship_to", "address", "postal_code", "city", "state", "country"]
                for value in map(shipping.get, keys):
                    if value is None:
                        raise Exception("Missing shipping field")

            # verify buyer ID
            pubkeys = self.contract["buyer_order"]["order"]["id"]["pubkeys"]
            keys = ["guid", "bitcoin", "encryption"]
            for value in map(pubkeys.get, keys):
                if value is None:
                    raise Exception("Missing pubkey field")

            # verify redeem script
            chaincode = self.contract["buyer_order"]["order"]["payment"]["chaincode"]
            for mod in self.contract["vendor_offer"]["listing"]["moderators"]:
                if mod["guid"] == self.contract["buyer_order"]["order"]["moderator"]:
                    masterkey_m = mod["pubkeys"]["bitcoin"]["key"]

            masterkey_v = bitcoin.bip32_extract_key(self.keychain.bitcoin_master_pubkey)
            masterkey_b = self.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"]
            buyer_key = derive_childkey(masterkey_b, chaincode)
            vendor_key = derive_childkey(masterkey_v, chaincode)
            moderator_key = derive_childkey(masterkey_m, chaincode)

            redeem_script = "75" + bitcoin.mk_multisig_script([buyer_key, vendor_key, moderator_key], 2)
            if redeem_script != self.contract["buyer_order"]["order"]["payment"]["redeem_script"]:
                raise Exception("Invalid redeem script")

            # verify the payment address
            if self.testnet:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script, 196)
            else:
                payment_address = bitcoin.p2sh_scriptaddr(redeem_script)
            if payment_address != self.contract["buyer_order"]["order"]["payment"]["address"]:
                raise Exception("Incorrect payment address")

            return True

        except Exception:
            return False
예제 #46
0
def load_wallet(wallet_file, get_password_fn):
    """load and if necessary decrypt a bitcoinj wallet file

    :param wallet_file: an open bitcoinj wallet file
    :type wallet_file: file
    :param get_password_fn: a callback returning a password that's called iff one is required
    :type get_password_fn: function
    :return: the Wallet protobuf message or None if no password was entered when required
    :rtype: wallet_pb2.Wallet
    """

    wallet_file.seek(0)
    magic_bytes = wallet_file.read(12)
    
    wallet_file.seek(0, os.SEEK_END)
    wallet_size = wallet_file.tell()
    wallet_file.seek(0)

    if magic_bytes[2:6] != b"org." and wallet_size % 16 == 0:
        import pylibscrypt
        takes_long = not pylibscrypt._done  # if a binary library wasn't found, this'll take a while

        ciphertext = wallet_file.read()
        assert len(ciphertext) % 16 == 0

        password = get_password_fn(takes_long)
        if not password:
            return None

        # Derive the encryption key
        salt = '\x35\x51\x03\x80\x75\xa3\xb0\xc5'
        key  = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32)

        # Decrypt the wallet ( v0.5.0+ )
        try:
            plaintext = aes256_cbc_decrypt(ciphertext[16:], key, ciphertext[:16])
            if plaintext[2:6] != b"org.":
                raise ValueError('incorrect password')
        except ValueError as e:
            if e.args[0] == 'incorrect password':

                # Decrypt the wallet ( < v0.5.0 )
                iv = '\xa3\x44\x39\x1f\x53\x83\x11\xb3\x29\x54\x86\x16\xc4\x89\x72\x3e'
                plaintext = aes256_cbc_decrypt(ciphertext, key, iv)

        global multibit_hd_password
        multibit_hd_password = password

    # Else it's not whole-file encrypted
    else:
        password  = None
        plaintext = wallet_file.read()

    # Parse the wallet protobuf
    pb_wallet = wallet_pb2.Wallet()
    try:
        pb_wallet.ParseFromString(plaintext)
    except Exception as e:
        msg = 'not a wallet file: ' + str(e)
        if password:
            msg = "incorrect password (or " + msg + ")"
        raise ValueError(msg)
    
    f = open('parsed_wallet.txt','w')
    f.write(pb_wallet.__str__())
    f.close()
    
    foundAddr = []
    
    for trans in pb_wallet.transaction:
      if trans.pool == 4:
        print("--------------------------------------------------------------------------------")
        print("TXID: " + binascii.hexlify(trans.hash))
        for out in trans.transaction_output:
          print("")
          faddr = bitcoin.bin_to_b58check(bitcoin.deserialize_script(out.script_bytes)[2])
          print("Addr: " + faddr)
          foundAddr.append(faddr)
          print("Amt: " + str(out.value * 0.00000001) + " BTC")
        print("")
        print("--------------------------------------------------------------------------------")
    
    seed = None
    
    sys.stdout.write('Finding Seed....')
    
    salt = pb_wallet.encryption_parameters.salt
    dkey = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32)
    
    for wkey in pb_wallet.key:
      if wkey.type == 3:
        seed = aes256_cbc_decrypt(wkey.encrypted_deterministic_seed.encrypted_private_key, dkey, wkey.encrypted_deterministic_seed.initialisation_vector)
        break
        
    if not seed:
      print("No DETERMINISTIC_MNEMONIC seed found!")
      return None
    else:
      print("Done!")
    xprv = bitcoin.bip32_master_key(seed)
    
    xprvReceive = bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 2**31),0) #m/0'/0
    xprvChange = bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 2**31),1) #m/0'/1
    
    rcvAddr = []
    chgAddr = []
    rcvPrivKey = []
    chgPrivKey = []
    
    sys.stdout.write("Generating Addresses/Keys.")
    for x in range(0,1000):
      if x % 10 == 0:
        sys.stdout.write(".")
      childprivReceive = bitcoin.bip32_ckd(xprvReceive, x)
      childprivChange = bitcoin.bip32_ckd(xprvChange, x)
      
      pkeyReceive = bitcoin.bip32_extract_key(childprivReceive)
      pkeyChange = bitcoin.bip32_extract_key(childprivChange)
      
      #addressReceive = privtoaddr(pkeyReceive)
      #addressChange = privtoaddr(pkeyChange)
      rcvAddr.append(bitcoin.privtoaddr(pkeyReceive))
      chgAddr.append(bitcoin.privtoaddr(pkeyChange))
      
      rcvPrivKey.append(bitcoin.encode_privkey(pkeyReceive, 'wif_compressed'))
      chgPrivKey.append(bitcoin.encode_privkey(pkeyChange, 'wif_compressed'))
    print("Done!")  
    
    print("--------------------------------------------------------------------------------")
    
    for addy in foundAddr:
      if addy in rcvAddr:
        print("")
        print("Found Address: " + addy)
        print("PrivateKey: " + rcvPrivKey[rcvAddr.index(addy)])
      elif addy in chgAddr:
        print("")
        print("Found Change Address: " + addy)
        print("PrivateKey: " + chgPrivKey[chgAddr.index(addy)])
      else:
        print("")
        print("Address not found: " + addy)
    
    print("")
    print("--------------------------------------------------------------------------------")
      
    return pb_wallet
예제 #47
0
    def create(
        self,
        expiration_date,
        metadata_category,
        title,
        description,
        currency_code,
        price,
        process_time,
        nsfw,
        shipping_origin=None,
        shipping_regions=None,
        est_delivery_domestic=None,
        est_delivery_international=None,
        terms_conditions=None,
        returns=None,
        keywords=None,
        category=None,
        condition=None,
        sku=None,
        images=None,
        free_shipping=None,
        shipping_currency_code=None,
        shipping_domestic=None,
        shipping_international=None,
        options=None,
        moderators=None,
    ):
        """
        All parameters are strings except:

        :param expiration_date: `string` (must be formatted UTC datetime)
        :param keywords: `list`
        :param nsfw: `boolean`
        :param images: a `list` of image files
        :param free_shipping: `boolean`
        :param shipping_origin: a 'string' formatted `CountryCode`
        :param shipping_regions: a 'list' of 'string' formatted `CountryCode`s
        :param options: a 'dict' containing options as keys and 'list' as option values.
        :param moderators: a 'list' of 'string' guids (hex encoded).
        """

        profile = Profile(self.db).get()
        self.contract = OrderedDict(
            {
                "vendor_offer": {
                    "listing": {
                        "metadata": {
                            "version": "0.1",
                            "category": metadata_category.lower(),
                            "category_sub": "fixed price",
                        },
                        "id": {
                            "guid": self.keychain.guid.encode("hex"),
                            "pubkeys": {
                                "guid": self.keychain.guid_signed_pubkey[64:].encode("hex"),
                                "bitcoin": bitcoin.bip32_extract_key(self.keychain.bitcoin_master_pubkey),
                                "encryption": self.keychain.encryption_pubkey.encode("hex"),
                            },
                        },
                        "item": {
                            "title": title,
                            "description": description,
                            "process_time": process_time,
                            "price_per_unit": {},
                            "nsfw": nsfw,
                        },
                    }
                }
            }
        )
        if expiration_date.lower() == "never":
            self.contract["vendor_offer"]["listing"]["metadata"]["expiry"] = "never"
        else:
            self.contract["vendor_offer"]["listing"]["metadata"]["expiry"] = expiration_date + " UTC"
        if metadata_category == "physical good" and condition is not None:
            self.contract["vendor_offer"]["listing"]["item"]["condition"] = condition
        if currency_code.upper() == "BTC":
            item = self.contract["vendor_offer"]["listing"]["item"]
            item["price_per_unit"]["bitcoin"] = price
        else:
            item = self.contract["vendor_offer"]["listing"]["item"]
            item["price_per_unit"]["fiat"] = {}
            item["price_per_unit"]["fiat"]["price"] = price
            item["price_per_unit"]["fiat"]["currency_code"] = currency_code
        if keywords is not None:
            self.contract["vendor_offer"]["listing"]["item"]["keywords"] = []
            self.contract["vendor_offer"]["listing"]["item"]["keywords"].extend(keywords)
        if category is not None:
            self.contract["vendor_offer"]["listing"]["item"]["category"] = category
        if sku is not None:
            self.contract["vendor_offer"]["listing"]["item"]["sku"] = sku
        if options is not None:
            self.contract["vendor_offer"]["listing"]["item"]["options"] = options
        if metadata_category == "physical good":
            self.contract["vendor_offer"]["listing"]["shipping"] = {}
            shipping = self.contract["vendor_offer"]["listing"]["shipping"]
            shipping["shipping_origin"] = shipping_origin
            if free_shipping is False:
                self.contract["vendor_offer"]["listing"]["shipping"]["free"] = False
                self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"] = {}
                if shipping_currency_code == "BTC":
                    self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"]["bitcoin"] = {}
                    self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"]["bitcoin"][
                        "domestic"
                    ] = shipping_domestic
                    self.contract["vendor_offer"]["listing"]["shipping"]["flat_fee"]["bitcoin"][
                        "international"
                    ] = shipping_international
                else:
                    shipping = self.contract["vendor_offer"]["listing"]["shipping"]
                    shipping["flat_fee"]["fiat"] = {}
                    shipping["flat_fee"]["fiat"]["price"] = {}
                    shipping["flat_fee"]["fiat"]["price"]["domestic"] = shipping_domestic
                    shipping["flat_fee"]["fiat"]["price"]["international"] = shipping_international
                    shipping["flat_fee"]["fiat"]["currency_code"] = shipping_currency_code
            else:
                self.contract["vendor_offer"]["listing"]["shipping"]["free"] = True
            self.contract["vendor_offer"]["listing"]["shipping"]["shipping_regions"] = []
            for region in shipping_regions:
                shipping = self.contract["vendor_offer"]["listing"]["shipping"]
                shipping["shipping_regions"].append(region)
            listing = self.contract["vendor_offer"]["listing"]
            listing["shipping"]["est_delivery"] = {}
            listing["shipping"]["est_delivery"]["domestic"] = est_delivery_domestic
            listing["shipping"]["est_delivery"]["international"] = est_delivery_international
        if profile.HasField("handle"):
            self.contract["vendor_offer"]["listing"]["id"]["blockchain_id"] = profile.handle
        if images is not None:
            self.contract["vendor_offer"]["listing"]["item"]["image_hashes"] = []
            for image_hash in images:
                self.contract["vendor_offer"]["listing"]["item"]["image_hashes"].append(image_hash)
        if terms_conditions is not None or returns is not None:
            self.contract["vendor_offer"]["listing"]["policy"] = {}
            if terms_conditions is not None:
                self.contract["vendor_offer"]["listing"]["policy"]["terms_conditions"] = terms_conditions
            if returns is not None:
                self.contract["vendor_offer"]["listing"]["policy"]["returns"] = returns
        if moderators is not None:
            self.contract["vendor_offer"]["listing"]["moderators"] = []
            for mod in moderators:
                mod_info = self.db.ModeratorStore().get_moderator(unhexlify(mod))
                print mod_info
                if mod_info is not None:
                    moderator = {
                        "guid": mod,
                        "blockchain_id": mod_info[6],
                        "pubkeys": {
                            "signing": {
                                "key": mod_info[1][64:].encode("hex"),
                                "signature": mod_info[1][:64].encode("hex"),
                            },
                            "encryption": {"key": mod_info[2].encode("hex"), "signature": mod_info[3].encode("hex")},
                            "bitcoin": {"key": mod_info[4].encode("hex"), "signature": mod_info[5].encode("hex")},
                        },
                    }
                    self.contract["vendor_offer"]["listing"]["moderators"].append(moderator)

        listing = json.dumps(self.contract["vendor_offer"]["listing"], indent=4)
        self.contract["vendor_offer"]["signature"] = self.keychain.signing_key.sign(
            listing, encoder=nacl.encoding.HexEncoder
        )[:128]
        self.save()