Esempio n. 1
0
 async def append(
         self,
         transactions: Union[List[Transaction], List[dict]],
         txn_time: Union[str, int] = None) -> (int, int, List[Transaction]):
     transactions_to_append = []
     for txn in transactions:
         if isinstance(txn, Transaction):
             transactions_to_append.append(txn)
         elif isinstance(txn, dict):
             transactions_to_append.append(Transaction.create(txn))
         else:
             raise RuntimeError('Unexpected transaction type')
     transactions_with_meta = await self.__api.remote_call(
         msg_type=
         'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/microledgers/1.0/append_txns_metadata',
         params={
             'name': self.name,
             'txns': transactions_to_append,
             'txn_time': txn_time
         })
     self.__state, start, end, appended_txns = await self.__api.remote_call(
         msg_type=
         'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/microledgers/1.0/append_txns',
         params={
             'name': self.name,
             'txns': transactions_with_meta,
         })
     return start, end, Transaction.from_value(appended_txns)
Esempio n. 2
0
 def __init__(self, transactions: List[Transaction] = None, state: Optional[MicroLedgerState] = None, *args, **kwargs):
     super().__init__(*args, **kwargs)
     if transactions is not None:
         for txn in transactions:
             txn = Transaction(txn)
             if not txn.has_metadata():
                 raise SiriusContextError('Transaction must have processed by Ledger engine and has metadata')
         self['transactions'] = transactions
     if state:
         state = MicroLedgerState(state)
         self['state'] = state
         self['hash'] = state.hash
Esempio n. 3
0
 async def get_uncommitted_transactions(self) -> List[Transaction]:
     txns = await self.__api.remote_call(
         msg_type=
         'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/microledgers/1.0/get_uncommitted_txns',
         params={'name': self.name})
     txns = Transaction.from_value(txns)
     assert isinstance(txns, list)
     return txns
Esempio n. 4
0
 async def get_last_committed_transaction(self) -> Transaction:
     txn = await self.__api.remote_call(
         msg_type=
         'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/microledgers/1.0/get_last_committed_txn',
         params={'name': self.name})
     txn = Transaction.from_value(txn)
     assert isinstance(txn, Transaction)
     return txn
Esempio n. 5
0
 async def commit(self, count: int) -> (int, int, List[Transaction]):
     self.__state, start, end, committed_txns = await self.__api.remote_call(
         msg_type=
         'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/microledgers/1.0/commit_txns',
         params={
             'name': self.name,
             'count': count,
         })
     return start, end, Transaction.from_value(committed_txns)
Esempio n. 6
0
 async def init(self, genesis: List[Transaction]) -> List[Transaction]:
     self.__state, txns = await self.__api.remote_call(
         msg_type=
         'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/microledgers/1.0/initialize',
         params={
             'name': self.name,
             'genesis_txns': genesis
         })
     txns = [Transaction.from_value(txn) for txn in txns]
     return txns
Esempio n. 7
0
 async def get_transaction(self, seq_no: int) -> Transaction:
     txn = await self.__api.remote_call(
         msg_type=
         'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/microledgers/1.0/get_by_seq_no',
         params={
             'name': self.name,
             'seqNo': seq_no
         })
     txn = Transaction.from_value(txn)
     assert isinstance(txn, Transaction)
     return txn
Esempio n. 8
0
 def __init__(
         self, transactions: List[Transaction] = None,
         states: List[Union[MicroLedgerState, dict]] = None, *args, **kwargs
 ):
     super().__init__(*args, **kwargs)
     if transactions is not None:
         for txn in transactions:
             txn = Transaction(txn)
             if not txn.has_metadata():
                 raise SiriusContextError('Transaction must have metadata for specific Ledger')
         self['transactions'] = transactions
     if states:
         # Fix states as hash
         states = [MicroLedgerState(state) for state in states]
         # sort by ledger name, assume ledger name is unique in system
         # to make available to calc accumulated hash predictable
         states = list(sorted(states, key=lambda s: s.name))
         accum = hashlib.sha256()
         for state in states:
             accum.update(state.hash.encode())
         self['hash'] = accum.hexdigest()
Esempio n. 9
0
 async def create(
     self, name: str, genesis: Union[List[Transaction], List[dict]]
 ) -> (AbstractMicroledger, List[Transaction]):
     genesis_txns = []
     for txn in genesis:
         if isinstance(txn, Transaction):
             genesis_txns.append(txn)
         elif isinstance(txn, dict):
             genesis_txns.append(Transaction.create(txn))
         else:
             raise RuntimeError('Unexpected transaction type')
     instance = Microledger(name, self.__api)
     txns = await instance.init(genesis_txns)
     self.instances[name] = instance
     return instance, txns
Esempio n. 10
0
 async def append(
         self, transactions: Union[List[Transaction], List[dict]], txn_time: Union[str, int] = None
 ) -> (int, int, List[Transaction]):
     txns = []
     for i, txn in enumerate(Transaction.from_value(transactions)):
         metadata = txn.get('txnMetadata', {})
         if 'seq_no' not in metadata:
             metadata['seq_no'] = self.seq_no + 1 + i
         if 'time' not in metadata:
             metadata['time'] = txn_time or str(datetime.datetime.utcnow())
         txn['txnMetadata'] = metadata
         txns.append(txn)
     start = self.seq_no + 1
     end = start + len(txns) - 1
     self.__uncommitted.extend(txns)
     return start, end, txns
