def txn_from_json(txn_json): inputs = [] for i in txn_json['inputs']: if 'output_hash' in i: outpoint = Hash(i['output_hash']) script = Script(bytes.fromhex(i['script_signature_hex'])) # Do this to test script de/serialization script._disassemble() inp = TransactionInput(outpoint, i['output_index'], script, i['sequence']) else: # Coinbase txn, we pass in a block version of 1 since the # coinbase script from api.chain.com already has the # height in there. Don't want our stuff to repack it in. inp = CoinbaseInput(txn_json['block_height'], bytes.fromhex(i['coinbase']), i['sequence'], 1) inputs.append(inp) outputs = [] for o in txn_json['outputs']: scr = Script(bytes.fromhex(o['script_hex'])) scr._disassemble() out = TransactionOutput(o['value'], scr) outputs.append(out) txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs, txn_json['lock_time']) return txn
def test_op_checklocktimeverify(): prev_txn_hash = Hash( '6eae1e03964799c4e29039db459ea4fad4df57c2b06f730b60032a48fb075620') txn_input = TransactionInput(prev_txn_hash, 0, Script(""), 1) addr = "1HJiL6AYYmtkbJzC9bxAorznWijwNK5Z8E" out_script_pub_key = Script.build_p2pkh(utils.address_to_key_hash(addr)[1]) txn_output = TransactionOutput(9000, out_script_pub_key) # Create the txn txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, [txn_input], [txn_output], 367987) # This is one more (367988) so it should fail s = Script("0x749d05 OP_CHECKLOCKTIMEVERIFY") si = ScriptInterpreter(txn=txn, input_index=0, sub_script=out_script_pub_key) si.run_script(s) assert not si.valid # This is negative, so it should fail s = Script("0xfff74d05 OP_CHECKLOCKTIMEVERIFY") si = ScriptInterpreter(txn=txn, input_index=0, sub_script=out_script_pub_key) si.run_script(s) assert not si.valid # This is one less (367986) so it should pass s = Script("0x729d05 OP_CHECKLOCKTIMEVERIFY") si = ScriptInterpreter(txn=txn, input_index=0, sub_script=out_script_pub_key) si.run_script(s) assert not si.stop # Now reformulate the txn so that the input is finalized txn_input.sequence_num = 0xffffffff si.run_script(s) assert not si.valid # The last check is if there are mismatching notions of locktime txn_input.sequence_num = 1 txn.lock_time = 500000001 si = ScriptInterpreter(txn=txn, input_index=0, sub_script=out_script_pub_key) si.run_script(s) assert not si.valid
def set_txn_side_effect_for_hd_discovery(self): # For each used account, there are at least 2 calls required: # 1 for the first DISCOVERY_INCREMENT payout addresses and 1 # for the first DISCOVERY_INCREMENT change # addresses. Depending on the number of used addresses for the # account, this will change. effects = [] n = self._num_used_accounts if n == 0: n = 1 for acct_num in range(n): for change in [0, 1]: num_used = self._num_used_addresses[acct_num][change] r = math.ceil((num_used + HDAccount.GAP_LIMIT) / self.address_increment) k = 'change_addresses' if change else 'payout_addresses' addr_list = self._acct_keys[acct_num][k] if change: metadata = dict(block=234790 + r, block_hash=Hash("000000000000000007d57f03ebe36dbe4f87ab2f340e93b45999ab249b6dc0df"), confirmations=23890 - r) else: metadata = dict(block=None, block_hash=None, confirmations=0) if r == 0: r = 1 for i in range(r): start = i * self.address_increment end = (i + 1) * self.address_increment addr_range = range(start, end) out = TransactionOutput(value=100000, script=Script.build_p2pkh( address_to_key_hash( addr_list[i])[1])) dummy_txn = Transaction(1, [], [out], 0) m = MockTxnDict(num_used=num_used, addr_range=addr_range, addr_list=addr_list, used_value=[dict(metadata=metadata, transaction=dummy_txn)], unused_value=[]) effects.append(m) self.get_transactions.side_effect = effects return len(effects)
def txn_from_json(txn_json): """ Returns a new Transaction from a JSON-serialized transaction Args: txn_json: JSON with the following format: { "hash": "0bf0de38c26195919179f...", "block_hash": "000000000000000...", "block_height": 303404, "block_time": "2014-05-30T23:54:55Z", "chain_received_at": "2015-08-13T10:52:21.718Z", "confirmations": 69389, "lock_time": 0, "inputs": [ { "transaction_hash": "0bf0de38c2619...", "output_hash": "b84a66c46e24fe71f9...", "output_index": 0, "value": 300000, "addresses": [ "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr" ], "script_signature": "03046022100de7b67b9...", "script_signature_hex": "00493046022100de7b...", "sequence": 4294967295 } ], "outputs": [ { "transaction_hash": "0bf0de38c261959...", "output_index": 0, "value": 290000, "addresses": [ "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb" ], "script": "OP_DUP OP_HASH160 c629680b8d...", "script_hex": "76a914c629680b8d13...", "script_type": "pubkeyhash", "required_signatures": 1, "spent": false, "spending_transaction": null } ], "fees": 10000, "amount": 290000 }, Transaction.DEFAULT_TRANSACTION_VERSION Returns: two1.bitcoin.Transaction: a deserialized transaction derived from the provided json. """ inputs = [] outputs = [] addr_keys = set() for i in txn_json["inputs"]: if 'coinbase' in i: inputs.append( CoinbaseInput(height=txn_json["block_height"] or 0, raw_script=bytes.fromhex(i['coinbase']), sequence=i['sequence'], block_version=1)) else: # Script length etc. are not returned so we need to # prepend that. script, _ = Script.from_bytes( pack_var_str(bytes.fromhex(i["script_signature_hex"]))) inputs.append( TransactionInput(Hash(i["output_hash"]), i["output_index"], script, i["sequence"])) if "addresses" in i: addr_keys.add(i["addresses"][0]) for i in txn_json["outputs"]: script, _ = Script.from_bytes( pack_var_str(bytes.fromhex(i["script_hex"]))) outputs.append(TransactionOutput(i["value"], script)) if "addresses" in i: addr_keys.add(i["addresses"][0]) txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs, txn_json["lock_time"]) return txn, addr_keys
def txn_from_json(txn_json): """ Returns a new Transaction from a JSON-serialized transaction Args: txn_json: JSON with the following format: { "hash": "0bf0de38c26195919179f...", "block_hash": "000000000000000...", "block_height": 303404, "block_time": "2014-05-30T23:54:55Z", "chain_received_at": "2015-08-13T10:52:21.718Z", "confirmations": 69389, "lock_time": 0, "inputs": [ { "transaction_hash": "0bf0de38c2619...", "output_hash": "b84a66c46e24fe71f9...", "output_index": 0, "value": 300000, "addresses": [ "3L7dKYQGNoZub928CJ8NC2WfrM8U8GGBjr" ], "script_signature": "03046022100de7b67b9...", "script_signature_hex": "00493046022100de7b...", "sequence": 4294967295 } ], "outputs": [ { "transaction_hash": "0bf0de38c261959...", "output_index": 0, "value": 290000, "addresses": [ "1K4nPxBMy6sv7jssTvDLJWk1ADHBZEoUVb" ], "script": "OP_DUP OP_HASH160 c629680b8d...", "script_hex": "76a914c629680b8d13...", "script_type": "pubkeyhash", "required_signatures": 1, "spent": false, "spending_transaction": null } ], "fees": 10000, "amount": 290000 }, Transaction.DEFAULT_TRANSACTION_VERSION Returns: two1.bitcoin.Transaction: a deserialized transaction derived from the provided json. """ inputs = [] outputs = [] addr_keys = set() for i in sorted(txn_json["vin"], key=lambda i: i["n"]): if 'coinbase' in i: inputs.append( CoinbaseInput(height=0, raw_script=bytes.fromhex(i['coinbase']), sequence=i['sequence'], block_version=1)) else: script = Script.from_hex(i["scriptSig"]["hex"]) inputs.append( TransactionInput(Hash(i["txid"]), i["vout"], script, i["sequence"])) if "addr" in i: addr_keys.add(i["addr"]) for o in sorted(txn_json["vout"], key=lambda o: o["n"]): script = Script.from_hex(o["scriptPubKey"]["hex"]) value = int( decimal.Decimal(str(o["value"])) * decimal.Decimal('1e8')) outputs.append(TransactionOutput(value, script)) if "addresses" in o["scriptPubKey"]: for a in o["scriptPubKey"]["addresses"]: addr_keys.add(a) txn = Transaction(Transaction.DEFAULT_TRANSACTION_VERSION, inputs, outputs, txn_json["locktime"]) assert txn.hash == Hash(txn_json['txid']) return txn, addr_keys