コード例 #1
0
 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
コード例 #2
0
ファイル: segwit_test.py プロジェクト: alanxu89/pycoin
 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
コード例 #3
0
ファイル: BlockChain.py プロジェクト: alanxu89/pycoin
 def __repr__(self):
     local_block_chain = self._longest_local_block_chain()
     if local_block_chain:
         finish = b2h_rev(local_block_chain[0])
         start = b2h_rev(local_block_chain[-1])
         longest_chain = "longest chain %s to %s of size %d" % (start, finish, self.unlocked_length())
     else:
         longest_chain = "no unlocked elements"
     return "<BlockChain with %d locked elements and %s>" % (self.locked_length(), longest_chain)
コード例 #4
0
ファイル: BlockChain.py プロジェクト: mebagger/pycoin-1
 def __repr__(self):
     local_block_chain = self._longest_local_block_chain()
     if local_block_chain:
         finish = b2h_rev(local_block_chain[0])
         start = b2h_rev(local_block_chain[-1])
         longest_chain = "longest chain %s to %s of size %d" % (
             start, finish, self.unlocked_length())
     else:
         longest_chain = "no unlocked elements"
     return "<BlockChain with %d locked elements and %s>" % (
         self.locked_length(), longest_chain)
コード例 #5
0
    def validate_unspents(self, tx_db):
        """
        Spendable objects returned from blockchain.info or
        similar services contain coin_value information that must be trusted
        on faith. Mistaken coin_value data can result in coins being wasted
        to fees.

        This function solves this problem by iterating over the incoming
        transactions, fetching them from the tx_db in full, and verifying
        that the coin_values are as expected.

        Returns the fee for this transaction. If any of the spendables set by
        tx.set_unspents do not match the authenticated transactions, a
        ValidationFailureError is raised.
        """
        tx_hashes = set((tx_in.previous_hash for tx_in in self.txs_in))

        # build a local copy of the DB
        tx_lookup = {}
        for h in tx_hashes:
            if h == ZERO32:
                continue
            the_tx = tx_db.get(h)
            if the_tx is None:
                raise KeyError("hash id %s not in tx_db" % b2h_rev(h))
            if the_tx.hash() != h:
                raise KeyError(
                    "attempt to load Tx %s yielded a Tx with id %s" %
                    (h2b_rev(h), the_tx.id()))
            tx_lookup[h] = the_tx

        for idx, tx_in in enumerate(self.txs_in):
            if tx_in.previous_hash == ZERO32:
                continue
            txs_out = tx_lookup[tx_in.previous_hash].txs_out
            if tx_in.previous_index > len(txs_out):
                raise BadSpendableError(
                    "tx_out index %d is too big for Tx %s" %
                    (tx_in.previous_index, b2h_rev(tx_in.previous_hash)))
            tx_out1 = txs_out[tx_in.previous_index]
            tx_out2 = self.unspents[idx]
            if tx_out1.coin_value != tx_out2.coin_value:
                raise BadSpendableError(
                    "unspents[%d] coin value mismatch (%d vs %d)" %
                    (idx, tx_out1.coin_value, tx_out2.coin_value))
            if tx_out1.script != tx_out2.script:
                raise BadSpendableError("unspents[%d] script mismatch!" % idx)

        return self.fee()
コード例 #6
0
ファイル: hexbytes.py プロジェクト: mebagger/pycoin-1
 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")
コード例 #7
0
ファイル: btgexp.py プロジェクト: alanxu89/pycoin
 def tx_for_tx_hash(self, tx_hash):
     URL = "%s/getrawtransaction?txid=%s&decrypt=0" % (self.base_url, b2h_rev(tx_hash))
     r = urlopen(URL).read().decode("utf8")
     tx = Tx.from_hex(r)
     if tx.hash() == tx_hash:
         return tx
     return None
コード例 #8
0
ファイル: insight.py プロジェクト: alanxu89/pycoin
 def tx_for_tx_hash(self, tx_hash):
     URL = "%s/tx/%s" % (self.base_url, b2h_rev(tx_hash))
     r = json.loads(urlopen(URL).read().decode("utf8"))
     tx = tx_from_json_dict(r)
     if tx.hash() == tx_hash:
         return tx
     return None
コード例 #9
0
ファイル: Tx.py プロジェクト: richardkiss/pycoin
    def w_id(self):
        """Return the segwit-specific binary hash for this :class:`Tx` object as a hex string.
        Note that this is a ``reversed`` version of :func:`Tx.w_hash <w_hash>`.

        :return: 64 character long hex string corresponding to the hash
        """
        return b2h_rev(self.w_hash())
