def write(self, data: str, pubkey, prikey) -> Response or None: ''' First discovers the empty address, then writes into it, if successful, moves self.current_write_addr one hash further ''' self._find_empty_addr() if self.read_pwd: data = AESCipher(self.read_pwd).encrypt(data).decode() if self.stream_type == 'broadcast': forward_addr = hash_tryte(self.current_write_addr + self.write_pwd) else: forward_addr = '' msg = StreamAuthMessage().finalize(data, pubkey, prikey, self.current_write_addr, forward_addr) response_tangle = self.auth_comm.tangle_con.send_msg_to_addr( Address(self.current_write_addr), msg.to_json(), tag='PYTHONMAML') if response_tangle: if self.read_pwd: msg.payload = AESCipher(self.read_pwd).decrypt(msg.payload) response = Response( self.current_write_addr, hash_tryte(self.current_write_addr + self.write_pwd), [msg], True, True) self.current_write_addr = hash_tryte(self.current_write_addr + self.write_pwd) else: logger.error(f'Could not write into: {self.current_write_addr}') response = None return response
def split_channel(self, new_channel_pwd: str): ''' Moves till the end of stream, then resets self.write_pwd, sets self.current_read_addr, self.current_write_addr to new positions ''' self._find_empty_addr() self.write_pwd = new_channel_pwd self.current_write_addr = hash_tryte(self.current_write_addr + self.write_pwd) self.current_read_addr = self.current_write_addr
def read(self) -> Response or None: ''' Reads from self.current_read_addr, if successful moves self.current_read_addr one hash further ''' response = self._get_MAM_from_address(Address(self.current_read_addr)) if response: self.current_read_addr = hash_tryte(self.current_read_addr + self.write_pwd) return response else: return None
def get_self_auth_txs_from_endpoint(self, pubkey: str) -> List[AuthTransaction]: ''' Retrieve list of AuthTransaction from endpoint authenticated by the pubkey and authored by the same pubkey :param address: Address :param pubkeys_list: List[str] :return: List[AuthTransaction] ''' endpoint_address = Address(hash_tryte(pubkey)) auth_tx = self.get_auth_txs_from_address(endpoint_address, [pubkey]) return auth_tx
def _find_empty_addr(self): ''' Loops from current_read_addr till the empty address, moves self.current_write_addr address pointer to the discovered empty address ''' check_addr = self.current_read_addr while True: previous_addr = check_addr response = self._get_MAM_from_address(Address(check_addr)) check_addr = hash_tryte(check_addr + self.write_pwd) if not response: self.current_write_addr = previous_addr break
def send_msg_to_endpoint(self, auth_msg: AuthMessage, pubkey: str, tag: str = 'AUTH9MSG') -> AuthTransaction: ''' Send AuthMessage to the endpoint authenticated by the pubkey :param auth_msg: AuthMessage :param pubkey: str :param tag: str :return: AuthTransaction ''' endpoint_address = Address(hash_tryte(pubkey)) auth_tx = self.send_msg(auth_msg, endpoint_address, tag) return auth_tx
def _get_MAM_from_address(self, address: Address) -> Response or None: ''' Discover whether the address contains messages that belong to the stream ''' try: auth_txs = self.auth_comm.get_auth_txs_from_address( address, list(self.trusted_pubkeys.keys())) if auth_txs: auth_msgs = [tx.auth_msg for tx in auth_txs] auth_msgs = self._decrypt_msgs(auth_msgs) response = Response( address.__str__(), hash_tryte(address.__str__() + self.write_pwd), auth_msgs, True, True) else: response = None except: response = None return response
def submit_page(): prikey, pubkey = Ed25519Cipher.generate_keys() pubkey_str = pubkey.to_ascii(encoding='base64').decode() address = hash_tryte(pubkey_str) html = ''' <!DOCTYPE html> <html> <head> <title>Web+IOTA test page</title> </head> <body> <h1>Welcome to IOTA-based decentralized internet!</h1> </body> </html> ''' msg = AuthMessage().finalize(html, pubkey, prikey) tangle_con.send_msg_to_addr(Address(address), msg.to_json(), tag='IOTA9GATEWAY') return jsonify(msg.to_json()), 200
def test_hash_tryte(self): msg = 'data_to_be_hashed' actual_hash = hash_tryte(msg) expected_hash = 'SCTCYAXA9B9BVAQCXATCZAABWATCPCTCUAZAUAYATCPCZACBUCTCUAWAZAQCUATCPCUAUCQCXAUCQCBBA' self.assertTrue(expected_hash, actual_hash)