def test_timelocked_output_signing(setup_wallet): jm_single().config.set('BLOCKCHAIN', 'network', 'testnet') ensure_bip65_activated() storage = VolatileStorage() SegwitLegacyWalletFidelityBonds.initialize(storage, get_network()) wallet = SegwitLegacyWalletFidelityBonds(storage) index = 0 timenumber = 0 script = wallet.get_script_and_update_map( FidelityBondMixin.FIDELITY_BOND_MIXDEPTH, FidelityBondMixin.BIP32_TIMELOCK_ID, index, timenumber) utxo = fund_wallet_addr(wallet, wallet.script_to_addr(script)) timestamp = wallet._time_number_to_timestamp(timenumber) tx = btc.mktx([utxo], [{ "address": str( btc.CCoinAddress.from_scriptPubKey( btc.standard_scripthash_scriptpubkey(btc.Hash160(b"\x00")))), "value": 10**8 - 9000 }], locktime=timestamp + 1) success, msg = wallet.sign_tx(tx, {0: (script, 10**8)}) assert success, msg txout = jm_single().bc_interface.pushtx(tx.serialize()) assert txout
def sync_burner_outputs(self, burner_txes): mixdepth = FidelityBondMixin.FIDELITY_BOND_MIXDEPTH address_type = FidelityBondMixin.BIP32_BURN_ID self.wallet.set_next_index(mixdepth, address_type, self.wallet.gap_limit, force=True) highest_used_index = 0 known_burner_outputs = self.wallet.get_burner_outputs() index = -1 while index - highest_used_index < self.wallet.gap_limit: index += 1 self.wallet.set_next_index(mixdepth, address_type, index, force=True) path = self.wallet.get_path(mixdepth, address_type, index) path_privkey, engine = self.wallet._get_key_from_path(path) path_pubkey = engine.privkey_to_pubkey(path_privkey) path_pubkeyhash = btc.Hash160(path_pubkey) for burner_tx in burner_txes: burner_pubkeyhash, gettx = burner_tx if burner_pubkeyhash != path_pubkeyhash: continue highest_used_index = index path_repr = self.wallet.get_path_repr(path) if path_repr.encode() in known_burner_outputs: continue txid = gettx["txid"] jlog.info("Found a burner transaction txid=" + txid + " path = " + path_repr) try: merkle_branch = self.bci.get_tx_merkle_branch( txid, gettx["blockhash"]) except ValueError as e: jlog.warning(repr(e)) jlog.warning("Merkle branch likely not available, use " + "wallet-tool `addtxoutproof`") merkle_branch = None block_height = self.bci.get_block_height(gettx["blockhash"]) if merkle_branch: assert self.bci.verify_tx_merkle_branch( txid, block_height, merkle_branch) self.wallet.add_burner_output(path_repr, gettx["hex"], block_height, merkle_branch, gettx["blockindex"]) self.wallet.set_next_index(mixdepth, address_type, highest_used_index + 1)
def test_mk_shuffled_tx(): # prepare two addresses for the outputs pub = btc.privkey_to_pubkey(btc.Hash(b"priv") + b"\x01") scriptPubKey = btc.CScript([btc.OP_0, btc.Hash160(pub)]) addr1 = btc.P2WPKHCoinAddress.from_scriptPubKey(scriptPubKey) scriptPubKey_p2sh = scriptPubKey.to_p2sh_scriptPubKey() addr2 = btc.CCoinAddress.from_scriptPubKey(scriptPubKey_p2sh) ins = [(btc.Hash(b"blah"), 7), (btc.Hash(b"foo"), 15)] # note the casts str() ; most calls to mktx will have addresses fed # as strings, so this is enforced for simplicity. outs = [{"address": str(addr1), "value": btc.coins_to_satoshi(float("0.1"))}, {"address": str(addr2), "value": btc.coins_to_satoshi(float("45981.23331234"))}] tx = btc.make_shuffled_tx(ins, outs, version=2, locktime=500000)
def test_sign_standard_txs(addrtype): # liberally copied from python-bitcoinlib tests, # in particular see: # https://github.com/petertodd/python-bitcoinlib/pull/227 # Create the (in)famous correct brainwallet secret key. priv = hashlib.sha256(b'correct horse battery staple').digest() + b"\x01" pub = btc.privkey_to_pubkey(priv) # Create an address from that private key. # (note that the input utxo is fake so we are really only creating # a destination here). scriptPubKey = btc.CScript([btc.OP_0, btc.Hash160(pub)]) address = btc.P2WPKHCoinAddress.from_scriptPubKey(scriptPubKey) # Create a dummy outpoint; use same 32 bytes for convenience txid = priv[:32] vout = 2 amount = btc.coins_to_satoshi(float('0.12345')) # Calculate an amount for the upcoming new UTXO. Set a high fee to bypass # bitcoind minfee setting. amount_less_fee = int(amount - btc.coins_to_satoshi(0.01)) # Create a destination to send the coins. destination_address = address target_scriptPubKey = scriptPubKey # Create the unsigned transaction. txin = btc.CTxIn(btc.COutPoint(txid[::-1], vout)) txout = btc.CTxOut(amount_less_fee, target_scriptPubKey) tx = btc.CMutableTransaction([txin], [txout]) # Calculate the signature hash for the transaction. This is then signed by the # private key that controls the UTXO being spent here at this txin_index. if addrtype == "p2wpkh": sig, msg = btc.sign(tx, 0, priv, amount=amount, native="p2wpkh") elif addrtype == "p2sh-p2wpkh": sig, msg = btc.sign(tx, 0, priv, amount=amount, native=False) elif addrtype == "p2pkh": sig, msg = btc.sign(tx, 0, priv) else: assert False if not sig: print(msg) raise print("created signature: ", bintohex(sig)) print("serialized transaction: {}".format(bintohex(tx.serialize()))) print("deserialized transaction: {}\n".format( btc.human_readable_transaction(tx)))
def test_all_same_priv(setup_tx_creation): #recipient priv = b"\xaa"*32 + b"\x01" pub = bitcoin.privkey_to_pubkey(priv) addr = str(bitcoin.CCoinAddress.from_scriptPubKey( bitcoin.CScript([bitcoin.OP_0, bitcoin.Hash160(pub)]))) wallet_service = make_wallets(1, [[1,0,0,0,0]], 1)[0]['wallet'] #make another utxo on the same address addrinwallet = wallet_service.get_addr(0,0,0) jm_single().bc_interface.grab_coins(addrinwallet, 1) wallet_service.sync_wallet(fast=True) insfull = wallet_service.select_utxos(0, 110000000) outs = [{"address": addr, "value": 1000000}] ins = list(insfull.keys()) tx = bitcoin.mktx(ins, outs) scripts = {} for i, j in enumerate(ins): scripts[i] = (insfull[j]["script"], insfull[j]["value"]) success, msg = wallet_service.sign_tx(tx, scripts) assert success, msg