コード例 #10
0
    def test_block(self):
        expected_checksum = '0000000000089F7910F6755C10EA2795EC368A29B435D80770AD78493A6FECF1'.lower()

        block_data = h2b(
            "010000007480150B299A16BBCE5CCDB1D1BBC65CFC5893B01E6619107C552000000000"
            "007900A2B203D24C69710AB6A94BEB937E1B1ADD64C2327E268D8C3E5F8B41DBED8796"
            "974CED66471B204C324703010000000100000000000000000000000000000000000000"
            "00000000000000000000000000FFFFFFFF0804ED66471B024001FFFFFFFF0100F2052A"
            "010000004341045FEE68BAB9915C4EDCA4C680420ED28BBC369ED84D48AC178E1F5F7E"
            "EAC455BBE270DABA06802145854B5E29F0A7F816E2DF906E0FE4F6D5B4C9B92940E4F0"
            "EDAC000000000100000001F7B30415D1A7BF6DB91CB2A272767C6799D721A4178AA328"
            "E0D77C199CB3B57F010000008A4730440220556F61B84F16E637836D2E74B8CB784DE4"
            "0C28FE3EF93CCB7406504EE9C7CAA5022043BD4749D4F3F7F831AC696748AD8D8E79AE"
            "B4A1C539E742AA3256910FC88E170141049A414D94345712893A828DE57B4C2054E2F5"
            "96CDCA9D0B4451BA1CA5F8847830B9BE6E196450E6ABB21C540EA31BE310271AA00A49"
            "ED0BA930743D1ED465BAD0FFFFFFFF0200E1F505000000001976A914529A63393D63E9"
            "80ACE6FA885C5A89E4F27AA08988ACC0ADA41A000000001976A9145D17976537F30886"
            "5ED533CCCFDD76558CA3C8F088AC00000000010000000165148D894D3922EF5FFDA962"
            "BE26016635C933D470C8B0AB7618E869E3F70E3C000000008B48304502207F5779EBF4"
            "834FEAEFF4D250898324EB5C0833B16D7AF4C1CB0F66F50FCF6E85022100B78A65377F"
            "D018281E77285EFC31E5B9BA7CB7E20E015CF6B7FA3E4A466DD195014104072AD79E0A"
            "A38C05FA33DD185F84C17F611E58A8658CE996D8B04395B99C7BE36529CAB7606900A0"
            "CD5A7AEBC6B233EA8E0FE60943054C63620E05E5B85F0426FFFFFFFF02404B4C000000"
            "00001976A914D4CAA8447532CA8EE4C80A1AE1D230A01E22BFDB88AC8013A0DE010000"
            "001976A9149661A79AE1F6D487AF3420C13E649D6DF3747FC288AC00000000")

        # try to parse a block

        block = Block.parse(io.BytesIO(block_data))
        assert b2h_rev(block.hash()) == expected_checksum
        block.check_merkle_hash()

        # parse already validated block
        block = Block.parse(io.BytesIO(block_data), check_merkle_hash=False)
        assert block.as_bin() == block_data
コード例 #11
0
    def w_id(self):
        """Return the segwit-specific binary hash for this :class:`Tx` object as a hex string.
        Note that this is a ``reversed`` version of :func:`Tx.w_hash <w_hash>`.

        :return: 64 character long hex string corresponding to the hash
        """
        return b2h_rev(self.w_hash())
コード例 #12
0
ファイル: insight.py プロジェクト: mebagger/pycoin-1
 def tx_for_tx_hash(self, tx_hash):
     URL = "%s/tx/%s" % (self.base_url, b2h_rev(tx_hash))
     r = json.loads(urlopen(URL).read().decode("utf8"))
     tx = tx_from_json_dict(r)
     if tx.hash() == tx_hash:
         return tx
     return None
コード例 #13
0
ファイル: serialize_test.py プロジェクト: alanxu89/pycoin
 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")
コード例 #14
0
 def save_spendable(self, spendable):
     tx_hash = b2h_rev(spendable.tx_hash)
     script = b2h(spendable.script)
     self._exec_sql(
         "insert or replace into Spendable values (?, ?, ?, ?, ?, ?, ?)",
         tx_hash, spendable.tx_out_index, spendable.coin_value, script,
         spendable.block_index_available, spendable.does_seem_spent,
         spendable.block_index_spent)
コード例 #15
0
ファイル: Tx.py プロジェクト: richardkiss/pycoin
    def validate_unspents(self, tx_db):
        """
        Spendable objects returned from blockchain.info or
        similar services contain coin_value information that must be trusted
        on faith. Mistaken coin_value data can result in coins being wasted
        to fees.

        This function solves this problem by iterating over the incoming
        transactions, fetching them from the tx_db in full, and verifying
        that the coin_values are as expected.

        Returns the fee for this transaction. If any of the spendables set by
        tx.set_unspents do not match the authenticated transactions, a
        ValidationFailureError is raised.
        """
        tx_hashes = set((tx_in.previous_hash for tx_in in self.txs_in))

        # build a local copy of the DB
        tx_lookup = {}
        for h in tx_hashes:
            if h == ZERO32:
                continue
            the_tx = tx_db.get(h)
            if the_tx is None:
                raise KeyError("hash id %s not in tx_db" % b2h_rev(h))
            if the_tx.hash() != h:
                raise KeyError("attempt to load Tx %s yielded a Tx with id %s" % (h2b_rev(h), the_tx.id()))
            tx_lookup[h] = the_tx

        for idx, tx_in in enumerate(self.txs_in):
            if tx_in.previous_hash == ZERO32:
                continue
            txs_out = tx_lookup[tx_in.previous_hash].txs_out
            if tx_in.previous_index > len(txs_out):
                raise BadSpendableError("tx_out index %d is too big for Tx %s" %
                                        (tx_in.previous_index, b2h_rev(tx_in.previous_hash)))
            tx_out1 = txs_out[tx_in.previous_index]
            tx_out2 = self.unspents[idx]
            if tx_out1.coin_value != tx_out2.coin_value:
                raise BadSpendableError(
                    "unspents[%d] coin value mismatch (%d vs %d)" % (
                        idx, tx_out1.coin_value, tx_out2.coin_value))
            if tx_out1.script != tx_out2.script:
                raise BadSpendableError("unspents[%d] script mismatch!" % idx)

        return self.fee()
