Beispiel #1
0
 async def test_transfer_from(self):
     sdk.rpc.connect_to_test_net()
     b58_from_address = acct1.get_address_base58()
     b58_recv_address = acct2.get_address_base58()
     ont = sdk.native_vm.aio_ont()
     amount = 1
     tx_hash = await ont.transfer_from(acct2, b58_from_address,
                                       b58_recv_address, amount, acct2,
                                       self.gas_price, self.gas_limit)
     self.assertEqual(64, len(tx_hash))
     await asyncio.sleep(randint(10, 15))
     event = await sdk.aio_rpc.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(
         event,
         sdk.native_vm.ong().contract_address)
     self.assertEqual('transfer', notify['States'][0])
     self.assertEqual(b58_recv_address, notify['States'][1])
     self.assertEqual(self.gas_price * self.gas_limit, notify['States'][3])
     notify = Event.get_notify_by_contract_address(
         event,
         sdk.native_vm.ont().contract_address)
     self.assertEqual('transfer', notify['States'][0])
     self.assertEqual(b58_from_address, notify['States'][1])
     self.assertEqual(b58_recv_address, notify['States'][2])
     self.assertEqual(amount, notify['States'][3])
Beispiel #2
0
    def test_add_and_remove_public_key(self):
        identity = sdk.wallet_manager.create_identity(password)
        ctrl_acct = sdk.wallet_manager.get_control_account_by_index(
            identity.ont_id, 0, password)
        ont_id = sdk.native_vm.ont_id()
        tx_hash = ont_id.registry_ont_id(identity.ont_id, ctrl_acct, acct3,
                                         self.gas_price, self.gas_limit)
        self.assertEqual(64, len(tx_hash))
        time.sleep(randint(10, 15))
        event = sdk.restful.get_contract_event_by_tx_hash(tx_hash)
        hex_contract_address = ont_id.contract_address
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Register', notify['States'][0])
        self.assertEqual(identity.ont_id, notify['States'][1])

        private_key = utils.get_random_bytes(32)
        public_key = Signature.ec_get_public_key_by_private_key(
            private_key, Curve.P256)
        hex_new_public_key = public_key.hex()

        tx_hash = sdk.native_vm.ont_id().add_public_key(
            identity.ont_id, ctrl_acct, hex_new_public_key, acct4,
            self.gas_price, self.gas_limit)
        time.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        hex_contract_address = sdk.native_vm.ont_id().contract_address
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertIn('PublicKey', notify['States'])
        self.assertIn('add', notify['States'])
        self.assertIn(identity.ont_id, notify['States'])
        self.assertIn(hex_new_public_key, notify['States'])
        try:
            ont_id.add_public_key(identity.ont_id, ctrl_acct,
                                  hex_new_public_key, acct4, self.gas_price,
                                  self.gas_limit)
        except SDKException as e:
            self.assertIn('already exists', e.args[1])
        tx_hash = sdk.native_vm.ont_id().revoke_public_key(
            identity.ont_id, ctrl_acct, hex_new_public_key, acct3,
            self.gas_price, self.gas_limit)
        time.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertIn('PublicKey', notify['States'])
        self.assertIn('remove', notify['States'])
        self.assertIn(identity.ont_id, notify['States'])
        self.assertIn(hex_new_public_key, notify['States'])
        try:
            ont_id.revoke_public_key(identity.ont_id, ctrl_acct,
                                     hex_new_public_key, acct3, self.gas_price,
                                     self.gas_limit)
        except SDKException as e:
            self.assertIn('public key has already been revoked', e.args[1])
    async def test_add_and_remove_attribute(self):
        ont_id = sdk.native_vm.aio_ont_id()
        identity = sdk.wallet_manager.create_identity(password)
        ctrl_acct = sdk.wallet_manager.get_control_account_by_index(
            identity.ont_id, 0, password)
        tx_hash = await ont_id.registry_ont_id(identity.ont_id, ctrl_acct,
                                               acct3, self.gas_price,
                                               self.gas_limit)
        self.assertEqual(64, len(tx_hash))
        await asyncio.sleep(randint(10, 15))
        event = await sdk.default_aio_network.get_contract_event_by_tx_hash(
            tx_hash)
        hex_contract_address = ont_id.contract_address
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Register', notify['States'][0])
        self.assertEqual(identity.ont_id, notify['States'][1])

        attribute = Attribute('hello', 'string', 'attribute')
        tx_hash = await ont_id.add_attribute(identity.ont_id, ctrl_acct,
                                             attribute, acct2, self.gas_price,
                                             self.gas_limit)
        await asyncio.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual('Attribute', notify['States'][0])
        self.assertEqual('add', notify['States'][1])
        self.assertEqual(identity.ont_id, notify['States'][2])
        self.assertEqual('hello', Data.to_utf8_str(notify['States'][3][0]))

        attrib_key = 'hello'
        tx_hash = await ont_id.remove_attribute(identity.ont_id, ctrl_acct,
                                                attrib_key, acct3,
                                                self.gas_price, self.gas_limit)
        await asyncio.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual('Attribute', notify['States'][0])
        self.assertEqual('remove', notify['States'][1])
        self.assertEqual(identity.ont_id, notify['States'][2])
        self.assertEqual('hello', Data.to_utf8_str(notify['States'][3]))
        try:
            await ont_id.remove_attribute(identity.ont_id, ctrl_acct,
                                          attrib_key, acct3, self.gas_price,
                                          self.gas_limit)
        except SDKException as e:
            self.assertIn('attribute not exist', e.args[1])
        attrib_key = 'key'
        try:
            await ont_id.remove_attribute(identity.ont_id, ctrl_acct,
                                          attrib_key, acct3, self.gas_price,
                                          self.gas_limit)
        except SDKException as e:
            self.assertIn('attribute not exist', e.args[1])
