示例#1
0
    def to_seed(self, words, password='', validate=True):
        """
        Use Mnemonic words and password to create a PBKDF2 seed (Password-Based Key Derivation Function 2)
        
        First use 'sanitize_mnemonic' to determine language and validate and check words

        :param words: Mnemonic passphrase as string with space seperated words
        :type words: str
        :param password: A password to protect key, leave empty to disable
        :type password: str
        :param validate: Validate checksum for given word phrase, default is True
        :type validate: bool
        
        :return bytes: PBKDF2 seed
        """
        words = self.sanitize_mnemonic(words)
        # Check if passphrase is valid
        if validate:
            self.to_entropy(words)
        mnemonic = to_bytes(words)
        password = to_bytes(password)
        return hashlib.pbkdf2_hmac(hash_name='sha512',
                                   password=mnemonic,
                                   salt=b'mnemonic' + password,
                                   iterations=2048)
示例#2
0
    def to_seed(self, words, password='', validate=True):
        """
        Use Mnemonic words and optionally a password to create a PBKDF2 seed (Password-Based Key Derivation Function 2)
        
        First use 'sanitize_mnemonic' to determine language and validate and check words

        >>> from bitcoinlib.encoding import to_hexstring
        >>> to_hexstring(Mnemonic().to_seed('chunk gun celery million wood kite tackle twenty story episode raccoon dutch'))
        '6969ed4666db67fc74fae7869e2acf3c766b5ef95f5e31eb2fcebd93d76069c6de971225f700042b0b513f0ad6c8562277fc4b5ee1344b720f1686dc2dccc220'

        :param words: Mnemonic passphrase as string with space separated words
        :type words: str
        :param password: A password to protect key, leave empty to disable
        :type password: str
        :param validate: Validate checksum for given word phrase, default is True
        :type validate: bool
        
        :return bytes: PBKDF2 seed
        """
        words = self.sanitize_mnemonic(words)
        # Check if passphrase is valid
        if validate:
            self.to_entropy(words)
        mnemonic = to_bytes(words)
        password = to_bytes(password)
        return hashlib.pbkdf2_hmac(hash_name='sha512',
                                   password=mnemonic,
                                   salt=b'mnemonic' + password,
                                   iterations=2048)
示例#3
0
 def pubkey_to_msg(self, pubkey: str):
     key_bytes = encoding.to_bytes(pubkey)
     return (
         encoding.to_bytes(TYPE_PREFIX["PubKey"])
         + encode(len(key_bytes))
         + key_bytes
     )
示例#4
0
    def wif_prefix(self,
                   is_private=False,
                   witness_type='legacy',
                   multisig=False):
        """
        Get WIF prefix for this network and specifications in arguments

        :param is_private: Private or public key, default is True
        :type is_private: bool
        :param witness_type: Legacy, segwit or p2sh-segwit
        :type witness_type: str
        :param multisig: Multisignature or single signature wallet. Default is not multisig
        :type multisig: True

        :return bytes:
        """
        script_type = script_type_default(witness_type,
                                          multisig,
                                          locking_script=True)
        if script_type == 'p2sh' and witness_type in ['p2sh-segwit', 'segwit']:
            script_type = 'p2sh_p2wsh' if multisig else 'p2sh_p2wpkh'
        if is_private:
            ip = 'private'
        else:
            ip = 'public'
        found_prefixes = [
            to_bytes(pf[1]) for pf in self.prefixes_wif
            if pf[0] == ip and script_type in pf[3]
        ]
        if found_prefixes:
            return found_prefixes[0]
        else:
            raise NetworkError("WIF Prefix for script type %s not found" %
                               script_type)