コード例 #16
0
 def as_dict(self):
     # for use with JSON
     return dict(coin_value=self.coin_value,
                 script_hex=b2h(self.script),
                 tx_hash_hex=b2h_rev(self.tx_hash),
                 tx_out_index=self.tx_out_index,
                 block_index_available=self.block_index_available,
                 does_seem_spent=int(self.does_seem_spent),
                 block_index_spent=self.block_index_spent)
コード例 #17
0
ファイル: tx_db.py プロジェクト: alanxu89/pycoin
 def put(self, tx):
     name = b2h_rev(tx.hash())
     if self.writable_cache_path:
         try:
             path = os.path.join(self.writable_cache_path, "%s_tx.bin" % name)
             with open(path, "wb") as f:
                 tx.stream(f)
         except IOError:
             pass
コード例 #18
0
ファイル: blockexplorer.py プロジェクト: alanxu89/pycoin
 def tx_for_tx_hash(self, tx_hash):
     """
     Get a Tx by its hash.
     """
     url = "%s/rawtx/%s" % (self.url, b2h_rev(tx_hash))
     d = urlopen(url).read()
     j = json.loads(d.decode("utf8"))
     tx = Tx.from_hex(j.get("rawtx", ""))
     if tx.hash() == tx_hash:
         return tx
コード例 #19
0
 def as_text(self):
     return "/".join([
         b2h_rev(self.tx_hash),
         str(self.tx_out_index),
         b2h(self.script),
         str(self.coin_value),
         str(self.block_index_available),
         "%d" % self.does_seem_spent,
         str(self.block_index_spent)
     ])
コード例 #20
0
 def tx_for_tx_hash(self, tx_hash):
     """
     Get a Tx by its hash.
     """
     url = "%s/rawtx/%s" % (self.url, b2h_rev(tx_hash))
     d = urlopen(url).read()
     j = json.loads(d.decode("utf8"))
     tx = Tx.from_hex(j.get("rawtx", ""))
     if tx.hash() == tx_hash:
         return tx
コード例 #21
0
ファイル: tx_db.py プロジェクト: mebagger/pycoin-1
 def put(self, tx):
     name = b2h_rev(tx.hash())
     if self.writable_cache_path:
         try:
             path = os.path.join(self.writable_cache_path,
                                 "%s_tx.bin" % name)
             with open(path, "wb") as f:
                 tx.stream(f)
         except IOError:
             pass
コード例 #22
0
ファイル: Spendable.py プロジェクト: alanxu89/pycoin
 def as_dict(self):
     # for use with JSON
     return dict(
         coin_value=self.coin_value,
         script_hex=b2h(self.script),
         tx_hash_hex=b2h_rev(self.tx_hash),
         tx_out_index=self.tx_out_index,
         block_index_available=self.block_index_available,
         does_seem_spent=int(self.does_seem_spent),
         block_index_spent=self.block_index_spent
     )
コード例 #23
0
def post_unpack_merkleblock(d, f):
    """
    A post-processing "post_unpack" to merkleblock messages.

    It validates the merkle proofs (throwing an exception if there's
    an error), and returns the list of transaction hashes in "tx_hashes".

    The transactions are supposed to be sent immediately after the merkleblock message.
    """
    level_widths = []
    count = d["total_transactions"]
    while count > 1:
        level_widths.append(count)
        count += 1
        count //= 2
    level_widths.append(1)
    level_widths.reverse()

    tx_acc = []
    flags = d["flags"]
    hashes = list(reversed(d["hashes"]))
    left_hash, flag_index = _recurse(level_widths, 0, 0, hashes, flags, 0,
                                     tx_acc)

    if len(hashes) > 0:
        raise ValueError("extra hashes: %s" % hashes)

    idx, r = divmod(flag_index - 1, 8)
    if idx != len(flags) - 1:
        raise ValueError("not enough flags consumed")

    if flags[idx] > (1 << (r + 1)) - 1:
        raise ValueError("unconsumed 1 flag bits set")

    if left_hash != d["header"].merkle_root:
        raise ValueError(
            "merkle root %s does not match calculated hash %s" %
            (b2h_rev(d["header"].merkle_root), b2h_rev(left_hash)))

    d["tx_hashes"] = tx_acc
    return d
コード例 #24
0
ファイル: blockcypher.py プロジェクト: zhp562176325/pycoin
 def tx_for_tx_hash(self, tx_hash):
     """
     returns the pycoin.tx object for tx_hash
     """
     try:
         url_append = "?token=%s&includeHex=true" % self.api_key
         url = self.base_url("txs/%s%s" % (b2h_rev(tx_hash), url_append))
         result = json.loads(urlopen(url).read().decode("utf8"))
         tx = Tx.parse(io.BytesIO(h2b(result.get("hex"))))
         return tx
     except Exception:
         raise Exception
コード例 #25
0
ファイル: blockcypher.py プロジェクト: alanxu89/pycoin
 def tx_for_tx_hash(self, tx_hash):
     """
     returns the pycoin.tx object for tx_hash
     """
     try:
         url_append = "?token=%s&includeHex=true" % self.api_key
         url = self.base_url("txs/%s%s" % (b2h_rev(tx_hash), url_append))
         result = json.loads(urlopen(url).read().decode("utf8"))
         tx = Tx.parse(io.BytesIO(h2b(result.get("hex"))))
         return tx
     except Exception:
         raise Exception