Beispiel #4
0
 def test_transfer(self):
     amount = 1
     ont = sdk.native_vm.ont()
     tx_hash = ont.transfer(acct1, acct2.get_address(), amount, acct4, self.gas_price, self.gas_limit)
     time.sleep(randint(14, 20))
     event = sdk.default_network.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(event, ont.contract_address)
     self.assertEqual('transfer', notify['States'][0])
     self.assertEqual(acct1.get_address_base58(), notify['States'][1])
     self.assertEqual(acct2.get_address_base58(), notify['States'][2])
     self.assertEqual(amount, notify['States'][3])
     notify = Event.get_notify_by_contract_address(event, sdk.native_vm.aio_ong().contract_address)
     self.assertEqual('transfer', notify['States'][0])
     self.assertEqual(acct4.get_address_base58(), notify['States'][1])
     self.assertEqual(self.gas_price * self.gas_limit, notify['States'][3])
Beispiel #5
0
 def __commit_invoke(self, contract_address: str, func: Func):
     invoke_func = InvokeFunction(func.name, func.args_normalized)
     payer_address = func.payer
     if len(payer_address) == 0:
         payer_address = self.invoke_config.get('defaultPayer', '')
     if len(payer_address) == 0:
         payer_address = input('Please input payer address: ')
     tx = self.ontology.neo_vm.make_invoke_transaction(contract_address,
                                                       invoke_func,
                                                       payer_address,
                                                       self.invoke_config.get('gasPrice', 500),
                                                       self.invoke_config.get('gasLimit', 20000))
     tx = self.__add_signature(tx, func.signers, payer_address)
     tx_hash = self._send_raw_tx_with_spinner(tx)
     if len(tx_hash) != 64:
         return ''
     if self._echo_pending_tx_info(tx_hash):
         event = self.ontology.rpc.get_contract_event_by_tx_hash(tx_hash)
         notify = Event.get_notify_by_contract_address(event, contract_address)
         if len(notify) != 0:
             notify['States'] = self.parse_states(notify.get('States', dict()), func.event)
             echo('> Contract emit event:\n')
             echo('  ' + json.dumps(notify, indent=2).replace('\n', '\n  ') + '\n')
     echo(f"Using 'punica info tx {tx_hash}' to query all events in transaction.\n")
     return tx_hash
 async def query_transfer_from_event(self, tx_hash: str):
     event = await self._sdk.default_aio_network.get_contract_event_by_tx_hash(
         tx_hash)
     notify = Event.get_notify_by_contract_address(event,
                                                   self._contract_address)
     notify = Data.parse_addr_addr_int_notify(notify)
     return notify
