Пример #1
0
    def refund_tx(self, payer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction refunding the funder of
            the P2SH address.
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([payer_sig + '\x01', OP_FALSE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("refund_tx: TXID is %s", txid)
        self.logger.info("refund_tx: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Пример #2
0
    def spend_escrow(self, payer_sig, redeemer_sig, serial_tx, redeem_script):
        '''
            Sends a transaction fulfilling the redeem script of escrow tx
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Set script sig
        txin.scriptSig = CScript([
            OP_FALSE, payer_sig + '\x01', redeemer_sig + '\x01', OP_TRUE,
            redeem_script
        ])

        # Verify script
        redeem_script = CScript(redeem_script)
        serial_tx = tx.serialize()
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_escrow: TXID is %s", txid)
        self.logger.info("spend_escrow: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Пример #3
0
    def send_inventory(self, serialized_transaction) -> msg_getdata:
        message = msg_inv()
        inventory = CInv()
        inventory.type = MSG_TX
        hash_transaction = Hash(serialized_transaction)
        inventory.hash = hash_transaction
        message.inv.append(inventory)

        timeout = time() + NODE_COMMUNICATION_TIMEOUT

        while time() < timeout:
            node = self.connect()
            if node is None:
                self.reset_connection()
                continue

            if not self.send_message(message):
                self.terminate(node)
                continue

            messages = self.capture_messages([
                msg_getdata,
            ])
            if not messages:
                self.terminate(node)
                continue

            logger.info('[%s] Node responded correctly.', node)
            return messages[0]
Пример #4
0
    def build_merkle_tree_from_txids(txids):
        """Build a full Block merkle tree from txids

        txids - iterable of txids

        Returns a new merkle tree in deepest first order. The last element is
        the merkle root.

        WARNING! If you're reading this because you're learning about crypto
        and/or designing a new system that will use merkle trees, keep in mind
        that the following merkle tree algorithm has a serious flaw related to
        duplicate txids, resulting in a vulnerability. (CVE-2012-2459) Bitcoin
        has since worked around the flaw, but for new applications you should
        use something different; don't just copy-and-paste this code without
        understanding the problem first.
        """
        merkle_tree = list(txids)

        size = len(txids)
        j = 0
        while size > 1:
            for i in range(0, size, 2):
                i2 = min(i+1, size-1)
                merkle_tree.append(Hash(merkle_tree[j+i] + merkle_tree[j+i2]))

            j += size
            size = (size + 1) // 2

        return merkle_tree
Пример #5
0
    def broadcast_transaction(self, raw_transaction: str) -> Optional[str]:
        '''
        Sends given transaction to connected node.

        Args:
            raw_transaction (str): hex string containing signed transaction

        Returns:
            str, None: transaction address if transaction was sent, None otherwise.
        '''
        deserialized_transaction = self.deserialize_raw_transaction(
            raw_transaction)
        serialized_transaction = deserialized_transaction.serialize()

        get_data = self.send_inventory(serialized_transaction)
        if not get_data:
            logger.debug(
                ConnectionProblem(
                    'Clove could not get connected with any of the nodes for too long.'
                ))
            self.reset_connection()
            return

        node = self.get_current_node()

        if all(el.hash != Hash(serialized_transaction) for el in get_data.inv):
            logger.debug(
                UnexpectedResponseFromNode(
                    'Node did not ask for our transaction', node))
            self.reset_connection()
            return

        message = msg_tx()
        message.tx = deserialized_transaction

        if not self.send_message(message, 20):
            return

        logger.info('[%s] Looking for reject message.', node)
        messages = self.capture_messages([
            msg_reject,
        ],
                                         timeout=REJECT_TIMEOUT,
                                         buf_size=8192,
                                         ignore_empty=True)
        if messages:
            logger.debug(TransactionRejected(messages[0], node))
            self.reset_connection()
            return
        logger.info('[%s] Reject message not found.', node)

        transaction_address = b2lx(deserialized_transaction.GetHash())
        logger.info('[%s] Transaction %s has just been sent.', node,
                    transaction_address)
        return transaction_address
Пример #6
0
    def spend_preimage(self, preimages, redeemer_sig, serial_tx,
                       redeem_script):
        '''
            Sends a transaction fulfilling the redeem script
            of the preimage P2SH
        '''
        # Read in transaction
        temp_tx = CTransaction.deserialize(serial_tx)
        tx = CMutableTransaction.from_tx(temp_tx)

        txin = tx.vin[0]

        # Setup preimages in reverse order
        script = []
        for p in reversed(preimages):
            script += [p]

        # Create script sig
        txin.scriptSig = CScript([redeemer_sig + '\x01'] + script +
                                 [OP_TRUE, redeem_script])

        # Verify script
        redeem_script = CScript(redeem_script)
        VerifyScript(txin.scriptSig, redeem_script.to_p2sh_scriptPubKey(), tx,
                     0, [SCRIPT_VERIFY_P2SH])

        serial_tx = tx.serialize()
        if not self.test:
            # txid = self.proxy.sendrawtransaction(tx)
            txid = b2lx(Hash(serial_tx))
        else:
            txid = b2lx(Hash(serial_tx))

        self.logger.info("spend_preimage: TXID is %s", txid)
        self.logger.info("spend_preimage: RAW TX is %s", b2x(serial_tx))

        return serial_tx
Пример #7
0
 def parse_partial_mekel_tree(self, node, bit_list, hashes_list,
                              transactions_hashes):
     flag = bit_list.pop(0)
     if (flag == "0"):
         return hashes_list.pop(0)
     if (flag == "1" and node.left is None):
         transaction_hash = hashes_list.pop(0)
         transactions_hashes.append(b2lx(transaction_hash))
         return transaction_hash
     hash_left = self.parse_partial_mekel_tree(node.left, bit_list,
                                               hashes_list,
                                               transactions_hashes)
     if node.right:
         hash_right = self.parse_partial_mekel_tree(node.right, bit_list,
                                                    hashes_list,
                                                    transactions_hashes)
     else:
         hash_right = hash_left
     return Hash(hash_left + hash_right)
Пример #8
0
    def send_inventory(self, serialized_transaction) -> Optional[msg_getdata]:
        '''
        Sends inventory message with given serialized transaction to connected node.

        Returns:
            msg_getdata, None: get data request or None if something went wrong

        Note:
            This method is used by `broadcast_transaction` to inform connected node about existence
            of the new transaction.
        '''
        message = msg_inv()
        inventory = CInv()
        inventory.type = MSG_TX
        hash_transaction = Hash(serialized_transaction)
        inventory.hash = hash_transaction
        message.inv.append(inventory)

        timeout = time() + NODE_COMMUNICATION_TIMEOUT

        while time() < timeout:
            node = self.connect()
            if node is None:
                self.reset_connection()
                continue

            if not self.send_message(message):
                self.terminate(node)
                continue

            messages = self.capture_messages([
                msg_getdata,
            ])
            if not messages:
                self.terminate(node)
                continue

            logger.info('[%s] Node responded correctly.', node)
            return messages[0]
Пример #9
0
print("\nTransformed properties")
print("%s %s" % ("Version hex little endian:", reversed_version_hex))
print("%s %s" % ("Previous block hash little endian:", reversed_prev_block_hash))
print("%s %s" % ("Merkle root little endian:", reversed_merkle_root))
print("%s %s" % ("Timestamp hex little endian:", reversed_time_hex))
print("%s %s" % ("Difficulty hex little endian:", reversed_diff_bits))
print("%s %s" % ("Nonce hex little endian:", reversed_nonce_hex))

header_str = (
    reversed_version_hex 
    + reversed_prev_block_hash 
    + reversed_merkle_root 
    + reversed_time_hex
    + reversed_diff_bits
    + reversed_nonce_hex
)

header_bytes = header_str.decode('hex')
block_hash_bytes_le = Hash(header_bytes)

computed_block_hash = b2lx(block_hash_bytes_le)
print("%s %s" % ("\nComputed block hash:", computed_block_hash))

if computed_block_hash == block_hash:
    print("Block's hash is valid!")
else:
    print("Block's hash is not valid!")
    print("%s %s" % ("Expected:", computed_block_hash))
    print("%s %s" % ("Actual:", block_hash))
print("")
Пример #10
0
 def hex_hash(self):
     # bytes to little-endian hex
     return b2lx(Hash(self.native().serialize()))
Пример #11
0
 def txid(self):
     return Hash(self.serialize())