コード例 #26
0
def post_unpack_merkleblock(d, f):
    """
    A post-processing "post_unpack" to merkleblock messages.

    It validates the merkle proofs (throwing an exception if there's
    an error), and returns the list of transaction hashes in "tx_hashes".

    The transactions are supposed to be sent immediately after the merkleblock message.
    """
    level_widths = []
    count = d["total_transactions"]
    while count > 1:
        level_widths.append(count)
        count += 1
        count //= 2
    level_widths.append(1)
    level_widths.reverse()

    tx_acc = []
    flags = d["flags"]
    hashes = list(reversed(d["hashes"]))
    left_hash, flag_index = _recurse(level_widths, 0, 0, hashes, flags, 0, tx_acc)

    if len(hashes) > 0:
        raise ValueError("extra hashes: %s" % hashes)

    idx, r = divmod(flag_index-1, 8)
    if idx != len(flags) - 1:
        raise ValueError("not enough flags consumed")

    if flags[idx] > (1 << (r+1))-1:
        raise ValueError("unconsumed 1 flag bits set")

    if left_hash != d["header"].merkle_root:
        raise ValueError(
            "merkle root %s does not match calculated hash %s" % (
                b2h_rev(d["header"].merkle_root), b2h_rev(left_hash)))

    d["tx_hashes"] = tx_acc
    return d
コード例 #27
0
ファイル: block.py プロジェクト: mebagger/pycoin-1
def dump_block(output, block, network):
    blob = stream_to_bytes(block.stream)
    output.append("%d bytes   block hash %s" % (len(blob), block.id()))
    output.append("version %d" % block.version)
    output.append("prior block hash %s" % b2h_rev(block.previous_block_hash))
    output.append("merkle root %s" % b2h(block.merkle_root))
    output.append("timestamp %s" % datetime.datetime.utcfromtimestamp(block.timestamp).isoformat())
    output.append("difficulty %d" % block.difficulty)
    output.append("nonce %s" % block.nonce)
    output.append("%d transaction%s" % (len(block.txs), "s" if len(block.txs) != 1 else ""))
    for idx, tx in enumerate(block.txs):
        output.append("Tx #%d:" % idx)
        dump_tx(
            output, tx, network=network, verbose_signature=False, disassembly_level=0, do_trace=False, use_pdb=False)
    output.append("")
コード例 #28
0
ファイル: Tx.py プロジェクト: richardkiss/pycoin
 def unspents_from_db(self, tx_db, ignore_missing=False):
     unspents = []
     for tx_in in self.txs_in:
         if tx_in.is_coinbase():
             unspents.append(None)
             continue
         tx = tx_db.get(tx_in.previous_hash)
         if tx and tx.hash() == tx_in.previous_hash:
             unspents.append(tx.txs_out[tx_in.previous_index])
         elif ignore_missing:
             unspents.append(None)
         else:
             raise KeyError(
                 "can't find tx_out for %s:%d" % (b2h_rev(tx_in.previous_hash), tx_in.previous_index))
     self.unspents = unspents
コード例 #29
0
 def spendable_for_hash_index(self, tx_hash, tx_out_index, spendable_class):
     tx_hash_hex = b2h_rev(tx_hash)
     SQL = ("select coin_value, script, block_index_available, "
            "does_seem_spent, block_index_spent from Spendable where "
            "tx_hash = ? and tx_out_index = ?")
     c = self._exec_sql(SQL, tx_hash_hex, tx_out_index)
     r = c.fetchone()
     if r is None:
         return r
     return spendable_class(coin_value=r[0],
                            script=h2b(r[1]),
                            tx_hash=tx_hash,
                            tx_out_index=tx_out_index,
                            block_index_available=r[2],
                            does_seem_spent=r[3],
                            block_index_spent=r[4])
コード例 #30
0
 def unspents_from_db(self, tx_db, ignore_missing=False):
     unspents = []
     for tx_in in self.txs_in:
         if tx_in.is_coinbase():
             unspents.append(None)
             continue
         tx = tx_db.get(tx_in.previous_hash)
         if tx and tx.hash() == tx_in.previous_hash:
             unspents.append(tx.txs_out[tx_in.previous_index])
         elif ignore_missing:
             unspents.append(None)
         else:
             raise KeyError(
                 "can't find tx_out for %s:%d" %
                 (b2h_rev(tx_in.previous_hash), tx_in.previous_index))
     self.unspents = unspents
コード例 #31
0
ファイル: insight.py プロジェクト: alanxu89/pycoin
 def get_blockheader_with_transaction_hashes(self, block_hash):
     URL = "%s/block/%s" % (self.base_url, b2h_rev(block_hash))
     r = json.loads(urlopen(URL).read().decode("utf8"))
     version = r.get("version")
     previous_block_hash = h2b_rev(r.get("previousblockhash"))
     merkle_root = h2b_rev(r.get("merkleroot"))
     timestamp = r.get("time")
     difficulty = int(r.get("bits"), 16)
     nonce = int(r.get("nonce"))
     tx_hashes = [h2b_rev(tx_hash) for tx_hash in r.get("tx")]
     blockheader = Block(version, previous_block_hash, merkle_root, timestamp, difficulty, nonce)
     if blockheader.hash() != block_hash:
         return None, None
     calculated_hash = merkle(tx_hashes, double_sha256)
     if calculated_hash != merkle_root:
         return None, None
     blockheader.height = r.get("height")
     return blockheader, tx_hashes
