Пример #1
0
    def __init__(self,
                 network,
                 contract: str,
                 raw_transaction: Optional[str] = None,
                 transaction_address: Optional[str] = None):

        if not raw_transaction and not transaction_address:
            raise ValueError(
                'Provide raw_transaction or transaction_address argument.')

        self.network = network
        self.symbol = self.network.default_symbol
        self.contract = contract
        self.tx = None
        self.vout = None
        self.confirmations = None
        self.tx_address = transaction_address
        if raw_transaction:
            self.tx = self.network.deserialize_raw_transaction(raw_transaction)
            try:
                self.vout = self.tx.vout[0]
            except IndexError:
                raise ValueError('Given transaction has no outputs.')
        else:
            tx_json = self.network.get_transaction(transaction_address)
            if not tx_json:
                raise ValueError('No transaction found under given address.')

            self.vout = self.network.get_first_vout_from_tx_json(tx_json)
            self.confirmations = self.network.get_confirmations_from_tx_json(
                tx_json)

        if not self.vout:
            raise ValueError('Given transaction has no outputs.')

        contract_tx_out = self.vout
        contract_script = script.CScript.fromhex(self.contract)
        script_pub_key = contract_script.to_p2sh_scriptPubKey()
        valid_p2sh = script_pub_key == contract_tx_out.scriptPubKey
        self.address = str(CBitcoinAddress.from_scriptPubKey(script_pub_key))
        try:
            self.balance = self.network.get_balance(self.address)
        except NotImplementedError:
            self.balance = None

        script_ops = list(contract_script)
        if valid_p2sh and self.is_valid_contract_script(script_ops):
            self.recipient_address = str(
                P2PKHBitcoinAddress.from_bytes(script_ops[6]))
            self.refund_address = str(
                P2PKHBitcoinAddress.from_bytes(script_ops[13]))
            self.locktime_timestamp = int.from_bytes(script_ops[8],
                                                     byteorder='little')
            self.locktime = datetime.utcfromtimestamp(self.locktime_timestamp)
            self.secret_hash = b2x(script_ops[2])
            self.value = from_base_units(contract_tx_out.nValue)
        else:
            raise ValueError('Given transaction is not a valid contract.')
Пример #2
0
def get_radd_from_pub(pub):
    try:
        taker_addr = str(P2PKHBitcoinAddress.from_pubkey(x("02"+pub)))
    except:
        try:
            taker_addr = str(P2PKHBitcoinAddress.from_pubkey(x("03"+pub)))
        except:
            pass
        taker_addr = pub
        pass
    return str(taker_addr)
Пример #3
0
    def redeem_contract(self, contract, secret):
        print("Parsing script for redeem_contract...")
        scriptarray = self.parse_script(contract.redeemScript)
        redeemblocknum = scriptarray[8]
        redeemPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[6]))
        refundPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[13]))
        p2sh = contract.p2sh
        #checking there are funds in the address
        amount = self.check_funds(p2sh)
        if(amount == 0):
            print("address ", p2sh, " not funded")
            quit()
        fundtx = self.find_transaction_to_address(p2sh)
        amount = fundtx['amount'] / COIN
        # print("Found fund_tx: ", fundtx)
        p2sh = P2SHBitcoinAddress(p2sh)
        if fundtx['address'] == p2sh:
            print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh))

            blockcount = self.bitcoind.getblockcount()
            print("\nCurrent blocknum at time of redeem on Zcash:", blockcount)
            if blockcount < int(redeemblocknum):
                print('redeemPubKey', redeemPubKey)
                zec_redeemScript = CScript(x(contract.redeemScript))
                txin = CMutableTxIn(fundtx['outpoint'])
                txout = CMutableTxOut(fundtx['amount'] - FEE, redeemPubKey.to_scriptPubKey())
                # Create the unsigned raw transaction.
                tx = CMutableTransaction([txin], [txout])
                sighash = SignatureHash(zec_redeemScript, tx, 0, SIGHASH_ALL)
                # TODO: protect privkey better, separate signing from rawtx creation
                privkey = self.bitcoind.dumpprivkey(redeemPubKey)
                sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
                preimage = secret.encode('utf-8')
                txin.scriptSig = CScript([sig, privkey.pub, preimage, OP_TRUE, zec_redeemScript])

                # print("txin.scriptSig", b2x(txin.scriptSig))
                txin_scriptPubKey = zec_redeemScript.to_p2sh_scriptPubKey()
                print('Raw redeem transaction hex: ', b2x(tx.serialize()))
                VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,))
                print("Script verified, sending raw transaction...")
                txid = self.bitcoind.sendrawtransaction(tx)
                fund_tx = str(fundtx['outpoint'])
                redeem_tx =  b2x(lx(b2x(txid)))
                return  {"redeem_tx": redeem_tx, "fund_tx": fund_tx}
            else:
                print("nLocktime exceeded, refunding")
                print('refundPubKey', refundPubKey)
                txid = self.bitcoind.sendtoaddress(refundPubKey, fundtx['amount'] - FEE)
                fund_tx = str(fundtx['outpoint'])
                refund_tx =  b2x(lx(b2x(txid)))
                return  {"refund_tx": refund_tx, "fund_tx": fund_tx}
        else:
            print("No contract for this p2sh found in database", p2sh)
Пример #4
0
def get_radd_from_pub(pub):
    try:
        taker_addr = str(P2PKHBitcoinAddress.from_pubkey(x("02"+pub)))
    except Exception as e:
        print(e)
        try:
            taker_addr = str(P2PKHBitcoinAddress.from_pubkey(x("03"+pub)))
        except Exception as e:
            print(e)
            taker_addr = pub
            pass
        pass
    return str(taker_addr)
Пример #5
0
def get_radd_from_pub(pub):
    try:
        addr = str(P2PKHBitcoinAddress.from_pubkey(x(pub)))
    except Exception as e:
        try:
            addr = str(P2PKHBitcoinAddress.from_pubkey(x(pub)))
        except Exception as e:
            print(colorize(str(e) + ": " + pub, 'red'))
            print(e)
            addr = pub
            pass
        pass
    return str(addr)