Beispiel #7
0
 async def test_subscribe(self):
     hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     oep4 = sdk.neo_vm.aio_oep4(hex_contract_address)
     response = await sdk.websocket.subscribe(hex_contract_address, True, False, False, False)
     self.assertEqual([hex_contract_address], response['ContractsFilter'])
     self.assertEqual(True, response['SubscribeEvent'])
     self.assertEqual(False, response['SubscribeJsonBlock'])
     self.assertEqual(False, response['SubscribeRawBlock'])
     b58_to_address = acct2.get_address_base58()
     value = 10
     tx_hash = await oep4.transfer(acct1, b58_to_address, value, acct3, 500, 20000)
     self.assertEqual(64, len(tx_hash))
     try:
         event = await asyncio.wait_for(sdk.websocket.recv_subscribe_info(), timeout=10)
         self.assertEqual(False, response['SubscribeBlockTxHashs'])
         self.assertEqual(64, len(event['TxHash']))
         notify = Event.get_notify_by_contract_address(event, hex_contract_address)
         notify = Data.parse_addr_addr_int_notify(notify)
         self.assertEqual(hex_contract_address, notify['ContractAddress'])
         self.assertEqual('transfer', notify['States'][0])
         self.assertEqual(acct1.get_address_base58(), notify['States'][1])
         self.assertEqual(b58_to_address, notify['States'][2])
         self.assertEqual(value, notify['States'][3])
     except asyncio.TimeoutError:
         pass
     finally:
         await sdk.websocket.close_connect()
    async def test_verify_signature(self):
        identity = sdk.wallet_manager.create_identity(password)
        ctrl_acct = sdk.wallet_manager.get_control_account_by_index(
            identity.ont_id, 0, password)
        tx_hash = await sdk.native_vm.aio_ont_id().registry_ont_id(
            identity.ont_id, ctrl_acct, acct3, self.gas_price, self.gas_limit)
        self.assertEqual(64, len(tx_hash))
        await asyncio.sleep(randint(10, 15))
        event = await sdk.default_aio_network.get_contract_event_by_tx_hash(
            tx_hash)
        hex_contract_address = sdk.native_vm.aio_ont_id().contract_address
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Register', notify['States'][0])
        self.assertEqual(identity.ont_id, notify['States'][1])

        private_key = utils.get_random_bytes(32)
        public_key = Signature.ec_get_public_key_by_private_key(
            private_key, Curve.P256)
        new_ctrl_acct = Account(private_key)
        hex_new_public_key = public_key.hex()

        tx_hash = await sdk.native_vm.aio_ont_id().add_public_key(
            identity.ont_id, ctrl_acct, hex_new_public_key, acct4,
            self.gas_price, self.gas_limit)
        await asyncio.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        hex_contract_address = sdk.native_vm.aio_ont_id().contract_address
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertIn('PublicKey', notify['States'])
        self.assertIn('add', notify['States'])
        self.assertIn(identity.ont_id, notify['States'])
        self.assertIn(hex_new_public_key, notify['States'])
        result = await sdk.native_vm.aio_ont_id().verify_signature(
            identity.ont_id, 1, ctrl_acct)
        self.assertTrue(result)
        result = await sdk.native_vm.aio_ont_id().verify_signature(
            identity.ont_id, 2, ctrl_acct)
        self.assertFalse(result)
        result = await sdk.native_vm.aio_ont_id().verify_signature(
            identity.ont_id, 1, new_ctrl_acct)
        self.assertFalse(result)
        result = await sdk.native_vm.aio_ont_id().verify_signature(
            identity.ont_id, 2, new_ctrl_acct)
        self.assertTrue(result)