コード例 #32
0
ファイル: insight.py プロジェクト: mebagger/pycoin-1
 def get_blockheader_with_transaction_hashes(self, block_hash):
     URL = "%s/block/%s" % (self.base_url, b2h_rev(block_hash))
     r = json.loads(urlopen(URL).read().decode("utf8"))
     version = r.get("version")
     previous_block_hash = h2b_rev(r.get("previousblockhash"))
     merkle_root = h2b_rev(r.get("merkleroot"))
     timestamp = r.get("time")
     difficulty = int(r.get("bits"), 16)
     nonce = int(r.get("nonce"))
     tx_hashes = [h2b_rev(tx_hash) for tx_hash in r.get("tx")]
     blockheader = Block(version, previous_block_hash, merkle_root,
                         timestamp, difficulty, nonce)
     if blockheader.hash() != block_hash:
         return None, None
     calculated_hash = merkle(tx_hashes, double_sha256)
     if calculated_hash != merkle_root:
         return None, None
     blockheader.height = r.get("height")
     return blockheader, tx_hashes
コード例 #33
0
def dump_inputs(output, tx, network, verbose_signature, traceback_f, disassembly_level):
    for idx, tx_in in enumerate(tx.txs_in):
        if tx.is_coinbase():
            output.append("%4d: COINBASE  %12.5f m%s" % (idx, satoshi_to_mbtc(tx.total_in()), network.symbol))
            continue
        suffix = ""
        if tx.missing_unspent(idx):
            tx_out = None
            address = tx_in.address(address_api=network.address)
        else:
            tx_out = tx.unspents[idx]
            sig_result = " sig ok" if tx.is_solution_ok(idx, traceback_f=traceback_f) else " BAD SIG"
            suffix = " %12.5f m%s %s" % (satoshi_to_mbtc(tx_out.coin_value), network.symbol, sig_result)
            address = network.address.for_script(tx_out.puzzle_script())
        t = "%4d: %34s from %s:%-4d%s" % (idx, address, b2h_rev(tx_in.previous_hash),
                                          tx_in.previous_index, suffix)
        output.append(t.rstrip())
        if disassembly_level > 0:
            dump_disassembly(output, tx, idx, network.annotate)

        if verbose_signature:
            dump_signatures(output, tx, tx_in, tx_out, idx, network, traceback_f)
コード例 #34
0
    def test_block(self):
        expected_checksum = '0000000000089F7910F6755C10EA2795EC368A29B435D80770AD78493A6FECF1'.lower(
        )

        block_data = h2b(
            "010000007480150B299A16BBCE5CCDB1D1BBC65CFC5893B01E6619107C552000000000"
            "007900A2B203D24C69710AB6A94BEB937E1B1ADD64C2327E268D8C3E5F8B41DBED8796"
            "974CED66471B204C324703010000000100000000000000000000000000000000000000"
            "00000000000000000000000000FFFFFFFF0804ED66471B024001FFFFFFFF0100F2052A"
            "010000004341045FEE68BAB9915C4EDCA4C680420ED28BBC369ED84D48AC178E1F5F7E"
            "EAC455BBE270DABA06802145854B5E29F0A7F816E2DF906E0FE4F6D5B4C9B92940E4F0"
            "EDAC000000000100000001F7B30415D1A7BF6DB91CB2A272767C6799D721A4178AA328"
            "E0D77C199CB3B57F010000008A4730440220556F61B84F16E637836D2E74B8CB784DE4"
            "0C28FE3EF93CCB7406504EE9C7CAA5022043BD4749D4F3F7F831AC696748AD8D8E79AE"
            "B4A1C539E742AA3256910FC88E170141049A414D94345712893A828DE57B4C2054E2F5"
            "96CDCA9D0B4451BA1CA5F8847830B9BE6E196450E6ABB21C540EA31BE310271AA00A49"
            "ED0BA930743D1ED465BAD0FFFFFFFF0200E1F505000000001976A914529A63393D63E9"
            "80ACE6FA885C5A89E4F27AA08988ACC0ADA41A000000001976A9145D17976537F30886"
            "5ED533CCCFDD76558CA3C8F088AC00000000010000000165148D894D3922EF5FFDA962"
            "BE26016635C933D470C8B0AB7618E869E3F70E3C000000008B48304502207F5779EBF4"
            "834FEAEFF4D250898324EB5C0833B16D7AF4C1CB0F66F50FCF6E85022100B78A65377F"
            "D018281E77285EFC31E5B9BA7CB7E20E015CF6B7FA3E4A466DD195014104072AD79E0A"
            "A38C05FA33DD185F84C17F611E58A8658CE996D8B04395B99C7BE36529CAB7606900A0"
            "CD5A7AEBC6B233EA8E0FE60943054C63620E05E5B85F0426FFFFFFFF02404B4C000000"
            "00001976A914D4CAA8447532CA8EE4C80A1AE1D230A01E22BFDB88AC8013A0DE010000"
            "001976A9149661A79AE1F6D487AF3420C13E649D6DF3747FC288AC00000000")

        # try to parse a block

        block = Block.parse(io.BytesIO(block_data))
        assert b2h_rev(block.hash()) == expected_checksum
        block.check_merkle_hash()

        # parse already validated block
        block = Block.parse(io.BytesIO(block_data), check_merkle_hash=False)
        assert block.as_bin() == block_data