Пример #6
0
def mock_listunspent_mainnet(self, addrs):
    output1 = {
        'outpoint':
        COutPoint(
            lx('34eb81bc0d1a822369f75174fd4916b1ec490d8fbcba33168e820cc78a52f608'
               ), 0),
        'confirmations':
        123,
        'address':
        P2PKHBitcoinAddress('13yNf3azc8sUrjf6UFjUCRZx4B6JnQ4XeJ'),
        'spendable':
        False,
        'amount':
        6342,
        'solvable':
        False,
        'scriptPubKey':
        CScript([
            OP_DUP, OP_HASH160,
            x('cc0a909c4c83068be8b45d69b60a6f09c2be0fda'), OP_EQUALVERIFY,
            OP_CHECKSIG
        ]),
        'account':
        ''
    }
    output2 = {
        'address':
        P2PKHBitcoinAddress('13yNf3azc8sUrjf6UFjUCRZx4B6JnQ4XeJ'),
        'amount':
        2750,
        'account':
        '',
        'spendable':
        False,
        'solvable':
        False,
        'confirmations':
        456,
        'outpoint':
        COutPoint(
            lx('6773785b4dc5d2cced67d26fc0820329307a8e10dfaef50d506924984387bf0b'
               ), 1),
        'scriptPubKey':
        CScript([
            OP_DUP, OP_HASH160,
            x('cc0a909c4c83068be8b45d69b60a6f09c2be0fda'), OP_EQUALVERIFY,
            OP_CHECKSIG
        ])
    }
    unspent_outputs = [output1, output2]
    return unspent_outputs
Пример #7
0
def get_public_addresses(key_file):
    keys = read_keys(key_file)
    bitcoin_secrets = [CBitcoinSecret(key) for key in keys]
    bitcoin_addresses = [
        P2PKHBitcoinAddress.from_pubkey(key.pub) for key in bitcoin_secrets
    ]
    return bitcoin_addresses
Пример #8
0
    def redeem_contract(self, contract, secret):
        print("Parsing script for redeem_contract...")
        scriptarray = self.parse_script(contract.redeemScript)
        redeemblocknum = scriptarray[8]
        self.redeemPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[6]))
        # refundPubKey = P2PKHBitcoinAddress.from_bytes(x(scriptarray[13]))
        p2sh = contract.p2sh
        # checking there are funds in the address
        amount = self.check_funds(p2sh)
        if(amount == 0):
            print("address ", p2sh, " not funded")
            quit()
        fundtx = self.find_transaction_to_address(p2sh)
        amount = fundtx['amount'] / COIN
        # print("Found fund_tx: ", fundtx)
        p2sh = P2SHBitcoinAddress(p2sh)
        if fundtx['address'] == p2sh:
            print("Found {0} in p2sh {1}, redeeming...".format(amount, p2sh))

            blockcount = self.bitcoind.getblockcount()
            print("\nCurrent blocknum at time of redeem on Bitcoin:", blockcount)
            if blockcount < int(redeemblocknum):
                return self.redeem(contract, fundtx, secret)
            else:
                print("nLocktime exceeded, refunding")
                return self.refund(contract)
        else:
            print("No contract for this p2sh found in database", p2sh)
Пример #9
0
def privkey_to_address(privkey):
    try:
        key = CBitcoinSecret(privkey)
        address = str(P2PKHBitcoinAddress.from_pubkey(key.pub))
    except:
        return False
    return address
Пример #10
0
 def get_wallet_unspent_fastgraph_transactions(self, address):
     result = [
         x for x in self.mongo.db.fastgraph_transactions.find(
             {'txn.outputs.to': address})
     ]
     reverse_public_key = None
     for x in result:
         xaddress = str(
             P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(
                 x['public_key'])))
         if xaddress == address:
             reverse_public_key = x['public_key']
             break
     if not reverse_public_key:
         for x in result:
             yield x['txn']
         return
     for x in result:
         spent_on_fastgraph = self.mongo.db.fastgraph_transactions.find({
             'public_key':
             reverse_public_key,
             'txn.inputs.id':
             x['id']
         })
         spent_on_blockchain = self.mongo.db.blocks.find({
             'public_key':
             reverse_public_key,
             'transactions.inputs.id':
             x['id']
         })
         if not spent_on_fastgraph.count(
         ) and not spent_on_blockchain.count():
             # x['txn']['height'] = x['height'] # TODO: make height work for frastgraph transactions so we can order messages etc.
             yield x['txn']
Пример #11
0
def calc_addr_from_pubkey(coin, pubkey):
    bitcoin.params = COIN_PARAMS[coin]
    try:
        return str(P2PKHBitcoinAddress.from_pubkey(x(pubkey)))
    except Exception as e:
        logger.error(f"[calc_addr_from_pubkey] Exception: {e}")
        return {"error": str(e)}
Пример #12
0
    async def collect_needed_inputs(self, input_obj, input_txn, my_address,
                                    input_sum, inputs, outputs_and_fee_total):

        if isinstance(input_obj, ExternalInput):
            await input_txn.verify()
            address = str(
                P2PKHBitcoinAddress.from_pubkey(
                    bytes.fromhex(input_txn.public_key)))
        else:
            address = my_address

        for txn_output in input_txn.outputs:
            if txn_output.to == address and float(txn_output.value) > 0.0:
                fix1 = fix_float1(txn_output.value)
                fix2 = fix_float2(txn_output.value)
                fixtotal1 = fix_float1(outputs_and_fee_total)
                fixtotal2 = fix_float2(outputs_and_fee_total)
                if (self.exact_match and fix1 != fixtotal1
                        and fix2 != fixtotal2):
                    continue
                input_sum += txn_output.value

                if input_txn not in inputs:
                    inputs.append(input_obj)

                if input_sum >= outputs_and_fee_total:
                    return input_sum
        return input_sum
