def raw_bip32_ckd(rawtuple, i): vbytes, depth, fingerprint, oldi, chaincode, key = rawtuple i = int(i) if vbytes in PRIVATE: priv = key pub = privtopub(key) else: pub = key if i >= 2**31: if vbytes in PUBLIC: raise Exception("Can't do private derivation on public key!") I = hmac.new(chaincode, b'\x00' + priv[:32] + struct.pack(b'>L', i), hashlib.sha512).digest() else: I = hmac.new(chaincode, pub + struct.pack(b'>L', i), hashlib.sha512).digest() if vbytes in PRIVATE: newkey = add_privkeys(I[:32] + b'\x01', priv) fingerprint = Hash160(privtopub(key))[:4] if vbytes in PUBLIC: newkey = add_pubkeys([privtopub(I[:32] + b'\x01'), key]) fingerprint = Hash160(key)[:4] return (vbytes, depth + 1, fingerprint, i, I[32:], newkey)
def sign_input(tx, input_index, utxo): """Sign an input of transaction. Single-signature signing with SIGHASH_ALL""" key = utxo['key'] src_addr = CCoinAddress(utxo['address']) script_for_sighash = CScript( [OP_DUP, OP_HASH160, Hash160(key.pub), OP_EQUALVERIFY, OP_CHECKSIG]) assert isinstance(src_addr, (P2PKHCoinAddress, P2SHCoinAddress, P2WPKHCoinAddress)),\ 'only p2pkh, p2wpkh and p2sh_p2wpkh addresses are supported' if isinstance(src_addr, P2PKHCoinAddress): sigversion = SIGVERSION_BASE else: sigversion = SIGVERSION_WITNESS_V0 if 'amountcommitment' in utxo: amountcommitment = CConfidentialValue(x(utxo['amountcommitment'])) else: amountcommitment = CConfidentialValue(coins_to_satoshi(utxo['amount'])) sighash = script_for_sighash.sighash(tx, input_index, SIGHASH_ALL, amount=amountcommitment, sigversion=sigversion) sig = key.sign(sighash) + bytes([SIGHASH_ALL]) if isinstance(src_addr, P2PKHCoinAddress): tx.vin[input_index].scriptSig = CScript( [CScript(sig), CScript(key.pub)]) scriptpubkey = src_addr.to_scriptPubKey() elif isinstance(src_addr, P2WPKHCoinAddress): tx.vin[input_index].scriptSig = CScript() tx.wit.vtxinwit[input_index] = CTxInWitness( CScriptWitness([CScript(sig), CScript(key.pub)])) scriptpubkey = src_addr.to_scriptPubKey() else: # Assume that this is p2sh-wrapped p2wpkh address inner_scriptPubKey = CScript([0, Hash160(key.pub)]) tx.vin[input_index].scriptSig = CScript([inner_scriptPubKey]) tx.wit.vtxinwit[input_index] = CTxInWitness( CScriptWitness([CScript(sig), CScript(key.pub)])) scriptpubkey = inner_scriptPubKey.to_p2sh_scriptPubKey() VerifyScript(tx.vin[input_index].scriptSig, scriptpubkey, tx, input_index, amount=amountcommitment, flags=(SCRIPT_VERIFY_P2SH, ))
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 __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 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 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))
async def async_testnet() -> None: select_chain_params('bitcoin/testnet') await wait_async('regtest') a = P2SHCoinAddress.from_redeemScript( CScript(b'\xa9' + Hash160(pub) + b'\x87')) assert CBase58Data(str(a))[0] == 196 check_core_modules() ready('testnet') await wait_async('mainnet') self.assertEqual(get_current_chain_params().NAME, 'bitcoin/testnet') finish('testnet')
def __new__(cls, buf=b''): self = super().__new__(cls, buf) self._fullyvalid = False if self.is_valid(): tmp_pub = ctypes.create_string_buffer(64) result = _secp256k1.secp256k1_ec_pubkey_parse( secp256k1_context_verify, tmp_pub, self, len(self)) self._fullyvalid = (result == 1) self.key_id = Hash160(self) return self
async def async_regtest() -> None: select_chain_params('bitcoin/regtest') a = P2WPKHCoinAddress.from_pubkey(pub) witver, data = bitcointx.segwit_addr.decode( P2WPKHBitcoinRegtestAddress.bech32_hrp, str(a)) assert witver == 0 assert data == Hash160(pub) check_core_modules() ready('regtest') await wait_async('testnet') await wait_async('mainnet') self.assertEqual(get_current_chain_params().NAME, 'bitcoin/regtest') finish('regtest')
def test_confidenital(aclass, pub): if getattr(aclass, '_unconfidential_address_class', None): ucaclass = aclass._unconfidential_address_class if getattr(ucaclass, 'from_pubkey', None): a = ucaclass.from_pubkey(pub) else: a = ucaclass.from_redeemScript( CScript(b'\xa9' + Hash160(pub) + b'\x87')) ca = aclass.from_unconfidential(a, pub) self.assertEqual(ca.blinding_pubkey, pub) self.assertEqual(ca.to_unconfidential(), a) ca2 = CCoinConfidentialAddress(str(ca)) self.assertEqual(ca, ca2) ca2 = CCoinConfidentialAddress.from_unconfidential(a, pub) self.assertEqual(ca, ca2) return True return False
def make_scripts(lines, n): # The n makes sure every p2sh addr is unique; the pubkey lets us # control the order the vin order vs. just using hashlocks. redeemScript = [] for chunk in reversed(lines): if len(chunk) > MAX_SCRIPT_ELEMENT_SIZE: parser.exit('Lines must be less than %d characters; ' 'got %d characters' % (MAX_SCRIPT_ELEMENT_SIZE, len(chunk))) redeemScript.extend([OP_HASH160, Hash160(chunk), OP_EQUALVERIFY]) redeemScript = CScript(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) + redeemScript, redeemScript
# hex and converts it to bytes. txid = lx('7e195aa3de827814f172c362fcf838d92ba10e3f9fdd9c3ecaf79522b311b22d') vout = 0 # Create the txin structure, which includes the outpoint. The scriptSig # defaults to being empty. txin = CMutableTxIn(COutPoint(txid, vout)) # We also need the scriptPubKey of the output we're spending because # SignatureHash() replaces the transaction scriptSig's with it. # # Here we'll create that scriptPubKey from scratch using the pubkey that # corresponds to the secret key we generated above. txin_scriptPubKey = CScript( [OP_DUP, OP_HASH160, Hash160(seckey.pub), OP_EQUALVERIFY, OP_CHECKSIG]) # Create the txout. This time we create the scriptPubKey from a Bitcoin # address. txout = CMutableTxOut( 0.001 * COIN, CBitcoinAddress('1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8').to_scriptPubKey()) # Create the unsigned transaction. tx = CMutableTransaction([txin], [txout]) # Calculate the signature hash for that transaction. sighash = SignatureHash(txin_scriptPubKey, tx, 0, SIGHASH_ALL) # Now sign it. We have to append the type of signature we want to the end, in # this case the usual SIGHASH_ALL.
# use mypy to do static checking, we need to use the elements-specific # classes. mypy does cannot know about dynamic class dispatch. input_tx = CElementsTransaction.deserialize(x(f.readline().rstrip())) # Read in the key, expected to be in WIF format. with open(sys.argv[2]) as f: key = CCoinKey(f.readline().rstrip()) # Read in the unblinding key, expected to be in HEX format. with open(sys.argv[3]) as f: bkey = CCoinKey.from_secret_bytes(x(f.readline().rstrip())) dst_addr = CElementsAddress(sys.argv[4]) # Construct P2SH_P2WPKH address from the loaded key spk = CScript([0, Hash160(key.pub)]).to_p2sh_scriptPubKey() src_addr = P2SHCoinAddress.from_scriptPubKey(spk) sys.stderr.write( '\nSearching for ouptut with address {}\n'.format(src_addr)) utxo = None fee_asset = None # Search for output in the transaction that spends to the address that # we have. We are going to spend the first output that we find. for in_n, in_vout in enumerate(input_tx.vout): if utxo is None and in_vout.scriptPubKey == src_addr.to_scriptPubKey(): utxo = in_vout utxo_n = in_n if in_vout.is_fee(): assert fee_asset is None or fee_asset == in_vout.nAsset,\