Esempio n. 11
0
    async def issue_test_results(self, cred_def: sirius_sdk.CredentialDefinition, schema: sirius_sdk.Schema, test_results: dict):
        async with sirius_sdk.context(**self.hub_credentials): # работаем от имени агента лабы
            connection_key = await sirius_sdk.Crypto.create_key() # создаем случайный уникальный ключ соединения между агентом лабы и сириус коммуникатором пользователя
            endpoints = await sirius_sdk.endpoints()
            simple_endpoint = [e for e in endpoints if e.routing_keys == []][0]  # точка подключения к агенту лабы (интернет адрес)
            invitation = sirius_sdk.aries_rfc.Invitation(  # Создаем приглашение пользователю подключиться к лабе
                label="Invitation to connect with medical organization",
                recipient_keys=[connection_key],
                endpoint=simple_endpoint.address
            )

            qr_content = invitation.invitation_url
            qr_url = await sirius_sdk.generate_qr_code(qr_content) # агент лабы генерирует уникальный qr код для ранее созданного приглашения

            # пользователь сканирует qr код при помощи sirius коммуникатора. Коммуникатор отправляет агенту лабы запрос на подключение
            print("Scan this QR by Sirius App for receiving the Covid test result " + qr_url)

            listener = await sirius_sdk.subscribe()
            async for event in listener:
                if event.recipient_verkey == connection_key and isinstance(event.message, sirius_sdk.aries_rfc.ConnRequest):
                    #  агент лабы получает запрос от пользователя на подключение (запрос соответствкет ранее сгенерированному уникальному ключу соединения)
                    request: sirius_sdk.aries_rfc.ConnRequest = event.message
                    #  агент лабы создает уникальный децентрализованный идентификатор (did) для связи с пользователем (который тоже создает уникальный did для этого соединения)
                    my_did, my_verkey = await sirius_sdk.DID.create_and_store_my_did()
                    sm = sirius_sdk.aries_rfc.Inviter(
                        me=sirius_sdk.Pairwise.Me(
                            did=my_did,
                            verkey=my_verkey
                        ),
                        connection_key=connection_key,
                        my_endpoint=simple_endpoint
                    )
                    # Запускается процесс установки соединения в соответствии с открытым протоколом Aries 0160
                    success, p2p = await sm.create_connection(request)
                    if success:
                        # соединение успешно установлено, о чем сообщается пользователю путем отправки простого текстового сообщения на его сириус коммуникатор
                        message = sirius_sdk.aries_rfc.Message(
                            content="Welcome to the covid laboratory!",
                            locale="en"
                        )
                        print(message)
                        await sirius_sdk.send_to(message, p2p)

                        issuer = sirius_sdk.aries_rfc.Issuer(p2p)
                        preview = [sirius_sdk.aries_rfc.ProposedAttrib(key, str(value)) for key, value in test_results.items()]
                        translation = [
                            sirius_sdk.aries_rfc.AttribTranslation("full_name", "Patient Full Name"),
                            sirius_sdk.aries_rfc.AttribTranslation("location", "Patient location"),
                            sirius_sdk.aries_rfc.AttribTranslation("bio_location", "Biomaterial sampling point"),
                            sirius_sdk.aries_rfc.AttribTranslation("timestamp", "Timestamp"),
                            sirius_sdk.aries_rfc.AttribTranslation("approved", "Laboratory specialist"),
                            sirius_sdk.aries_rfc.AttribTranslation("has_covid", "Covid test result")
                        ]

                        # лаборатория выдает результаты теста на ковид пользователю.
                        # Результаты оформлены в соответствии с ранее зареестрированной схемой и подписаны ЦП лаборатории.
                        # Пользователь сохраняет полученные результаты на своем сириус коммуникаторе
                        ok = await issuer.issue(
                            values=test_results,
                            schema=schema,
                            cred_def=cred_def,
                            preview=preview,
                            translation=translation,
                            comment="Here is your covid test results",
                            locale="en"
                        )
                        if ok:
                            print("Covid test confirmation was successfully issued")
                            # если результат теста оказался положительным, он записывается в соответствующий распределенный микрореестр,
                            # достут к которому имеет лаборатория, авиакомпания и аэропорт
                            if test_results["has_covid"]:
                                ledger = await sirius_sdk.Microledgers.ledger(COVID_MICROLEDGER_NAME)
                                machine = MicroLedgerSimpleConsensus(self.me, logger=Logger())
                                tr = Transaction({
                                    "test_res": test_results
                                })
                                await machine.commit(ledger, self.covid_microledger_participants, [tr])

                    break
Esempio n. 12
0
 def transactions(self) -> Optional[List[Transaction]]:
     txns = self.get('transactions', None)
     if txns is not None:
         return [Transaction(txn) for txn in txns]
     else:
         return None