Esempio n. 1
0
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
Esempio n. 3
0
    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)
Esempio n. 4
0
    def set_txn_side_effect_for_index(self, account_index, address_index,
                                      change):
        dummy_txn = Transaction(1, [], [], 0)
        metadata = dict(block_height=234790,
                        block_hash=Hash("000000000000000007d57f03ebe36dbe4f87ab2f340e93b45999ab249b6dc0df"),
                        confirmations=23890)

        k = 'change_addresses' if change else 'payout_addresses'
        addr_list = self._acct_keys[account_index][k]
        mtd = MockTxnDict(num_used=address_index + 1,
                          addr_range=range(address_index, address_index + 1),
                          addr_list=addr_list,
                          used_value=[dict(metadata=metadata,
                                           transaction=dummy_txn)],
                          unused_value=[])
        self.get_transactions.side_effect = [mtd]
Esempio n. 5
0
    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