Пример #13
0
    def from_dict(cls, config):
        cls.seed = config.get('seed', '')
        cls.xprv = config.get('xprv', '')
        cls.username = config.get('username', '')
        cls.public_key = config.get('public_key')
        cls.address = str(
            P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(cls.public_key)))

        cls.private_key = config.get('private_key')
        cls.wif = cls.to_wif(cls.private_key)
        cls.bulletin_secret = cls.get_bulletin_secret()

        cls.mongodb_host = config.get('mongodb_host')
        cls.database = config.get('database')
        cls.site_database = config.get('site_database')
        cls.web_server_host = config.get('web_server_host')
        cls.web_server_port = config.get('web_server_port')
        if config.get('peer_host') == '0.0.0.0' or config.get(
                'peer_host') == 'localhost':
            raise Exception(
                "cannot use localhost or 0.0.0.0, must specify public ipv4 address"
            )
        if config.get('peer_host') == '[my public ip]':
            raise Exception(
                "please configure your peer_post to your public ipv4 address")
        cls.peer_host = config.get('peer_host')
        cls.peer_port = config.get('peer_port')
        cls.serve_host = config.get('serve_host')
        cls.serve_port = config.get('serve_port')
        cls.callbackurl = config.get('callbackurl')
        cls.fcm_key = config.get('fcm_key')
Пример #14
0
def calc_addr_tool(pubkey, pubtype, p2shtype, wiftype):
    class CoinParams(CoreMainParams):
        MESSAGE_START = b'\x24\xe9\x27\x64'
        DEFAULT_PORT = 7770
        BASE58_PREFIXES = {
            'PUBKEY_ADDR': int(pubtype),
            'SCRIPT_ADDR': int(p2shtype),
            'SECRET_KEY': int(wiftype)
        }

    bitcoin.params = CoinParams

    try:
        address = str(P2PKHBitcoinAddress.from_pubkey(x(pubkey)))
        return {
            "pubkey": pubkey,
            "pubtype": pubtype,
            "p2shtype": p2shtype,
            "wiftype": wiftype,
            "address": address
        }

    except Exception as e:
        logger.error(f"[calc_addr_tool] Exception: {e}")
        return {"error": str(e)}
Пример #15
0
 def _find_payment(self, msg, txid, txtype):
     """ search ix/tx for transaction matching current address """
     addr = None
     value = 0
     refund = 0
     for vout in msg.tx.vout:
         try:
             addr = str(P2PKHBitcoinAddress.from_scriptPubKey(vout.scriptPubKey))
         except CBitcoinAddressError:
             continue
         if addr == self.current_address:
             value = int(vout.nValue)
             break
     # current address received something
     if addr and value:
         # calculate under/overpay refund
         if value < self.vend.cost:
             refund = AmountToJSON(value)
         elif value > self.vend.cost:
             refund = AmountToJSON(value - self.vend.cost)
         if txid not in self.mempool:
             self.mempool[txid] = {}
         # set transaction type, tx refund
         self.mempool[txid][txtype] = True
         if txtype == "tx":
             tx = self.mempool[txid]["processed"]
             tx["refund"] = AmountToJSON(tx["value"])
         self.mempool[txid]["processed"] = {
             "addr": addr,
             "value": value,
             "refund": refund,
             "sale": (value >= self.vend.cost and True or False),
         }
         self.vend.get_next_address(increment=True)
         return True
Пример #16
0
def privkey_to_address(privkey):
    try:
        key = CBitcoinSecret(privkey)
        address = str(P2PKHBitcoinAddress.from_pubkey(key.pub))
    except:
        return False
    return address
Пример #17
0
def VerifyMessage(address, message, sig):
    sig = base64.b64decode(sig)
    hash = message.GetHash()

    pubkey = CPubKey.recover_compact(hash, sig)

    return str(P2PKHBitcoinAddress.from_pubkey(pubkey)) == str(address)
Пример #18
0
 def save(self):
     self.verify()
     for txn in self.transactions:
         if txn.inputs:
             address = str(
                 P2PKHBitcoinAddress.from_pubkey(
                     txn.public_key.decode('hex')))
             unspent = BU.get_wallet_unspent_transactions(
                 self.config, self.mongo, address,
                 [x.id for x in txn.inputs])
             unspent_ids = [x['id'] for x in unspent]
             failed = False
             used_ids_in_this_txn = []
             for x in txn.inputs:
                 if x.id not in unspent_ids:
                     failed = True
                 if x.id in used_ids_in_this_txn:
                     failed = True
                 used_ids_in_this_txn.append(x.id)
             if failed:
                 raise BaseException('double spend',
                                     [x.id for x in txn.inputs])
     res = self.mongo.db.blocks.find({"index": (int(self.index) - 1)})
     if res.count() and res[0]['hash'] == self.prev_hash or self.index == 0:
         self.mongo.db.blocks.insert(self.to_dict())
     else:
         print "CRITICAL: block rejected..."
Пример #19
0
    def from_dict(cls, config):
        cls.public_key = config['public_key']
        cls.address = str(
            P2PKHBitcoinAddress.from_pubkey(cls.public_key.decode('hex')))

        cls.private_key = config['private_key']
        cls.username = config['username']
        cls.wif = cls.to_wif()
        cipher = Crypt(str(cls.private_key))
        cls.bulletin_secret = cls.get_bulletin_secret()

        cls.mongodb_host = config['mongodb_host']
        cls.database = config['database']
        cls.site_database = config['site_database']
        cls.web_server_host = config['web_server_host']
        cls.web_server_port = config['web_server_port']
        if config['peer_host'] == '0.0.0.0' or config[
                'peer_host'] == 'localhost':
            raise Exception(
                "cannot use localhost or 0.0.0.0, must specify public ipv4 address"
            )
        if config['peer_host'] == '[my public ip]':
            raise Exception(
                "please configure your peer_post to your public ipv4 address")
        cls.peer_host = config['peer_host']
        cls.peer_port = config['peer_port']
        cls.serve_host = config['serve_host']
        cls.serve_port = config['serve_port']
        cls.callbackurl = config['callbackurl']
        cls.fcm_key = config['fcm_key']
