def _build_witnesses(self, tx_aux_hash: str): witnesses = [] for index, node in enumerate(self.nodes): message = (b"\x01" + cbor.encode(self.protocol_magic) + b"\x58\x20" + tx_aux_hash) signature = ed25519.sign_ext(node.private_key(), node.private_key_ext(), message) extended_public_key = (remove_ed25519_prefix(node.public_key()) + node.chain_code()) witnesses.append([ self.types[index], cbor.Tagged(24, cbor.encode([extended_public_key, signature])), ]) return witnesses
def _build_witnesses(self, tx_aux_hash: str): witnesses = [] for input in self.inputs: _, node = derive_address_and_node(self.keychain, input.address_n) message = (b"\x01" + cbor.encode(self.protocol_magic) + b"\x58\x20" + tx_aux_hash) signature = ed25519.sign_ext(node.private_key(), node.private_key_ext(), message) extended_public_key = (remove_ed25519_prefix(node.public_key()) + node.chain_code()) witnesses.append([ (input.type or 0), cbor.Tagged(24, cbor.encode([extended_public_key, signature])), ]) return witnesses
def derive_address_and_node(keychain, path: list): node = keychain.derive(path) address_payload = None address_attributes = {} address_root = _get_address_root(node, address_payload) address_type = 0 address_data = [address_root, address_attributes, address_type] address_data_encoded = cbor.encode(address_data) address = base58.encode( cbor.encode( [cbor.Tagged(24, address_data_encoded), crc.crc32(address_data_encoded)] ) ) return (address, node)
def _build_witnesses(self, tx_aux_hash: str): witnesses = [] for index, node in enumerate(self.nodes): message = self.CARDANO_WITNESS_MAGIC_PREFIX + tx_aux_hash signature = ed25519.sign_ext( node.private_key(), node.private_key_ext(), message ) extended_public_key = ( seed.remove_ed25519_prefix(node.public_key()) + node.chain_code() ) witnesses.append( [ self.types[index], cbor.Tagged(24, cbor.encode([extended_public_key, signature])), ] ) return witnesses
def serialise_tx(self): self._process_inputs() self._process_outputs() inputs_cbor = [] for i, output_index in enumerate(self.output_indexes): inputs_cbor.append( [ self.types[i], cbor.Tagged(24, cbor.encode([self.input_hashes[i], output_index])), ] ) inputs_cbor = cbor.IndefiniteLengthArray(inputs_cbor) outputs_cbor = [] for index, address in enumerate(self.output_addresses): outputs_cbor.append( [cbor.Raw(base58.decode(address)), self.outgoing_coins[index]] ) for index, address in enumerate(self.change_addresses): outputs_cbor.append( [cbor.Raw(base58.decode(address)), self.change_coins[index]] ) outputs_cbor = cbor.IndefiniteLengthArray(outputs_cbor) tx_aux_cbor = [inputs_cbor, outputs_cbor, self.attributes] tx_hash = hashlib.blake2b(data=cbor.encode(tx_aux_cbor), outlen=32).digest() witnesses = self._build_witnesses(tx_hash) tx_body = cbor.encode([tx_aux_cbor, witnesses]) self.fee = self.compute_fee( self.input_coins, self.outgoing_coins, self.change_coins ) return tx_body, tx_hash
def _encode_address_raw(address_data_encoded): return base58.encode( cbor.encode([ cbor.Tagged(24, address_data_encoded), crc.crc32(address_data_encoded) ]))