def test_signature_hash(self): compressed = False exponent_2 = int( "137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) address_2 = public_pair_to_bitcoin_address(exponent_2 * secp256k1_generator, compressed=compressed) key = BitcoinMainnet.ui.parse( "5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") exponent = key.secret_exponent() public_key_sec = public_pair_to_sec(exponent * secp256k1_generator, compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), address_2)] unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to) tx_out_script_to_check = the_coinbase_tx.txs_out[0].script idx = 0 solution_checker = BitcoinSolutionChecker(unsigned_coinbase_spend_tx) actual_hash = solution_checker._signature_hash(tx_out_script_to_check, idx, hash_type=SIGHASH_ALL) self.assertEqual( actual_hash, 29819170155392455064899446505816569230970401928540834591675173488544269166940 )
def test_coinbase_tx(self): tx = Tx.coinbase_tx(COINBASE_PUB_KEY_FROM_80971, int(50 * 1e8), COINBASE_BYTES_FROM_80971) s = io.BytesIO() tx.stream(s) tx1 = s.getvalue() s = io.BytesIO() block_80971.txs[0].stream(s) tx2 = s.getvalue() self.assertEqual(tx1, tx2)
def test_build_spends(self): # first, here is the tx database TX_DB = {} # create a coinbase Tx where we know the public & private key exponent = wif_to_secret_exponent("5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") compressed = False public_key_sec = public_pair_to_sec(exponent * secp256k1_generator, compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) TX_DB[the_coinbase_tx.hash()] = the_coinbase_tx # now create a Tx that spends the coinbase compressed = False exponent_2 = int("137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address(exponent_2 * secp256k1_generator, compressed=compressed) self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ", bitcoin_address_2) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), bitcoin_address_2)] unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to) solver = build_hash160_lookup([exponent]) coinbase_spend_tx = unsigned_coinbase_spend_tx.sign(solver) # now check that it validates self.assertEqual(coinbase_spend_tx.bad_signature_count(), 0) TX_DB[coinbase_spend_tx.hash()] = coinbase_spend_tx # now try to respend from priv_key_2 to priv_key_3 compressed = True exponent_3 = int("f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff", 16) bitcoin_address_3 = public_pair_to_bitcoin_address(exponent_3 * secp256k1_generator, compressed=compressed) self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5", bitcoin_address_3) coins_from = [(coinbase_spend_tx.hash(), 0, coinbase_spend_tx.txs_out[0])] unsigned_spend_tx = standard_tx(coins_from, [(int(50 * 1e8), bitcoin_address_3)]) solver.update(build_hash160_lookup([exponent_2])) spend_tx = unsigned_spend_tx.sign(solver) # now check that it validates self.assertEqual(spend_tx.bad_signature_count(), 0)
def test_signature_hash(self): compressed = False exponent_2 = int("137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) bitcoin_address_2 = public_pair_to_bitcoin_address(exponent_2 * secp256k1_generator, compressed=compressed) exponent = wif_to_secret_exponent("5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") public_key_sec = public_pair_to_sec(exponent * secp256k1_generator, compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), bitcoin_address_2)] unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to) tx_out_script_to_check = the_coinbase_tx.txs_out[0].script idx = 0 actual_hash = unsigned_coinbase_spend_tx.signature_hash(tx_out_script_to_check, idx, hash_type=SIGHASH_ALL) self.assertEqual(actual_hash, 29819170155392455064899446505816569230970401928540834591675173488544269166940)
def _make_tx(self, input_script, other_scripts=[]): from pycoin.tx.tx_utils import create_signed_tx from pycoin.solve.utils import build_p2sh_lookup cv = int(50 * 1e8) key = self._key sec = key.sec() wif = key.wif() address = key.address() p2sh_lookup = build_p2sh_lookup(other_scripts) coinbase_tx = Tx.coinbase_tx(public_key_sec=sec, coin_value=cv) coinbase_tx.txs_out[0].script = input_script spendable = coinbase_tx.tx_outs_as_spendable()[0] payables = [(address, cv)] tx = create_signed_tx(spendables=[spendable], payables=payables, wifs=[wif], p2sh_lookup=p2sh_lookup) tx.unspents = [spendable] print(tx.as_hex(include_unspents=True)) return tx
def _test_sighash_single(self, netcode): k0 = Key(secret_exponent=PRIV_KEYS[0], is_compressed=True, netcode=netcode) k1 = Key(secret_exponent=PRIV_KEYS[1], is_compressed=True, netcode=netcode) k2 = Key(secret_exponent=PRIV_KEYS[2], is_compressed=True, netcode=netcode) k3 = Key(secret_exponent=PRIV_KEYS[3], is_compressed=True, netcode=netcode) k4 = Key(secret_exponent=PRIV_KEYS[4], is_compressed=True, netcode=netcode) k5 = Key(secret_exponent=PRIV_KEYS[5], is_compressed=True, netcode=netcode) # Fake a coinbase transaction coinbase_tx = Tx.coinbase_tx(k0.sec(), 500000000) coinbase_tx.txs_out.append( TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k1.sec())))) coinbase_tx.txs_out.append( TxOut(1000000000, pycoin_compile('%s OP_CHECKSIG' % b2h(k2.sec())))) self.assertEqual( '2acbe1006f7168bad538b477f7844e53de3a31ffddfcfc4c6625276dd714155a', b2h_rev(coinbase_tx.hash())) # Make the test transaction txs_in = [ TxIn(coinbase_tx.hash(), 0), TxIn(coinbase_tx.hash(), 1), TxIn(coinbase_tx.hash(), 2), ] txs_out = [ TxOut(900000000, standard_tx_out_script(k3.address())), TxOut(800000000, standard_tx_out_script(k4.address())), TxOut(800000000, standard_tx_out_script(k5.address())), ] tx = Tx(1, txs_in, txs_out) tx.set_unspents(coinbase_tx.txs_out) self.assertEqual( '791b98ef0a3ac87584fe273bc65abd89821569fd7c83538ac0625a8ca85ba587', b2h_rev(tx.hash())) sig_type = SIGHASH_SINGLE sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual( 'cc52d785a3b4133504d1af9e60cd71ca422609cb41df3a08bbb466b2a98a885e', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual( '93bb883d70fccfba9b8aa2028567aca8357937c65af7f6f5ccc6993fd7735fb7', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual( '53ef7f67c3541bffcf4e0d06c003c6014e2aa1fb38ff33240b3e1c1f3f8e2a35', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2)) sig_type = SIGHASH_SINGLE | SIGHASH_ANYONECANPAY sig_hash = tx.signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type) self.assertEqual( '2003393d246a7f136692ce7ab819c6eadc54ffea38eb4377ac75d7d461144e75', b2h(to_bytes_32(sig_hash))) sig = sigmake(k0, sig_hash, sig_type) self.assertTrue(sigcheck(k0, sig_hash, sig[:-1])) tx.txs_in[0].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(0)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type) self.assertEqual( 'e3f469ac88e9f35e8eff0bd8ad4ad3bf899c80eb7645947d60860de4a08a35df', b2h(to_bytes_32(sig_hash))) sig = sigmake(k1, sig_hash, sig_type) self.assertTrue(sigcheck(k1, sig_hash, sig[:-1])) tx.txs_in[1].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(1)) sig_hash = tx.signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type) self.assertEqual( 'bacd7c3ab79cad71807312677c1788ad9565bf3c00ab9a153d206494fb8b7e6a', b2h(to_bytes_32(sig_hash))) sig = sigmake(k2, sig_hash, sig_type) self.assertTrue(sigcheck(k2, sig_hash, sig[:-1])) tx.txs_in[2].script = pycoin_compile(b2h(sig)) self.assertTrue(tx.is_signature_ok(2))
def coinbase_tx(secret_exponent): public_pair = ecdsa.public_pair_for_secret_exponent( ecdsa.secp256k1.generator_secp256k1, secret_exponent) public_key_sec = public_pair_to_sec(public_pair) return Tx.coinbase_tx(public_key_sec, 2500000000)
def test_build_spends(self): # first, here is the tx database TX_DB = {} # create a coinbase Tx where we know the public & private key key = BitcoinMainnet.ui.parse( "5JMys7YfK72cRVTrbwkq5paxU7vgkMypB55KyXEtN5uSnjV7K8Y") exponent = key.secret_exponent() compressed = False public_key_sec = public_pair_to_sec(exponent * secp256k1_generator, compressed=compressed) the_coinbase_tx = Tx.coinbase_tx(public_key_sec, int(50 * 1e8), COINBASE_BYTES_FROM_80971) TX_DB[the_coinbase_tx.hash()] = the_coinbase_tx # now create a Tx that spends the coinbase compressed = False exponent_2 = int( "137f3276686959c82b454eea6eefc9ab1b9e45bd4636fb9320262e114e321da1", 16) address_2 = public_pair_to_bitcoin_address(exponent_2 * secp256k1_generator, compressed=compressed) self.assertEqual("12WivmEn8AUth6x6U8HuJuXHaJzDw3gHNZ", address_2) coins_from = [(the_coinbase_tx.hash(), 0, the_coinbase_tx.txs_out[0])] coins_to = [(int(50 * 1e8), address_2)] unsigned_coinbase_spend_tx = standard_tx(coins_from, coins_to) solver = build_hash160_lookup([exponent], [secp256k1_generator]) coinbase_spend_tx = unsigned_coinbase_spend_tx.sign(solver) TX_DB[coinbase_spend_tx.hash()] = coinbase_spend_tx # now try to respend from priv_key_2 to priv_key_3 compressed = True exponent_3 = int( "f8d39b8ecd0e1b6fee5a340519f239097569d7a403a50bb14fb2f04eff8db0ff", 16) address_3 = public_pair_to_bitcoin_address(exponent_3 * secp256k1_generator, compressed=compressed) self.assertEqual("13zzEHPCH2WUZJzANymow3ZrxcZ8iFBrY5", address_3) coins_from = [(coinbase_spend_tx.hash(), 0, coinbase_spend_tx.txs_out[0])] unsigned_spend_tx = standard_tx(coins_from, [(int(50 * 1e8), address_3)]) solver.update(build_hash160_lookup([exponent_2], [secp256k1_generator])) spend_tx = unsigned_spend_tx.sign(solver) # now check that it validates self.assertEqual(spend_tx.bad_signature_count(), 0)
def test_tx_out_address(self): tx = Tx.coinbase_tx(COINBASE_PUB_KEY_FROM_80971, int(50 * 1e8), COINBASE_BYTES_FROM_80971) address = BitcoinMainnet.ui.address_for_script( tx.txs_out[0].puzzle_script()) self.assertEqual(address, '1DmapcnrJNGeJB13fv9ngRFX1iRvR4zamn')
def test_tx_out_bitcoin_address(self): tx = Tx.coinbase_tx(COINBASE_PUB_KEY_FROM_80971, int(50 * 1e8), COINBASE_BYTES_FROM_80971) self.assertEqual(tx.txs_out[0].bitcoin_address(), '1DmapcnrJNGeJB13fv9ngRFX1iRvR4zamn')
def test_tx_out_bitcoin_address(self): coinbase_bytes = h2b("04ed66471b02c301") tx = Tx.coinbase_tx(COINBASE_PUB_KEY_FROM_80971, int(50 * 1e8), COINBASE_BYTES_FROM_80971) self.assertEqual(tx.txs_out[0].bitcoin_address(), '1DmapcnrJNGeJB13fv9ngRFX1iRvR4zamn')