Пример #20
0
    async def from_dict(cls, block):
        transactions = []
        for txn in block.get('transactions'):
            # TODO: do validity checking for coinbase transactions
            if str(P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(block.get('public_key')))) in [x['to'] for x in txn.get('outputs', '')] and len(txn.get('outputs', '')) == 1 and not txn.get('inputs') and not txn.get('relationship'):
                txn['coinbase'] = True  
            else:
                txn['coinbase'] = False
            transactions.append(Transaction.from_dict(txn))

        if block.get('special_target', 0) == 0:
            block['special_target'] = block.get('target')

        return await cls.init_async(
            version=block.get('version'),
            block_time=block.get('time'),
            block_index=block.get('index'),
            public_key=block.get('public_key'),
            prev_hash=block.get('prevHash'),
            nonce=block.get('nonce'),
            transactions=transactions,
            block_hash=block.get('hash'),
            merkle_root=block.get('merkleRoot'),
            signature=block.get('id'),
            special_min=block.get('special_min'),
            header=block.get('header', ''),
            target=int(block.get('target'), 16),
            special_target=int(block.get('special_target', 0), 16)
        )
Пример #21
0
    def from_dict(cls, config, mongo, block):
        transactions = []
        for txn in block.get('transactions'):
            # TODO: do validify checking for coinbase transactions
            if str(
                    P2PKHBitcoinAddress.from_pubkey(
                        block.get('public_key').decode('hex'))) in [
                            x['to'] for x in txn.get('outputs', '')
                        ] and len(
                            txn.get('outputs',
                                    '')) == 1 and not txn.get('relationship'):
                txn['coinbase'] = True
            else:
                txn['coinbase'] = False
            if 'signatures' in txn:
                transactions.append(FastGraph.from_dict(config, mongo, txn))
            else:
                transactions.append(Transaction.from_dict(config, mongo, txn))

        return cls(config=config,
                   mongo=mongo,
                   version=block.get('version'),
                   block_time=block.get('time'),
                   block_index=block.get('index'),
                   public_key=block.get('public_key'),
                   prev_hash=block.get('prevHash'),
                   nonce=block.get('nonce'),
                   transactions=transactions,
                   block_hash=block.get('hash'),
                   merkle_root=block.get('merkleRoot'),
                   signature=block.get('id'),
                   special_min=block.get('special_min'),
                   target=int(block.get('target'), 16))
Пример #22
0
    def __init__(self, config):
        self.seed = config.get('seed', '')
        self.xprv = config.get('xprv', '')
        self.username = config.get('username', '')
        self.public_key = config.get('public_key')
        self.address = str(
            P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(self.public_key)))

        self.private_key = config.get('private_key')
        self.wif = self.to_wif(self.private_key)
        self.bulletin_secret = self.inst_get_bulletin_secret()

        self.mongodb_host = config.get('mongodb_host')
        self.database = config.get('database')
        self.site_database = config.get('site_database')
        self.web_server_host = config.get('web_server_host')
        self.web_server_port = config.get('web_server_port')
        if config.get('peer_host') == '0.0.0.0' or config.get(
                'peer_host') == 'localhost':
            raise Exception(
                "cannot use localhost or 0.0.0.0, must specify public ipv4 address"
            )
        if config.get('peer_host') == '[my public ip]':
            raise Exception(
                "please configure your peer_post to your public ipv4 address")
        self.peer_host = config.get('peer_host')
        self.peer_port = config.get('peer_port')
        self.serve_host = config.get('serve_host')
        self.serve_port = config.get('serve_port')
        self.callbackurl = config.get('callbackurl')
        self.fcm_key = config.get('fcm_key')
Пример #23
0
    def from_dict(cls, config):
        from transactionutils import TU
        cls.seed = config.get('seed', '')
        cls.xprv = config.get('xprv', '')
        cls.username = config.get('username', '')
        cls.network = config.get('network', 'mainnet')
        cls.public_key = config['public_key']
        cls.address = str(P2PKHBitcoinAddress.from_pubkey(cls.public_key.decode('hex')))

        cls.private_key = config['private_key']
        cls.wif = cls.generate_wif(cls.private_key)
        cls.bulletin_secret = TU.generate_deterministic_signature(config, config['username'], config['private_key'])

        cls.mongodb_host = config['mongodb_host']
        cls.database = config['database']
        cls.site_database = config['site_database']
        cls.web_server_host = config['web_server_host']
        cls.web_server_port = config['web_server_port']
        if config['peer_host'] == '0.0.0.0' or config['peer_host'] == 'localhost':
            raise Exception("cannot use localhost or 0.0.0.0, must specify public ipv4 address")
        if config['peer_host'] == '[my public ip]':
            raise Exception("please configure your peer_post to your public ipv4 address")
        cls.peer_host = config['peer_host']
        cls.peer_port = config['peer_port']
        cls.serve_host = config['serve_host']
        cls.serve_port = config['serve_port']
        cls.callbackurl = config['callbackurl']
        cls.fcm_key = config['fcm_key']
Пример #24
0
 async def recover_missing_transaction(self, txn_id, exclude_ids=[]):
     return False
     if await self.config.mongo.async_db.failed_recoveries.find_one({'txn_id': txn_id}):
         return False
     self.app_log.warning("recovering missing transaction input: {}".format(txn_id))
     address = str(P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(self.public_key)))
     missing_txns = self.config.mongo.async_db.blocks.aggregate([
         {
             '$unwind': '$transactions'
         },
         {
             '$project': {
                 'transaction': '$transactions',
                 'index': '$index'
             }
         }
     ], allowDiskUse=True)
     async for missing_txn in missing_txns:
         self.app_log.warning('recovery searching block index: {}'.format(missing_txn['index']))
         try:
             result = verify_signature(base64.b64decode(txn_id), missing_txn['transaction']['hash'].encode(),
                                     bytes.fromhex(self.public_key))
             if result:
                 block_index = await self.find_unspent_missing_index(missing_txn['transaction']['hash'], exclude_ids)
                 if block_index:
                     await self.replace_missing_transaction_input(
                         block_index,
                         missing_txn['transaction']['hash'],
                         txn_id
                     )
                     return True
             else:
                 if len(base64.b64decode(txn_id)) != 65:
                     continue
                 result = VerifyMessage(
                     address,
                     BitcoinMessage(missing_txn['transaction']['hash'], magic=''),
                     txn_id
                 )
                 if result:
                     block_index = await self.find_unspent_missing_index(missing_txn['transaction']['hash'], exclude_ids)
                     if block_index:
                         await self.replace_missing_transaction_input(
                             block_index,
                             missing_txn['transaction']['hash'],
                             txn_id
                         )
                         return True
         except:
             continue
     await self.config.mongo.async_db.failed_recoveries.update_one({
         'txn_id': txn_id
     },
     {
         '$set': {
             'txn_id': txn_id
         }
     }, upsert=True)
     return False