Beispiel #9
0
 def test_transfer_from(self):
     b58_from_address = acct2.get_address_base58()
     b58_recv_address = acct1.get_address_base58()
     ont = sdk.native_vm.ont()
     amount = 1
     tx_hash = ont.transfer_from(acct1, b58_from_address, b58_recv_address, amount, acct2, self.gas_price,
                                 self.gas_limit)
     self.assertEqual(64, len(tx_hash))
     time.sleep(randint(10, 15))
     event = sdk.default_network.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(event, sdk.native_vm.ong().contract_address)
     self.assertEqual('transfer', notify['States'][0])
     self.assertEqual(b58_from_address, notify['States'][1])
     self.assertEqual(self.gas_price * self.gas_limit, notify['States'][3])
     notify = Event.get_notify_by_contract_address(event, sdk.native_vm.ont().contract_address)
     self.assertEqual('transfer', notify['States'][0])
     self.assertEqual(b58_from_address, notify['States'][1])
     self.assertEqual(b58_recv_address, notify['States'][2])
     self.assertEqual(amount, notify['States'][3])
 async def test_withdraw_ong(self):
     amount, gas_price, gas_limit = 1, 500, 20000
     tx_hash = await sdk.native_vm.aio_ong().withdraw(
         acct1, acct1.get_address(), amount, acct2, gas_price, gas_limit)
     self.assertEqual(64, len(tx_hash))
     await asyncio.sleep(randint(14, 20))
     event = await sdk.aio_rpc.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(
         event,
         sdk.native_vm.aio_ong().contract_address)
     self.assertEqual('transfer', notify[0]['States'][0])
     self.assertEqual(acct1.get_address_base58(), notify[0]['States'][2])
     self.assertEqual(amount, notify[0]['States'][3])
     notify = Event.get_notify_by_contract_address(
         event,
         sdk.native_vm.aio_ong().contract_address)
     self.assertEqual('transfer', notify[1]['States'][0])
     self.assertEqual(acct2.get_address_base58(), notify[1]['States'][1])
     self.assertEqual(gas_price * gas_limit, notify[1]['States'][3])
    def test_invoke_transaction(self):
        """
        from ontology.interop.System.Runtime import Notify

        def main(operation, args):
            if operation == 'hello':
                return hello(args[0])
            return False


        def hello(msg):
            Notify(["hello", msg])
            return msg
        """
        avm_code = '51c56b6c58c56b6a00527ac46a51527ac46a52527ac46a51c30568656c6c6f7d9c7c756427' \
                   '00006a53527ac46a52c300c3516a53c3936a53527ac46a53c36a00c365f2006c7566620300' \
                   '006c75660111c56b6a00527ac46a51527ac46a51c300947600a0640c00c16a52527ac4620e' \
                   '007562030000c56a52527ac46a52c3c0517d9c7c75641c00006a53527ac46a52c300c36a54' \
                   '527ac4516a55527ac4625c006a52c3c0527d9c7c756421006a52c300c36a53527ac46a52c3' \
                   '51c36a54527ac4516a55527ac4616232006a52c3c0537d9c7c756424006a52c300c36a5352' \
                   '7ac46a52c351c36a54527ac46a52c352c36a55527ac462050000f100c176c96a56527ac46a' \
                   '53c36a57527ac46a57c36a54c37d9f7c756419006a56c36a57c3c86a57c36a55c3936a5752' \
                   '7ac462e0ff6a56c36c756656c56b6a00527ac46a51527ac46a52527ac46203000568656c6c' \
                   '6f6a52c352c176c9681553797374656d2e52756e74696d652e4e6f746966796a52c36c7566'
        contract_address = sdk.neo_vm.address_from_avm_code(avm_code).hex()
        self.assertEqual('f7b9970fd6def5229c1f30ad15372bd1c20bb260',
                         contract_address)
        hello = InvokeFunction('hello')
        hello.set_params_value('ontology')
        tx = sdk.neo_vm.make_invoke_transaction(contract_address, hello,
                                                acct1.get_address_base58(),
                                                500, 20000)
        response = sdk.rpc.send_raw_transaction_pre_exec(tx)
        self.assertEqual(1, response['State'])
        response['Result'] = Data.to_utf8_str(response['Result'])
        self.assertEqual('ontology', response['Result'])
        tx.sign_transaction(acct1)
        tx_hash = sdk.rpc.send_raw_transaction(tx)
        sleep(10)
        for _ in range(5):
            try:
                event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
                if isinstance(event, dict) and event.get('Notify', '') != '':
                    notify = Event.get_notify_by_contract_address(
                        event, contract_address)
                    self.assertEqual(contract_address,
                                     notify['ContractAddress'])
                    self.assertEqual('hello',
                                     Data.to_utf8_str(notify['States'][0]))
                    self.assertEqual('ontology',
                                     Data.to_utf8_str(notify['States'][1]))
                    break
            except SDKException:
                continue
            sleep(2)
