def get_tx_data(tx_hex): """Accepts unsigned transactions.""" tx = bitcoin.rpc('decoderawtransaction', [tx_hex]) # Get destination output and data output. destination, btc_amount, data = None, None, b'' for vout in tx['vout']: # Sum data chunks to get data. (Can mix OP_RETURN and multi-sig.) asm = vout['scriptPubKey']['asm'].split(' ') if asm[0] == 'OP_RETURN' and len(asm) == 2: # OP_RETURN data_chunk = binascii.unhexlify(bytes(asm[1], 'utf-8')) data += data_chunk elif asm[0] == '1' and asm[3] == '2' and asm[ 4] == 'OP_CHECKMULTISIG': # Multi-sig data_pubkey = binascii.unhexlify(bytes(asm[2], 'utf-8')) data_chunk_length = data_pubkey[0] # No ord() necessary?! data_chunk = data_pubkey[1:data_chunk_length + 1] data += data_chunk # Destination is the first output before the data. if not destination and not btc_amount and not data: if 'addresses' in vout['scriptPubKey']: address = vout['scriptPubKey']['addresses'][0] if bitcoin.base58_decode( address, config.ADDRESSVERSION): # If address is valid... destination, btc_amount = address, round( D(vout['value']) * config.UNIT) continue return destination, btc_amount, data
def get_tx_data (tx_hex): """Accepts unsigned transactions.""" tx = bitcoin.rpc('decoderawtransaction', [tx_hex]) # Get destination output and data output. destination, btc_amount, data = None, None, b'' for vout in tx['vout']: # Sum data chunks to get data. (Can mix OP_RETURN and multi-sig.) asm = vout['scriptPubKey']['asm'].split(' ') if asm[0] == 'OP_RETURN' and len(asm) == 2: # OP_RETURN data_chunk = binascii.unhexlify(bytes(asm[1], 'utf-8')) data += data_chunk elif asm[0] == '1' and asm[3] == '2' and asm[4] == 'OP_CHECKMULTISIG': # Multi-sig data_pubkey = binascii.unhexlify(bytes(asm[2], 'utf-8')) data_chunk_length = data_pubkey[0] # No ord() necessary?! data_chunk = data_pubkey[1:data_chunk_length + 1] data += data_chunk # Destination is the first output before the data. if not destination and not btc_amount and not data: if 'addresses' in vout['scriptPubKey']: address = vout['scriptPubKey']['addresses'][0] if bitcoin.base58_decode(address, config.ADDRESSVERSION): # If address is valid... destination, btc_amount = address, round(D(vout['value']) * config.UNIT) continue return destination, btc_amount, data
def test_base58_decode(): """ mainnet addresses here The leading zeros are not included in the pubkeyhash: see <http://www.bitcoinsecurity.org/wp-content/uploads/2012/07/tx_binary_map.png>. """ address = '16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM' pubkeyhash = bitcoin.base58_decode(address, b'\x00') assert binascii.hexlify(pubkeyhash).decode('utf-8') == '010966776006953D5567439E5E39F86A0D273BEE'.lower() assert len(pubkeyhash) == 20
def balances (address): if not bitcoin.base58_decode(address, config.ADDRESSVERSION): raise exceptions.InvalidAddressError('Not a valid Bitcoin address:', address) address_data = util.get_address(db, address=address) balances = address_data['balances'] table = PrettyTable(['Asset', 'Amount']) table.add_row(['BTC', bitcoin.get_btc_balance(address, normalize=True)]) # BTC for balance in balances: asset = balance['asset'] quantity = util.devise(db, balance['quantity'], balance['asset'], 'output') table.add_row([asset, quantity]) print('Balances') print(table.get_string())
def balances (address): if not bitcoin.base58_decode(address, config.ADDRESSVERSION): raise exceptions.AddressError('Not a valid Bitcoin address:', address) address_data = get_address(db, address=address) balances = address_data['balances'] table = PrettyTable(['Asset', 'Amount']) table.add_row(['BTC', bitcoin.get_btc_balance(address, normalize=True)]) # BTC for balance in balances: asset = balance['asset'] quantity = util.devise(db, balance['quantity'], balance['asset'], 'output') table.add_row([asset, quantity]) print('Balances') print(table.get_string())
def get_tx_data (tx_hex): """Accepts unsigned transactions.""" tx = bitcoin.rpc('decoderawtransaction', [tx_hex])['result'] # Get destination output and data output. destination, btc_amount, data = None, None, None for vout in tx['vout']: # Destination is the first output before the data. if not destination and not btc_amount and not data: if 'addresses' in vout['scriptPubKey']: address = vout['scriptPubKey']['addresses'][0] if bitcoin.base58_decode(address, config.ADDRESSVERSION): # If address is valid… destination, btc_amount = address, round(D(vout['value']) * config.UNIT) # Assume only one OP_RETURN output. if not data: asm = vout['scriptPubKey']['asm'].split(' ') if asm[0] == 'OP_RETURN' and len(asm) == 2: data = binascii.unhexlify(asm[1]) return destination, btc_amount, data
unsigned_tx_hex = dividend.create(db, args.source, quantity_per_share, args.share_asset) json_print(bitcoin.transmit(unsigned_tx_hex, unsigned=args.unsigned)) elif args.action == 'burn': quantity = util.devise(db, args.quantity, 'BTC', 'input') unsigned_tx_hex = burn.create(db, args.source, quantity) json_print(bitcoin.transmit(unsigned_tx_hex, unsigned=args.unsigned)) elif args.action == 'cancel': unsigned_tx_hex = cancel.create(db, args.offer_hash) json_print(bitcoin.transmit(unsigned_tx_hex, unsigned=args.unsigned)) elif args.action == 'address': try: bitcoin.base58_decode(args.address, config.ADDRESSVERSION) except Exception: raise exceptions.InvalidAddressError('Invalid Bitcoin address:', args.address) address(args.address) elif args.action == 'asset': if args.asset == 'XCP': burns = util.get_burns(db, validity='Valid', address=None) total = sum([burn['earned'] for burn in burns]) total = util.devise(db, total, args.asset, 'output') divisible = True issuer = None elif args.asset == 'BTC': total = None divisible = True
quantity = util.devise(db, args.quantity, 'BTC', 'input') cli('create_burn', [args.source, quantity], args.unsigned) elif args.action == 'cancel': cli('create_cancel', [args.offer_hash], args.unsigned) elif args.action == 'callback': cli('create_callback', [ args.source, util.devise(db, args.fraction, 'fraction', 'input'), args.asset ], args.unsigned) # VIEWING (temporary) elif args.action == 'balances': try: bitcoin.base58_decode(args.address, config.ADDRESSVERSION) except Exception: raise exceptions.InvalidAddressError('Invalid Bitcoin address:', args.address) balances(args.address) elif args.action == 'asset': results = util.api('get_asset_info', [args.asset]) asset_id = util.get_asset_id(args.asset) divisible = results['divisible'] total_issued = util.devise(db, results['total_issued'], args.asset, dest='output') call_date = util.isodt( results['call_date']
elif args.action == 'cancel': if args.fee: args.fee = util.devise(db, args.fee, 'BTC', 'input') cli('create_cancel', {'source': args.source, 'offer_hash': args.offer_hash, 'fee': args.fee, 'allow_unconfirmed_inputs': args.unconfirmed}, args.unsigned) elif args.action == 'callback': if args.fee: args.fee = util.devise(db, args.fee, 'BTC', 'input') cli('create_callback', {'source': args.source, 'fraction': util.devise(db, args.fraction, 'fraction', 'input'), 'asset': args.asset, 'fee': args.fee, 'allow_unconfirmed_inputs': args.unconfirmed}, args.unsigned) # VIEWING (temporary) elif args.action == 'balances': try: bitcoin.base58_decode(args.address, config.ADDRESSVERSION, config.ADDRESSVERSION_MULTISIG) except Exception: raise exceptions.AddressError('Invalid Bitcoin address:', args.address) balances(args.address) elif args.action == 'asset': results = util.api('get_asset_info', ([args.asset],)) if results: results = results[0] # HACK else: print('Asset ‘{}’ not found.'.format(args.asset)) exit(0) asset_id = util.asset_id(args.asset) divisible = results['divisible']