コード例 #35
0
ファイル: Tx.py プロジェクト: richardkiss/pycoin
 def id(self):
     """Return the human-readable hash for this Tx object."""
     return b2h_rev(self.hash())
コード例 #36
0
ファイル: bitcoind.py プロジェクト: alanxu89/pycoin
 def tx_for_tx_hash(self, tx_hash):
     raw_tx = self.connection.getrawtransaction(b2h_rev(tx_hash))
     tx = Tx.from_hex(raw_tx)
     return tx
コード例 #37
0
ファイル: bitcoind.py プロジェクト: alanxu89/pycoin
def unspent_to_bitcoind_dict(tx_in, tx_out):
    return dict(
        txid=b2h_rev(tx_in.previous_hash),
        vout=tx_in.previous_index,
        scriptPubKey=b2h(tx_out.script)
    )
コード例 #38
0
 def tx_for_tx_hash(self, tx_hash):
     "Get a Tx by its hash."
     URL = "https://blockchain.info/rawtx/%s?format=hex" % b2h_rev(tx_hash)
     tx = Tx.from_hex(urlopen(URL).read().decode("utf8"))
     return tx
コード例 #39
0
ファイル: chain_so.py プロジェクト: alanxu89/pycoin
 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
コード例 #40
0
ファイル: bitcoind.py プロジェクト: mebagger/pycoin-1
 def tx_for_tx_hash(self, tx_hash):
     raw_tx = self.connection.getrawtransaction(b2h_rev(tx_hash))
     tx = Tx.from_hex(raw_tx)
     return tx
コード例 #41
0
ファイル: tx_db.py プロジェクト: mebagger/pycoin-1
 def __setitem__(self, key, val):
     if val.hash() != key:
         raise ValueError("bad key %s for %s" % (b2h_rev(key), val))
     self.put(val)
コード例 #42
0
    def _test_sighash_single(self, network):
        Key = network.ui._key_class
        k0 = Key(secret_exponent=PRIV_KEYS[0],
                 generator=secp256k1_generator,
                 is_compressed=True)
        k1 = Key(secret_exponent=PRIV_KEYS[1],
                 generator=secp256k1_generator,
                 is_compressed=True)
        k2 = Key(secret_exponent=PRIV_KEYS[2],
                 generator=secp256k1_generator,
                 is_compressed=True)
        k3 = Key(secret_exponent=PRIV_KEYS[3],
                 generator=secp256k1_generator,
                 is_compressed=True)
        k4 = Key(secret_exponent=PRIV_KEYS[4],
                 generator=secp256k1_generator,
                 is_compressed=True)
        k5 = Key(secret_exponent=PRIV_KEYS[5],
                 generator=secp256k1_generator,
                 is_compressed=True)

        # Fake a coinbase transaction
        coinbase_tx = Tx.coinbase_tx(k0.sec(), 500000000)
        coinbase_tx.txs_out.append(
            TxOut(1000000000,
                  BitcoinScriptTools.compile('%s OP_CHECKSIG' %
                                             b2h(k1.sec()))))
        coinbase_tx.txs_out.append(
            TxOut(1000000000,
                  BitcoinScriptTools.compile('%s OP_CHECKSIG' %
                                             b2h(k2.sec()))))

        self.assertEqual(
            '2acbe1006f7168bad538b477f7844e53de3a31ffddfcfc4c6625276dd714155a',
            b2h_rev(coinbase_tx.hash()))

        script_for_address = network.ui.script_for_address

        # 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, script_for_address(k3.address())),
            TxOut(800000000, script_for_address(k4.address())),
            TxOut(800000000, script_for_address(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

        solution_checker = BitcoinSolutionChecker(tx)
        sig_hash = solution_checker._signature_hash(
            coinbase_tx.txs_out[0].script, 0, sig_type)
        self.assertEqual(
            0xcc52d785a3b4133504d1af9e60cd71ca422609cb41df3a08bbb466b2a98a885e,
            sig_hash)

        sig = sigmake(k0, sig_hash, sig_type)
        self.assertTrue(sigcheck(k0, sig_hash, sig[:-1]))

        tx.txs_in[0].script = BitcoinScriptTools.compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(0))

        sig_hash = solution_checker._signature_hash(
            coinbase_tx.txs_out[1].script, 1, sig_type)
        self.assertEqual(
            0x93bb883d70fccfba9b8aa2028567aca8357937c65af7f6f5ccc6993fd7735fb7,
            sig_hash)

        sig = sigmake(k1, sig_hash, sig_type)
        self.assertTrue(sigcheck(k1, sig_hash, sig[:-1]))

        tx.txs_in[1].script = BitcoinScriptTools.compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(1))

        sig_hash = solution_checker._signature_hash(
            coinbase_tx.txs_out[2].script, 2, sig_type)
        self.assertEqual(
            0x53ef7f67c3541bffcf4e0d06c003c6014e2aa1fb38ff33240b3e1c1f3f8e2a35,
            sig_hash)

        sig = sigmake(k2, sig_hash, sig_type)
        self.assertTrue(sigcheck(k2, sig_hash, sig[:-1]))

        tx.txs_in[2].script = BitcoinScriptTools.compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(2))

        sig_type = SIGHASH_SINGLE | SIGHASH_ANYONECANPAY

        sig_hash = solution_checker._signature_hash(
            coinbase_tx.txs_out[0].script, 0, sig_type)
        self.assertEqual(
            0x2003393d246a7f136692ce7ab819c6eadc54ffea38eb4377ac75d7d461144e75,
            sig_hash)

        sig = sigmake(k0, sig_hash, sig_type)
        self.assertTrue(sigcheck(k0, sig_hash, sig[:-1]))

        tx.txs_in[0].script = BitcoinScriptTools.compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(0))

        sig_hash = solution_checker._signature_hash(
            coinbase_tx.txs_out[1].script, 1, sig_type)
        self.assertEqual(
            0xe3f469ac88e9f35e8eff0bd8ad4ad3bf899c80eb7645947d60860de4a08a35df,
            sig_hash)

        sig = sigmake(k1, sig_hash, sig_type)
        self.assertTrue(sigcheck(k1, sig_hash, sig[:-1]))

        tx.txs_in[1].script = BitcoinScriptTools.compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(1))

        sig_hash = solution_checker._signature_hash(
            coinbase_tx.txs_out[2].script, 2, sig_type)
        self.assertEqual(
            0xbacd7c3ab79cad71807312677c1788ad9565bf3c00ab9a153d206494fb8b7e6a,
            sig_hash)

        sig = sigmake(k2, sig_hash, sig_type)
        self.assertTrue(sigcheck(k2, sig_hash, sig[:-1]))

        tx.txs_in[2].script = BitcoinScriptTools.compile(b2h(sig))
        self.assertTrue(tx.is_signature_ok(2))