Пример #25
0
 def get_coinbase(self):
     for txn in self.transactions:
         if str(
                 P2PKHBitcoinAddress.from_pubkey(
                     self.public_key.decode('hex'))) in [
                         x.to for x in txn.outputs
                     ] and len(txn.outputs) == 1 and not txn.relationship:
             return txn
Пример #26
0
    def verify(self):
        super(FastGraph, self).verify()
        result = self.mongo.db.fastgraph_transactions.find_one({
            'txn.hash': self.hash
        })
        
        if not self.signatures:
            raise InvalidFastGraphTransactionException('no signatures were provided')

        xaddress = str(P2PKHBitcoinAddress.from_pubkey(self.public_key.decode('hex')))
        unspent = [x['id'] for x in BU.get_wallet_unspent_transactions(self.config, self.mongo, xaddress)]
        unspent_fastgraph = [x['id'] for x in BU.get_wallet_unspent_fastgraph_transactions(self.config, self.mongo, xaddress)]
        inputs = [x.id for x in self.inputs]
        if len(set(inputs) & set(unspent)) != len(inputs) and len(set(inputs) & set(unspent_fastgraph)) != len(inputs):
            raise InvalidFastGraphTransactionException('Input not found in unspent')

        txn_for_rids = self.get_origin_relationship()
        if not txn_for_rids:
            raise InvalidFastGraphTransactionException('no origin transactions found')
        public_key = txn_for_rids['public_key']

        for signature in self.signatures:
            signature.passed = False
            signed = verify_signature(
                base64.b64decode(signature.signature),
                self.hash,
                public_key.decode('hex')
            )
            if signed:
                signature.passed = True

            """
            # This is for a later fork to include a wider consensus area for a larger spending group
            else:
                mutual_friends = [x for x in BU.get_transactions_by_rid(self.config, self.mongo, self.rid, self.config.bulletin_secret, raw=True, rid=True, lt_block_height=highest_height)]
                for mutual_friend in mutual_friends:
                    mutual_friend = Transaction.from_dict(self.config, self.mongo, mutual_friend)
                    if isinstance(mutual_friend.relationship, Relationship) and signature.bulletin_secret == mutual_friend.relationship.their_bulletin_secret:
                        other_mutual_friend = mutual_friend
                for mutual_friend in mutual_friends:
                    mutual_friend = Transaction.from_dict(self.config, self.mongo, mutual_friend)
                    if mutual_friend.public_key != self.config.public_key:
                        identity = verify_signature(
                            base64.b64decode(other_mutual_friend.relationship.their_bulletin_secret),
                            other_mutual_friend.relationship.their_username,
                            mutual_friend.public_key.decode('hex')
                        )
                        signed = verify_signature(
                            base64.b64decode(signature.signature),
                            self.hash,
                            mutual_friend.public_key.decode('hex')
                        )
                        if identity and signed:
                            signature.passed = True
            """
        for signature in self.signatures:
            if not signature.passed:
                raise InvalidFastGraphTransactionException('not all signatures verified')
Пример #27
0
    def verify(self):
        getcontext().prec = 8
        if int(self.version) != int(CHAIN.get_version_for_height(self.index)):
            raise Exception("Wrong version for block height", self.version, CHAIN.get_version_for_height(self.index))

        txns = self.get_transaction_hashes()
        verify_merkle_root = self.get_merkle_root(txns)
        if verify_merkle_root != self.merkle_root:
            raise Exception("Invalid block merkle root")

        header = self.generate_header()
        hashtest = self.generate_hash_from_header(self.index, header, str(self.nonce))
        # print("header", header, "nonce", self.nonce, "hashtest", hashtest)
        if self.hash != hashtest:
            getLogger("tornado.application").warning("Verify error hashtest {} header {} nonce {}".format(hashtest, header, self.nonce))
            raise Exception('Invalid block hash')

        address = P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(self.public_key))
        try:
            # print("address", address, "sig", self.signature, "pubkey", self.public_key)
            result = verify_signature(base64.b64decode(self.signature), self.hash.encode('utf-8'), bytes.fromhex(self.public_key))
            if not result:
                raise Exception("block signature1 is invalid")
        except:
            try:
                result = VerifyMessage(address, BitcoinMessage(self.hash.encode('utf-8'), magic=''), self.signature)
                if not result:
                    raise
            except:
                raise Exception("block signature2 is invalid")

        # verify reward
        coinbase_sum = 0
        for txn in self.transactions:
            if int(self.index) > CHAIN.CHECK_TIME_FROM and (int(txn.time) > int(self.time) + CHAIN.TIME_TOLERANCE):
                #yadacoin.core.config.CONFIG.mongo.db.miner_transactions.remove({'id': txn.transaction_signature}, multi=True)
                #raise Exception("Block embeds txn too far in the future")
                pass

            if txn.coinbase:
                for output in txn.outputs:
                    coinbase_sum += float(output.value)

        fee_sum = 0.0
        for txn in self.transactions:
            if not txn.coinbase:
                fee_sum += float(txn.fee)
        reward = CHAIN.get_block_reward(self.index)

        #if Decimal(str(fee_sum)[:10]) != Decimal(str(coinbase_sum)[:10]) - Decimal(str(reward)[:10]):
        """
        KO for block 13949
        0.02099999 50.021 50.0
        Integrate block error 1 ('Coinbase output total does not equal block reward + transaction fees', 0.020999999999999998, 0.021000000000000796)
        """
        if quantize_eight(fee_sum) != quantize_eight(coinbase_sum - reward):
            print(fee_sum, coinbase_sum, reward)
            raise Exception("Coinbase output total does not equal block reward + transaction fees", fee_sum, (coinbase_sum - reward))
