def _read_tx_parts(self): '''Return a (deserialized TX, tx_hash, vsize) tuple.''' start = self.cursor marker = self.binary[self.cursor + 4] if marker: tx = super().read_tx() tx_hash = double_sha256(self.binary[start:self.cursor]) return tx, tx_hash, self.binary_length # Ugh, this is nasty. version = self._read_le_int32() orig_ser = self.binary[start:self.cursor] marker = self._read_byte() flag = self._read_byte() start = self.cursor inputs = self._read_inputs() outputs = self._read_outputs() orig_ser += self.binary[start:self.cursor] base_size = self.cursor - start witness = self._read_witness(len(inputs)) start = self.cursor locktime = self._read_le_uint32() orig_ser += self.binary[start:self.cursor] vsize = (3 * base_size + self.binary_length) // 4 return TxSegWit(version, marker, flag, inputs, outputs, witness, locktime), double_sha256(orig_ser), vsize
async def tx_merkle(self, tx_hash, height): '''tx_hash is a hex string.''' hex_hashes = await self.daemon_request('block_hex_hashes', height, 1) block = await self.daemon_request('deserialised_block', hex_hashes[0]) tx_hashes = block['tx'] try: pos = tx_hashes.index(tx_hash) except ValueError: raise RPCError( BAD_REQUEST, f'tx hash {tx_hash} not in ' f'block {hex_hashes[0]} at height {height:,d}') idx = pos hashes = [hex_str_to_hash(txh) for txh in tx_hashes] merkle_branch = [] while len(hashes) > 1: if len(hashes) & 1: hashes.append(hashes[-1]) idx = idx - 1 if (idx & 1) else idx + 1 merkle_branch.append(hash_to_str(hashes[idx])) idx //= 2 hashes = [ double_sha256(hashes[n] + hashes[n + 1]) for n in range(0, len(hashes), 2) ] return {"block_height": height, "merkle": merkle_branch, "pos": pos}
def _read_tx_parts(self): '''Return a (deserialized TX, tx_hash, vsize) tuple.''' start = self.cursor version = self._read_le_int32() orig_ser = self.binary[start:self.cursor] flag = self._read_byte() # for witness orig_ser += b'\x00' # for serialization hash flag is always 0 start = self.cursor inputs = self._read_inputs() outputs = self._read_outputs() locktime = self._read_le_uint32() orig_ser += self.binary[start:self.cursor] start = self.cursor witness_in = [] witness_out = [] if flag & 1: witness_in = self._read_witness_in(len(inputs)) witness_out = self._read_witness_out(len(outputs)) flag ^= 1 base_size = len(orig_ser) full_size = base_size + len(self.binary[start:self.cursor]) vsize = ((self.WITNESS_SCALE_FACTOR - 1) * base_size + full_size + self.WITNESS_SCALE_FACTOR - 1) // self.WITNESS_SCALE_FACTOR #print(double_sha256(orig_ser)) return TxOcean(version, flag, inputs, outputs, witness_in, witness_out, locktime), double_sha256(orig_ser), vsize
def read_tx_and_hash(self): '''Return a (deserialized TX, tx_hash) pair. The hash needs to be reversed for human display; for efficiency we process it in the natural serialized order. ''' start = self.cursor return self.read_tx(), double_sha256(self.binary[start:self.cursor])
def read_tx_and_hash(self): '''Return a (deserialized TX, tx_hash) pair. The hash needs to be reversed for human display; for efficiency we process it in the natural serialized order. ''' start = self.cursor tx, end = read_tx(self.view, self.cursor) self.cursor = end return tx, double_sha256(self.view[start:end])
def _read_tx_parts(self, produce_hash=True): start = self.cursor version = self._read_le_int32() inputs = self._read_inputs() outputs = self._read_outputs() locktime = self._read_le_uint32() end_prefix = self.cursor if produce_hash: prefix_tx = self.binary[start + 4:end_prefix] tx_hash = double_sha256(prefix_tx) else: tx_hash = None return TxVeil( version, inputs, outputs, locktime, ), tx_hash, self.cursor - start
def random_tx(hash160s, utxos): '''Create a random TX paying to some of the hash160s using some of the UTXOS. Return the TX. UTXOs is updated for the effects of the TX. ''' inputs = [] n_inputs = min(randrange(1, 4), len(utxos)) input_value = 0 # Create inputs spending random UTXOs. total the inpu for n in range(n_inputs): prevout = choice(list(utxos)) hashX, value = utxos.pop(prevout) inputs.append(TxInput(prevout[0], prevout[1], b'', 4294967295)) input_value += value # Seomtimes add a generation/coinbase like input that is present # in some coins if randrange(0, 10) == 0: inputs.append(TxInput(bytes(32), 4294967295, b'', 4294967295)) fee = min(input_value, randrange(500)) input_value -= fee outputs = [] n_outputs = randrange(1, 4) for n in range(n_outputs): value = randrange(input_value + 1) input_value -= value pk_script = coin.hash160_to_P2PKH_script(choice(hash160s)) outputs.append(TxOutput(value, pk_script)) tx = Tx(2, inputs, outputs, 0) tx_bytes = tx.serialize() tx_hash = double_sha256(tx_bytes) for n, output in enumerate(tx.outputs): utxos[(tx_hash, n)] = (coin.hashX_from_script(output.pk_script), output.value) return tx, tx_hash, tx_bytes
def header_hash(cls, header): '''Given a header return hash''' return double_sha256(header)
def hash(self): _content = self.serialize_unsigned() return double_sha256(_content)
def hash(self, payload_version): _content = self.serialize(payload_version) return double_sha256(_content)
def test_double_sha256(): assert lib_hash.double_sha256( b'double_sha256' ) == b'ksn\x8e\xb7\xb9\x0f\xf6\xd9\xad\x88\xd9#\xa1\xbcU(j1Bx\xce\xd5;s\xectL\xe7\xc5\xb4\x00'
def header_hash(cls, header): '''Given a header return hash''' return double_sha256(header[:cls.BASIC_HEADER_SIZE])
def header_hash(cls, header): ''' nonce of all zeroes indicates a pos block. ''' if b'00000000' in header[76:79]: return double_sha256(header) else: return argon2m_hash.getPoWHash(header)