Beispiel #12
0
 def query_revoke_event(self, tx_hash: str):
     event = self._sdk.default_network.get_contract_event_by_tx_hash(
         tx_hash)
     notify = Event.get_notify_by_contract_address(
         event, self.__hex_contract_address)
     if len(notify['States']) == 4:
         notify['States'][0] = Data.to_utf8_str(notify['States'][0])
         notify['States'][1] = Data.to_b58_address(notify['States'][1])
         notify['States'][2] = Data.to_utf8_str(notify['States'][2])
         notify['States'][3] = Data.to_hex_str(notify['States'][3])
     return notify
Beispiel #13
0
 def test_transfer_from_tx(self):
     acct2_b58_address = acct2.get_address_base58()
     tx_hash = sdk.native_vm.ont().transfer_from(acct2, acct1.get_address(), acct2_b58_address, 1, acct2,
                                                 self.gas_price, self.gas_limit)
     self.assertEqual(64, len(tx_hash))
     time.sleep(randint(14, 20))
     event = sdk.default_network.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(event, sdk.native_vm.ont().contract_address)
     self.assertEqual('transfer', notify['States'][0])
     self.assertEqual(acct1.get_address_base58(), notify['States'][1])
     self.assertEqual(acct2.get_address_base58(), notify['States'][2])
     self.assertEqual(1, notify['States'][3])
 async def test_transfer_from_tx(self):
     acct2_b58_address = acct2.get_address_base58()
     tx_hash = await sdk.native_vm.aio_ong().transfer_from(
         acct2, acct1.get_address(), acct2_b58_address, 1, acct2, 500,
         20000)
     self.assertEqual(64, len(tx_hash))
     await asyncio.sleep(randint(14, 20))
     event = await sdk.aio_rpc.get_contract_event_by_tx_hash(tx_hash)
     notify_list = Event.get_notify_by_contract_address(
         event,
         sdk.native_vm.aio_ong().contract_address)
     self.assertEqual(2, len(notify_list))
 async def test_init(self):
     oep4 = sdk.neo_vm.aio_oep4()
     oep4.hex_contract_address = contract_address
     tx_hash = await oep4.init(acct1, acct2, 500, 20000000)
     self.assertEqual(len(tx_hash), 64)
     await asyncio.sleep(randint(14, 20))
     event = await sdk.default_aio_network.get_contract_event_by_tx_hash(
         tx_hash)
     notify = Event.get_notify_by_contract_address(
         event, oep4.hex_contract_address)
     self.assertEqual('Already initialized!',
                      Data.to_utf8_str(notify['States']))
Beispiel #16
0
 def test_withdraw_ong(self):
     amount = 1
     tx_hash = sdk.native_vm.ong().withdraw(acct1, acct1.get_address(),
                                            amount, acct2, self.gas_price,
                                            self.gas_limit)
     self.assertEqual(64, len(tx_hash))
     time.sleep(randint(14, 20))
     event = sdk.default_network.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(
         event,
         sdk.native_vm.ong().contract_address)
     self.assertEqual('transfer', notify[0]['States'][0])
     self.assertEqual(acct1.get_address_base58(), notify[0]['States'][2])
     self.assertEqual(amount, notify[0]['States'][3])
     notify = Event.get_notify_by_contract_address(
         event,
         sdk.native_vm.ong().contract_address)
     self.assertEqual('transfer', notify[1]['States'][0])
     self.assertEqual(acct2.get_address_base58(), notify[1]['States'][1])
     self.assertEqual(self.gas_price * self.gas_limit,
                      notify[1]['States'][3])
Beispiel #17
0
 def test_transfer_from(self):
     sdk.rpc.connect_to_test_net()
     b58_from_address = acct1.get_address_base58()
     b58_recv_address = acct2.get_address_base58()
     ong = sdk.native_vm.ong()
     tx_hash = ong.transfer_from(acct2, b58_from_address, b58_recv_address,
                                 1, acct2, self.gas_price, self.gas_limit)
     self.assertEqual(64, len(tx_hash))
     time.sleep(randint(14, 20))
     event = sdk.default_network.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(event,
                                                   ong.contract_address)
     self.assertEqual(2, len(notify))
 async def test_transfer_from(self):
     sdk.rpc.connect_to_test_net()
     b58_from_address = acct1.get_address_base58()
     b58_recv_address = acct2.get_address_base58()
     ong = sdk.native_vm.aio_ong()
     tx_hash = await ong.transfer_from(acct2, b58_from_address,
                                       b58_recv_address, 1, acct2, 500,
                                       20000)
     self.assertEqual(64, len(tx_hash))
     await asyncio.sleep(randint(14, 20))
     event = await sdk.aio_rpc.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(event,
                                                   ong.contract_address)
     self.assertEqual(2, len(notify))