示例#5
0
 def gettransaction(self, txid, latest_block=None):
     tx = self.compose_request('rawtx', txid)
     raw_tx = self.getrawtransaction(txid)
     t = Transaction.import_raw(raw_tx, self.network)
     input_total = 0
     for n, i in enumerate(t.inputs):
         if 'prev_out' in tx['inputs'][n]:
             i.value = tx['inputs'][n]['prev_out']['value']
             input_total += i.value
     for n, o in enumerate(t.outputs):
         o.spent = tx['out'][n]['spent']
     if 'block_height' in tx and tx['block_height']:
         if not latest_block:
             latest_block = self.blockcount()
         t.status = 'confirmed'
         t.date = datetime.utcfromtimestamp(tx['time'])
         t.block_height = tx['block_height']
         t.confirmations = 1
         if latest_block > t.block_height:
             t.confirmations = latest_block - t.block_height
     else:
         t.status = 'unconfirmed'
         t.confirmations = 0
         t.date = None
     t.rawtx = to_bytes(raw_tx)
     t.size = tx['size']
     t.network_name = self.network
     t.locktime = tx['lock_time']
     t.version = struct.pack('>L', tx['ver'])
     t.input_total = input_total
     t.fee = t.input_total - t.output_total
     return t
示例#6
0
 def _parse_db_transaction(db_tx):
     if not db_tx.raw:
         return False
     t = Transaction.import_raw(db_tx.raw, db_tx.network_name)
     # locktime, version, coinbase?, witness_type
     # t = Transaction(locktime=tx['locktime'], version=tx['version'], network=self.network,
     #                 fee=tx['fee'], size=tx['size'], hash=tx['txid'],
     #                 date=tdate, input_total=tx['input_total'], output_total=tx['output_total'],
     #                 confirmations=confirmations, block_height=block_height, status=tx['status'],
     #                 coinbase=tx['coinbase'], rawtx=tx['raw_hex'], witness_type=tx['witness_type'])
     for n in db_tx.nodes:
         if n.is_input:
             t.inputs[n.output_n].value = n.value
             t.inputs[n.output_n].address = n.address
         else:
             t.outputs[n.output_n].spent = n.spent
             t.outputs[n.output_n].spending_txid = n.spending_txid
             t.outputs[n.output_n].spending_index_n = n.spending_index_n
     t.hash = to_bytes(db_tx.txid)
     t._txid = db_tx.txid
     t.date = db_tx.date
     t.block_hash = db_tx.block_hash
     t.block_height = db_tx.block_height
     t.confirmations = db_tx.confirmations
     t.status = 'confirmed'
     t.fee = db_tx.fee
     t.update_totals()
     if t.coinbase:
         t.input_total = t.output_total
     _logger.info("Retrieved transaction %s from cache" % t.txid)
     return t
示例#7
0
 def gettransaction(self, txid):
     variables = {'id': txid, 'hex': None}
     tx = self.compose_request(path_type='explorer', variables=variables)
     t = Transaction.import_raw(tx['hex'], self.network)
     variables = {'t': txid}
     tx_api = self.compose_request('txinfo',
                                   path_type='api',
                                   variables=variables)
     for n, i in enumerate(t.inputs):
         if i.script_type != 'coinbase':
             i.value = int(
                 round(tx_api['inputs'][n]['amount'] * self.units, 0))
         else:
             i.value = 0
             t.coinbase = True
     for n, o in enumerate(t.outputs):
         o.spent = None
     if tx['confirmations']:
         t.status = 'confirmed'
     else:
         t.status = 'unconfirmed'
     t.date = datetime.utcfromtimestamp(tx['time'])
     t.block_height = tx_api['block']
     t.block_hash = tx['blockhash']
     t.confirmations = tx['confirmations']
     t.rawtx = to_bytes(tx['hex'])
     t.size = tx['size']
     t.network = self.network
     t.locktime = tx['locktime']
     t.version = struct.pack('>L', tx['version'])
     t.output_total = int(round(tx_api['total_output'] * self.units, 0))
     t.input_total = t.output_total
     t.fee = t.input_total - t.output_total
     return t
