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)
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)
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 )
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)
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
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
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
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
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]))
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
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
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]))
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')
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)
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
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')
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': {}}
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
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
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
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
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
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]
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
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
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
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)
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
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]))