Beispiel #19
0
 def query_approve_event(self, tx_hash: str):
     event = self._sdk.default_network.get_contract_event_by_tx_hash(tx_hash)
     notify = Event.get_notify_by_contract_address(event, self._contract_address)
     notify = Data.parse_addr_addr_int_notify(notify)
     return notify
Beispiel #20
0
 def _parse_multi_transfer_event(self, event: dict):
     notify_list = Event.get_notify_by_contract_address(event, self._contract_address)
     for index, notify in enumerate(notify_list):
         if notify.get('ContractAddress', '') == self._contract_address:
             notify_list[index] = Data.parse_addr_addr_int_notify(notify_list[index])
     return notify_list
Beispiel #21
0
    def test_change_recovery(self):
        identity = sdk.wallet_manager.create_identity(password)
        ctrl_acct = sdk.wallet_manager.get_control_account_by_index(
            identity.ont_id, 0, password)
        tx_hash = sdk.native_vm.ont_id().registry_ont_id(
            identity.ont_id, ctrl_acct, acct3, self.gas_price, self.gas_limit)
        self.assertEqual(64, len(tx_hash))
        time.sleep(randint(10, 15))
        event = sdk.restful.get_contract_event_by_tx_hash(tx_hash)
        hex_contract_address = sdk.native_vm.ont_id().contract_address
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Register', notify['States'][0])
        self.assertEqual(identity.ont_id, notify['States'][1])

        rand_private_key = utils.get_random_bytes(32).hex()
        recovery = Account(rand_private_key, SignatureScheme.SHA256withECDSA)
        b58_recovery_address = recovery.get_address_base58()
        tx_hash = sdk.native_vm.ont_id().add_recovery(identity.ont_id,
                                                      ctrl_acct,
                                                      b58_recovery_address,
                                                      acct2, self.gas_price,
                                                      self.gas_limit)
        time.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Recovery', notify['States'][0])
        self.assertEqual('add', notify['States'][1])
        self.assertEqual(identity.ont_id, notify['States'][2])
        self.assertEqual(recovery.get_address_hex(little_endian=False),
                         notify['States'][3])
        ddo = sdk.native_vm.ont_id().get_ddo(identity.ont_id)
        self.assertIn(ctrl_acct.get_ont_id(), ddo['Owners'][0]['PubKeyId'])
        self.assertEqual('ECDSA', ddo['Owners'][0]['Type'])
        self.assertEqual('P256', ddo['Owners'][0]['Curve'])
        self.assertEqual(ctrl_acct.get_public_key_hex(),
                         ddo['Owners'][0]['Value'])
        self.assertEqual(0, len(ddo['Attributes']))
        self.assertEqual(recovery.get_address_base58(), ddo['Recovery'])
        self.assertEqual(identity.ont_id, ddo['OntId'])

        rand_private_key = utils.get_random_bytes(32).hex()
        new_recovery = Account(rand_private_key,
                               SignatureScheme.SHA256withECDSA)
        b58_new_recovery_address = new_recovery.get_address_base58()

        try:
            sdk.native_vm.ont_id().change_recovery(identity.ont_id,
                                                   b58_new_recovery_address,
                                                   ctrl_acct, acct2,
                                                   self.gas_price,
                                                   self.gas_limit)
        except SDKException as e:
            self.assertIn('operator is not the recovery', e.args[1])
        tx_hash = sdk.native_vm.ont_id().change_recovery(
            identity.ont_id, b58_new_recovery_address, recovery, acct2,
            self.gas_price, self.gas_limit)
        time.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)

        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Recovery', notify['States'][0])
        self.assertEqual('change', notify['States'][1])
        self.assertEqual(identity.ont_id, notify['States'][2])
        self.assertEqual(new_recovery.get_address_hex(little_endian=False),
                         notify['States'][3])
    def test_multi_serialize(self):
        pub_keys = [
            acct1.get_public_key_bytes(),
            acct2.get_public_key_bytes(),
            acct3.get_public_key_bytes()
        ]
        m = 2
        multi_address = Address.from_multi_pub_keys(m, pub_keys)
        b58_multi_address = multi_address.b58encode()
        b58_acct1_address = acct1.get_address_base58()
        b58_acct2_address = acct2.get_address_base58()
        gas_price = 500
        gas_limit = 20000
        tx1 = sdk.native_vm.ong().new_transfer_tx(b58_multi_address,
                                                  b58_acct2_address, 1,
                                                  b58_acct1_address, gas_price,
                                                  gas_limit)
        tx_bytes = tx1.serialize()
        tx2 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx1), dict(tx2))

        tx2.sign_transaction(acct1)
        tx_bytes = tx2.serialize()
        tx3 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx2), dict(tx3))
        tx3.add_multi_sign_transaction(m, pub_keys, acct1)
        tx_bytes = tx3.serialize()
        tx4 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx3), dict(tx4))
        tx4.add_multi_sign_transaction(m, pub_keys, acct2)
        tx_bytes = tx4.serialize()
        tx5 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx4), dict(tx5))
        tx_hash = sdk.rpc.send_raw_transaction(tx5)
        self.assertEqual(64, len(tx_hash))
        time.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        contract_address = '0200000000000000000000000000000000000000'
        notify = Event.get_notify_by_contract_address(event, contract_address)
        for event in notify:
            self.assertEqual(event['States'][0], 'transfer')
        multi_address = Address.from_multi_pub_keys(m, pub_keys[::-1])
        b58_multi_address = multi_address.b58encode()
        b58_acct1_address = acct1.get_address_base58()
        b58_acct2_address = acct2.get_address_base58()
        tx1 = sdk.native_vm.ong().new_transfer_tx(b58_multi_address,
                                                  b58_acct2_address, 100000,
                                                  b58_acct1_address, gas_price,
                                                  gas_limit)
        tx_bytes = tx1.serialize()
        tx2 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx1), dict(tx2))

        tx2.sign_transaction(acct1)
        tx_bytes = tx2.serialize()
        tx3 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx2), dict(tx3))
        tx3.add_multi_sign_transaction(m, pub_keys, acct1)
        tx_bytes = tx3.serialize()
        tx4 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx3), dict(tx4))
        tx4.add_multi_sign_transaction(m, pub_keys, acct2)
        tx_bytes = tx4.serialize()
        tx5 = Transaction.deserialize_from(tx_bytes)
        self.assertEqual(dict(tx4), dict(tx5))
        tx_hash = sdk.rpc.send_raw_transaction(tx5)
        self.assertEqual(64, len(tx_hash))
        time.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        contract_address = '0200000000000000000000000000000000000000'
        notify = Event.get_notify_by_contract_address(event, contract_address)
        for event in notify:
            self.assertEqual(event['States'][0], 'transfer')
    async def test_add_recovery(self):
        identity = sdk.wallet_manager.create_identity(password)
        ctrl_acct = sdk.wallet_manager.get_control_account_by_index(
            identity.ont_id, 0, password)
        tx_hash = await sdk.native_vm.aio_ont_id().registry_ont_id(
            identity.ont_id, ctrl_acct, acct3, self.gas_price, self.gas_limit)
        self.assertEqual(64, len(tx_hash))
        await asyncio.sleep(randint(10, 15))
        event = await sdk.default_aio_network.get_contract_event_by_tx_hash(
            tx_hash)
        hex_contract_address = sdk.native_vm.aio_ont_id().contract_address
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Register', notify['States'][0])
        self.assertEqual(identity.ont_id, notify['States'][1])

        rand_private_key = utils.get_random_bytes(32).hex()
        recovery = Account(rand_private_key, SignatureScheme.SHA256withECDSA)
        b58_recovery_address = recovery.get_address_base58()
        tx_hash = await sdk.native_vm.aio_ont_id().add_recovery(
            identity.ont_id, ctrl_acct, b58_recovery_address, acct2,
            self.gas_price, self.gas_limit)
        await asyncio.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('Recovery', notify['States'][0])
        self.assertEqual('add', notify['States'][1])
        self.assertEqual(identity.ont_id, notify['States'][2])
        self.assertEqual(recovery.get_address_hex(little_endian=False),
                         notify['States'][3])
        ddo = await sdk.native_vm.aio_ont_id().get_ddo(identity.ont_id)
        self.assertIn(ctrl_acct.get_ont_id(), ddo['Owners'][0]['PubKeyId'])
        self.assertEqual('ECDSA', ddo['Owners'][0]['Type'])
        self.assertEqual('P256', ddo['Owners'][0]['Curve'])
        self.assertEqual(ctrl_acct.get_public_key_hex(),
                         ddo['Owners'][0]['Value'])
        self.assertEqual(0, len(ddo['Attributes']))
        self.assertEqual(recovery.get_address_base58(), ddo['Recovery'])
        self.assertEqual(identity.ont_id, ddo['OntId'])

        rand_private_key = utils.get_random_bytes(32).hex()
        new_recovery = Account(rand_private_key,
                               SignatureScheme.SHA256withECDSA)
        b58_new_recovery_address = new_recovery.get_address_base58()
        try:
            await sdk.native_vm.aio_ont_id().add_recovery(
                identity.ont_id, ctrl_acct, b58_new_recovery_address, acct2,
                self.gas_price, self.gas_limit)
        except SDKException as e:
            self.assertIn('already set recovery', e.args[1])

        private_key = utils.get_random_bytes(32)
        public_key = Signature.ec_get_public_key_by_private_key(
            private_key, Curve.P256)
        hex_new_public_key = public_key.hex()
        tx_hash = await sdk.native_vm.aio_ont_id().add_public_key(
            identity.ont_id,
            recovery,
            hex_new_public_key,
            acct2,
            self.gas_price,
            self.gas_limit,
            is_recovery=True)
        await asyncio.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertEqual(hex_contract_address, notify['ContractAddress'])
        self.assertEqual('PublicKey', notify['States'][0])
        self.assertEqual('add', notify['States'][1])
        self.assertEqual(identity.ont_id, notify['States'][2])
        self.assertEqual(2, notify['States'][3])
        self.assertEqual(hex_new_public_key, notify['States'][4])

        ddo = await sdk.native_vm.aio_ont_id().get_ddo(identity.ont_id)
        self.assertIn(ctrl_acct.get_ont_id(), ddo['Owners'][0]['PubKeyId'])
        self.assertEqual('ECDSA', ddo['Owners'][0]['Type'])
        self.assertEqual('P256', ddo['Owners'][0]['Curve'])
        self.assertEqual(ctrl_acct.get_public_key_hex(),
                         ddo['Owners'][0]['Value'])
        self.assertIn(ctrl_acct.get_ont_id(), ddo['Owners'][1]['PubKeyId'])
        self.assertEqual('ECDSA', ddo['Owners'][1]['Type'])
        self.assertEqual('P256', ddo['Owners'][1]['Curve'])
        self.assertEqual(hex_new_public_key, ddo['Owners'][1]['Value'])
        self.assertEqual(0, len(ddo['Attributes']))
        self.assertEqual(recovery.get_address_base58(), ddo['Recovery'])
        self.assertEqual(identity.ont_id, ddo['OntId'])
        self.assertEqual(b58_recovery_address, ddo['Recovery'])

        tx_hash = await sdk.native_vm.aio_ont_id().revoke_public_key(
            identity.ont_id, recovery, hex_new_public_key, acct3,
            self.gas_price, self.gas_limit, True)
        await asyncio.sleep(randint(10, 15))
        event = sdk.rpc.get_contract_event_by_tx_hash(tx_hash)
        notify = Event.get_notify_by_contract_address(event,
                                                      hex_contract_address)
        self.assertIn('PublicKey', notify['States'])
        self.assertIn('remove', notify['States'])
        self.assertIn(identity.ont_id, notify['States'])
        self.assertIn(hex_new_public_key, notify['States'])
        try:
            await sdk.native_vm.aio_ont_id().revoke_public_key(
                identity.ont_id, recovery, hex_new_public_key, acct3,
                self.gas_price, self.gas_limit, True)
        except SDKException as e:
            self.assertIn('public key has already been revoked', e.args[1])

        private_key = utils.get_random_bytes(32)
        public_key = Signature.ec_get_public_key_by_private_key(
            private_key, Curve.P256)
        hex_new_public_key = public_key.hex()
        try:
            await sdk.native_vm.aio_ont_id().add_public_key(
                identity.ont_id, new_recovery, hex_new_public_key, acct2,
                self.gas_price, self.gas_limit, True)
        except SDKException as e:
            self.assertIn('no authorization', e.args[1])