示例#8
0
    def get_transfer_msg(self, to_address: str, symbol: str, amount: number_type):
        """Generate transfer StdMsg for StdTx and SignMessage for current transaction"""
        amount = int(Decimal(amount) * BASE)
        self.msg = {
            "inputs": [
                {
                    "address": self.address,
                    "coins": [{"denom": symbol, "amount": amount}],
                }
            ],
            "outputs": [
                {"address": to_address, "coins": [{"denom": symbol, "amount": amount}]}
            ],
        }
        self.StdSignMsg["msgs"] = [self.msg]

        self.SignMessage = json.dumps(
            self.StdSignMsg, sort_keys=True, separators=(",", ":")
        ).encode()
        std = Send()
        input = Input()
        output = Output()
        token_proto = Token()
        token_proto.amount = amount
        token_proto.denom = symbol.encode()
        input.address = address_decode(self.address)
        input.coins.extend([token_proto])
        output.address = address_decode(to_address)
        output.coins.extend([token_proto])
        std.inputs.extend([input])
        std.outputs.extend([output])
        self.stdMsg = encoding.to_bytes(TYPE_PREFIX["Send"]) + std.SerializeToString()
        return self.SignMessage
示例#9
0
 def to_mnemonic(self, data, add_checksum=True, check_on_curve=True):
     """
     Convert key data entropy to Mnemonic sentence
     
     :param data: Key data entropy
     :type data: bytes, hexstring
     :param add_checksum: Included a checksum? Default is True
     :type add_checksum: bool
     :param check_on_curve: Check if data integer value is on secp256k1 curve. Should be enabled when not testing and working with crypto
     :type check_on_curve: bool
     
     :return str: Mnemonic passphrase consisting of a space seperated list of words
     """
     data = to_bytes(data)
     data_int = change_base(data, 256, 10)
     if check_on_curve and not 0 < data_int < secp256k1_n:
         raise ValueError(
             "Integer value of data should be in secp256k1 domain between 1 and secp256k1_n-1"
         )
     if add_checksum:
         binresult = change_base(data_int, 10, 2,
                                 len(data) * 8) + self.checksum(data)
         wi = change_base(binresult, 2, 2048)
     else:
         wi = change_base(data_int, 10, 2048)
     return normalize_string(' '.join([self._wordlist[i] for i in wi]))
示例#10
0
 def get_multi_transfer_msg(
     self, to_address: str, transfers: List[Dict[str, number_type]]
 ):
     """ Generate StdMsg and SignMessage for multiple tokens send in one transaction"""
     coins = []
     input = Input()
     output = Output()
     for transfer in transfers:
         coin = {}
         token = Token()
         amount = transfer["amount"]
         coin["denom"] = transfer["symbol"]
         coin["amount"] = token.amount = int(Decimal(amount) * BASE)
         token.denom = str(transfer["symbol"]).encode()
         coins.append(coin)
         input.coins.extend([token])
         output.coins.extend([token])
     self.msg = {
         "inputs": [{"address": self.address, "coins": coins}],
         "outputs": [{"address": to_address, "coins": coins}],
     }
     self.StdSignMsg["msgs"] = [self.msg]
     self.SignMessage = json.dumps(
         self.StdSignMsg, sort_keys=True, separators=(",", ":")
     ).encode()
     std = Send()
     input.address = address_decode(self.address)
     output.address = address_decode(to_address)
     std.inputs.extend([input])
     std.outputs.extend([output])
     self.stdMsg = encoding.to_bytes(TYPE_PREFIX["Send"]) + std.SerializeToString()
     return self.SignMessage
示例#11
0
    def getblock(self, blockid):
        """
        Get specific block from database cache.

        :param blockid: Block height or block hash
        :type blockid: int, str

        :return Block:
        """
        if not self.cache_enabled():
            return False
        qr = self.session.query(DbCacheBlock)
        if isinstance(blockid, int):
            block = qr.filter_by(height=blockid,
                                 network_name=self.network.name).scalar()
        else:
            block = qr.filter_by(block_hash=to_bytes(blockid)).scalar()
        if not block:
            return False
        b = Block(block_hash=block.block_hash,
                  height=block.height,
                  network=block.network_name,
                  merkle_root=block.merkle_root,
                  time=block.time,
                  nonce=block.nonce,
                  version=block.version,
                  prev_block=block.prev_block,
                  bits=block.bits)
        b.tx_count = block.tx_count
        _logger.info("Retrieved block with height %d from cache" % b.height)
        return b
