def test_p2wsh_signaturehash2(self): unsigned_tx = x( '0100000002e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac00000000' ) value1 = coins_to_satoshi(0.16777215) scriptcode1 = CScript( x('0063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac' )) value2 = coins_to_satoshi(0.16777215) scriptcode2 = CScript( x('68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac' )) self.assertEqual( SignatureHash(scriptcode1, CTransaction.deserialize(unsigned_tx), 0, SIGHASH_SINGLE | SIGHASH_ANYONECANPAY, value1, SIGVERSION_WITNESS_V0), x('e9071e75e25b8a1e298a72f0d2e9f4f95a0f5cdf86a533cda597eb402ed13b3a' )) self.assertEqual( SignatureHash(scriptcode2, CTransaction.deserialize(unsigned_tx), 1, SIGHASH_SINGLE | SIGHASH_ANYONECANPAY, value2, SIGVERSION_WITNESS_V0), x('cd72f1f1a433ee9df816857fad88d8ebd97e09a75cd481583eb841c330275e54' ))
def parse_script(s: str) -> CScript: def ishex(s: str) -> bool: return set(s).issubset(set('0123456789abcdefABCDEF')) r: List[bytes] = [] # Create an opcodes_by_name table with both OP_ prefixed names and # shortened ones with the OP_ dropped. opcodes_by_name = {} for name, code in OPCODES_BY_NAME.items(): opcodes_by_name[name] = code opcodes_by_name[name[3:]] = code for word in s.split(): if word.isdigit() or (word[0] == '-' and word[1:].isdigit()): r.append(CScript([int(word)])) elif word.startswith('0x') and ishex(word[2:]): # Raw ex data, inserted NOT pushed onto stack: r.append(unhexlify(word[2:].encode('utf8'))) elif len(word) >= 2 and word[0] == "'" and word[-1] == "'": r.append(CScript([bytes(word[1:-1].encode('utf8'))])) elif word in opcodes_by_name: r.append(CScript([opcodes_by_name[word]])) else: raise ValueError("Error parsing script: %r" % s) return CScript(b''.join(r))
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 make_scripts(lines: List[bytes], n: int) -> Tuple[CScript, CScript]: # The n makes sure every p2sh addr is unique; the pubkey lets us # control the order the vin order vs. just using hashlocks. redeemScript: List[ScriptElement_Type] = [] for chunk in reversed(lines): if len(chunk) > MAX_SCRIPT_ELEMENT_SIZE: parser.exit( status=-1, message=('Error: lines must be less than %d characters; ' 'got %d characters\n' % (MAX_SCRIPT_ELEMENT_SIZE, len(chunk)))) redeemScript.extend([OP_HASH160, Hash160(chunk), OP_EQUALVERIFY]) redeemScript += [ args.privkey.pub, OP_CHECKSIGVERIFY, # deduplicate push dropped to meet BIP62 rules n, OP_DROP, # prevent scriptSig malleability OP_DEPTH, 0, OP_EQUAL ] return CScript(lines) + CScript(redeemScript), CScript(redeemScript)
def test_blind_unnblind_sign(self): if not secp256k1_has_zkp: warn_zkp_unavailable() return with open( os.path.dirname(__file__) + '/data/elements_txs_blinding.json', 'r') as fd: for bundle in json.load(fd): blinded_tx_raw = x(bundle['blinded']['hex']) blinded_tx = CTransaction.deserialize(blinded_tx_raw) self.assertEqual(blinded_tx.serialize(), blinded_tx_raw) self.check_serialize_deserialize(blinded_tx, blinded_tx_raw, bundle['blinded']) unblinded_tx_raw = x(bundle['unblinded']['hex']) unblinded_tx = CTransaction.deserialize(unblinded_tx_raw) self.assertEqual(unblinded_tx.serialize(), unblinded_tx_raw) self.check_serialize_deserialize(unblinded_tx, unblinded_tx_raw, bundle['unblinded']) signed_tx_raw = x(bundle['signed_hex']) signed_tx = CTransaction.deserialize(signed_tx_raw) self.assertEqual(signed_tx.serialize(), signed_tx_raw) blinding_derivation_key = CKey( lx(bundle['blinding_derivation_key'])) # ensure that str and repr works for f in (str, repr): f(unblinded_tx) f(blinded_tx) f(signed_tx) if len(blinded_tx.vout) != len(unblinded_tx.vout): assert len(blinded_tx.vout) == len(unblinded_tx.vout) + 1 assert blinded_tx.vout[-1].scriptPubKey == b'\x6a',\ "expected last output of blinded tx to be OP_RETURN" scriptPubKey = CScript([OP_RETURN]) unblinded_tx = unblinded_tx.to_mutable() unblinded_tx.vout.append( CMutableTxOut( nValue=CConfidentialValue(0), nAsset=CConfidentialAsset( unblinded_tx.vout[-1].nAsset.to_asset()), nNonce=CConfidentialNonce( scriptPubKey.derive_blinding_key( blinding_derivation_key).pub), scriptPubKey=scriptPubKey)) unblinded_tx = unblinded_tx.to_immutable() unblinded_tx_raw = unblinded_tx.serialize() self.check_blind(unblinded_tx, unblinded_tx_raw, blinded_tx, blinded_tx_raw, bundle, blinding_derivation_key) self.check_unblind(unblinded_tx, unblinded_tx_raw, blinded_tx, blinded_tx_raw, bundle, blinding_derivation_key) self.check_sign(blinded_tx, signed_tx, bundle)
def T(serialized1, serialized2, are_equal): script1 = CScript(x(serialized1)) script2 = CScript(x(serialized2)) if are_equal: self.assertEqual(script1, script2) else: self.assertNotEqual(script1, script2)
def __init__(self, key: CBitcoinSecret, address_type: str = "p2pkh"): self.key_index = None self.type = address_type self.key = key if address_type == "p2pkh": self.address = P2PKHBitcoinAddress.from_pubkey(self.key.pub) elif address_type == "p2sh": self.address = P2SHBitcoinAddress.from_redeemScript( CScript([self.key.pub, OP_CHECKSIG])) elif address_type == "p2wpkh": key_hash = Hash160(self.key.pub) script_pub_key = CScript([OP_0, key_hash]) self.address = P2WPKHBitcoinAddress.from_scriptPubKey( script_pub_key) elif address_type == "p2wsh": self.witness_program = CScript([self.key.pub, OP_CHECKSIG]) script_hash = hashlib.sha256(self.witness_program).digest() script_pub_key = CScript([OP_0, script_hash]) self.address = P2WSHBitcoinAddress.from_scriptPubKey( script_pub_key) else: raise UnsupportedAddressTypeError() self.value = 0 self.txid = None self.vout = None
def T(serialized1: str, serialized2: str, are_equal: bool) -> None: script1 = CScript(x(serialized1)) script2 = CScript(x(serialized2)) if are_equal: self.assertEqual(script1, script2) else: self.assertNotEqual(script1, script2)
def test_from_redeemScript(self) -> None: def T(script: CScript, expected_str_address: str) -> None: addr = P2SHBitcoinAddress.from_redeemScript(script) self.assertEqual(str(addr), expected_str_address) T(CScript(), '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy') T(CScript(x('76a914751e76e8199196d454941c45d1b3a323f1433bd688ac')), '3LRW7jeCvQCRdPF8S3yUCfRAx4eqXFmdcr')
def T(serialized_script, expected_tokens, test_roundtrip=True): serialized_script = x(serialized_script) script_obj = CScript(serialized_script) actual_tokens = list(script_obj) self.assertEqual(actual_tokens, expected_tokens) if test_roundtrip: recreated_script = CScript(actual_tokens) self.assertEqual(recreated_script, serialized_script)
def create_test_txs(self, scriptSig, scriptPubKey, witness, nValue): txCredit = CTransaction([CTxIn(COutPoint(), CScript([OP_0, OP_0]), nSequence=0xFFFFFFFF)], [CTxOut(nValue, scriptPubKey)], witness=CTxWitness(), nLockTime=0, nVersion=1) txSpend = CTransaction([CTxIn(COutPoint(txCredit.GetTxid(), 0), scriptSig, nSequence=0xFFFFFFFF)], [CTxOut(nValue, CScript())], nLockTime=0, nVersion=1, witness=CTxWitness([CTxInWitness(witness)])) return (txCredit, txSpend)
def test_repr(self): def T(script, expected_repr): actual_repr = repr(script) self.assertEqual(actual_repr, expected_repr) T(CScript([]), 'CBitcoinScript([])') T(CScript([1]), 'CBitcoinScript([1])') T(CScript([1, 2, 3]), 'CBitcoinScript([1, 2, 3])') T(CScript([1, x('7ac977d8373df875eceda362298e5d09d4b72b53'), OP_DROP]), "CBitcoinScript([1, x('7ac977d8373df875eceda362298e5d09d4b72b53'), OP_DROP])") T(CScript(x('0001ff515261ff')), "CBitcoinScript([0, x('ff'), 1, 2, OP_NOP, OP_INVALIDOPCODE])") # truncated scripts T(CScript(x('6101')), "CBitcoinScript([OP_NOP, x('')...<ERROR: PUSHDATA(1): truncated data>])") T(CScript(x('614bff')), "CBitcoinScript([OP_NOP, x('ff')...<ERROR: PUSHDATA(75): truncated data>])") T(CScript(x('614c')), "CBitcoinScript([OP_NOP, <ERROR: PUSHDATA1: missing data length>])") T(CScript(x('614c0200')), "CBitcoinScript([OP_NOP, x('00')...<ERROR: PUSHDATA1: truncated data>])")
def T(serialized_script_str: str, expected_tokens: List[Union[bytes, int]], test_roundtrip: bool = True) -> None: serialized_script = x(serialized_script_str) script_obj = CScript(serialized_script) actual_tokens = list(script_obj) self.assertEqual(actual_tokens, expected_tokens) if test_roundtrip: recreated_script = CScript(actual_tokens) self.assertEqual(recreated_script, serialized_script)
def generate_vault(): bitcointx.SelectParams('mainnet') m = int(input('How many total signatures will be required (aka "m"): ')) n = int(input('How many total keys do you want to generate (aka "n"): ')) privkeys = [] pubkeys = [] for counter in range(1, n): privkey = CBitcoinSecret.from_secret_bytes(os.urandom(32)) pubkey = privkey.pub privkeys.append(privkey) pubkeys.append(pubkey) counter = counter + 1 redeem_list = generate_multisig_redeem_list(pubkeys, m) script_pub_key = CScript([OP_0, sha256(CScript(redeem_list)).digest()]) address = P2WSHBitcoinAddress.from_scriptPubKey(script_pub_key) PATH = '/mnt/keys' if not os.path.isdir(PATH): subprocess.run(['mkdir', PATH]) counter = 1 while counter <= len(privkeys): if counter == 1: input('Insert a USB Drive. Press any key when complete.') else: input('Insert another USB Drive. Press any key when complete or \ press CTL+C to cancel.') subprocess.run(['lsblk']) dev = input( 'Enter the device and partition of the USB drive (ex: sdb1): ') subprocess.run(['umount', f'/dev/{dev}'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.run(['mount', f'/dev/{dev}', PATH]) try: if not dev: raise ValueError('Bad Path.') keypath = os.path.join(PATH, f'key{counter}') addresspath = os.path.join(PATH, 'address') scriptpath = os.path.join(PATH, 'script') with open(keypath, 'w') as key_file: key_file.write(str(privkeys[(counter - 1)])) with open(addresspath, 'w') as address_file: address_file.write(str(address)) with open(scriptpath, 'w') as script_file: script_file.write(str(redeem_list)) for file in [keypath, addresspath, scriptpath]: os.chmod(file, S_IREAD | S_IRGRP | S_IROTH) except Exception as e: print(e) print('Bad path given. Try again.') continue subprocess.run(['umount', f'/dev/{dev}']) counter = counter + 1 print('Process complete.')
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 check_sign(self, blinded_tx: CTransaction, signed_tx: CTransaction, bundle: Dict[str, Any]) -> None: tx_to_sign = blinded_tx.to_mutable() for n, vin in enumerate(tx_to_sign.vin): utxo = bundle['vin_utxo'][n] amount = -1 if utxo['amount'] == -1 else coins_to_satoshi( utxo['amount']) scriptPubKey = CScript(x(utxo['scriptPubKey'])) a = CCoinAddress(utxo['address']) if 'privkey' in utxo: privkey = CCoinKey(utxo['privkey']) assert isinstance(a, P2PKHCoinAddress),\ "only P2PKH is supported for single-sig" assert a == P2PKHElementsAddress.from_pubkey(privkey.pub) assert scriptPubKey == a.to_scriptPubKey() sighash = SignatureHash(scriptPubKey, tx_to_sign, n, SIGHASH_ALL, amount=amount, sigversion=SIGVERSION_BASE) sig = privkey.sign(sighash) + bytes([SIGHASH_ALL]) tx_to_sign.vin[n].scriptSig = CScript( [CScript(sig), CScript(privkey.pub)]) else: pk_list = [CCoinKey(pk) for pk in utxo['privkey_list']] redeem_script_data = [utxo['num_p2sh_participants']] redeem_script_data.extend([pk.pub for pk in pk_list]) redeem_script_data.extend([len(pk_list), OP_CHECKMULTISIG]) redeem_script = CScript(redeem_script_data) assert isinstance(a, P2SHCoinAddress),\ "only P2SH is supported for multi-sig." assert scriptPubKey == redeem_script.to_p2sh_scriptPubKey() assert a == P2SHElementsAddress.from_scriptPubKey( redeem_script.to_p2sh_scriptPubKey()) sighash = SignatureHash(redeem_script, tx_to_sign, n, SIGHASH_ALL, amount=amount, sigversion=SIGVERSION_BASE) sigs = [ pk.sign(sighash) + bytes([SIGHASH_ALL]) for pk in pk_list ] tx_to_sign.vin[n].scriptSig = CScript([b''] + sigs + [redeem_script]) VerifyScript(tx_to_sign.vin[n].scriptSig, scriptPubKey, tx_to_sign, n, amount=amount) self.assertEqual(tx_to_sign.serialize(), signed_tx.serialize())
def test_immutable_tx_creation_with_mutable_parts_specified(self): tx = CTransaction( vin=[CMutableTxIn(prevout=COutPoint(hash=b'a' * 32, n=0))], vout=[CMutableTxOut(nValue=1)], witness=CMutableTxWitness( [CMutableTxInWitness(CScriptWitness([CScript([0])]))])) def check_immutable_parts(tx): self.assertTrue(tx.vin[0].is_immutable()) self.assertTrue(tx.vin[0].is_immutable()) self.assertTrue(tx.vout[0].is_immutable()) self.assertTrue(tx.wit.is_immutable()) self.assertTrue(tx.wit.vtxinwit[0].is_immutable()) check_immutable_parts(tx) # Test that if we deserialize with CTransaction, # all the parts are immutable tx = CTransaction.deserialize(tx.serialize()) check_immutable_parts(tx) # Test some parts separately, because when created via # CMutableTransaction instantiation, they are created with from_* # methods, and not directly txin = CTxIn(prevout=CMutableOutPoint(hash=b'a' * 32, n=0)) self.assertTrue(txin.prevout.is_immutable()) wit = CTxWitness((CMutableTxInWitness(), )) self.assertTrue(wit.vtxinwit[0].is_immutable())
def test_from_bare_checksig_scriptPubKey(self): def T(hex_scriptpubkey, expected_str_address): scriptPubKey = CScript(x(hex_scriptpubkey)) # test that CBitcoinAddressError is raised, we do not support # bare checksig with self.assertRaises(CBitcoinAddressError): P2PKHBitcoinAddress.from_scriptPubKey(scriptPubKey) # compressed T( '21000000000000000000000000000000000000000000000000000000000000000000ac', '14p5cGy5DZmtNMQwTQiytBvxMVuTmFMSyU') # uncompressed T( '410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ac', '13VmALKHkCdSN1JULkP6RqW3LcbpWvgryV') # non-canonical encoding T( '4c21000000000000000000000000000000000000000000000000000000000000000000ac', '14p5cGy5DZmtNMQwTQiytBvxMVuTmFMSyU') # odd-lengths are *not* accepted with self.assertRaises(CBitcoinAddressError): P2PKHBitcoinAddress.from_scriptPubKey( CScript( x('2200000000000000000000000000000000000000000000000000000000000000000000ac' )))
def op_return(self): source = self.next_address("p2pkh") self.fund_address(source, 2 * self.fee) tx_ins = [CMutableTxIn(COutPoint(source.txid, source.vout))] tx_outs = [CMutableTxOut(Coin(self.fee).satoshi(), CScript([OP_RETURN, x("4c6f726420566f6c64656d6f7274")]))] tx = CMutableTransaction(tx_ins, tx_outs) key = source.key script = source.address.to_scriptPubKey() sig = self._sign(script, tx, 0, Coin(source.value).satoshi(), key) tx_ins[0].scriptSig = CScript([sig, key.pub]) txid = self._send_transaction(tx, []) self.log_value("op-return-tx", txid)
def test_repr(self): def T(txout, expected): actual = repr(txout) self.assertEqual(actual, expected) T(CMutableTxOut(1000, CScript(b'\x03abc')), "CBitcoinMutableTxOut(0.00001*COIN, CBitcoinScript([x('616263')]))")
def test_repr(self) -> None: def T(txout: CTxOut, expected: str) -> None: actual = repr(txout) self.assertEqual(actual, expected) T(CTxOut(1000, CScript(b'\x03abc')), "CBitcoinTxOut(0.00001*COIN, CBitcoinScript([x('616263')]))")
def listunspent(self, minconf=0, maxconf=9999999, addrs=None): """Return unspent transaction outputs in wallet Outputs will have between minconf and maxconf (inclusive) confirmations, optionally filtered to only include txouts paid to addresses in addrs. """ r = None if addrs is None: r = self._call('listunspent', minconf, maxconf) else: addrs = [str(addr) for addr in addrs] r = self._call('listunspent', minconf, maxconf, addrs) r2 = [] for unspent in r: unspent['outpoint'] = COutPoint(lx(unspent['txid']), unspent['vout']) del unspent['txid'] del unspent['vout'] # address isn't always available as Bitcoin Core allows scripts w/o # an address type to be imported into the wallet, e.g. non-p2sh # segwit try: unspent['address'] = CBitcoinAddress(unspent['address']) except KeyError: pass unspent['scriptPubKey'] = CScript( unhexlify(unspent['scriptPubKey'])) unspent['amount'] = int(unspent['amount'] * COIN) r2.append(unspent) return r2
def from_redeemScript(cls: Type[T_P2SHCoinAddress], redeemScript: CScript) -> T_P2SHCoinAddress: """Convert a redeemScript to a P2SH address Convenience function: equivalent to P2SHBitcoinAddress.from_scriptPubKey(redeemScript.to_p2sh_scriptPubKey()) """ return cls.from_scriptPubKey(redeemScript.to_p2sh_scriptPubKey())
def test_get_output_size(self) -> None: pub = CPubKey(x('0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71')) a0 = P2PKHCoinAddress.from_pubkey(pub) self.assertEqual(P2PKHCoinAddress.get_output_size(), 34) self.assertEqual(a0.get_output_size(), 34) a1 = P2WPKHCoinAddress.from_pubkey(pub) self.assertEqual(P2WPKHCoinAddress.get_output_size(), 31) self.assertEqual(a1.get_output_size(), 31) a2 = P2SHCoinAddress.from_redeemScript( CScript(b'\xa9' + Hash160(pub) + b'\x87')) self.assertEqual(P2SHCoinAddress.get_output_size(), 32) self.assertEqual(a2.get_output_size(), 32) a3 = P2WSHCoinAddress.from_redeemScript( CScript(b'\xa9' + Hash160(pub) + b'\x87')) self.assertEqual(P2WSHCoinAddress.get_output_size(), 43) self.assertEqual(a3.get_output_size(), 43)
def recursive_check(aclass: type) -> None: assert issubclass(aclass, CCoinAddress) if extra_addr_testfunc(aclass, pub): pass else: a = None if getattr(aclass, 'from_pubkey', None): a = aclass.from_pubkey(pub) elif getattr(aclass, 'from_redeemScript', None): a = aclass.from_redeemScript( CScript(b'\xa9' + Hash160(pub) + b'\x87')) else: assert len(dispatcher_mapped_list(aclass)) > 0,\ ("dispatcher mapped list for {} " "must not be empty".format(aclass)) if a is not None: spk = a.to_scriptPubKey() test.assertEqual(a, aclass.from_scriptPubKey(spk)) a2 = aclass.from_bytes(a) test.assertEqual(bytes(a), bytes(a2)) test.assertEqual(str(a), str(a2)) a3 = aclass(str(a)) test.assertEqual(bytes(a), bytes(a3)) test.assertEqual(str(a), str(a3)) for next_aclass in dispatcher_mapped_list(aclass): recursive_check(next_aclass)
def test_clone(self): outpoint = COutPoint( lx('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b' ), 0) txin = CMutableTxIn(prevout=outpoint, scriptSig=CScript(b'\x03abc'), nSequence=0xffffffff) self.assertEqual(txin.serialize(), txin.clone().serialize())
def get_unconfidential_address_samples(pub1, pub2): return AddressSamples( p2pkh=P2PKHCoinAddress.from_pubkey(pub1), p2wpkh=P2WPKHCoinAddress.from_pubkey(pub1), p2sh=P2SHCoinAddress.from_redeemScript( CScript(b'\xa9' + Hash160(pub1) + b'\x87')), p2wsh=P2WSHCoinAddress.from_redeemScript( CScript(b'\xa9' + Hash160(pub1) + b'\x87')), conf_p2pkh=P2PKHCoinConfidentialAddress.from_unconfidential( P2PKHCoinAddress.from_pubkey(pub1), pub2), conf_p2wpkh=P2WPKHCoinConfidentialAddress.from_unconfidential( P2WPKHCoinAddress.from_pubkey(pub1), pub2), conf_p2sh=P2SHCoinConfidentialAddress.from_unconfidential( P2SHCoinAddress.from_redeemScript( CScript(b'\xa9' + Hash160(pub1) + b'\x87')), pub2), conf_p2wsh=P2WSHCoinConfidentialAddress.from_unconfidential( P2WSHCoinAddress.from_redeemScript( CScript(b'\xa9' + Hash160(pub1) + b'\x87')), pub2))
def T(hex_scriptpubkey, expected_str_address): scriptPubKey = CScript(x(hex_scriptpubkey)) addr = P2PKHBitcoinAddress.from_scriptPubKey(scriptPubKey) self.assertEqual(str(addr), expected_str_address) # now test that CBitcoinAddressError is raised with accept_non_canonical_pushdata=False with self.assertRaises(CBitcoinAddressError): P2PKHBitcoinAddress.from_scriptPubKey( scriptPubKey, accept_bare_checksig=False)
def from_scriptPubKey(cls: Type[T_P2PKHCoinAddress], scriptPubKey: CScript) -> T_P2PKHCoinAddress: """Convert a scriptPubKey to a P2PKH address Raises CCoinAddressError if the scriptPubKey isn't of the correct form. """ if scriptPubKey.is_p2pkh(): return cls.from_bytes(scriptPubKey[3:23]) raise P2PKHCoinAddressError('not a P2PKH scriptPubKey')
def from_scriptPubKey(cls: Type[T_P2WPKHCoinAddress], scriptPubKey: CScript) -> T_P2WPKHCoinAddress: """Convert a scriptPubKey to a P2WPKH address Raises CCoinAddressError if the scriptPubKey isn't of the correct form. """ if scriptPubKey.is_witness_v0_keyhash(): return cls.from_bytes(scriptPubKey[2:22]) else: raise P2WPKHCoinAddressError('not a P2WPKH scriptPubKey')