def get_tx(tx_hash): """ Get a Tx by its hash. """ # TODO: fix this j = get_json_for_hash(tx_hash) txs_in = [] for j_in in j.get("in"): if j_in.get("coinbase"): txs_in.append( TxIn.coinbase_tx_in(binascii.unhexlify(j_in["coinbase"]))) else: txs_in.append( TxIn(h2b_rev(j_in["prev_out"]["hash"]), int(j_in["prev_out"]["n"]), tools.compile(j_in["scriptSig"]))) txs_out = [] for j_out in j.get("out"): txs_out.append( TxOut(int(btc_to_satoshi(j_out["value"])), tools.compile(j_out["scriptPubKey"]))) tx = Tx(int(j["ver"]), txs_in, txs_out, int(j["lock_time"])) assert tx.hash() == tx_hash return tx
def tx_from_json_dict(r): version = r.get("version") lock_time = r.get("locktime") txs_in = [] for vin in r.get("vin"): if "coinbase" in vin: previous_hash = b'\0' * 32 script = h2b(vin.get("coinbase")) previous_index = 4294967295 else: previous_hash = h2b_rev(vin.get("txid")) scriptSig = vin.get("scriptSig") if "hex" in scriptSig: script = h2b(scriptSig.get("hex")) else: script = tools.compile(scriptSig.get("asm")) previous_index = vin.get("vout") sequence = vin.get("sequence") txs_in.append(TxIn(previous_hash, previous_index, script, sequence)) txs_out = [] for vout in r.get("vout"): coin_value = btc_to_satoshi(decimal.Decimal(vout.get("value"))) script = tools.compile(vout.get("scriptPubKey").get("asm")) txs_out.append(TxOut(coin_value, script)) tx = Tx(version, txs_in, txs_out, lock_time) bh = r.get("blockhash") if bh: bh = h2b_rev(bh) tx.confirmation_block_hash = bh return tx
def test_multisig_one_at_a_time(self): M = 3 N = 3 keys = [ Key(secret_exponent=i, generator=secp256k1_generator) for i in range(1, N + 2) ] tx_in = TxIn.coinbase_tx_in(script=b'') script = script_for_multisig(m=M, sec_keys=[key.sec() for key in keys[:N]]) tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()]) ids = [ "403e5bfc59e097bb197bf77a692d158dd3a4f7affb4a1fa41072dafe7bec7058", "5931d9995e83721243dca24772d7012afcd4378996a8b953c458175f15a544db", "9bb4421088190bbbb5b42a9eaa9baed7ec7574a407c25f71992ba56ca43d9c44", "03a1dc2a63f93a5cf5a7cb668658eb3fc2eda88c06dc287b85ba3e6aff751771" ] for i in range(1, N + 1): self.assertEqual(tx2.bad_signature_count(), 1) self.assertEqual(tx2.id(), ids[i - 1]) hash160_lookup = build_hash160_lookup( (key.secret_exponent() for key in keys[i - 1:i]), [secp256k1_generator]) tx2.sign(hash160_lookup=hash160_lookup) self.assertEqual(tx2.id(), ids[i]) self.assertEqual(tx2.bad_signature_count(), 0)
def build_spending_tx(script_in_bin, credit_tx): txs_in = [TxIn(credit_tx.hash(), 0, script_in_bin, sequence=4294967295)] txs_out = [TxOut(credit_tx.txs_out[0].coin_value, b'')] spend_tx = Tx(1, txs_in, txs_out, unspents=credit_tx.tx_outs_as_spendable()) return spend_tx
def coinbase(): account = Account.Account(TEST_EMAIL1) wallet = Wallet.Wallet.from_wallet_key(account.get_wallet_keys()[0]) address = wallet.address() assert is_address_valid(address) tx_in = TxIn.coinbase_tx_in(script=b'') tx_out = TxOut(50 * 1e8, standard_tx_out_script(address)) tx = Tx(1, [tx_in], [tx_out]) return tx.as_hex()
def make_tx(i): key = Key(12345 * (i + 29)) script = standard_tx_out_script(key.address()) txs_in = [ TxIn(make_hash(i * 10000 + idx), (i + idx) % 2) for idx in range(3) ] txs_out = [TxOut(i * 40000, script) for idx in range(2)] tx = Tx(1, txs_in, txs_out) return tx
def make_tx(i): txs_in = [ TxIn(make_hash(i * 10000 + idx), (i + idx) % 2) for idx in range(3) ] txs_out = [ TxOut(i * 40000, make_hash(i * 20000 + idx)) for idx in range(2) ] tx = Tx(1, txs_in, txs_out) return tx
def test_sign_p2sh(self): tx_out_script = h2b( "76a91491b24bf9f5288532960ac687abb035127b1d28a588ac") script = script_for_address("1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm") self.assertEqual(tx_out_script, script) tx_out = TxOut(100, tx_out_script) tx = Tx(1, [TxIn(b'\1' * 32, 1)], [TxOut(100, tx_out_script)]) tx.set_unspents([tx_out]) hl = build_hash160_lookup([1], [secp256k1_generator]) self.assertEqual(tx.bad_signature_count(), 1) tx.sign(hash160_lookup=hl) self.assertEqual(tx.bad_signature_count(), 0)
def do_test_tx(self, sighash, index_, flags): txhash, seq, script, witness_script = b'0' * 32, 0xffffffff, b'\x51', b'000000' out_script, spend_script, locktime = b'\x00\x00\x51', b'\x00\x51', 999999 txs_in = [TxIn(txhash, 0, script, seq), TxIn(txhash, 1, script+b'\x51', seq-1), TxIn(txhash, 2, script+b'\x51\x51', seq-2), TxIn(txhash, 3, script+b'\x51\x51\x51', seq-3)] txs_out = [TxOut(55, out_script), TxOut(54, out_script+b'\x51'), TxOut(53, out_script+b'\x51\x51')] pytx = Tx(2, txs_in, txs_out, lock_time=locktime) pytx.unspents = {0: TxOut(5000, spend_script), # FIXME: Make script unique 1: TxOut(5001, spend_script), 2: TxOut(5002, spend_script), 3: TxOut(5003, spend_script)} unspent = pytx.unspents[index_] pytx_hex = pytx.as_hex() if flags & USE_WITNESS: pytx_hash = pytx.signature_for_hash_type_segwit(unspent.script, index_, sighash) else: pytx_hash = pytx.signature_hash(spend_script, index_, sighash) pytx_hash = hex_from_bytes(to_bytes_32(pytx_hash)) tx = tx_init(2, locktime, 3, 3) tx_add_input(tx, tx_input_init(txhash, 0, seq, script, None)) tx_add_raw_input(tx, txhash, 1, seq-1, script+b'\x51', None) tx_add_raw_input(tx, txhash, 2, seq-2, script+b'\x51\x51', None) tx_add_raw_input(tx, txhash, 3, seq-3, script+b'\x51\x51\x51', None) tx_add_raw_output(tx, 55, out_script, 0) tx_add_raw_output(tx, 54, out_script+b'\x51', 0) tx_add_raw_output(tx, 53, out_script+b'\x51\x51', 0) tx_hex = tx_to_hex(tx, 0) amount = (index_ + 1) * 5000 tx_hash = tx_get_btc_signature_hash(tx, index_, unspent.script, unspent.coin_value, sighash, flags) tx_hash = hex_from_bytes(tx_hash) self.assertEqual(pytx_hex, tx_hex) self.assertEqual(pytx_hash, tx_hash)
def multisig_M_of_N(self, M, N, unsigned_id, signed_id): keys = [Key(secret_exponent=i) for i in range(1, N+2)] tx_in = TxIn.coinbase_tx_in(script=b'') script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script() tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()]) self.assertEqual(tx2.id(), unsigned_id) self.assertEqual(tx2.bad_signature_count(), 1) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys) tx2.sign(hash160_lookup=hash160_lookup) self.assertEqual(tx2.id(), signed_id) self.assertEqual(tx2.bad_signature_count(), 0)
def multisig_M_of_N_individually(self, M, N): keys = [Key(secret_exponent=i) for i in range(1, N+2)] tx_in = TxIn.coinbase_tx_in(script=b'') script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script() tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) for partial_key_list in itertools.permutations(keys[:N], M): tx2 = create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()]) for key in partial_key_list: self.assertEqual(tx2.bad_signature_count(), 1) hash160_lookup = build_hash160_lookup([key.secret_exponent()]) tx2.sign(hash160_lookup=hash160_lookup) self.assertEqual(tx2.bad_signature_count(), 0)
def make_test_tx(self, input_script): previous_hash = b'\1' * 32 txs_in = [TxIn(previous_hash, 0)] txs_out = [ TxOut( 1000, script_for_address( Key(1, generator=secp256k1_generator).address())) ] version, lock_time = 1, 0 tx = Tx(version, txs_in, txs_out, lock_time) unspents = [TxOut(1000, input_script)] tx.set_unspents(unspents) return tx
def multisig_M_of_N_individually(self, M, N): keys = [Key(secret_exponent=i) for i in range(1, N + 2)] tx_in = TxIn.coinbase_tx_in(script=b'') script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script() tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) for partial_key_list in itertools.permutations(keys[:N], M): tx2 = create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()]) for key in partial_key_list: self.assertEqual(tx2.bad_signature_count(), 1) hash160_lookup = build_hash160_lookup([key.secret_exponent()]) tx2.sign(hash160_lookup=hash160_lookup) self.assertEqual(tx2.bad_signature_count(), 0)
def main(): if len(sys.argv) != 2: print("usage: %s address" % sys.argv[0]) sys.exit(-1) # validate the address address = sys.argv[1] assert is_address_valid(address) print("creating coinbase transaction to %s" % address) tx_in = TxIn.coinbase_tx_in(script=b'') tx_out = TxOut(50*1e8, script_for_address(address)) tx = Tx(1, [tx_in], [tx_out]) print("Here is the tx as hex:\n%s" % tx.as_hex())
def main(): if len(sys.argv) != 2: print("usage: %s address" % sys.argv[0]) sys.exit(-1) # validate the address address = sys.argv[1] assert is_address_valid(address) print("creating coinbase transaction to %s" % address) tx_in = TxIn.coinbase_tx_in(script=b'') tx_out = TxOut(50*1e8, standard_tx_out_script(address)) tx = Tx(1, [tx_in], [tx_out]) print("Here is the tx as hex:\n%s" % tx.as_hex())
def test_sign_pay_to_script_multisig(self): M, N = 3, 3 keys = [Key(secret_exponent=i) for i in range(1, N+2)] tx_in = TxIn.coinbase_tx_in(script=b'') underlying_script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script() address = address_for_pay_to_script(underlying_script) self.assertEqual(address, "39qEwuwyb2cAX38MFtrNzvq3KV9hSNov3q") script = standard_tx_out_script(address) tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [address]) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[:N]) p2sh_lookup = build_p2sh_lookup([underlying_script]) tx2.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) self.assertEqual(tx2.bad_signature_count(), 0)
def test_p2sh_multisig_sequential_signing(self): raw_scripts = [h2b('52210234abcffd2e80ad01c2ec0276ad02682808169c6fafdd25ebfb60703df272b4612102e5baaafff8094e4d77ce8b009d5ebc3de9110085ebd3d96e50cc7ce70faf1752210316ee25e80eb6e6fc734d9c86fa580cbb9c4bfd94a19f0373a22353ececd4db6853ae')] txs_in = [TxIn(previous_hash=h2b('43c95d14724437bccc102ccf86aba1ac02415524fd1aefa787db886bba52a10c'), previous_index=0)] txs_out = [TxOut(10000, standard_tx_out_script('3KeGeLFmsbmbVdeMLrWp7WYKcA3tdsB4AR'))] spendable = {'script_hex': 'a914c4ed4de526461e3efbb79c8b688a6f9282c0464687', 'does_seem_spent': 0, 'block_index_spent': 0, 'tx_hash_hex': '0ca152ba6b88db87a7ef1afd24554102aca1ab86cf2c10ccbc374472145dc943', 'coin_value': 10000, 'block_index_available': 0, 'tx_out_index': 0} tx__prototype = Tx(version=DEFAULT_VERSION, txs_in=txs_in, txs_out=txs_out, unspents=[Spendable.from_dict(spendable)]) key_1, key_2 = 'Kz6pytJCigYHeMsGLmfHQPJhN5og2wpeSVrU43xWwgHLCAvpsprh', 'Kz7NHgX7MBySA3RSKj9GexUSN6NepEDoPNugSPr5absRDoKgn2dT' for ordered_keys in [(key_1, key_2), (key_2, key_1)]: tx = copy.deepcopy(tx__prototype) for key in ordered_keys: self.assertEqual(tx.bad_signature_count(), 1) tx.sign(LazySecretExponentDB([key], {}), p2sh_lookup=build_p2sh_lookup(raw_scripts)) self.assertEqual(tx.bad_signature_count(), 0)
def test_multisig_one_at_a_time(self): M = 3 N = 3 keys = [Key(secret_exponent=i) for i in range(1, N+2)] tx_in = TxIn.coinbase_tx_in(script=b'') script = ScriptMultisig(m=M, sec_keys=[key.sec() for key in keys[:N]]).script() tx_out = TxOut(1000000, script) tx1 = Tx(version=1, txs_in=[tx_in], txs_out=[tx_out]) tx2 = tx_utils.create_tx(tx1.tx_outs_as_spendable(), [keys[-1].address()]) ids = ["403e5bfc59e097bb197bf77a692d158dd3a4f7affb4a1fa41072dafe7bec7058", "5931d9995e83721243dca24772d7012afcd4378996a8b953c458175f15a544db", "9bb4421088190bbbb5b42a9eaa9baed7ec7574a407c25f71992ba56ca43d9c44", "03a1dc2a63f93a5cf5a7cb668658eb3fc2eda88c06dc287b85ba3e6aff751771"] for i in range(1, N+1): self.assertEqual(tx2.bad_signature_count(), 1) self.assertEqual(tx2.id(), ids[i-1]) hash160_lookup = build_hash160_lookup(key.secret_exponent() for key in keys[i-1:i]) tx2.sign(hash160_lookup=hash160_lookup) self.assertEqual(tx2.id(), ids[i]) self.assertEqual(tx2.bad_signature_count(), 0)
def main(): the_hash = sys.argv[1] j = get_json_for_hash(the_hash) txs_in = [] for j_in in j.get("in"): txs_in.append( TxIn(h2b_rev(j_in["prev_out"]["hash"]), int(j_in["prev_out"]["n"]), tools.compile(j_in["scriptSig"]))) txs_out = [] for j_out in j.get("out"): txs_out.append( TxOut(int(float(j_out["value"]) * 1e8 + 0.5), tools.compile(j_out["scriptPubKey"]))) tx = Tx(int(j["ver"]), txs_in, txs_out, int(j["lock_time"])) assert tx.id() == the_hash s = io.BytesIO() tx.stream(s) v = s.getvalue() print(linebreak(binascii.b2a_base64(v).decode("utf8"), 72))
def get_tx(tx_hash): """ Get a Tx by its hash. """ # TODO: fix this j = get_json_for_hash(tx_hash) txs_in = [] for j_in in j.get("in"): if j_in.get("coinbase"): txs_in.append(TxIn.coinbase_tx_in(binascii.unhexlify(j_in["coinbase"]))) else: txs_in.append(TxIn( h2b_rev(j_in["prev_out"]["hash"]), int(j_in["prev_out"]["n"]), tools.compile(j_in["scriptSig"]))) txs_out = [] for j_out in j.get("out"): txs_out.append(TxOut(int(btc_to_satoshi(j_out["value"])), tools.compile(j_out["scriptPubKey"]))) tx = Tx(int(j["ver"]), txs_in, txs_out, int(j["lock_time"])) assert tx.hash() == tx_hash 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 build_credit_tx(script_out_bin, coin_value=0): txs_in = [TxIn(b'\0'*32, 4294967295, b'\0\0', sequence=4294967295)] txs_out = [TxOut(coin_value, script_out_bin)] return Tx(1, txs_in, txs_out)