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 check_bip143_tx(self, tx_u_hex, tx_s_hex, txs_out_value_scripthex_pair, tx_in_count, tx_out_count, version, lock_time): tx_u = Tx.from_hex(tx_u_hex) tx_s = Tx.from_hex(tx_s_hex) txs_out = [ TxOut(int(coin_value * 1e8), h2b(script_hex)) for coin_value, script_hex in txs_out_value_scripthex_pair ] for tx in (tx_u, tx_s): self.assertEqual(len(tx.txs_in), tx_in_count) self.assertEqual(len(tx.txs_out), tx_out_count) self.assertEqual(tx.version, version) self.assertEqual(tx.lock_time, lock_time) tx.set_unspents(txs_out) self.check_unsigned(tx_u) self.check_signed(tx_s) tx_hex = tx_u.as_hex() self.assertEqual(tx_hex, tx_u_hex) tx_hex = tx_s.as_hex() self.assertEqual(tx_hex, tx_s_hex) tx_u_prime = self.unsigned_copy(tx_s) tx_hex = tx_u_prime.as_hex() self.assertEqual(tx_hex, tx_u_hex) self.assertEqual(b2h_rev(double_sha256(h2b(tx_s_hex))), tx_s.w_id()) self.assertEqual(b2h_rev(double_sha256(h2b(tx_u_hex))), tx_u.w_id()) self.assertEqual(b2h_rev(double_sha256(h2b(tx_u_hex))), tx_u.id()) return tx_u, tx_s
def parse_scripts(args): scripts = [] warnings = [] for p2s in args.pay_to_script or []: try: scripts.append(h2b(p2s)) except Exception: warnings.append("warning: error parsing pay-to-script value %s" % p2s) hex_re = re.compile(r"[0-9a-fA-F]+") for f in args.pay_to_script_file or []: count = 0 for l in f: try: m = hex_re.search(l) if m: p2s = m.group(0) scripts.append(h2b(p2s)) count += 1 except Exception: warnings.append("warning: error parsing pay-to-script file %s" % f.name) if count == 0: warnings.append("warning: no scripts found in %s" % f.name) return scripts, warnings
def test_to_from_long(self): def do_test(as_int, prefix, as_rep, base): self.assertEqual((as_int, prefix), encoding.to_long(base, encoding.byte_to_int, as_rep)) self.assertEqual(as_rep, encoding.from_long(as_int, prefix, base, lambda v:v)) do_test(10000101, 2, h2b("00009896e5"), 256) do_test(10000101, 3, h2b("0000009896e5"), 256) do_test(1460765565493402645157733592332121663123460211377, 1, b'\0\xff\xde\xfeOHu\xcf\x11\x9f\xc3\xd8\xf4\xa0\x9a\xe3~\xc4\xccB\xb1', 256)
def create_tx_io(amount, addr, wallet_nodes, change_nodes, fee): txins = [] txouts = [] spendables = [] wifs = [] dust_threshold = Decimal('0.00000543') collected = Decimal(0) single = None assert amount > dust_threshold for op in unspents: op_amount = convention.satoshi_to_btc( op.as_dict()['coin_value'] ) if op_amount >= amount + fee: single = op collected = op_amount if not single: for op in unspents: spendables.append(op) op_amount = convention.satoshi_to_btc( op.as_dict()['coin_value'] ) collected += op_amount if collected >= amount + fee: break else: raise Exception("Insufficient funds!") else: spendables.append(single) for op in spendables: txin = op.tx_in() txins.append( txin ) op_script = serialize.h2b( op.as_dict()['script_hex'] ) hash160 = serialize.h2b( script.tools.opcode_list(op_script)[2] ) prev_addr = Key(hash160=hash160, netcode=NETCODE).address() # from pycoin import networks # address_prefix = networks.address_prefix_for_netcode(NETCODE) # prev_addr = txin.bitcoin_address(address_prefix=address_prefix) for nodes in (wallet_nodes, change_nodes): if prev_addr in nodes['used'].keys(): wifs.append( nodes['used'][prev_addr]['key'].wif() ) change = collected - (amount + fee) amount_btc = convention.btc_to_satoshi(amount) spend = TxOut( amount_btc, standard_tx_out_script(addr) ) txouts.append(spend) if change > dust_threshold: change_addr = get_unused_node(change_nodes, change=True)['key'].address() change_btc = convention.btc_to_satoshi(change) change_txout = TxOut( change_btc, standard_tx_out_script(change_addr) ) txouts.append(change_txout) return (txins, txouts, spendables, wifs)
def deserialize(class_, blob): """ Deserialize from a JSON blob, so that the transaction can be retried. Includes transaction, unspents and chain paths. """ d = json.loads(blob) tx = class_.parse_with_paths(io.BytesIO(h2b(d['tx'])), d['input_chain_paths'], d['output_chain_paths']) tx.parse_unspents(io.BytesIO(h2b(d['unspents']))) return tx
def test_verify_transaction(self): bitcoin.SelectParams('testnet') b = h2b('8443b07464c762d7fb404ea918a5ac9b3618d5cd6a0c5ea6e4dd5d7bbe28b154') tx_input = Spendable(200, b'18eKkAWyU9kvRNHPKxnZb6wwtPMrNmRRRA', b, 0) tx_outs = [tx_utils.create_transaction_output('mgAqW5ZCnEp7fjvpj8RUL3WxsBy8rcDcCi', 0.0000275)] op_return_val = h2b('e9cee71ab932fde863338d08be4de9dfe39ea049bdafb342ce659ec5450b69ae') tx = tx_utils.create_trx(op_return_val, 3, 'mgAqW5ZCnEp7fjvpj8RUL3WxsBy8rcDcCi', tx_outs, [tx_input]) hextx = b2h(tx.serialize()) tx_utils.verify_transaction(hextx, b2h(op_return_val))
def test_verify_transaction(self): cost = TransactionCosts(0.0001, 0.0000275, 3) tx_input = Spendable(200, '18eKkAWyU9kvRNHPKxnZb6wwtPMrNmRRRA', h2b('8443b07464c762d7fb404ea918a5ac9b3618d5cd6a0c5ea6e4dd5d7bbe28b154'), 0) tx_outs = [trx_utils.create_transaction_output('mgAqW5ZCnEp7fjvpj8RUL3WxsBy8rcDcCi', 0.0000275)] op_return_val = h2b('e9cee71ab932fde863338d08be4de9dfe39ea049bdafb342ce659ec5450b69ae') tx = trx_utils.create_trx(op_return_val, cost, 'mgAqW5ZCnEp7fjvpj8RUL3WxsBy8rcDcCi', tx_outs, tx_input) hextx = hexlify(tx.serialize()) trx_utils.verify_transaction(hextx, hexlify(op_return_val))
def do_test(exp_hex, wif, c_wif, public_pair_sec, c_public_pair_sec, address_b58, c_address_b58): secret_exponent = int(exp_hex, 16) sec = h2b(public_pair_sec) c_sec = h2b(c_public_pair_sec) keys_wif = [ Key(secret_exponent=secret_exponent), Key.from_text(wif), Key.from_text(c_wif), ] key_sec = Key.from_sec(sec) key_sec_c = Key.from_sec(c_sec) keys_sec = [key_sec, key_sec_c] for key in keys_wif: self.assertEqual(key.secret_exponent(), secret_exponent) self.assertEqual(key.public_copy().secret_exponent(), None) repr(key) if key._prefer_uncompressed: self.assertEqual(key.wif(), wif) else: self.assertEqual(key.wif(), c_wif) self.assertEqual(key.wif(use_uncompressed=True), wif) self.assertEqual(key.wif(use_uncompressed=False), c_wif) for key in keys_wif + keys_sec: if key._prefer_uncompressed: self.assertEqual(key.sec(), sec) else: self.assertEqual(key.sec(), c_sec) self.assertEqual(key.sec(use_uncompressed=True), sec) self.assertEqual(key.sec(use_uncompressed=False), c_sec) if key._prefer_uncompressed: self.assertEqual(key.address(), address_b58) else: self.assertEqual(key.address(), c_address_b58) self.assertEqual(key.address(use_uncompressed=False), c_address_b58) self.assertEqual(key.address(use_uncompressed=True), address_b58) key_pub = Key.from_text(address_b58, is_compressed=False) key_pub_c = Key.from_text(c_address_b58, is_compressed=True) self.assertEqual(key_pub.address(), address_b58) self.assertEqual(key_pub.address(use_uncompressed=True), address_b58) self.assertEqual(key_pub.address(use_uncompressed=False), None) self.assertEqual(key_pub_c.address(), c_address_b58) self.assertEqual(key_pub_c.address(use_uncompressed=True), None) self.assertEqual(key_pub_c.address(use_uncompressed=False), c_address_b58)
def spendables_for_address(self, bitcoin_address): """ Return a list of Spendable objects for the given bitcoin address. """ URL = "https://blockchain.info/unspent?active=%s" % bitcoin_address r = json.loads(urlopen(URL).read().decode("utf8")) spendables = [] for u in r["unspent_outputs"]: coin_value = u["value"] script = h2b(u["script"]) previous_hash = h2b(u["tx_hash"]) previous_index = u["tx_output_n"] spendables.append(Spendable(coin_value, script, previous_hash, previous_index)) return spendables
def test_sign_bitcoind_partially_signed_2_of_2(self): # Finish signing a 2 of 2 transaction, that already has one signature signed by bitcoind # This tx can be found on testnet3 blockchain, txid: 9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2 raw_script = "522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452ae" p2sh_lookup = build_p2sh_lookup([h2b(raw_script)]) partially_signed_raw_tx = "010000000196238f11a5fd3ceef4efd5a186a7e6b9217d900418e72aca917cd6a6e634e74100000000910047304402201b41b471d9dd93cf97eed7cfc39a5767a546f6bfbf3e0c91ff9ad23ab9770f1f02205ce565666271d055be1f25a7e52e34cbf659f6c70770ff59bd783a6fcd1be3dd0147522103e33b41f5ed67a77d4c4c54b3e946bd30d15b8f66e42cb29fde059c16885116552102b92cb20a9fb1eb9656a74eeb7387636cf64cdf502ff50511830328c1b479986452aeffffffff01a0bb0d00000000001976a9143b3beefd6f7802fa8706983a76a51467bfa36f8b88ac00000000" tx = Tx.from_hex(partially_signed_raw_tx) tx_out = TxOut(1000000, h2b("a914a10dfa21ee8c33b028b92562f6fe04e60563d3c087")) tx.set_unspents([tx_out]) key = Key.from_text("cThRBRu2jAeshWL3sH3qbqdq9f4jDiDbd1SVz4qjTZD2xL1pdbsx") hash160_lookup = build_hash160_lookup([key.secret_exponent()]) self.assertEqual(tx.bad_signature_count(), 1) tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) self.assertEqual(tx.bad_signature_count(), 0) self.assertEqual(tx.id(), "9618820d7037d2f32db798c92665231cd4599326f5bd99cb59d0b723be2a13a2")
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 populate_unspents(nodes): global balance global unspents if nodes['used'] == {}: return addresses = nodes['used'].keys() response = json.load( urlopen("http://%s.blockr.io/api/v1/address/unspent/" % BLOCKR + \ ','.join(addresses)) ) data = response['data'] if type(data) == type({}): data = [data] for entry in data: if entry['unspent'] == []: continue for unspent in entry['unspent']: balance += Decimal(unspent['amount']) amount = convention.btc_to_satoshi(unspent['amount']) script = serialize.h2b(unspent['script']) txid = serialize.h2b_rev(unspent['tx']) unspent_spendable = Spendable( amount, script, txid, unspent['n'] ) unspents.append(unspent_spendable) time.sleep(1) # Don't overload blockr.io API
def test_h2b(self): h = "000102" b = b"\x00\x01\x02" self.assertEqual(h2b(h), b) self.assertEqual(b2h(b), h) self.assertEqual(h2b_rev(h), b[::-1]) self.assertEqual(b2h_rev(b), "020100")
def unspents_for_address(self, address): """ Return a list of Spendable objects for the given bitcoin address. """ spendables = [] r = json.loads(urlopen(self.base_url('get_tx_unspent', address)).read().decode("utf8")) for u in r['data']['txs']: coin_value = int (float (u['value']) * 100000000) script = h2b(u["script_hex"]) previous_hash = h2b(u["txid"]) previous_index = u["output_no"] spendables.append(Spendable(coin_value, script, previous_hash, previous_index)) return spendables
def main(): if len(sys.argv) != 4: print("usage: %s tx-hex-file-path wif-file-path p2sh-file-path" % sys.argv[0]) sys.exit(-1) # get the tx with open(sys.argv[1], "r") as f: tx_hex = f.readline().strip() tx = Tx.from_hex(tx_hex) # get the WIF with open(sys.argv[2], "r") as f: wif = f.readline().strip() assert is_wif_valid(wif) # create the p2sh_lookup with open(sys.argv[3], "r") as f: p2sh_script_hex = f.readline().strip() p2sh_script = h2b(p2sh_script_hex) # build a dictionary of script hashes to scripts p2sh_lookup = build_p2sh_lookup([p2sh_script]) # sign the transaction with the given WIF sign_tx(tx, wifs=[wif], p2sh_lookup=p2sh_lookup) bad_signature_count = tx.bad_signature_count() print("tx %s now has %d bad signature(s)" % (tx.id(), bad_signature_count)) include_unspents = (bad_signature_count > 0) print("Here is the tx as hex:\n%s" % tx.as_hex(include_unspents=include_unspents))
def main(): logging.basicConfig( level=logging.DEBUG, format=('%(asctime)s [%(process)d] [%(levelname)s] ' '%(filename)s:%(lineno)d %(message)s')) from pycoinnet.helpers.networks import MAINNET from pycoinnet.util.BlockChainView import BlockChainView from pycoinnet.bloom import BloomFilter from pycoin.tx import Spendable from pycoin.serialize import h2b_rev, h2b network = MAINNET initial_blockchain_view = BlockChainView() bloom_filter = BloomFilter(2048, hash_function_count=8, tweak=3) bloom_filter.add_address("14gZfnEn8Xd3ofkjr5s7rKoC3bi8J4Yfyy") # bloom_filter.add_address("1GL6i1ty44RnERgqYLKS1CrnhrahW4JhQZ") bloom_filter.add_item(h2b("0478abb18c0c7c95348fa77eb5fd43ce963e450d797cf4878894230ca528e6c8e866c3" "8ad93746e04f2161a01787c82a858ee24940e9a06e41fddb3494dfe29380")) spendable = Spendable( 0, b'', h2b_rev("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"), 0) bloom_filter.add_spendable(spendable) merkle_block_index_queue = asyncio.Queue() spv = SPVClient( network, initial_blockchain_view, bloom_filter, merkle_block_index_queue, host_port_q=None) def fetch(merkle_block_index_queue): while True: merkle_block, index = yield from merkle_block_index_queue.get() logging.info( "block #%d %s with %d transactions", index, merkle_block.id(), len(merkle_block.txs)) t = asyncio.Task(fetch(merkle_block_index_queue)) asyncio.get_event_loop().run_forever()
def get_tx(tx_hash): """ Get a Tx by its hash. """ URL = "%s/tx/raw/%s" % (blockrendpoint.url, b2h_rev(tx_hash)) r = json.loads(urlopen(URL).read().decode("utf8")) tx = Tx.parse(io.BytesIO(h2b(r.get("data").get("tx").get("hex")))) return tx
def get_blockchain_data(self): """ Finalize tree and return byte array to issue on blockchain :return: """ self.tree.make_tree() merkle_root = self.tree.get_merkle_root() return h2b(ensure_string(merkle_root))
def test_validate_multisig(self): # this is a transaction in the block chain # the unspents are included too, so it can be validated f = io.BytesIO(h2b("01000000025718fb915fb8b3a802bb699ddf04dd91261ef6715f5f2820a2b1b9b7e38b4f27000000004a004830450221008c2107ed4e026ab4319a591e8d9ec37719cdea053951c660566e3a3399428af502202ecd823d5f74a77cc2159d8af2d3ea5d36a702fef9a7edaaf562aef22ac35da401ffffffff038f52231b994efb980382e4d804efeadaee13cfe01abe0d969038ccb45ec17000000000490047304402200487cd787fde9b337ab87f9fe54b9fd46d5d1692aa58e97147a4fe757f6f944202203cbcfb9c0fc4e3c453938bbea9e5ae64030cf7a97fafaf460ea2cb54ed5651b501ffffffff0100093d00000000001976a9144dc39248253538b93d3a0eb122d16882b998145888ac0000000002000000000000004751210351efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da782100f2b7816db49d55d24df7bdffdbc1e203b424e8cd39f5651ab938e5e4a193569e52ae404b4c00000000004751210351efb6e91a31221652105d032a2508275f374cea63939ad72f1b1e02f477da7821004f0331742bbc917ba2056a3b8a857ea47ec088dd10475ea311302112c9d24a7152ae")) tx = Tx.parse(f) tx.parse_unspents(f) self.assertEqual(tx.id(), "70c4e749f2b8b907875d1483ae43e8a6790b0c8397bbb33682e3602617f9a77a") self.assertEqual(tx.bad_signature_count(), 0)
def get_tx(tx_hash): """ Get a Tx by its hash. """ URL = "http://btc.blockr.io/api/v1/tx/raw/%s" % b2h_rev(tx_hash) r = json.loads(urlopen(URL).read().decode("utf8")) tx = Tx.parse(io.BytesIO(h2b(r.get("data").get("tx").get("hex")))) return tx
def unspents_for_addresses(self, address_iter): """ Return a list of Spendable objects for the given bitcoin address. """ address_list = ",".join(address_iter) URL = self.base_url() % ("addresses/%s/unspents" % address_list) r = json.loads(urlopen(URL).read().decode("utf8")) spendables = [] for u in r: coin_value = u["value"] script = h2b(u["script_hex"]) previous_hash = h2b(u["transaction_hash"]) previous_index = u["output_index"] spendables.append(Spendable(coin_value, script, previous_hash, previous_index)) return spendables
def test_recognize_multisig(self): h = '010000000139c92b102879eb95f14e7344e4dd7d481e1238b1bfb1fa0f735068d2927b231400000000910047304402208fc06d216ebb4b6a3a3e0f906e1512c372fa8a9c2a92505d04e9b451ea7acd0c0220764303bb7e514ddd77855949d941c934e9cbda8e3c3827bfdb5777477e73885b014730440220569ec6d2e81625dd18c73920e0079cdb4c1d67d3d7616759eb0c18cf566b3d3402201c60318f0a62e3ba85ca0f158d4dfe63c0779269eb6765b6fc939fc51e7a8ea901ffffffff0140787d01000000001976a914641ad5051edd97029a003fe9efb29359fcee409d88ac0000000040787d0100000000c952410496ec45f878b62c46c4be8e336dff7cc58df9b502178cc240eb3d31b1266f69f5767071aa3e017d1b82a0bb28dab5e27d4d8e9725b3e68ed5f8a2d45c730621e34104cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4410461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af53ae' f = io.BytesIO(h2b(h)) tx = Tx.parse(f) tx.parse_unspents(f) self.assertEqual(tx.id(), "10c61e258e0a2b19b245a96a2d0a1538fe81cd4ecd547e0a3df7ed6fd3761ada") the_script = tx.unspents[0].script s = script_obj_from_script(tx.unspents[0].script) self.assertEqual(s.script(), the_script)
def test_PeerAddress(self): pa = PeerAddress(188, IP4_HEADER + h2b("c0a80163"), 8333) pa_bytes = to_bin(pa) pa1 = from_bin(PeerAddress, pa_bytes) self.assertEqual(pa, pa1) pa2 = PeerAddress(188, IP4_HEADER + h2b("c0a80162"), 8333) self.assertTrue(pa1 > pa2) self.assertTrue(pa1 >= pa2) self.assertTrue(pa2 < pa1) self.assertTrue(pa2 <= pa1) self.assertNotEqual(pa2, pa1) self.assertNotEqual(pa1, pa2) self.assertEqual(pa1.host(), "192.168.1.99") self.assertEqual(repr(pa1), "192.168.1.99/8333") pa_v6 = PeerAddress(945, h2b("2607f8b04006080a000000000000200e"), 8333) self.assertEqual(pa_v6.host(), "2607:f8b0:4006:80a:0:0:0:200e")
def test_simple_account_testnet(self): master_key = MasterKey.from_seed(h2b("000102030405060708090a0b0c0d0e0f"), netcode='XTN') account_key = master_key.account_for_path("0H/1/2H") account = SimpleAccount(account_key) self.assertEqual('mgMy4vmqChGT8XeKPb1zD6RURWsiNmoNvR', account.current_address()) account._provider = MySimpleTestnetProvider() self.assertEqual(1, len(account.spendables())) tx = account.tx([("mvccWwntgfQaj7TVYEw2C2avymxHwjixDz", 2000)]) account.sign(tx)
def test_create_trx(self): cost = TransactionCosts(0.0001, 0.0000275, 3) tx_input = Spendable(200, '18eKkAWyU9kvRNHPKxnZb6wwtPMrNmRRRA', h2b('8443b07464c762d7fb404ea918a5ac9b3618d5cd6a0c5ea6e4dd5d7bbe28b154'), 0) tx_outs = [trx_utils.create_transaction_output('mgAqW5ZCnEp7fjvpj8RUL3WxsBy8rcDcCi', 0.0000275)] tx = trx_utils.create_trx('TEST'.encode('utf-8'), cost, 'mgAqW5ZCnEp7fjvpj8RUL3WxsBy8rcDcCi', tx_outs, tx_input) hextx = hexlify(tx.serialize()) self.assertEquals(hextx, '01000000018443b07464c762d7fb404ea918a5ac9b3618d5cd6a0c5ea6e4dd5d7bbe28b1540000000000ffffffff0300000000000000001976a914072a22e5913cd939904c46bbd0bc56755543384b88acc5000000000000001976a914072a22e5913cd939904c46bbd0bc56755543384b88ac0000000000000000066a045445535400000000')
def test_testnet(self): # WARNING: these values have not been verified independently. TODO: do so master = BIP32Node.from_master_secret(h2b("000102030405060708090a0b0c0d0e0f"), netcode='XTN') self.assertEqual( master.wallet_key(as_private=True), "tprv8ZgxMBicQKsPeDgjzdC36fs6bMjGApWDNLR9erAXMs5skhMv36j9MV5ecvfavji5kh" "qjWaWSFhN3YcCUUdiKH6isR4Pwy3U5y5egddBr16m") self.assertEqual(master.bitcoin_address(), "mkHGce7dctSxHgaWSSbmmrRWsZfzz7MxMk") self.assertEqual(master.wif(), "cVPXTF2TnozE1PenpP3x9huctiATZmp27T9Ue1d8nqLSExoPwfN5")
def get_tx(self, tx_hash): """ Get a Tx by its hash. """ url_append = "tx/raw/%s" %(tx_hash) URL = self.base_url("%s" %url_append) r = json.loads(urlopen(URL).read().decode("utf8")) tx = Tx.parse(io.BytesIO(h2b(r.get("data").get("tx").get("hex")))) return tx
def test_electrum(self): # Electrum seed v6: fade really needle dinner excuse half rabbit sorry stomach confusion bid twice suffer m = MasterKey.from_seed(h2b("7043e6911790bbcc5d0c5c00ab4c3deb2641af606f987113bcc28b7ccd94b2b6be3a0203be1c61fe64e6d6e4e806107fec9e80d5bf9a62284d3bb45550d797f0")) a = m.electrum_account(0) l = a.leaf(0) self.assertEqual(l.address(), "1AGWXxRe7FwWJJ6k5uAfwcoA7Sov9AYNVK") # Simulate generation of an Electrum master public key for the 1of1 hierarchy em = MasterKey.from_key(m.account_for_path("0H").hwif()) a1 = em.bip32_account(0, hardened=False) self.assertEqual(a.hwif(), a1.hwif())
def test_coinbase_tx(self): coinbase_bytes = h2b("04ed66471b02c301") 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 main(): networks = "MTLD" parser = argparse.ArgumentParser( description='Crypto coin utility ku ("key utility") to show' ' information about Bitcoin or other cryptocoin data structures.', epilog='Known networks codes:\n ' \ + ', '.join(['%s (%s)'%(i, full_network_name_for_netcode(i)) for i in NETWORK_NAMES]) ) parser.add_argument('-w', "--wallet", help='show just Bitcoin wallet key', action='store_true') parser.add_argument('-W', "--wif", help='show just Bitcoin WIF', action='store_true') parser.add_argument('-a', "--address", help='show just Bitcoin address', action='store_true') parser.add_argument( '-u', "--uncompressed", help='show output in uncompressed form', action='store_true') parser.add_argument( '-P', "--public", help='only show public version of wallet keys', action='store_true') parser.add_argument('-j', "--json", help='output as JSON', action='store_true') parser.add_argument('-s', "--subkey", help='subkey path (example: 0H/2/15-20)') parser.add_argument('-n', "--network", help='specify network (default: BTC = Bitcoin)', default='BTC', choices=NETWORK_NAMES) parser.add_argument("--override-network", help='override detected network type', default=None, choices=NETWORK_NAMES) parser.add_argument( 'item', nargs="+", help='a BIP0032 wallet key string;' ' a WIF;' ' a bitcoin address;' ' an SEC (ie. a 66 hex chars starting with 02, 03 or a 130 hex chars starting with 04);' ' the literal string "create" to create a new wallet key using strong entropy sources;' ' P:wallet passphrase (NOT RECOMMENDED);' ' H:wallet passphrase in hex (NOT RECOMMENDED);' ' secret_exponent (in decimal or hex);' ' x,y where x,y form a public pair (y is a number or one of the strings "even" or "odd");' ' hash160 (as 40 hex characters)') args = parser.parse_args() if args.override_network: # force network arg to match override, but also will override decoded data below. args.network = args.override_network PREFIX_TRANSFORMS = ( ("P:", lambda s: BIP32Node.from_master_secret(s.encode("utf8"), netcode=args.network)), ("H:", lambda s: BIP32Node.from_master_secret(h2b(s), netcode=args.network)), ("create", lambda s: BIP32Node.from_master_secret(get_entropy(), netcode=args.network)), ) for item in args.item: key = None for k, f in PREFIX_TRANSFORMS: if item.startswith(k): try: key = f(item[len(k):]) break except Exception: pass else: try: key = Key.from_text(item) except encoding.EncodingError: pass if key is None: secret_exponent = parse_as_secret_exponent(item) if secret_exponent: key = Key(secret_exponent=secret_exponent, netcode=args.network) if SEC_RE.match(item): key = Key.from_sec(h2b(item)) if key is None: public_pair = parse_as_public_pair(item) if public_pair: key = Key(public_pair=public_pair, netcode=args.network) if HASH160_RE.match(item): key = Key(hash160=h2b(item), netcode=args.network) if key is None: print("can't parse %s" % item, file=sys.stderr) continue if args.override_network: # Override the network value, so we can take the same xpubkey and view what # the values would be on each other network type. # XXX public interface for this is needed... key._netcode = args.override_network key._hierarchical_wallet.netcode = args.override_network for key in key.subkeys(args.subkey or ""): if args.public: key = key.public_copy() output_dict, output_order = create_output(item, key) if args.json: print(json.dumps(output_dict, indent=3, sort_keys=True)) elif args.wallet: print(output_dict["wallet_key"]) elif args.wif: print(output_dict["wif_uncompressed" if args.uncompressed else "wif"]) elif args.address: print(output_dict[ args.network.lower() + "_address" + ("_uncompressed" if args.uncompressed else "")]) else: dump_output(output_dict, output_order)
phrase = m.generate() print phrase phrase = "sample core fitness wrong unusual inch hurry chaos myself credit welcome margin" seed = mnemonic.Mnemonic.to_seed(phrase) wallet = BIP32Node.from_master_secret(seed, 'XTN') path = '%X' % random.randint(0, 2**64 - 1) # http://api.greenaddress.it/examples/mnemonic_login.html while len(path) < 16: path = '0' + path print path path_bin = h2b(path) path_str = '/'.join( str(struct.unpack('!H', path_bin[i * 2:(i + 1) * 2])[0]) for i in xrange(4)) print path_str wallet_login = wallet.subkey_for_path(path_str) print wallet_login subkey = wallet_login print "PRIVATE", wallet.is_private() print "PUBLIC X", wallet.public_pair print "CHILD INDEX", wallet.child_index() print "WIF", wallet.wif() key = wallet.subkey_for_path("0/0/458") print "SUB KEY WIF", key.wif()
def broadcast_tx(self, transaction): as_hex = transaction.as_hex() transaction = CTransaction.deserialize(h2b(as_hex)) tx_id = bitcoin.rpc.Proxy().sendrawtransaction(transaction) # reverse endianness for bitcoind return b2h_rev(tx_id)
# this file is deprecated and will soon be folded into all.py from collections import namedtuple from pycoin.serialize import h2b NetworkValues = namedtuple('NetworkValues', ('network_name', 'subnet_name', 'code', 'wif', 'address', 'pay_to_script', 'prv32', 'pub32')) NETWORKS = ( # VIA viacoin mainnet : xprv/xpub NetworkValues("Viacoin", "mainnet", "VIA", b'\xc7', b'\x47', b'\x21', h2b('0488ADE4'), h2b('0488B21E')), # VIA viacoin testnet : tprv/tpub NetworkValues("Viacoin", "testnet", "TVI", b'\xff', b'\x7f', b'\xc4', h2b('04358394'), h2b('043587CF')), # FTC feathercoin mainnet : xprv/xpub NetworkValues("Feathercoin", "mainnet", "FTC", b'\x8e', b'\x0e', b'\x60', h2b('0488ADE4'), h2b('0488B21E')), # FTC feathercoin testnet : tprv/tpub NetworkValues("Feathercoin", "testnet", "FTX", b'\xC1', b'\x41', b'\xc4', h2b('04358394'), h2b('043587CF')), # DOGE Dogecoin mainnet : dogv/dogp NetworkValues("Dogecoin", "mainnet", "DOGE", b'\x9e', b'\x1e', b'\x16', h2b("02FD3955"), h2b("02FD3929")), # DOGE Dogecoin testnet : tgpv/tgub NetworkValues("Dogecoin", "testnet", "XDT", b'\xf1', b'\x71', b'\xc4', h2b("0432a9a8"), h2b("0432a243")),
#!/usr/bin/env python import unittest import os import sys import tempfile from pycoin.serialize import h2b # binary data with GPG-encrypted WIF KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn for secret exponent 1 WIF_1_GPG = h2b( "8c0d040303026c3030b7518a94eb60c950bc87ab26f0604a37f247f74f88deda10b180bb807" "2879b728b8f056808baea0c8e511e7cf2eba77cce937d2f69a67a79e163bf70b57113d27cb6" "a1c2390a1e8069b447c34a7c9b5ba268c2beedd85b50") class ScriptsTest(unittest.TestCase): def launch_tool(self, tool): # set python_path = sys.executable script_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "pycoin", "cmds")) cwd = os.getcwd() os.chdir(script_dir) tool = "%s %s" % (python_path, tool) os.environ["PYCOIN_BTC_PROVIDERS"] = "blockr.io blockchain.info biteasy.com blockexplorer.com" r = os.system(tool) os.chdir(cwd) assert r == 0 def set_cache_dir(self): temp_dir = tempfile.mkdtemp()
from pycoin.block import Block from pycoin import ecdsa from pycoin.encoding import public_pair_to_sec, public_pair_to_bitcoin_address, wif_to_secret_exponent from pycoin.serialize import h2b from pycoin.tx import Tx, SIGHASH_ALL from pycoin.tx.TxIn import TxIn from pycoin.tx.TxOut import TxOut from pycoin.tx.exceptions import SolvingError from pycoin.tx.pay_to import build_hash160_lookup from pycoin.ui import standard_tx_out_script # block 80971 block_80971_cs = h2b( '00000000001126456C67A1F5F0FF0268F53B4F22E0531DC70C7B69746AF69DAC') block_80971_data = h2b('01000000950A1631FB9FAC411DFB173487B9E18018B7C6F7147E78C06258410000000000A881352F97F14B'\ 'F191B54915AE124E051B8FE6C3922C5082B34EAD503000FC34D891974CED66471B4016850A040100'\ '0000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF080'\ '4ED66471B02C301FFFFFFFF0100F2052A01000000434104CB6B6B4EADC96C7D08B21B29D0ADA5F29F937'\ '8978CABDB602B8B65DA08C8A93CAAB46F5ABD59889BAC704925942DD77A2116D10E0274CAD944C71D3D1A'\ '670570AC0000000001000000018C55ED829F16A4E43902940D3D33005264606D5F7D555B5F67EE4C033390'\ 'C2EB010000008A47304402202D1BF606648EDCDB124C1254930852D99188E1231715031CBEAEA80CCFD2B39A'\ '02201FA9D6EE7A1763580E342474FC1AEF59B0468F98479953437F525063E25675DE014104A01F763CFBF5E518'\ 'C628939158AF3DC0CAAC35C4BA7BC1CE8B7E634E8CDC44E15F0296B250282BD649BAA8398D199F2424FCDCD88'\ 'D3A9ED186E4FD3CB9BF57CFFFFFFFFF02404B4C00000000001976A9148156FF75BEF24B35ACCE3C05289A241'\ '1E1B0E57988AC00AA38DF010000001976A914BC7E692A5FFE95A596712F5ED83393B3002E452E88AC000000'\ '0001000000019C97AFDF6C9A31FFA86D71EA79A079001E2B59EE408FD418498219400639AC0A010000008B4'\ '830450220363CFFAE09599397B21E6D8A8073FB1DFBE06B6ACDD0F2F7D3FEA86CA9C3F605022100FA255A6ED'\ '23FD825C759EF1A885A31CAD0989606CA8A3A16657D50FE3CEF5828014104FF444BAC08308B9EC97F56A652A'\ 'D8866E0BA804DA97868909999566CB377F4A2C8F1000E83B496868F3A282E1A34DF78565B65C15C3FA21A076'\
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')
# this file is deprecated and will soon be folded into all.py from collections import namedtuple from pycoin.serialize import h2b NetworkValues = namedtuple('NetworkValues', ('network_name', 'subnet_name', 'code', 'wif', 'address', 'pay_to_script', 'prv32', 'pub32')) NETWORKS = ( # LTC litecoin mainnet : Ltpv/Ltub NetworkValues("Litecoin", "mainnet", "LTC", b'\xb0', b'\x30', b'\5', h2b('019d9cfe'), h2b('019da462')), # LTC litecoin testnet : ttpv/ttub NetworkValues("Litecoin", "testnet", "XLT", b'\xef', b'\x6f', b'\xc4', h2b('0436ef7d'), h2b('0436f6e1')), # VIA viacoin mainnet : xprv/xpub NetworkValues("Viacoin", "mainnet", "VIA", b'\xc7', b'\x47', b'\x21', h2b('0488ADE4'), h2b('0488B21E')), # VIA viacoin testnet : tprv/tpub NetworkValues("Viacoin", "testnet", "TVI", b'\xff', b'\x7f', b'\xc4', h2b('04358394'), h2b('043587CF')), # FTC feathercoin mainnet : xprv/xpub NetworkValues("Feathercoin", "mainnet", "FTC", b'\x8e', b'\x0e', b'\x60', h2b('0488ADE4'), h2b('0488B21E')), # FTC feathercoin testnet : tprv/tpub NetworkValues("Feathercoin", "testnet", "FTX", b'\xC1', b'\x41', b'\xc4', h2b('04358394'), h2b('043587CF')),
def create_multisig(self, escrow): logging.info("starting creation of multisig address") N, M = 2, 3 subkeydb = MONGOSUBKEYS.find_one() # first time running and we don't have a subkey set in the database if not subkeydb: subkeydb = MONGOSUBKEYS.insert({'subkey': 1}) # TODO: this has to be moved to the private key server # create the first public key. Needed for signing up from the website or the native client. subkey = subkeydb['subkey'] phrase = "sample core fitness wrong unusual inch hurry chaos myself credit welcome margin" seed = mnemonic.Mnemonic.to_seed(phrase) wallet = BIP32Node.from_master_secret(seed) subkeys = [] keys = [] if not escrow.has_key('sellerpubky') or not escrow['sellerpubkey']: logging.info( 'seller public key was not provided. We re making and storing the key' ) subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key1 = wallet.subkey_for_path(subkeystring) else: logging.info( 'seller public key was provided from the native client') key1 = Key.from_sec(h2b(escrow['sellerpubkey'])) keys.append(key1) if not escrow.has_key('buyerpubkey') or not escrow['buyerpubkey']: logging.info( 'buyer public key was not provided. We re making and storing the key' ) subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key2 = wallet.subkey_for_path(subkeystring) else: logging.info( 'buyer public key was provided from the native client.') key2 = Key.from_sec(h2b(escrow['buyerpubkey'])) keys.append(key2) # this is our own, no matter what subkey += 1 subkeystring = "0/0/" + str(subkey) subkeys.append(subkeystring) key3 = wallet.subkey_for_path(subkeystring) keys.append(key3) redeemscript = ScriptMultisig(n=N, sec_keys=[key.sec() for key in keys[:M]]).script() multisigaddress = address_for_pay_to_script(redeemscript) logging.info('multi-sig address was made: %s' % multisigaddress) MONGOSUBKEYS.update({'_id': subkeydb['_id']}, {"$set": { 'subkey': subkey }}) if escrow.has_key('_id'): MONGODB.update({'_id': escrow['_id']}, { "$set": { 'multisigaddress': multisigaddress, 'subkeys': subkeys } }) return (multisigaddress, subkeys)
def augmented_leaf(block_header_hex, timestamp_int): block_header_int = int(b2h(utils.sha3(h2b(block_header_hex))), 16) return augmented_node(block_header_int, block_header_int, timestamp_int, timestamp_int)
def test_public_pair_to_sec(self): def do_test(as_public_pair, as_sec, is_compressed, as_hash160_sec, as_bitcoin_address): self.assertEqual(encoding.sec_to_public_pair(as_sec), as_public_pair) self.assertEqual( encoding.public_pair_to_sec(as_public_pair, compressed=is_compressed), as_sec) self.assertEqual(encoding.is_sec_compressed(as_sec), is_compressed) self.assertEqual( encoding.public_pair_to_hash160_sec(as_public_pair, compressed=is_compressed), as_hash160_sec) self.assertEqual( encoding.hash160_sec_to_bitcoin_address(as_hash160_sec), as_bitcoin_address) self.assertEqual( encoding.public_pair_to_bitcoin_address( as_public_pair, compressed=is_compressed), as_bitcoin_address) self.assertTrue( encoding.is_valid_bitcoin_address(as_bitcoin_address)) bad_address = as_bitcoin_address[:17] + chr( ord(as_bitcoin_address[17]) + 1) + as_bitcoin_address[18:] self.assertFalse(encoding.is_valid_bitcoin_address(bad_address)) SEC_TEST_DATA = [ ((35826991941973211494003564265461426073026284918572421206325859877044495085994, 25491041833361137486709012056693088297620945779048998614056404517283089805761 ), "034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", True, "fc7250a211deddc70ee5a2738de5f07817351cef", "1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9"), ((31855367722742370537280679280108010854876607759940877706949385967087672770343, 46659058944867745027460438812818578793297503278458148978085384795486842595210 ), "02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", True, "531260aa2a199e228c537dfa42c82bea2c7c1f4d", "18aF6pYXKDSXjXHpidt2G6okdVdBr8zA7z"), ((27341391395138457474971175971081207666803680341783085051101294443585438462385, 26772005640425216814694594224987412261034377630410179754457174380653265224672 ), "023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", True, "3bc28d6d92d9073fb5e3adf481795eaf446bceed", "16Syw4SugWs4siKbK8cuxJXM2ukh2GKpRi"), ((35826991941973211494003564265461426073026284918572421206325859877044495085994, 25491041833361137486709012056693088297620945779048998614056404517283089805761 ), "044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa" "385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1", False, "e4e517ee07984a4000cd7b00cbcb545911c541c4", "1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a"), ((31855367722742370537280679280108010854876607759940877706949385967087672770343, 46659058944867745027460438812818578793297503278458148978085384795486842595210 ), "04466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27" "6728176c3c6431f8eeda4538dc37c865e2784f3a9e77d044f33e407797e1278a", False, "b256082b934fe782adbacaafeadfca64c52a5384", "1HFxLkPTtMZeo5mDpZn6CF9sh4h2ycknwr"), ((27341391395138457474971175971081207666803680341783085051101294443585438462385, 26772005640425216814694594224987412261034377630410179754457174380653265224672 ), "043c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1" "3b306b0fe085665d8fc1b28ae1676cd3ad6e08eaeda225fe38d0da4de55703e0", False, "edf6bbd7ba7aad222c2b28e6d8d5001178e3680c", "1NhEipumt9Pug6pwTqMNRXhBG84K39Ebbi"), ] for public_pair, sec, compressed, hash160_sec, bitcoin_address in SEC_TEST_DATA: do_test(public_pair, h2b(sec), compressed, h2b(hash160_sec), bitcoin_address)
def test_bip143_tx_5(self): tx_u5, tx_s5 = self.check_bip143_tx( "010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787" "b96e0100000000ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631" "e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84" "c138dbbd3c3ee41588ac00000000", "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca2" "9787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1b" "b8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc" "0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e" "6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52e" "eb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e" "4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009" "a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62" "e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfe" "c54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a8913" "9c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b" "79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265" "f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553b" "a89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5" "d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1" "482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a" "34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae" "49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28" "bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703" "413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb8" "33092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94b" "a04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2" "f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000", [(9.87654321, "a9149993a429037b5d912407a71c252019287b8d27a587")], 1, 2, 1, 0) tx_u5prime = self.unsigned_copy(tx_s5) tx_s_hex = tx_s5.as_hex() tx_u5prime.set_unspents(tx_s5.unspents) ss = [ "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3" "2103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21" "034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a2103" "3400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6" "d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b6" "61b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae", "0020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54" ] p2sh_lookup = build_p2sh_lookup([h2b(x) for x in ss]) for se, sighash_type in [ (0x730fff80e1413068a05b57d6a58261f07551163369787f349438ea38ca80fac6, SIGHASH_ALL), (0x11fa3d25a17cbc22b29c44a484ba552b5a53149d106d3d853e22fdd05a2d8bb3, SIGHASH_NONE), (0x77bf4141a87d55bdd7f3cd0bdccf6e9e642935fec45f2f30047be7b799120661, SIGHASH_SINGLE), (0x14af36970f5025ea3e8b5542c0f8ebe7763e674838d08808896b63c3351ffe49, SIGHASH_ANYONECANPAY | SIGHASH_ALL), (0xfe9a95c19eef81dde2b95c1284ef39be497d128e2aa46916fb02d552485e0323, SIGHASH_ANYONECANPAY | SIGHASH_NONE), (0x428a7aee9f0c2af0cd19af3cf1c78149951ea528726989b2e83e4778d2c3f890, SIGHASH_ANYONECANPAY | SIGHASH_SINGLE), ]: tx_u5prime.sign(hash_type=sighash_type, hash160_lookup=build_hash160_lookup( [se], [secp256k1_generator]), p2sh_lookup=p2sh_lookup) self.check_signed(tx_u5prime) tx_hex = tx_u5prime.as_hex() self.assertEqual(tx_hex, tx_s_hex) sc = tx_s5.SolutionChecker(tx_s5) self.assertEqual( b2h(sc._hash_prevouts(SIGHASH_ALL)), "74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0") self.assertEqual( b2h(sc._hash_sequence(SIGHASH_ALL)), "3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044") self.assertEqual( b2h(sc._hash_outputs(SIGHASH_ALL, 0)), "bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc") self.assertEqual( b2h(sc._hash_outputs(SIGHASH_SINGLE, 0)), "9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a43063ca3cd4f708") script = tx_s5.txs_in[0].witness[-1] self.assertEqual( b2h( sc._segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_ALL)), "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aa" "a03bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e706650443664" "1869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf" "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3" "2103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21" "034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a2103" "3400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6" "d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b6" "61b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de" "3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fd" "bb8eb90307cc0000000001000000") self.assertEqual( b2h( sc._segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_NONE)), "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aa" "a000000000000000000000000000000000000000000000000000000000000000003664" "1869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf" "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3" "2103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21" "034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a2103" "3400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6" "d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b6" "61b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de" "3a00000000ffffffff0000000000000000000000000000000000000000000000000000" "0000000000000000000002000000") self.assertEqual( b2h( sc._segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_SINGLE)), "0100000074afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aa" "a000000000000000000000000000000000000000000000000000000000000000003664" "1869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf" "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3" "2103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21" "034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a2103" "3400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6" "d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b6" "61b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de" "3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a430" "63ca3cd4f7080000000003000000") self.assertEqual( b2h( sc._segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_ALL | SIGHASH_ANYONECANPAY)), "0100000000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000000000003664" "1869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf" "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3" "2103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21" "034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a2103" "3400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6" "d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b6" "61b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de" "3a00000000ffffffffbc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fd" "bb8eb90307cc0000000081000000") self.assertEqual( b2h( sc._segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_NONE | SIGHASH_ANYONECANPAY)), "0100000000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000000000003664" "1869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf" "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3" "2103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21" "034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a2103" "3400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6" "d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b6" "61b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de" "3a00000000ffffffff0000000000000000000000000000000000000000000000000000" "0000000000000000000082000000") self.assertEqual( b2h( sc._segwit_signature_preimage(script=script, tx_in_idx=0, hash_type=SIGHASH_SINGLE | SIGHASH_ANYONECANPAY)), "0100000000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000000000003664" "1869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e01000000cf" "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3" "2103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21" "034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a2103" "3400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6" "d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b6" "61b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56aeb168de" "3a00000000ffffffff9efe0c13a6b16c14a41b04ebe6a63f419bdacb2f8705b494a430" "63ca3cd4f7080000000083000000") tx = Tx.from_hex( "010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac83" "87f14c1d000000ffffffff0101000000000000000000000000") tx.set_witness(0, [ h2b(x) for x in [ "30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dc" "c9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c5" "3e01", "02a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c", "ad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d8915" "56dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae6" "26c53e01" ] ]) tx = Tx.from_hex( "0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1" "ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c497" "4de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f8" "45d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61f" "b5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487f" "b382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf9" "5feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000" ) tx_hex = tx.as_hex() print(tx) print(tx_hex) tx = Tx.from_hex( "010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac83" "87f14c1d000000ffffffff0101000000000000000000000000") self.assertEqual( tx_hex, "0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1" "ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c497" "4de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f8" "45d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61f" "b5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487f" "b382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf9" "5feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000" )
def test_validate(self): # block 80971 block_80971_cs = h2b( '00000000001126456C67A1F5F0FF0268F53B4F22E0531DC70C7B69746AF69DAC') block_80971_data = h2b('01000000950A1631FB9FAC411DFB173487B9E18018B7C6F7147E78C06258410000000000A881352F97F14B'\ 'F191B54915AE124E051B8FE6C3922C5082B34EAD503000FC34D891974CED66471B4016850A040100'\ '0000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF080'\ '4ED66471B02C301FFFFFFFF0100F2052A01000000434104CB6B6B4EADC96C7D08B21B29D0ADA5F29F937'\ '8978CABDB602B8B65DA08C8A93CAAB46F5ABD59889BAC704925942DD77A2116D10E0274CAD944C71D3D1A'\ '670570AC0000000001000000018C55ED829F16A4E43902940D3D33005264606D5F7D555B5F67EE4C033390'\ 'C2EB010000008A47304402202D1BF606648EDCDB124C1254930852D99188E1231715031CBEAEA80CCFD2B39A'\ '02201FA9D6EE7A1763580E342474FC1AEF59B0468F98479953437F525063E25675DE014104A01F763CFBF5E518'\ 'C628939158AF3DC0CAAC35C4BA7BC1CE8B7E634E8CDC44E15F0296B250282BD649BAA8398D199F2424FCDCD88'\ 'D3A9ED186E4FD3CB9BF57CFFFFFFFFF02404B4C00000000001976A9148156FF75BEF24B35ACCE3C05289A241'\ '1E1B0E57988AC00AA38DF010000001976A914BC7E692A5FFE95A596712F5ED83393B3002E452E88AC000000'\ '0001000000019C97AFDF6C9A31FFA86D71EA79A079001E2B59EE408FD418498219400639AC0A010000008B4'\ '830450220363CFFAE09599397B21E6D8A8073FB1DFBE06B6ACDD0F2F7D3FEA86CA9C3F605022100FA255A6ED'\ '23FD825C759EF1A885A31CAD0989606CA8A3A16657D50FE3CEF5828014104FF444BAC08308B9EC97F56A652A'\ 'D8866E0BA804DA97868909999566CB377F4A2C8F1000E83B496868F3A282E1A34DF78565B65C15C3FA21A076'\ '3FD81A3DFBBB6FFFFFFFF02C05EECDE010000001976A914588554E6CC64E7343D77117DA7E01357A6111B798'\ '8AC404B4C00000000001976A914CA6EB218592F289999F13916EE32829AD587DBC588AC00000000010000000'\ '1BEF5C9225CB9FE3DEF929423FA36AAD9980B9D6F8F3070001ACF3A5FB389A69F000000004A493046022100F'\ 'B23B1E2F2FB8B96E04D220D385346290A9349F89BBBC5C225D5A56D931F8A8E022100F298EB28294B90C1BAF'\ '319DAB713E7CA721AAADD8FCC15F849DE7B0A6CF5412101FFFFFFFF0100F2052A010000001976A9146DDEA80'\ '71439951115469D0D2E2B80ECBCDD48DB88AC00000000') # block 80974 block_80974_cs = h2b( '0000000000089F7910F6755C10EA2795EC368A29B435D80770AD78493A6FECF1') block_80974_data = h2b('010000007480150B299A16BBCE5CCDB1D1BBC65CFC5893B01E6619107C55200000000000790'\ '0A2B203D24C69710AB6A94BEB937E1B1ADD64C2327E268D8C3E5F8B41DBED8796974CED66471B204C3247030'\ '1000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF0804ED6'\ '6471B024001FFFFFFFF0100F2052A010000004341045FEE68BAB9915C4EDCA4C680420ED28BBC369ED84D48A'\ 'C178E1F5F7EEAC455BBE270DABA06802145854B5E29F0A7F816E2DF906E0FE4F6D5B4C9B92940E4F0EDAC000'\ '000000100000001F7B30415D1A7BF6DB91CB2A272767C6799D721A4178AA328E0D77C199CB3B57F010000008'\ 'A4730440220556F61B84F16E637836D2E74B8CB784DE40C28FE3EF93CCB7406504EE9C7CAA5022043BD4749D'\ '4F3F7F831AC696748AD8D8E79AEB4A1C539E742AA3256910FC88E170141049A414D94345712893A828DE57B4C'\ '2054E2F596CDCA9D0B4451BA1CA5F8847830B9BE6E196450E6ABB21C540EA31BE310271AA00A49ED0BA930743'\ 'D1ED465BAD0FFFFFFFF0200E1F505000000001976A914529A63393D63E980ACE6FA885C5A89E4F27AA08988AC'\ 'C0ADA41A000000001976A9145D17976537F308865ED533CCCFDD76558CA3C8F088AC000000000100000001651'\ '48D894D3922EF5FFDA962BE26016635C933D470C8B0AB7618E869E3F70E3C000000008B48304502207F5779EB'\ 'F4834FEAEFF4D250898324EB5C0833B16D7AF4C1CB0F66F50FCF6E85022100B78A65377FD018281E77285EFC3'\ '1E5B9BA7CB7E20E015CF6B7FA3E4A466DD195014104072AD79E0AA38C05FA33DD185F84C17F611E58A8658CE'\ '996D8B04395B99C7BE36529CAB7606900A0CD5A7AEBC6B233EA8E0FE60943054C63620E05E5B85F0426FFFFF'\ 'FFF02404B4C00000000001976A914D4CAA8447532CA8EE4C80A1AE1D230A01E22BFDB88AC8013A0DE0100000'\ '01976A9149661A79AE1F6D487AF3420C13E649D6DF3747FC288AC00000000') block_80971 = Block.parse(io.BytesIO(block_80971_data)) block_80974 = Block.parse(io.BytesIO(block_80974_data)) tx_db = {tx.hash(): tx for tx in block_80971.txs} tx_to_validate = block_80974.txs[2] self.assertEqual( "OP_DUP OP_HASH160 d4caa8447532ca8ee4c80a1ae1d230a01e22bfdb OP_EQUALVERIFY OP_CHECKSIG", tools.disassemble(tx_to_validate.txs_out[0].script)) self.assertEqual( tx_to_validate.id(), "7c4f5385050c18aa8df2ba50da566bbab68635999cc99b75124863da1594195b") tx_to_validate.unspents_from_db(tx_db) self.assertEqual(tx_to_validate.bad_signature_count(), 0) # now, let's corrupt the Tx and see what happens tx_out = tx_to_validate.txs_out[1] disassembly = tools.disassemble(tx_out.script) tx_out.script = tools.compile(disassembly) self.assertEqual(tx_to_validate.bad_signature_count(), 0) disassembly = disassembly.replace( "9661a79ae1f6d487af3420c13e649d6df3747fc2", "9661a79ae1f6d487af3420c13e649d6df3747fc3") tx_out.script = tools.compile(disassembly) self.assertEqual(tx_to_validate.bad_signature_count(), 1) self.assertFalse(tx_to_validate.is_signature_ok(0))
def send(self, wallet_id, passcode, address, amount, message='', fee=None, fan_unspend=10): """ Send bitcoins to address :param wallet_id: bitgo wallet id :param address: bitcoin address :param amount: btc amount in satoshis :param split: create new outputs if needed :return: boolean """ MINIMAL_FEE = 20000 MINIMAL_SPLIT = 10000000 wallet = self.get_wallet(wallet_id) if not wallet['spendingAccount']: raise NotSpendableWallet() if not wallet['isActive']: raise NotActiveWallet() if amount < 10000: raise Exception('amount to small') if wallet['confirmedBalance'] < amount: raise NotEnoughFunds('Not enough funds: balance %s amount %s' % (wallet['confirmedBalance'], amount) ) change_address = self.create_address(wallet_id, chain=1) usableKeychain = False spendables = [] chain_paths = [] p2sh = [] payables = [(address, amount)] keychain_path = "" for keychain in wallet['private']['keychains']: keychain_path = keychain['path'][1:] keychain = self.get_keychain(keychain['xpub']) if 'encryptedXprv' not in keychain: continue usableKeychain = True break if not usableKeychain: raise BitGoError("didn't found a spendable keychain") data = json.loads(keychain['encryptedXprv']) #add base64 paddings for k in ['iv', 'salt', 'ct']: data[k] = data[k] + "==" cipher = sjcl.SJCL() xprv = cipher.decrypt(data, passcode) unspents = self.get_unspents(wallet_id) unspents = filter(lambda u: u['confirmations'] > 0, unspents['unspents'][::-1]) total_value = 0 for d in unspents: path = keychain_path + d['chainPath'] chain_paths.append(path) p2sh.append(h2b(d["redeemScript"])) spendables.append(Spendable(d["value"], h2b(d["script"]), h2b_rev(d["tx_hash"]), d["tx_output_n"])) total_value += d['value'] if total_value > amount: break # make many outputs? if len(unspents) < 5 and (total_value > (amount + MINIMAL_SPLIT)) and fan_unspend > 0: fee = self.calculate_fee(len(spendables), fan_unspend) value = (total_value - amount - fee) / fan_unspend for i in range(fan_unspend): payables.append((change_address, value)) elif total_value > (amount + MINIMAL_FEE): # add a change address if fee is None: fee = self.calculate_fee(len(spendables), 2) value = total_value - amount - fee if value > 10000: #avoid dust payables.append((change_address, value)) p2sh_lookup = build_p2sh_lookup(p2sh) spendable_keys = [] priv_key = BIP32Node.from_hwif(xprv) spendable_keys = [priv_key.subkey_for_path(path) for path in chain_paths] hash160_lookup = build_hash160_lookup([key.secret_exponent() for key in spendable_keys]) tx = create_tx(spendables, payables) tx.sign(hash160_lookup=hash160_lookup, p2sh_lookup=p2sh_lookup) r = requests.post(self.url + '/tx/send', { 'tx': tx.as_hex(), 'message': message }, headers={ 'Authorization': 'Bearer %s' % self.access_token, }) return r.json()
import functools import struct from pycoin.intbytes import bytes_to_ints from pycoin.serialize import h2b from pycoin.serialize.bitcoin_streamer import parse_struct IP4_HEADER = h2b("00000000000000000000FFFF") def ip_bin_to_ip6_addr(ip_bin): return ":".join("%x" % v for v in struct.unpack(">HHHHHHHH", ip_bin)) def ip_bin_to_ip4_addr(ip_bin): return "%d.%d.%d.%d" % tuple(bytes_to_ints(ip_bin[-4:])) @functools.total_ordering class PeerAddress(object): def __init__(self, services, ip_bin, port): self.services = int(services) assert isinstance(ip_bin, bytes) if len(ip_bin) == 4: ip_bin = IP4_HEADER + ip_bin assert len(ip_bin) == 16 self.ip_bin = ip_bin self.port = port def __repr__(self):
def from_hex(hex_string): """Return the Tx for the given hex string.""" return from_bin(h2b(hex_string))
def from_seed_hex(cls, master_secret_hex, netcode='BTC'): return cls.from_seed(h2b(master_secret_hex), netcode)
def action(): try: action = request.form.get('action') if not action: return render_template("action.html") if action == 'createNewCFBitCoinTx': target_amount = int(request.form.get('target_amount')) pubkey_addr = request.form.get('pubkey_addr') end_time = int(time.time() + float(request.form.get('end_time')) * 3600 * 24) pre_out_ids_for_fee = request.form.get( 'pre_out_ids_for_fee').split(';') # pre_out_ids_for_fee = [pre_out_ids_for_fee[0], int(pre_out_ids_for_fee[1])] res = datass.createNewCFBitCoinTx(target_amount, pubkey_addr, end_time, pre_out_ids_for_fee) elif action == 'createNormalCFBitCoinTx': pre_out_ids = [ int(i) for i in request.form.get('pre_out_ids').split(';') ] pre_cf_hash = h2b(request.form.get('pre_cf_hash')) spendValue = int(request.form.get('spendValue')) otherPublicAddrToValueArray = [] addrs = request.form.getlist('otherPublicAddrToValueArray[]') coin_values = request.form.getlist('coin_value[]') for pubkey, coin in zip(addrs, coin_values): if '' == coin: continue otherPublicAddrToValueArray.append([pubkey, int(coin)]) refund_addr = request.form.get('refund_addr') res = datass.createNormalCFBitCoinTx(pre_out_ids, pre_cf_hash, spendValue, otherPublicAddrToValueArray, refund_addr) elif action == 'createNormalBitCoinTx': pre_out_ids = [ int(i) for i in request.form.get('pre_out_ids').split(';') ] publicAddrToValueArray = [] addrs = request.form.getlist('publicAddrToValueArray[]') coin_values = request.form.getlist('coin_value[]') for pubkey, coin in zip(addrs, coin_values): if coin != '': publicAddrToValueArray.append([pubkey, int(coin)]) res = datass.createNormalBitCoinTx(pre_out_ids, publicAddrToValueArray) elif action == 'createNewBitcoinTx': pubkey_addr = request.form.get('pubkey_addr') pubkey = request.form.get('publicAddrToValueArray') coin = request.form.get('newBotcoinValue') res = datass.createNewBitcoinTx([[pubkey, int(coin)]]) except Exception: res = None traceback.print_exc() if not res: alert = '''交易生成失败!请重新检查参数。''' else: alert = '''发送成功!交易Id为%s''' % res.hash().hex() return render_template("action.html", alert=alert)
# this file is deprecated and will soon be folded into all.py from collections import namedtuple from pycoin.serialize import h2b NetworkValues = namedtuple('NetworkValues', ('network_name', 'subnet_name', 'code', 'wif', 'address', 'pay_to_script', 'prv32', 'pub32')) NETWORKS = ( # LTC litecoin mainnet : Ltpv/Ltub NetworkValues("Litecoin", "mainnet", "LTC", b'\xb0', b'\x30', b'\5', h2b('019d9cfe'), h2b('019da462')), # LTC litecoin testnet : ttpv/ttub NetworkValues("Litecoin", "testnet", "XLT", b'\xef', b'\x6f', b'\xc4', h2b('0436ef7d'), h2b('0436f6e1')), # VIA viacoin mainnet : xprv/xpub NetworkValues("Viacoin", "mainnet", "VIA", b'\xc7', b'\x47', b'\x21', h2b('0488ADE4'), h2b('0488B21E')), # VIA viacoin testnet : tprv/tpub NetworkValues("Viacoin", "testnet", "TVI", b'\xff', b'\x7f', b'\xc4', h2b('04358394'), h2b('043587CF')), # FTC feathercoin mainnet : xprv/xpub NetworkValues( "Feathercoin", "mainnet", "FTC", b'\x8e', b'\x0e', b'\x60', h2b('0488ADE4'), h2b('0488B21E')), # FTC feathercoin testnet : tprv/tpub NetworkValues( "Feathercoin", "testnet", "FTX", b'\xC1', b'\x41', b'\xc4', h2b('04358394'), h2b('043587CF')), # DOGE Dogecoin mainnet : dogv/dogp
def parse_script_index_hex(input): index_s, opcodes = input.split("/", 1) index = int(index_s) return (index, h2b(opcodes))
def get_CF_project(project_id): allCFDict = TransactionCFDao.searchAllCFDict() cfs = allCFDict[h2b(project_id)] project = CFProject(cfs) project.get_details() return project
def tx_for_tx_hash(self, tx_hash): "Get a Tx by its hash." url = self.base_url("get_tx", b2h_rev(tx_hash)) r = json.loads(urlopen(url).read().decode("utf8")) tx = Tx.parse(io.BytesIO(h2b(r.get("data").get("tx_hex")))) return tx