Пример #28
0
 def test_json_roundtrip(self):
     VALUES = [
         42,
         0,
         -42,
         2100000000000000,
         -2100000000000000,
         "basic string",
         "\u1111Unicode",
         "\U00010000Wide Unicode",
         "\x00\n\t\r\nEscape codes",
         "\"'\"Quotes",
         "",
         None,
         b"\x00\x01\xFFBinary data",
         b"",
         CBase58Data.from_bytes(b'\x00\x01\xFF', 42),
         P2SHBitcoinAddress.from_bytes(b'\x00\x01\xFF'),
         P2PKHBitcoinAddress.from_bytes(b'\x00\x01\xFF'),
         CMutableTxIn(COutPoint(b'\x00' * 16 + b'\xFF' * 16, 42),
                      CScript(b'\x00\x01\xFF'), 42),
         CMutableTxOut(42, CScript(b'\x00\x01\xFF')),
         CMutableTransaction([
             CMutableTxIn(COutPoint(b'\x00' * 32, 42),
                          CScript(b'\x00\x01\xFF'), 42),
             CMutableTxIn(COutPoint(b'\xFF' * 32, 42),
                          CScript(b'\xFF\x01\x00'), 43)
         ], [
             CMutableTxOut(42, CScript(b'\x00\x01\xFF')),
             CMutableTxOut(43, CScript(b'\xFF\x01\x00'))
         ], 42, 3),
         [
             1,
             b'\x00\x01\xFF',
             "List Test",
         ],
         {
             'a': 1,
             'key': b'\xFF\x01\x00',
             1: 'Dictionary Test'
         },
         [
             {
                 3: [
                     0,
                     1,
                     2,
                 ],
             },
             [
                 [
                     b'\xFFRecursion Test',
                 ],
             ],
         ],
     ]
     for value in VALUES:
         self.assertEqual(from_json(to_json(value)), value)
Пример #29
0
def make_self_transaction():
	words = get_randomness('keys.txt')
	# seckey = CBitcoinSecret.from_secret_bytes(our_keys[1])
	h = hashlib.sha256(words).digest()
	seckey = CBitcoinSecret.from_secret_bytes(h)
	input_hashes = [('08f7e2c1238cc9b918649e40d72815f32be6dc1ad538cb25331bd1f1c58a5f46',0),
	('8642baa47de6ece50c2800221e5bc7eefd7adf4158f24af31fdcfa185cb54fce', 1)]
	address = P2PKHBitcoinAddress.from_pubkey(seckey.pub)  # "1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G"
	return make_transaction(0.00092, input_hashes, address, seckey)
Пример #30
0
    def verify(self):
        getcontext().prec = 8
        if int(self.version) != int(BU.get_version_for_height(self.index)):
            raise BaseException("Wrong version for block height", self.version,
                                BU.get_version_for_height(self.index))
        try:
            txns = self.get_transaction_hashes()
            self.set_merkle_root(txns)
            if self.verify_merkle_root != self.merkle_root:
                raise BaseException("Invalid block")
        except:
            raise

        try:
            header = BlockFactory.generate_header(self)
            hashtest = BlockFactory.generate_hash_from_header(
                header, str(self.nonce))
            if self.hash != hashtest:
                raise BaseException('Invalid block')
        except:
            raise

        address = P2PKHBitcoinAddress.from_pubkey(
            self.public_key.decode('hex'))
        try:
            result = verify_signature(base64.b64decode(self.signature),
                                      self.hash, self.public_key.decode('hex'))
            if not result:
                raise Exception("block signature is invalid")
        except:
            try:
                result = VerifyMessage(address,
                                       BitcoinMessage(self.hash, magic=''),
                                       self.signature)
                if not result:
                    raise
            except:
                raise BaseException("block signature is invalid")

        # verify reward
        coinbase_sum = 0
        for txn in self.transactions:
            if txn.coinbase:
                for output in txn.outputs:
                    coinbase_sum += float(output.value)

        fee_sum = 0.0
        for txn in self.transactions:
            if not txn.coinbase:
                fee_sum += float(txn.fee)
        reward = BU.get_block_reward(self.config, self.mongo, self)

        if Decimal(str(fee_sum)[:10]) != (Decimal(str(coinbase_sum)[:10]) -
                                          Decimal(str(reward)[:10])):
            raise BaseException(
                "Coinbase output total does not equal block reward + transaction fees",
                fee_sum, (coinbase_sum - reward))
Пример #31
0
 def parse_secret(self, txid):
     raw = zcashd.gettransaction(txid, True)['hex']
     decoded = zcashd.call('decoderawtransaction', raw)
     scriptSig = decoded['vin'][0]['scriptSig']
     asm = scriptSig['asm'].split(" ")
     pubkey = asm[1]
     secret = x2s(asm[2])
     redeemPubkey = P2PKHBitcoinAddress.from_pubkey(x(pubkey))
     return secret
Пример #32
0
    def create_checksum_signature(self):
        key = CBitcoinSecret(self.primary_private_key.wif())
        address = P2PKHBitcoinAddress.from_pubkey(key.pub)

        signature = None

        print(self.primary_private_key.wif(), str(address))

        return str(address), signature
Пример #33
0
def fetch_key_for_address(key_file, address):
    keys = read_keys(key_file)
    bitcoin_secrets = [CBitcoinSecret(key) for key in keys]
    for key in bitcoin_secrets:
        addr = P2PKHBitcoinAddress.from_pubkey(key.pub)
        if str(addr) == address:
            return key

    return None
Пример #34
0
def print_verbose(signature, key, msg):
    secret = CBitcoinSecret(key)
    address = P2PKHBitcoinAddress.from_pubkey(secret.pub)
    message = BitcoinMessage(msg)
    print('Address: %s' % address)
    print('Message: %s' % msg)
    print('Signature: %s' % signature)
    print('Verified: %s' % VerifyMessage(address, message, signature))
    print('\nTo verify using bitcoin core:')
    print('\n`bitcoin-cli verifymessage %s \'%s\' \'%s\'`\n' % (address, signature.decode('ascii'), msg))
