def test_from_nonstd_scriptPubKey(self) -> None: """CBitcoinAddress.from_scriptPubKey() with non-standard scriptPubKeys""" # Bad P2SH scriptPubKeys # non-canonical pushdata scriptPubKey = CScript(x('a94c14000000000000000000000000000000000000000087')) with self.assertRaises(CBitcoinAddressError): CBitcoinAddress.from_scriptPubKey(scriptPubKey) # Bad P2PKH scriptPubKeys # Missing a byte scriptPubKey = CScript(x('76a914000000000000000000000000000000000000000088')) with self.assertRaises(CBitcoinAddressError): CBitcoinAddress.from_scriptPubKey(scriptPubKey) # One extra byte scriptPubKey = CScript(x('76a914000000000000000000000000000000000000000088acac')) with self.assertRaises(CBitcoinAddressError): CBitcoinAddress.from_scriptPubKey(scriptPubKey) # One byte changed scriptPubKey = CScript(x('76a914000000000000000000000000000000000000000088ad')) with self.assertRaises(CBitcoinAddressError): CBitcoinAddress.from_scriptPubKey(scriptPubKey)
def test_from_invalid_scriptPubKey(self) -> None: """CBitcoinAddress.from_scriptPubKey() with invalid scriptPubKeys""" # We should raise a CBitcoinAddressError, not any other type of error # Truncated P2SH scriptPubKey = CScript(x('a91400000000000000000000000000000000000000')) with self.assertRaises(CBitcoinAddressError): CBitcoinAddress.from_scriptPubKey(scriptPubKey) # Truncated P2PKH scriptPubKey = CScript(x('76a91400000000000000000000000000000000000000')) with self.assertRaises(CBitcoinAddressError): CBitcoinAddress.from_scriptPubKey(scriptPubKey)
def _address_from_vout(self, txid, vout): script = vout.scriptPubKey if len(script) >= 38 and script[:6] == bitcoin.core.WITNESS_COINBASE_SCRIPTPUBKEY_MAGIC: return try: script = CScript(vout.scriptPubKey) if script.is_unspendable(): self.log.warn("Unspendable %s" % vout.scriptPubKey) if vout.scriptPubKey[2:4] == b'\xfe\xab': m = vout.scriptPubKey[4:].decode('utf-8') Message.create(message=m) return return str(TX_CBitcoinAddress.from_scriptPubKey(script)) except: self.log.warn('scriptPubKey invalid txid=%s scriptPubKey=%s value=%s' % (txid, b2lx(vout.scriptPubKey), vout.nValue))
def payment_ack(serialized_Payment_message): """Generates a PaymentACK object, captures client refund address and returns a message""" pao = o.PaymentACK() pao.payment.ParseFromString(serialized_Payment_message) pao.memo = 'String shown to user after payment confirmation' refund_address = CBitcoinAddress.from_scriptPubKey( CScript(pao.payment.refund_to[0].script)) sds_pa = pao.SerializeToString() open('sds_pa_blob', 'wb').write(sds_pa) headers = { 'Content-Type': 'application/bitcoin-payment', 'Accept': 'application/bitcoin-paymentack' } http_response_object = urllib2.Request('file:sds_pa_blob', None, headers) return http_response_object
def parse_vout(self, tx, txid, tx_data, vout, idx, batch=None, blockHeight=None): script = vout.scriptPubKey if len(script) >= 38 and script[:6] == bitcoin.core.WITNESS_COINBASE_SCRIPTPUBKEY_MAGIC: return try: script = CScript(vout.scriptPubKey) if script.is_unspendable(): self.log.warn("Unspendable %s" % vout.scriptPubKey) if vout.scriptPubKey[2:4] == b'\xfe\xab': m = vout.scriptPubKey[4:].decode('utf-8') Message.create(message=m) return address = str(TX_CBitcoinAddress.from_scriptPubKey(script)) except: self.log.warn('scriptPubKey invalid txid=%s scriptPubKey=%s value=%s' % (txid, b2lx(vout.scriptPubKey), vout.nValue)) return value = vout.nValue self.pututxo(txid, idx, address, value, wb=batch, scriptPubKey=vout.scriptPubKey.hex(), blockHeight=blockHeight) tx_data["vout"].append({"address": address, "value": value, "vout": idx}) if address in tx_data["addresses_out"]: tx_data["addresses_out"][address] += value else: tx_data["addresses_out"][address] = value tx_data["output_value"] += value # Update address tracking only when non-mempool (batch is not none) if batch: self.log.debug("Updating address %s with value %s" % (address, value)) if address in self.address_changes: self.address_changes[address]['balance'] += value self.address_changes[address]['received'] += value else: self.address_changes[address] = { 'balance': value, 'received': value, 'sent': 0, }
def T(hex_scriptpubkey: str, expected_str_address: str, expected_class: type) -> None: scriptPubKey = CScript(x(hex_scriptpubkey)) addr = CBitcoinAddress.from_scriptPubKey(scriptPubKey) self.assertEqual(str(addr), expected_str_address) self.assertEqual(addr.__class__, expected_class)
seckey = CBitcoinKey.from_secret_bytes(h) # Create a redeemScript. Similar to a scriptPubKey the redeemScript must be # satisfied for the funds to be spent. txin_redeemScript = CScript([seckey.pub, OP_CHECKSIG]) print(b2x(txin_redeemScript)) # Create the magic P2SH scriptPubKey format from that redeemScript. You should # look at the CScript.to_p2sh_scriptPubKey() function in bitcointx.core.script # to understand what's happening, as well as read BIP16: # https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey() # Convert the P2SH scriptPubKey to a base58 Bitcoin address and print it. # You'll need to send some funds to it to create a txout to spend. txin_p2sh_address = CBitcoinAddress.from_scriptPubKey(txin_scriptPubKey) print('Pay to:', str(txin_p2sh_address)) # Same as the txid:vout the createrawtransaction RPC call requires # # lx() takes *little-endian* hex and converts it to bytes; in Bitcoin # transaction hashes are shown little-endian rather than the usual big-endian. # There's also a corresponding x() convenience function that takes big-endian # hex and converts it to bytes. txid = lx('bff785da9f8169f49be92fa95e31f0890c385bfb1bd24d6b94d7900057c617ae') vout = 0 # Create the txin structure, which includes the outpoint. The scriptSig # defaults to being empty. txin = CMutableTxIn(COutPoint(txid, vout))