コード例 #43
0
ファイル: Spendable.py プロジェクト: alanxu89/pycoin
 def __str__(self):
     return 'Spendable<%s mbtc "%s:%d" %s/%s/%s>' % (
         satoshi_to_mbtc(self.coin_value), b2h_rev(self.tx_hash), self.tx_out_index,
         self.block_index_available, self.does_seem_spent, self.block_index_spent)
コード例 #44
0
    def _test_sighash_single(self, network):
        flags = network.validator.flags

        k0, k1, k2, k3, k4, k5 = [
            network.keys.private(secret_exponent=se, is_compressed=True) for se in PRIV_KEYS]

        # Fake a coinbase transaction
        coinbase_tx = network.tx.coinbase_tx(k0.sec(), 500000000)
        for k in [k1, k2]:
            coinbase_tx.txs_out.append(network.tx.TxOut(
                1000000000, network.script.compile('%s OP_CHECKSIG' % b2h(k.sec()))))

        self.assertEqual('2acbe1006f7168bad538b477f7844e53de3a31ffddfcfc4c6625276dd714155a',
                         b2h_rev(coinbase_tx.hash()))

        # Make the test transaction
        txs_in = [
            network.tx.TxIn(coinbase_tx.hash(), 0),
            network.tx.TxIn(coinbase_tx.hash(), 1),
            network.tx.TxIn(coinbase_tx.hash(), 2),
        ]
        txs_out = [
            network.tx.TxOut(900000000, network.contract.for_address(k3.address())),
            network.tx.TxOut(800000000, network.contract.for_address(k4.address())),
            network.tx.TxOut(800000000, network.contract.for_address(k5.address())),
        ]
        tx = network.tx(1, txs_in, txs_out)
        tx.set_unspents(coinbase_tx.txs_out)

        self.assertEqual('791b98ef0a3ac87584fe273bc65abd89821569fd7c83538ac0625a8ca85ba587', b2h_rev(tx.hash()))

        sig_type = flags.SIGHASH_SINGLE

        solution_checker = network.tx.SolutionChecker(tx)
        sig_hash = solution_checker._signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type)
        self.assertEqual(0xcc52d785a3b4133504d1af9e60cd71ca422609cb41df3a08bbb466b2a98a885e, sig_hash)

        sig = sigmake(k0, sig_hash, sig_type)
        self.assertTrue(sigcheck(k0, sig_hash, sig[:-1]))

        tx.txs_in[0].script = network.script.compile(b2h(sig))
        self.assertTrue(tx.is_solution_ok(0))

        sig_hash = solution_checker._signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type)
        self.assertEqual(0x93bb883d70fccfba9b8aa2028567aca8357937c65af7f6f5ccc6993fd7735fb7, sig_hash)

        sig = sigmake(k1, sig_hash, sig_type)
        self.assertTrue(sigcheck(k1, sig_hash, sig[:-1]))

        tx.txs_in[1].script = network.script.compile(b2h(sig))
        self.assertTrue(tx.is_solution_ok(1))

        sig_hash = solution_checker._signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type)
        self.assertEqual(0x53ef7f67c3541bffcf4e0d06c003c6014e2aa1fb38ff33240b3e1c1f3f8e2a35, sig_hash)

        sig = sigmake(k2, sig_hash, sig_type)
        self.assertTrue(sigcheck(k2, sig_hash, sig[:-1]))

        tx.txs_in[2].script = network.script.compile(b2h(sig))
        self.assertTrue(tx.is_solution_ok(2))

        sig_type = flags.SIGHASH_SINGLE | flags.SIGHASH_ANYONECANPAY

        sig_hash = solution_checker._signature_hash(coinbase_tx.txs_out[0].script, 0, sig_type)
        self.assertEqual(0x2003393d246a7f136692ce7ab819c6eadc54ffea38eb4377ac75d7d461144e75, sig_hash)

        sig = sigmake(k0, sig_hash, sig_type)
        self.assertTrue(sigcheck(k0, sig_hash, sig[:-1]))

        tx.txs_in[0].script = network.script.compile(b2h(sig))
        self.assertTrue(tx.is_solution_ok(0))

        sig_hash = solution_checker._signature_hash(coinbase_tx.txs_out[1].script, 1, sig_type)
        self.assertEqual(0xe3f469ac88e9f35e8eff0bd8ad4ad3bf899c80eb7645947d60860de4a08a35df, sig_hash)

        sig = sigmake(k1, sig_hash, sig_type)
        self.assertTrue(sigcheck(k1, sig_hash, sig[:-1]))

        tx.txs_in[1].script = network.script.compile(b2h(sig))
        self.assertTrue(tx.is_solution_ok(1))

        sig_hash = solution_checker._signature_hash(coinbase_tx.txs_out[2].script, 2, sig_type)
        self.assertEqual(0xbacd7c3ab79cad71807312677c1788ad9565bf3c00ab9a153d206494fb8b7e6a, sig_hash)

        sig = sigmake(k2, sig_hash, sig_type)
        self.assertTrue(sigcheck(k2, sig_hash, sig[:-1]))

        tx.txs_in[2].script = network.script.compile(b2h(sig))
        self.assertTrue(tx.is_solution_ok(2))