def make_address_from_passphrase(passphrase, compressed=True, as_str=True):
    """
    Create a Bitcoin address from a passphrase. The passphrase is hashed and
    then used as the secret bytes to construct the CBitcoinSecret.
    """
    if not isinstance(passphrase, bytes):
        passphrase = bytes(passphrase, "utf-8")
    passphrasehash = hashlib.sha256(passphrase).digest()
    private_key = CBitcoinSecret.from_secret_bytes(passphrasehash, compressed=compressed)
    address = P2PKHBitcoinAddress.from_pubkey(private_key.pub)
    if as_str:
        return str(address)
    else:
        return address
Пример #36
0
  def test_build_send_script(self):
    """ Run simple sanity checks on script generation """

    # Set up constants for this test
    sender_private_key = CBitcoinSecret.from_secret_bytes(x('4f65da9b656de4036076911707d2b2dbf065689245b8674faa8790e36d7e5850'))
    sender_public_key = sender_private_key.pub
    recipient_private_key = CBitcoinSecret.from_secret_bytes(x('cfe8e33672f7045f020210f3c7afbca660e053e4c9415c542ff185e97b175cf0'))
    recipient_public_key = recipient_private_key.pub
    send_to_key = CBitcoinSecret.from_secret_bytes(x('15a249b4c09286b877d4708191f1ee8de09903bae034dd9dc8e3286451fa1c80'))
    send_to_address = P2PKHBitcoinAddress.from_pubkey(send_to_key.pub)
    secret = x('88d6e51f777b0b8dc0f429da9f372fbc')
    secret_hash = Hash(secret)
    quantity = 1000

    # Build the send transaction
    txins = [] # TODO: Provide some random inputs
    txouts = [CTxOut(quantity, build_send_out_script(sender_public_key, recipient_public_key, secret_hash))]
    send_tx = CMutableTransaction(txins, txouts)
    send_tx_n = 0 # We're working with the first transaction input

    # Build the refund transaction
    nLockTime = 1422177943
    refund_tx = build_unsigned_refund_tx(send_tx, send_tx_n, send_to_address, nLockTime, CFeeRate(0))

    # Actually verify the signatures
    sighash = SignatureHash(send_tx.vout[0].scriptPubKey, refund_tx, 0, SIGHASH_ALL)
    sender_sig = get_refund_tx_sig(refund_tx, sender_private_key, sender_public_key, recipient_public_key, secret_hash)
    self.assertTrue(sender_public_key.verify(sighash, sender_sig[:-1]))
    recipient_sig = get_refund_tx_sig(refund_tx, recipient_private_key, sender_public_key, recipient_public_key, secret_hash)
    self.assertTrue(recipient_public_key.verify(sighash, recipient_sig[:-1]))

    # Test building a complete refund transaction
    refund_tx = build_signed_refund_tx(send_tx, send_tx_n, refund_tx,
      recipient_sig, recipient_public_key,
        sender_private_key, secret_hash)
    # This throws an exception in case of a problem
    VerifyScript(refund_tx.vin[0].scriptSig,
      send_tx.vout[send_tx_n].scriptPubKey, refund_tx, 0, (SCRIPT_VERIFY_P2SH,))
Пример #37
0
 def test_json_roundtrip(self):
     VALUES = [
         42,
         0,
         -42,
         2100000000000000,
         -2100000000000000,
         "basic string",
         "\u1111Unicode",
         "\U00010000Wide Unicode",
         "\x00\n\t\r\nEscape codes",
         '"\'"Quotes',
         "",
         None,
         b"\x00\x01\xFFBinary data",
         b"",
         CBase58Data.from_bytes(b"\x00\x01\xFF", 42),
         P2SHBitcoinAddress.from_bytes(b"\x00\x01\xFF"),
         P2PKHBitcoinAddress.from_bytes(b"\x00\x01\xFF"),
         CMutableTxIn(COutPoint(b"\x00" * 16 + b"\xFF" * 16, 42), CScript(b"\x00\x01\xFF"), 42),
         CMutableTxOut(42, CScript(b"\x00\x01\xFF")),
         CMutableTransaction(
             [
                 CMutableTxIn(COutPoint(b"\x00" * 32, 42), CScript(b"\x00\x01\xFF"), 42),
                 CMutableTxIn(COutPoint(b"\xFF" * 32, 42), CScript(b"\xFF\x01\x00"), 43),
             ],
             [CMutableTxOut(42, CScript(b"\x00\x01\xFF")), CMutableTxOut(43, CScript(b"\xFF\x01\x00"))],
             42,
             3,
         ),
         [1, b"\x00\x01\xFF", "List Test"],
         {"a": 1, "key": b"\xFF\x01\x00", 1: "Dictionary Test"},
         [{3: [0, 1, 2]}, [[b"\xFFRecursion Test"]]],
     ]
     for value in VALUES:
         self.assertEqual(from_json(to_json(value)), value)
Пример #38
0
#
# This file is part of python-bitcoinlib.
#
# It is subject to the license terms in the LICENSE file found in the top-level
# directory of this distribution.
#
# No part of python-bitcoinlib, including this file, may be copied, modified,
# propagated, or distributed except according to the terms contained in the
# LICENSE file.

from __future__ import absolute_import, division, print_function, unicode_literals

from bitcoin.wallet import CBitcoinSecret, P2PKHBitcoinAddress
from bitcoin.signmessage import BitcoinMessage, VerifyMessage, SignMessage

key = CBitcoinSecret("L4vB5fomsK8L95wQ7GFzvErYGht49JsCPJyJMHpB4xGM6xgi2jvG")
address = P2PKHBitcoinAddress.from_pubkey(key.pub)  # "1F26pNMrywyZJdr22jErtKcjF8R3Ttt55G"
message = "Hey I just met you, and this is crazy, but I'll verify my address, maybe ..."

message = BitcoinMessage(message)

signature = SignMessage(key, message)

