def hash(self): """ Computes the double SHA-256 hash of the serialized object. Returns: Hash: object containing the hash """ return Hash.dhash(bytes(self))
def hash(self): """ Computes the hash of the transaction. Returns: dhash (bytes): Double SHA-256 hash of the serialized transaction. """ return Hash.dhash(bytes(self))
def _op_hash256(self): """ The input is hashed two times with SHA-256. """ self._check_stack_len(1) x = self._stack.pop() self._stack.append(bytes(Hash.dhash(x)))
def _complete_merkle_edge(self): if self._cb_txn is None: # TODO: raise an error? return cur_hash = self._cb_txn.hash for e in self.merkle_edge: cur_hash = Hash.dhash(bytes(cur_hash) + bytes(e)) self.block_header.merkle_root_hash = cur_hash
def _invalidate_coinbase(self, merkle_node=None): if merkle_node is None: merkle_node = self.merkle_tree if(merkle_node.left_child is None and merkle_node.right_child is None): # This is the node corresponding to the coinbase, update hash merkle_node.hash = self.coinbase_transaction.hash return else: self._invalidate_coinbase(merkle_node.left_child) merkle_node.hash = Hash.dhash(bytes(merkle_node.left_child.hash) + bytes(merkle_node.right_child.hash)) # If we're back at the root, update the blockheader if merkle_node is self.merkle_tree: self.block_header.merkle_root_hash = self.merkle_tree.hash
def get_signature_for_input(self, input_index, hash_type, private_key, sub_script): """ Returns the signature for an input. This function only returns the signature for an input, it does not insert the signature into the script member of the input. It also does not validate that the given private key matches any public keys in the sub_script. Args: input_index (int): The index of the input to sign. hash_type (int): What kind of signature hash to do. private_key (crypto.PrivateKey): private key with which to sign the transaction. sub_script (Script): the scriptPubKey of the corresponding utxo being spent if the outpoint is P2PKH or the redeem script if the outpoint is P2SH. Returns: tuple: A tuple containing the signature object and the message that was signed. """ if input_index < 0 or input_index >= len(self.inputs): raise ValueError("Invalid input index.") tmp_script = sub_script.remove_op("OP_CODESEPARATOR") if hash_type & 0x1f == self.SIG_HASH_SINGLE and len(self.inputs) > len(self.outputs): # This is to deal with the bug where specifying an index # that is out of range (wrt outputs) results in a # signature hash of 0x1 (little-endian) msg_to_sign = 0x1.to_bytes(32, 'little') else: txn_copy = self._copy_for_sig(input_index, hash_type, tmp_script) msg_to_sign = bytes(Hash.dhash(bytes(txn_copy) + pack_u32(hash_type))) sig = private_key.sign(msg_to_sign, False) return sig, msg_to_sign
def _compute_merkle_tree(self): """ Computes the merkle tree from the transactions in self.transactions. The merkle root is the top node in the tree and can be accessed as self.merkle_tree.merkle_hash. """ # Tree gets built bottom up level_nodes = [MerkleNode(t.hash, None, None) for t in self.txns] while True: if len(level_nodes) == 1: self.merkle_tree = level_nodes[0] # This is the root return if len(level_nodes) % 2 != 0: # Make sure there are an even number of nodes level_nodes.append(level_nodes[-1]) new_level = [] for i in range(0, len(level_nodes), 2): left = level_nodes[i] right = level_nodes[i+1] n = MerkleNode(Hash.dhash(bytes(left.hash) + bytes(right.hash)), left, right) new_level.append(n) level_nodes = new_level
def _compute_merkle_tree(self): """ Computes the merkle tree from the transactions in self.txns. The merkle root is the top node in the tree and can be accessed as self.merkle_tree.merkle_hash. """ # Tree gets built bottom up level_nodes = [MerkleNode(t.hash, None, None) for t in self.txns] while True: if len(level_nodes) == 1: self.merkle_tree = level_nodes[0] # This is the root return if len(level_nodes) % 2 != 0: # Make sure there are an even number of nodes level_nodes.append(level_nodes[-1]) new_level = [] for i in range(0, len(level_nodes), 2): left = level_nodes[i] right = level_nodes[i+1] n = MerkleNode(Hash.dhash(bytes(left.hash) + bytes(right.hash)), left, right) new_level.append(n) level_nodes = new_level