コード例 #45
0
 def __str__(self):
     return 'Spendable<%s mbtc "%s:%d" %s/%s/%s>' % (
         satoshi_to_mbtc(self.coin_value), b2h_rev(
             self.tx_hash), self.tx_out_index, self.block_index_available,
         self.does_seem_spent, self.block_index_spent)
コード例 #46
0
 def tx_for_tx_hash(self, tx_hash):
     "Get a Tx by its hash."
     URL = self.api_domain + ("/rawtx/%s?format=hex" % b2h_rev(tx_hash))
     tx = Tx.from_hex(urlopen(URL).read().decode("utf8"))
     return tx
コード例 #47
0
ファイル: tx_db.py プロジェクト: mebagger/pycoin-1
 def paths_for_hash(self, hash):
     name = b2h_rev(hash)
     for base_dir in self.read_only_paths:
         p = os.path.join(base_dir, "%s_tx.bin" % name)
         if os.path.exists(p):
             yield p
コード例 #48
0
ファイル: chain_so.py プロジェクト: mebagger/pycoin-1
 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
コード例 #49
0
ファイル: bitcoind.py プロジェクト: mebagger/pycoin-1
def unspent_to_bitcoind_dict(tx_in, tx_out):
    return dict(txid=b2h_rev(tx_in.previous_hash),
                vout=tx_in.previous_index,
                scriptPubKey=b2h(tx_out.script))
コード例 #50
0
ファイル: blockchain_info.py プロジェクト: alanxu89/pycoin
 def tx_for_tx_hash(self, tx_hash):
     "Get a Tx by its hash."
     URL = self.api_domain + ("/rawtx/%s?format=hex" % b2h_rev(tx_hash))
     tx = Tx.from_hex(urlopen(URL).read().decode("utf8"))
     return tx
コード例 #51
0
 def delete_spendable(self, tx_hash, tx_out_index):
     self._exec_sql(
         "delete from Spendable where tx_hash = ? and tx_out_index = ?",
         b2h_rev(tx_hash), tx_out_index)
コード例 #52
0
ファイル: tx_db.py プロジェクト: alanxu89/pycoin
 def paths_for_hash(self, hash):
     name = b2h_rev(hash)
     for base_dir in self.read_only_paths:
         p = os.path.join(base_dir, "%s_tx.bin" % name)
         if os.path.exists(p):
             yield p
コード例 #53
0
ファイル: tx_db.py プロジェクト: alanxu89/pycoin
 def __setitem__(self, key, val):
     if val.hash() != key:
         raise ValueError("bad key %s for %s" % (b2h_rev(key), val))
     self.put(val)
コード例 #54
0
ファイル: TxIn.py プロジェクト: richardkiss/pycoin
 def __str__(self):
     if self.is_coinbase():
         return 'TxIn<COINBASE: %s>' % b2h(self.script)
     return 'TxIn<%s[%d] "%s">' % (
         b2h_rev(self.previous_hash), self.previous_index, ScriptTools.disassemble(self.script))
コード例 #55
0
 def __str__(self):
     INV_TYPES = ["?", "Tx", "Block", "Merkle"]
     idx = self.item_type
     if not 0 < idx < 4:
         idx = 0
     return "InvItem %s [%s]" % (INV_TYPES[idx], b2h_rev(self.data))
コード例 #56
0
ファイル: Spendable.py プロジェクト: alanxu89/pycoin
 def as_text(self):
     return "/".join([b2h_rev(self.tx_hash), str(self.tx_out_index), b2h(self.script),
                      str(self.coin_value), str(self.block_index_available),
                      "%d" % self.does_seem_spent, str(self.block_index_spent)])