print(key, address)
print("Address: %s" % address)
print("Message: %s" % message)
print("\nSignature: %s" % signature)
print("\nVerified: %s" % VerifyMessage(address, message, signature))

print("\nTo verify using bitcoin core;")
print("`bitcoin-cli verifymessage %s \"%s\" \"%s\"`" % (address, signature.decode('ascii'), message))
    return CBitcoinSecret.from_secret_bytes(secret_bytes)


def generate_fake_txin():
    fake_txid = Hash(open("/dev/random", "rb").read(100))
    fake_output_index = 0
    return CMutableTxIn(COutPoint(fake_txid, fake_output_index))


def set_txin_unlocking_script(txin, secret_key, tx):
    txin_locking_script = CScript([OP_DUP, OP_HASH160, Hash160(secret_key.pub), OP_EQUALVERIFY, OP_CHECKSIG])
    sighash = SignatureHash(txin_locking_script, tx, 0, SIGHASH_ALL)
    sig = secret_key.sign(sighash) + bytes([SIGHASH_ALL])
    txin.scriptSig = CScript([sig, secret_key.pub])
    VerifyScript(txin.scriptSig, txin_locking_script, tx, 0)
    return txin


def generate_tx(recipient_address, amount, miner_fee):
    txin_list = [generate_fake_txin() for _ in range(0, 10)]
    txout = CMutableTxOut(amount*COIN - miner_fee*COIN, recipient_address.to_scriptPubKey())
    tx = CMutableTransaction(txin_list, [txout])
    [set_txin_unlocking_script(txin, generate_secret_key(), tx) for txin in txin_list]
    return tx


if __name__ == "__main__":
    address = P2PKHBitcoinAddress.from_pubkey(generate_secret_key().pub)
    transaction = generate_tx(address, 0.1, 0.0001)
    print(b2x(transaction.serialize()))
Пример #40
0
def pubkey_to_address(pubkey):
    return str(P2PKHBitcoinAddress.from_pubkey(x(pubkey)))
Пример #41
0
  def test_send_script_spend(self):
    """
    Run more in-depth execution checks on the script generated for the send transaction
    """
    sender_private_key = CBitcoinSecret.from_secret_bytes(x('4f65da9b656de4036076911707d2b2dbf065689245b8674faa8790e36d7e5850'))
    sender_public_key = sender_private_key.pub
    recipient_private_key = CBitcoinSecret.from_secret_bytes(x('cfe8e33672f7045f020210f3c7afbca660e053e4c9415c542ff185e97b175cf0'))
    recipient_public_key = recipient_private_key.pub
    secret = x('88d6e51f777b0b8dc0f429da9f372fbc')
    secret_hash = Hash(secret)
    send_to_key = CBitcoinSecret.from_secret_bytes(x('15a249b4c09286b877d4708191f1ee8de09903bae034dd9dc8e3286451fa1c80'))
    send_to_address = P2PKHBitcoinAddress.from_pubkey(send_to_key.pub)
    random_tx_id = x('8390b4c8198198c6447da1a6fad498209436a785459936b95a1e3b63618c1d8a')
    value = 10 * COIN

    send_tx_script_pub_key = build_send_out_script(sender_public_key, recipient_public_key, secret_hash)

    send_txins = [CMutableTxIn(COutPoint(random_tx_id, 0))]
    send_txouts = [CMutableTxOut(value, send_tx_script_pub_key)]
    send_tx = CMutableTransaction(send_txins, send_txouts)

    # Test the standard spend transaction

    txins = [CMutableTxIn(COutPoint(Hash(send_tx.serialize()), 0))]
    txouts = [CMutableTxOut(value, send_to_address.to_scriptPubKey())]
    recv_tx = CMutableTransaction(txins, txouts)

    sighash = SignatureHash(send_tx_script_pub_key, recv_tx, 0, SIGHASH_ALL)
    recipient_sig = recipient_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL])
    recv_tx.vin[0].scriptSig = CScript([secret, 0, recipient_sig, recipient_public_key])

    VerifyScript(recv_tx.vin[0].scriptSig, send_tx.vout[0].scriptPubKey, recv_tx, 0, (SCRIPT_VERIFY_P2SH,))

    # Test a refund transaction
    refund_tx = CMutableTransaction(txins, txouts)

    sighash = SignatureHash(send_tx_script_pub_key, refund_tx, 0, SIGHASH_ALL)
    sender_sig = sender_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL])
    recipient_sig = recipient_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL])
    refund_tx.vin[0].scriptSig = CScript([sender_sig, sender_public_key, 1, recipient_sig, recipient_public_key])

    VerifyScript(refund_tx.vin[0].scriptSig, send_tx_script_pub_key, refund_tx, 0, (SCRIPT_VERIFY_P2SH,))

    # Test invalid transactions are rejected

    invalid_tx = CMutableTransaction(txins, txouts)

    sighash = SignatureHash(send_tx_script_pub_key, invalid_tx, 0, SIGHASH_ALL)
    sender_sig = sender_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL])
    recipient_sig = recipient_private_key.sign(sighash) + (b'\x01') # bytes([SIGHASH_ALL])

    invalid_tx.vin[0].scriptSig = CScript([])
    with self.assertRaises(MissingOpArgumentsError):
      VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,))

    invalid_tx.vin[0].scriptSig = CScript([recipient_sig, recipient_public_key, 0])
    with self.assertRaises(VerifyOpFailedError):
      VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,))

    invalid_tx.vin[0].scriptSig = CScript([recipient_sig, recipient_public_key, 1])
    with self.assertRaises(VerifyOpFailedError):
      VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,))

    invalid_tx.vin[0].scriptSig = CScript([recipient_sig, recipient_public_key, 1, recipient_sig, recipient_public_key])
    with self.assertRaises(VerifyOpFailedError):
      VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,))

    invalid_tx.vin[0].scriptSig = CScript([sender_sig, sender_public_key, 1, sender_sig, sender_public_key])
    with self.assertRaises(VerifyOpFailedError):
      VerifyScript(invalid_tx.vin[0].scriptSig, send_tx_script_pub_key, invalid_tx, 0, (SCRIPT_VERIFY_P2SH,))