示例#12
0
    def to_mnemonic(self, data, add_checksum=True, check_on_curve=True):
        """
        Convert key data entropy to Mnemonic sentence

        >>> Mnemonic().to_mnemonic('28acfc94465fd2f6774759d6897ec122')
        'chunk gun celery million wood kite tackle twenty story episode raccoon dutch'

        :param data: Key data entropy
        :type data: bytes, hexstring
        :param add_checksum: Included a checksum? Default is True
        :type add_checksum: bool
        :param check_on_curve: Check if data integer value is on secp256k1 curve. Should be enabled when not testing and working with crypto
        :type check_on_curve: bool
        
        :return str: Mnemonic passphrase consisting of a space seperated list of words
        """
        data = to_bytes(data)
        data_int = change_base(data, 256, 10)
        if check_on_curve and not 0 < data_int < secp256k1_n:
            raise ValueError(
                "Integer value of data should be in secp256k1 domain between 1 and secp256k1_n-1"
            )
        if add_checksum:
            binresult = change_base(data_int, 10, 2,
                                    len(data) * 8) + self.checksum(data)
            wi = change_base(binresult, 2, 2048)
        else:
            wi = change_base(data_int, 10, 2048,
                             len(data) // 1.375 + len(data) % 1.375 > 0)
        return normalize_string(' '.join([self._wordlist[i] for i in wi]))
示例#13
0
 def test_blocks_parse_block_and_transactions(self):
     b = Block.from_raw(self.rb250000, parse_transactions=True)
     self.assertEqual(to_hexstring(b.block_hash), '000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214')
     self.assertEqual(b.height, 250000)
     self.assertEqual(b.version_int, 2)
     self.assertEqual(b.prev_block, to_bytes('0000000000000009c2e82d884ec07b4aafb64ca3ef83baca2b6b0b5eb72c8f02'))
     self.assertEqual(b.merkle_root, to_bytes('16ec1eafaca8ca59d182cbf94f29b50b06ac4207b883f380b9bf547fe8fed723'))
     self.assertEqual(b.bits_int, 0x1972dbf2)
     self.assertEqual(b.time, 1375533383)
     self.assertEqual(b.nonce_int, 0x917661)
     self.assertEqual(int(b.difficulty), 37392766)
     self.assertEqual(b.target, 720982641204331278205950312227594303241470815982254303477760)
     self.assertEqual(b.tx_count, 156)
     self.assertEqual(b.transactions[0].txid, '7ae2ab185a6e501753f6e29e5b6a98ba040098acb7c11ffed9430f22ed5263a3')
     self.assertEqual(b.transactions[49].txid, '3b6d97f107cba804270f4d22fafda3295b3bfb735366da6c1473157cc94a5f7c')
     self.assertEqual(b.transactions[122].txid, 'a5cc9bd850b6eedc3e466b3e0f5c85fb640de0a3537259eb0cae761d0a4f78b4')
     self.assertEqual(b.transactions[155].txid, 'e3d6cb87bd37ca53509cdc9ecdabf82ef966d9b25a2598b7de87c8173beb40d5')
示例#14
0
 def wallet_from_keystore(keystore: dict,
                          password: str = "",
                          testnet: bool = False):
     "Recover Binance wallet from keystore"
     private_key = decode_keyfile_json(keystore,
                                       password=encoding.to_bytes(password))
     key = keys.HDKey(private_key)
     return Wallet(key=key, testnet=testnet)
示例#15
0
 def generate_stdSignatureMsg(self, pubkey_bytes: bytes, signature: str):
     """Generate StdSignature for StdTx"""
     std = StdSignature()
     std.pub_key = pubkey_bytes
     std.signature = encoding.to_bytes(signature)
     std.account_number = self.account_number
     std.sequence = self.sequence
     proto_bytes = std.SerializeToString()
     return proto_bytes
示例#16
0
 def test_blocks_parse_block_and_transactions(self):
     b = Block.from_raw(self.rb330000, parse_transactions=True, limit=5)
     self.assertEqual(to_hexstring(b.block_hash), '00000000000000000faabab19f17c0178c754dbed023e6c871dcaf74159c5f02')
     self.assertEqual(b.height, 330000)
     self.assertEqual(b.version_int, 2)
     self.assertEqual(b.prev_block, to_bytes('000000000000000003e20f90920dc065da4a507bcf045f44b9abac7fabff4857'))
     self.assertEqual(b.merkle_root, to_bytes('5a97519772c615a875c12859f447d9c1fea922f7e36bd08e96cc95eee235d28f'))
     self.assertEqual(b.bits_int, 404472624)
     self.assertEqual(b.time, 1415983209)
     self.assertEqual(b.nonce_int, 3756201140)
     self.assertEqual(int(b.difficulty), 39603666252)
     self.assertEqual(b.tx_count, 81)
     self.assertEqual(b.transactions[0].txid, 'dfd63430f8d14f6545117d74b20da63efd4a75c7e28f723b3dead431b88469ee')
     self.assertEqual(b.transactions[4].txid, '717bc8b42f12baf771b6719c2e3b2742925fe3912917c716abef03e35fe49020')
     self.assertEqual(len(b.transactions), 5)
     b.parse_transactions(70)
     self.assertEqual(len(b.transactions), 75)
     b.parse_transactions(10)
     self.assertEqual(len(b.transactions), 81)
     self.assertEqual(b.transactions[80].txid, '7c8483c890942334ecb73db3802f7571b06047b5c15febe3bad11e460065709b')
示例#17
0
 def generate_StdTxMsg(self):
     """Geneate StdTx"""
     std = StdTx()
     std.msgs.extend([self.stdMsg])
     std.signatures.extend([self.stdSignature])
     std.memo = self.memo
     std.source = 1
     std.data = self.data
     proto_bytes = std.SerializeToString()
     type_bytes = encoding.to_bytes(TYPE_PREFIX["StdTx"])
     return encode(len(proto_bytes) + len(type_bytes)) + type_bytes + proto_bytes
    def sendrawtransaction(self, rawtx):
        """
        Dummy method to send transactions on the bitcoinlib testnet. The bitcoinlib testnet does not exists,
        so it just returns the transaction hash.

        :param rawtx: A raw transaction hash
        :type rawtx: bytes, str

        :return str: Transaction hash
        """
        txid = double_sha256(to_bytes(rawtx))[::-1].hex()
        return {'txid': txid, 'response_dict': {}}
示例#19
0
 def _parse_transaction(self, tx, block_count=None):
     block_height = None if not tx['block_height'] else tx['block_height']
     confirmations = tx['confirmations']
     if block_height and not confirmations and tx['status'] == 'confirmed':
         if not block_count:
             block_count = self.blockcount()
         confirmations = block_count - block_height
     try:  # FIXME: On blocksmurfer side: always return timestamp
         tdate = datetime.strptime(tx['date'], "%Y-%m-%dT%H:%M:%S")
     except (KeyError, TypeError):
         tdate = datetime.utcfromtimestamp(tx['time'])
     t = Transaction(locktime=tx['locktime'],
                     version=tx['version'],
                     network=self.network,
                     fee=tx['fee'],
                     size=tx['size'],
                     hash=tx['txid'],
                     date=tdate,
                     input_total=tx['input_total'],
                     output_total=tx['output_total'],
                     confirmations=confirmations,
                     block_height=block_height,
                     status=tx['status'],
                     coinbase=tx['coinbase'],
                     rawtx=tx['raw_hex'],
                     witness_type=tx['witness_type'])
     for ti in tx['inputs']:
         t.add_input(prev_hash=ti['prev_hash'],
                     output_n=ti['output_n'],
                     index_n=ti['index_n'],
                     unlocking_script=ti['script'],
                     value=ti['value'],
                     public_hash=to_bytes(ti['public_hash']),
                     address=ti['address'],
                     witness_type=ti['witness_type'],
                     locktime_cltv=ti['locktime_cltv'],
                     locktime_csv=ti['locktime_csv'],
                     signatures=ti['signatures'],
                     compressed=ti['compressed'],
                     encoding=ti['encoding'],
                     unlocking_script_unsigned=ti['script_code'],
                     sigs_required=ti['sigs_required'])
     for to in tx['outputs']:
         t.add_output(value=to['value'],
                      address=to['address'],
                      public_hash=to['public_hash'],
                      lock_script=to['script'],
                      spent=to['spent'])
     if t.coinbase:  # TODO: Remove when blocksmurfer is fixed
         t.inputs[0].value = 0
     t.update_totals()
     return t
示例#20
0
 def get_burn_msg(self, symbol: str, amount: number_type):
     """ Generate burn_token StdMsg and SignMessage"""
     amount = int(Decimal(amount) * BASE)
     self.msg = {"from": self.address, "symbol": symbol, "amount": amount}
     self.StdSignMsg["msgs"] = [self.msg]
     self.SignMessage = json.dumps(
         self.StdSignMsg, sort_keys=True, separators=(",", ":")
     ).encode()
     std = Burn()
     setattr(std, "from", address_decode(self.address))
     std.symbol = symbol
     std.amount = amount
     self.stdMsg = encoding.to_bytes(TYPE_PREFIX["Burn"]) + std.SerializeToString()
     return self.SignMessage
示例#21
0
    def _parse_transaction(self, tx):
        status = 'unconfirmed'
        if tx['confirmations']:
            status = 'confirmed'
        witness_type = 'legacy'
        if 'inputs' in tx and [ti['witness'] for ti in tx['inputs'] if ti['witness'] and ti['witness'] != ['NULL']]:
            witness_type = 'segwit'
        input_total = tx['input_amount_int']
        t_time = None
        if tx['time']:
            t_time = datetime.utcfromtimestamp(tx['time'])
        if tx['coinbase']:
            input_total = tx['output_amount_int']
        t = Transaction(locktime=tx['locktime'], version=int(tx['version']), network=self.network, fee=tx['fee_int'],
                        size=tx['size'], hash=tx['txid'], date=t_time,
                        confirmations=tx['confirmations'], block_height=tx['block'], status=status,
                        input_total=input_total, coinbase=tx['coinbase'],
                        output_total=tx['output_amount_int'], witness_type=witness_type)
        index_n = 0
        if tx['coinbase']:
            t.add_input(prev_hash=b'\00' * 32, output_n=0, value=input_total)
        else:
            for ti in tx['inputs']:
                unlocking_script = ti['script_sig']['hex']
                witness_type = 'legacy'
                if ti['witness'] and ti['witness'] != ['NULL']:
                    address = Address.import_address(ti['addresses'][0])
                    if address.script_type == 'p2sh':
                        witness_type = 'p2sh-segwit'
                    else:
                        witness_type = 'segwit'
                    unlocking_script = b"".join([varstr(to_bytes(x)) for x in ti['witness']])
                t.add_input(prev_hash=ti['txid'], output_n=ti['vout'], unlocking_script=unlocking_script,
                            index_n=index_n, value=ti['value_int'], address=ti['addresses'][0], sequence=ti['sequence'],
                            witness_type=witness_type)
                index_n += 1

        for to in tx['outputs']:
            spent = False
            spending_txid = None
            if 'spend_txid' in to and to['spend_txid']:
                spent = True
                spending_txid = to['spend_txid']
            address = ''
            if to['addresses']:
                address = to['addresses'][0]
            t.add_output(value=to['value_int'], address=address, lock_script=to['script_pub_key']['hex'],
                         spent=spent, output_n=to['n'], spending_txid=spending_txid)
        return t
示例#22
0
    def gettransaction(self, tx_id):
        res = self.compose_request('dashboards/transaction/', data=tx_id)

        tx = res['data'][tx_id]['transaction']
        confirmations = 0 if tx['block_id'] <= 0 else res['context']['state'] - tx['block_id']
        status = 'unconfirmed'
        if confirmations:
            status = 'confirmed'
        witness_type = 'legacy'
        if tx['has_witness']:
            witness_type = 'segwit'
        input_total = tx['input_total']
        t = Transaction(locktime=tx['lock_time'], version=tx['version'], network=self.network,
                        fee=tx['fee'], size=tx['size'], hash=tx['hash'],
                        date=None if not confirmations else datetime.strptime(tx['time'], "%Y-%m-%d %H:%M:%S"),
                        confirmations=confirmations, block_height=tx['block_id'] if tx['block_id'] > 0 else None, status=status,
                        input_total=input_total, coinbase=tx['is_coinbase'],
                        output_total=tx['output_total'], witness_type=witness_type)
        index_n = 0
        if not res['data'][tx_id]['inputs']:
            # This is a coinbase transaction, add input
            t.add_input(prev_hash=b'\00' * 32, output_n=0, value=0)

        for ti in res['data'][tx_id]['inputs']:
            if ti['spending_witness']:
                witnesses = b"".join([varstr(to_bytes(x)) for x in ti['spending_witness'].split(",")])
                address = Address.import_address(ti['recipient'])
                if address.script_type == 'p2sh':
                    witness_type = 'p2sh-segwit'
                else:
                    witness_type = 'segwit'
                t.add_input(prev_hash=ti['transaction_hash'], output_n=ti['index'],
                            unlocking_script=witnesses, index_n=index_n, value=ti['value'],
                            address=address, witness_type=witness_type)
            else:
                t.add_input(prev_hash=ti['transaction_hash'], output_n=ti['index'],
                            unlocking_script=ti['spending_signature_hex'], index_n=index_n, value=ti['value'],
                            address=ti['recipient'], unlocking_script_unsigned=ti['script_hex'])
            index_n += 1
        for to in res['data'][tx_id]['outputs']:
            try:
                deserialize_address(to['recipient'], network=self.network.name)
                addr = to['recipient']
            except EncodingError:
                addr = ''
            t.add_output(value=to['value'], address=addr, lock_script=to['script_hex'],
                         spent=to['is_spent'], output_n=to['index'], spending_txid=to['spending_transaction_hash'],
                         spending_index_n=to['spending_index'])
        return t
示例#23
0
 def get_cancel_order_msg(self, symbol: str, refid: str):
     """Generate cancel_order StdMsg for StdTx and SignMessage for current transaction"""
     self.msg = {"sender": self.address, "symbol": symbol, "refid": refid}
     self.StdSignMsg["msgs"] = [self.msg]
     self.SignMessage = json.dumps(
         self.StdSignMsg, sort_keys=True, separators=(",", ":")
     ).encode()
     std = CancelOrder()
     std.symbol = symbol
     std.sender = address_decode(self.address)
     std.refid = refid
     self.stdMsg = (
         encoding.to_bytes(TYPE_PREFIX["CancelOrder"]) + std.SerializeToString()
     )
     return self.SignMessage
示例#24
0
    def checksum(data):
        """
        Calculates checksum for given data key

        :param data: key string
        :type data: bytes, hexstring
        
        :return str: Checksum of key in bits
        """
        data = to_bytes(data)
        if len(data) % 4 > 0:
            raise ValueError('Data length in bits should be divisible by 32, but it is not (%d bytes = %d bits).' %
                             (len(data), len(data) * 8))
        tx_hash = hashlib.sha256(data).digest()
        return change_base(tx_hash, 256, 2, 256)[:len(data) * 8 // 32]
示例#25
0
 def getblock(self, blockid):
     if not SERVICE_CACHING_ENABLED:
         return False
     qr = self.session.query(DbCacheBlock)
     if isinstance(blockid, int):
         block = qr.filter_by(height=blockid, network_name=self.network.name).scalar()
     else:
         block = qr.filter_by(block_hash=to_bytes(blockid)).scalar()
     if not block:
         return False
     b = Block(block_hash=block.block_hash, height=block.height, network=block.network_name,
               merkle_root=block.merkle_root, time=block.time, nonce=block.nonce,
               version=block.version, prev_block=block.prev_block, bits=block.bits)
     b.tx_count = block.tx_count
     _logger.info("Retrieved block with height %d from cache" % b.height)
     return b
示例#26
0
 def get_unfreeze_token_msg(self, symbol: str, amount: number_type):
     """Generate unfreeze_token StdMsg for StdTx and SignMessage for current transaction"""
     amount = int(Decimal(amount) * BASE)
     self.msg = {"from": self.address, "symbol": symbol, "amount": amount}
     self.StdSignMsg["msgs"] = [self.msg]
     self.SignMessage = json.dumps(
         self.StdSignMsg, sort_keys=True, separators=(",", ":")
     ).encode()
     std = Freeze()
     setattr(std, "from", address_decode(self.address))
     std.symbol = symbol
     std.amount = amount
     self.stdMsg = (
         encoding.to_bytes(TYPE_PREFIX["TokenUnfreeze"]) + std.SerializeToString()
     )
     return self.SignMessage
示例#27
0
 def generate_stdNewOrderMsg(self, msg: dict) -> bytes:
     """Generate StdMsg part of StdTx"""
     std = NewOrder()
     std.sender = address_decode(self.address)
     std.id = generate_id(self.address, self.sequence)
     std.ordertype = msg[
         "ordertype"
     ]  # currently only 1 type : limit =2, will change in the future
     std.symbol = msg["symbol"].encode()
     std.side = msg["side"]
     std.price = msg["price"]
     std.quantity = msg["quantity"]
     std.timeinforce = msg["timeinforce"]
     proto_bytes = std.SerializeToString()
     type_bytes = encoding.to_bytes(TYPE_PREFIX["NewOrder"])
     return type_bytes + proto_bytes
示例#28
0
    def from_seed(import_seed, network=DEFAULT_NETWORK):
        """
        Used by class init function, import key from seed

        :param import_seed: Private key seed as bytes or hexstring
        :type import_seed: str, bytes
        :param network: Network to use
        :type network: str
        
        :return HDKey: 
        """
        seed = to_bytes(import_seed)
        I = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest()
        key = I[:32]
        chain = I[32:]
        return HDKey(key=key, chain=chain, network=network)
示例#29
0
 def get_vote_msg(self, proposal_id: Union[str, int], option: Votes):
     """Generate cancel_order StdMsg for StdTx and SignMessage for current transaction"""
     self.msg = {
         "proposal_id": proposal_id,
         "voter": self.address,
         "option": option.value,
     }
     self.StdSignMsg["msgs"] = [self.msg]
     self.SignMessage = json.dumps(
         self.StdSignMsg, sort_keys=True, separators=(",", ":")
     ).encode()
     std = Vote()
     std.voter = address_decode(self.address)
     std.proposal_id = proposal_id
     std.option = option.value
     self.stdMsg = encoding.to_bytes(TYPE_PREFIX["Vote"]) + std.SerializeToString()
     return self.SignMessage
示例#30
0
 def to_mnemonic(self, data, add_checksum=True):
     """
     Convert key data entropy to Mnemonic sentence
     
     :param data: Key data entropy
     :type data: bytes, hexstring
     :param add_checksum: Included a checksum? Default is True
     :type add_checksum: bool
     
     :return str: Mnemonic passphrase consisting of a space seperated list of words
     """
     data = to_bytes(data)
     if add_checksum:
         binresult = change_base(data, 256, 2, len(data) * 8) + self.checksum(data)
         wi = change_base(binresult, 2, 2048)
     else:
         wi = change_base(data, 256, 2048)
     return normalize_string(' '.join([self._wordlist[i] for i in wi]))