def validate_proof(proof: List[dict], hex_target_hash: str,
                    hex_merkle_root: str):
     hex_merkle_root = ContractDataParser.to_reserve_hex_str(
         hex_merkle_root)
     hex_target_hash = ContractDataParser.to_reserve_hex_str(
         hex_target_hash)
     if len(proof) == 0:
         return hex_target_hash == hex_merkle_root
     else:
         hex_proof_hash = hex_target_hash
         for node in proof:
             sibling = ContractDataParser.to_reserve_hex_str(
                 node['TargetHash'])
             try:
                 direction = node['Direction'].lower()
             except KeyError:
                 raise SDKException(ErrorCode.other_error('Invalid proof'))
             if direction == 'left':
                 value = binascii.a2b_hex('01' + sibling + hex_proof_hash)
                 hex_proof_hash = Digest.sha256(value, is_hex=True)
             elif direction == 'right':
                 value = binascii.a2b_hex('01' + hex_proof_hash + sibling)
                 hex_proof_hash = Digest.sha256(value, is_hex=True)
             else:
                 raise SDKException(ErrorCode.other_error('Invalid proof.'))
         return hex_proof_hash == hex_merkle_root
Ejemplo n.º 2
0
 def test_dict_in_ctx(self):
     hex_contract_address = '6690b6638251be951dded8c537678200a470c679'
     bool_value = True
     int_value = 100
     str_value = 'value3'
     dict_value = {'key': 'value'}
     list_value = [1, 10, 1024, [1, 10, 1024, [1, 10, 1024]]]
     dict_msg = {
         'key': dict_value,
         'key1': int_value,
         'key2': str_value,
         'key3': bool_value,
         'key4': list_value
     }
     func = InvokeFunction('testMapInMap')
     func.set_params_value(dict_msg)
     tx_hash = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                               acct1, gas_limit, gas_price,
                                               func, False)
     time.sleep(randint(6, 10))
     event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('mapInfo', states[0])
     states[1] = ContractDataParser.to_dict(states[1])
     self.assertTrue(isinstance(states[1], dict))
Ejemplo n.º 3
0
 def test_oep4_transfer(self):
     hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     func = InvokeFunction('transfer')
     bytes_from_address = acct1.get_address().to_bytes()
     bytes_to_address = acct2.get_address().to_bytes()
     value = 1
     func.set_params_value(bytes_from_address, bytes_to_address, value)
     try:
         tx_hash = sdk.rpc.send_neo_vm_transaction(hex_contract_address,
                                                   acct1, acct2, gas_limit,
                                                   gas_price, func, False)
         self.assertEqual(64, len(tx_hash))
     except SDKException as e:
         self.assertIn('already in the tx pool', e.args[1])
         return
     time.sleep(randint(6, 10))
     event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('transfer', states[0])
     states[1] = ContractDataParser.to_b58_address(states[1])
     self.assertEqual(acct1.get_address().b58encode(), states[1])
     states[2] = ContractDataParser.to_b58_address(states[2])
     self.assertEqual(acct2.get_address().b58encode(), states[2])
     states[3] = ContractDataParser.to_int(states[3])
     self.assertEqual(value, states[3])
Ejemplo n.º 4
0
 def test_invoke_transaction(self):
     avm_code = '58c56b6a00527ac46a51527ac46a00c30548656c6c6f9c6416006a51c300c36a52527ac46a52c3650b006c756' \
                '661006c756655c56b6a00527ac46a00c3681553797374656d2e52756e74696d652e4e6f7469667961516c7566'
     hex_contract_address = sdk.neo_vm.avm_code_to_hex_contract_address(
         avm_code)
     self.assertEqual('39f3fb644842c808828817bd73da0946d99f237f',
                      hex_contract_address)
     hello = InvokeFunction('Hello')
     hello.set_params_value('Ontology')
     response = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                                None, 0, 0, hello, True)
     self.assertEqual(1, response['State'])
     result = response['Result']
     result = ContractDataParser.to_bool(result)
     self.assertEqual(True, result)
     gas_limit = 20000
     gas_price = 500
     tx_hash = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                               acct1, gas_limit, gas_price,
                                               hello, False)
     sleep(6)
     response = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     notify = response['Notify'][0]
     self.assertEqual(hex_contract_address, notify['ContractAddress'])
     notify['States'] = ContractDataParser.to_utf8_str(notify['States'])
     self.assertEqual('Ontology', notify['States'])
 def test_test_list_and_str(self):
     list_msg = [1, 2, 3]
     tx_hash = hello_ontology.test_list(list_msg, acct, gas_limit,
                                        gas_price)
     time.sleep(6)
     event = ontology.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('testMsgList', states[0])
     states[1] = ContractDataParser.to_int_list(states[1])
     self.assertEqual(list_msg, states[1])
Ejemplo n.º 6
0
    def test_transfer_multi(self):
        sdk = OntologySdk()
        sdk.rpc.connect_to_test_net()
        contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
        oep4 = sdk.neo_vm.oep4()
        oep4.hex_contract_address = contract_address
        transfer_list = list()

        b58_from_address1 = acct1.get_address_base58()
        b58_from_address2 = acct2.get_address_base58()
        hex_from_address1 = acct1.get_address_hex()
        hex_from_address2 = acct2.get_address_hex()
        from_address_list = [hex_from_address1, hex_from_address2]

        b58_to_address1 = acct2.get_address_base58()
        b58_to_address2 = acct3.get_address_base58()
        hex_to_address1 = acct2.get_address_hex()
        hex_to_address2 = acct3.get_address_hex()
        to_address_list = [hex_to_address1, hex_to_address2]

        value_list = [1, 2]

        transfer1 = [b58_from_address1, b58_to_address1, value_list[0]]
        transfer2 = [b58_from_address2, b58_to_address2, value_list[1]]

        signers = [acct1, acct2, acct3]
        transfer_list.append(transfer1)
        transfer_list.append(transfer2)

        gas_limit = 20000000
        gas_price = 500

        tx_hash = oep4.transfer_multi(transfer_list, signers[0], signers,
                                      gas_limit, gas_price)
        self.assertEqual(64, len(tx_hash))
        sdk = OntologySdk()
        sdk.rpc.connect_to_test_net()
        time.sleep(randint(6, 10))
        try:
            event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
            notify_list = event['Notify'][:-1]
            self.assertEqual(len(transfer_list), len(notify_list))
            for index, notify in enumerate(notify_list):
                self.assertEqual(
                    'transfer',
                    ContractDataParser.to_utf8_str(notify['States'][0]))
                self.assertEqual(from_address_list[index], notify['States'][1])
                self.assertEqual(to_address_list[index], notify['States'][2])
                notify_value = ContractDataParser.to_int(notify['States'][3])
                self.assertEqual(value_list[index], notify_value)
        except SDKException as e:
            raised = False
            self.assertTrue(raised, e)
Ejemplo n.º 7
0
 def query_transfer_event(self, tx_hash):
     event = self.__sdk.get_network().get_smart_contract_event_by_tx_hash(
         tx_hash)
     notify = ContractEventParser.get_notify_list_by_contract_address(
         event, self.__hex_contract_address)
     notify['States'][0] = ContractDataParser.to_utf8_str(
         notify['States'][0])
     notify['States'][1] = ContractDataParser.to_b58_address(
         notify['States'][1])
     notify['States'][2] = ContractDataParser.to_b58_address(
         notify['States'][2])
     notify['States'][3] = ContractDataParser.to_int(notify['States'][3])
     return notify
Ejemplo n.º 8
0
 def test_list(self):
     hex_contract_address = '6690b6638251be951dded8c537678200a470c679'
     list_msg = [1, 10, 1024, [1, 10, 1024, [1, 10, 1024]]]
     func = InvokeFunction('testList')
     func.set_params_value(list_msg)
     tx_hash = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                               acct1, gas_limit, gas_price,
                                               func, False)
     time.sleep(randint(6, 10))
     event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('testMsgList', states[0])
     states[1] = ContractDataParser.to_int_list(states[1])
     self.assertEqual(list_msg, states[1])
    async def subscribe_oep4_case(self, event_loop):
        from_acct = acct1
        hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
        b58_to_address = acct2.get_address_base58()
        value = 10
        subscribe_task = event_loop.create_task(TestWebsocketClient.subscribe_oep4_transfer_event(hex_contract_address))
        transfer_task = event_loop.create_task(
            TestWebsocketClient.oep4_transfer(hex_contract_address, from_acct, b58_to_address, value))

        try:
            response, event = await asyncio.wait_for(subscribe_task, timeout=10)
            self.assertEqual([hex_contract_address], response['ConstractsFilter'])
            self.assertEqual(True, response['SubscribeEvent'])
            self.assertEqual(False, response['SubscribeJsonBlock'])
            self.assertEqual(False, response['SubscribeRawBlock'])
            self.assertEqual(False, response['SubscribeBlockTxHashs'])
            self.assertEqual(64, len(event['TxHash']))
            notify = ContractEventParser.get_notify_list_by_contract_address(event, hex_contract_address)
            notify = ContractDataParser.parser_oep4_transfer_notify(notify)
            self.assertEqual(hex_contract_address, notify['ContractAddress'])
            self.assertEqual('transfer', notify['States'][0])
            self.assertEqual(from_acct.get_address_base58(), notify['States'][1])
            self.assertEqual(b58_to_address, notify['States'][2])
            self.assertEqual(value, notify['States'][3])
            tx_hash = await transfer_task
            self.assertEqual(64, len(tx_hash))
        except asyncio.TimeoutError:
            pass
        await websocket_client.close_connect()
Ejemplo n.º 10
0
 def test_get_storage(self):
     hex_contract_address = '0100000000000000000000000000000000000000'
     key = '746f74616c537570706c79'
     event_loop = asyncio.get_event_loop()
     value = event_loop.run_until_complete(TestWebsocketClient.get_storage(hex_contract_address, key))
     value = ContractDataParser.to_int(value)
     self.assertEqual(1000000000, value)
Ejemplo n.º 11
0
    def query_allowance(self, asset: str, b58_from_address: str, b58_to_address: str) -> int:
        """

        :param asset: a string which is used to indicate which asset's allowance we want to get.
        :param b58_from_address: a base58 encode address which indicate where the allowance from.
        :param b58_to_address: a base58 encode address which indicate where the allowance to.
        :return: the amount of allowance in the from of int.
        """
        contract_address = self.get_asset_address(asset)
        raw_from = Address.b58decode(b58_from_address).to_bytes()
        raw_to = Address.b58decode(b58_to_address).to_bytes()
        args = {"from": raw_from, "to": raw_to}
        invoke_code = build_native_invoke_code(contract_address, b'\x00', "allowance", args)
        unix_time_now = int(time())
        version = 0
        tx_type = 0xd1
        gas_price = 0
        gas_limit = 0
        attributes = bytearray()
        signers = list()
        tx = Transaction(version, tx_type, unix_time_now, gas_price, gas_limit, None, invoke_code, attributes, signers)
        response = self.__sdk.rpc.send_raw_transaction_pre_exec(tx)
        try:
            allowance = ContractDataParser.to_int(response['Result'])
            return allowance
        except SDKException:
            return 0
Ejemplo n.º 12
0
    def query_balance(self, asset: str, b58_address: str) -> int:
        """
        This interface is used to query the account's ONT or ONG balance.

        :param asset: a string which is used to indicate which asset we want to check the balance.
        :param b58_address: a base58 encode account address.
        :return: account balance.
        """
        raw_address = Address.b58decode(b58_address).to_bytes()
        contract_address = self.get_asset_address(asset)
        invoke_code = build_native_invoke_code(contract_address, b'\x00', "balanceOf", raw_address)
        unix_time_now = int(time())
        version = 0
        tx_type = 0xd1
        gas_price = 0
        gas_limit = 0
        attributes = bytearray()
        signers = list()
        tx = Transaction(version, tx_type, unix_time_now, gas_price, gas_limit, None, invoke_code, attributes, signers)
        response = self.__sdk.rpc.send_raw_transaction_pre_exec(tx)
        try:
            balance = ContractDataParser.to_int(response['Result'])
            return balance
        except SDKException:
            return 0
Ejemplo n.º 13
0
 def name(self):
     func = InvokeFunction('name')
     res = self.__sdk.neo_vm().send_transaction(self.__hex_contract_address,
                                                None, None, 0, 0, func,
                                                True)
     res = ContractDataParser.to_utf8_str(res)
     return res
 def test_get_storage(self):
     sdk = OntologySdk()
     sdk.rpc.connect_to_test_net()
     contract_address = "0100000000000000000000000000000000000000"
     key = "746f74616c537570706c79"
     value = sdk.rpc.get_storage(contract_address, key)
     value = ContractDataParser.to_int(value)
     self.assertEqual(1000000000, value)
Ejemplo n.º 15
0
 def test_oep4_total_supply(self):
     hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     func = InvokeFunction('totalSupply')
     result = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                              None, 0, 0, func, True)
     total_supply = result['Result']
     total_supply = ContractDataParser.to_int(total_supply)
     self.assertEqual(10000000000000000000, total_supply)
Ejemplo n.º 16
0
 def test_oep4_decimal(self):
     hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     func = InvokeFunction('decimals')
     result = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                              None, 0, 0, func, True)
     decimals = result['Result']
     decimals = ContractDataParser.to_int(decimals)
     self.assertEqual(10, decimals)
Ejemplo n.º 17
0
 def test_oep4_symbol(self):
     hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     func = InvokeFunction('symbol')
     result = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                              None, 0, 0, func, True)
     symbol = result['Result']
     symbol = ContractDataParser.to_utf8_str(symbol)
     self.assertEqual('DX', symbol)
 def test_test_struct_list_and_str(self):
     bool_msg = True
     int_msg = 10
     bytes_msg = b'Hello'
     str_msg = 'Hello'
     list_msg = [1, 10, 1024, [1, 10, 1024, [1, 10, 1024]]]
     struct_list = [bool_msg, int_msg, bytes_msg, str_msg, list_msg]
     tx_hash = hello_ontology.test_struct_list_and_str(
         struct_list, str_msg, acct, gas_limit, gas_price)
     time.sleep(6)
     event = ontology.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     states[1][0] = ContractDataParser.to_bool(states[1][0])
     self.assertEqual(bool_msg, states[1][0])
     states[1][1] = ContractDataParser.to_int(states[1][1])
     self.assertEqual(int_msg, states[1][1])
     states[1][2] = ContractDataParser.to_bytes(states[1][2])
     self.assertEqual(bytes_msg, states[1][2])
     states[1][3] = ContractDataParser.to_utf8_str(states[1][3])
     self.assertEqual(str_msg, states[1][3])
     states[1][4] = ContractDataParser.to_int_list(states[1][4])
     self.assertEqual(list_msg, states[1][4])
     states[2] = ContractDataParser.to_utf8_str(states[2])
Ejemplo n.º 19
0
    def get_symbol(self) -> str:
        """
        This interface is used to call the Symbol method in ope4
        that return the symbol of an oep4 token.

        :return: a short string symbol of the oep4 token
        """
        symbol = self.__get_token_setting('symbol')
        return ContractDataParser.to_utf8_str(symbol)
Ejemplo n.º 20
0
    def get_name(self) -> str:
        """
        This interface is used to call the Name method in ope4
        that return the name of an oep4 token.

        :return: the string name of the oep4 token.
        """
        name = self.__get_token_setting('name')
        return ContractDataParser.to_utf8_str(name)
Ejemplo n.º 21
0
    def get_decimal(self) -> int:
        """
        This interface is used to call the Decimal method in ope4
        that return the number of decimals used by the oep4 token.

        :return: the number of decimals used by the oep4 token.
        """
        decimals = self.__get_token_setting('decimals')
        return ContractDataParser.to_int(decimals)
Ejemplo n.º 22
0
 def test_get_dict_in_ctx(self):
     hex_contract_address = '6690b6638251be951dded8c537678200a470c679'
     key = 'key'
     func = InvokeFunction('testGetMapInMap')
     func.set_params_value(key)
     result = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                              None, 0, 0, func, True)
     value = result['Result']
     value = ContractDataParser.to_utf8_str(value)
     self.assertEqual('value', value)
Ejemplo n.º 23
0
 def test_dict(self):
     hex_contract_address = '6690b6638251be951dded8c537678200a470c679'
     dict_msg = {'key': 'value'}
     func = InvokeFunction('testMap')
     func.set_params_value(dict_msg)
     result = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                              None, 0, 0, func, True)
     dict_value = result['Result']
     dict_value = ContractDataParser.to_utf8_str(dict_value)
     self.assertEqual('value', dict_value)
     list_value = [1, 10, 1024, [1, 10, 1024, [1, 10, 1024]]]
     dict_msg = {'key': list_value}
     func = InvokeFunction('testMap')
     func.set_params_value(dict_msg)
     result = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                              None, 0, 0, func, True)
     dict_value = result['Result']
     dict_value = ContractDataParser.to_int_list(dict_value)
     self.assertEqual(list_value, dict_value)
Ejemplo n.º 24
0
 def test_oep4_balance_of(self):
     hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     func = InvokeFunction('balanceOf')
     bytes_address = acct1.get_address().to_bytes()
     func.set_params_value(bytes_address)
     result = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                              None, 0, 0, func, True)
     balance = result['Result']
     balance = ContractDataParser.to_int(balance)
     self.assertGreater(balance, 100)
Ejemplo n.º 25
0
 def hello(self, msg: str) -> str:
     if not isinstance(msg, str):
         raise RuntimeError('the type of msg should be str')
     func = InvokeFunction('hello')
     func.set_params_value(msg)
     res = self.__sdk.neo_vm().send_transaction(self.__hex_contract_address,
                                                None, None, 0, 0, func,
                                                True)
     res = ContractDataParser.to_utf8_str(res)
     return res
Ejemplo n.º 26
0
 def test_oep4_name(self):
     contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     bytearray_contract_address = bytearray(
         binascii.a2b_hex(contract_address))
     bytearray_contract_address.reverse()
     func = InvokeFunction('name')
     result = sdk.rpc.send_neo_vm_transaction(bytearray_contract_address,
                                              None, None, 0, 0, func, True)
     name = result['Result']
     name = ContractDataParser.to_utf8_str(name)
     self.assertEqual('DXToken', name)
 def test_test_hello(self):
     bool_msg = True
     int_msg = 1
     bytes_msg = b'Hello'
     str_msg = 'Hello'
     address_msg = acct.get_address().to_bytes()
     tx_hash = hello_ontology.test_hello(bool_msg, int_msg, bytes_msg,
                                         str_msg, address_msg, acct,
                                         gas_limit, gas_price)
     time.sleep(6)
     event = ontology.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('testHello', states[0])
     states[1] = ContractDataParser.to_bool(states[1])
     self.assertEqual(bool_msg, states[1])
     states[2] = ContractDataParser.to_int(states[2])
     self.assertEqual(int_msg, states[2])
     states[3] = ContractDataParser.to_bytes(states[3])
     self.assertEqual(bytes_msg, states[3])
     states[4] = ContractDataParser.to_utf8_str(states[4])
     self.assertEqual(str_msg, states[4])
     states[5] = ContractDataParser.to_b58_address(states[5])
     self.assertEqual(acct.get_address_base58(), states[5])
Ejemplo n.º 28
0
 def test_notify(self):
     hex_contract_address = '6690b6638251be951dded8c537678200a470c679'
     notify_args = InvokeFunction('testHello')
     bool_msg = True
     int_msg = 1
     bytes_msg = b'Hello'
     str_msg = 'Hello'
     bytes_address_msg = acct1.get_address().to_bytes()
     notify_args.set_params_value(bool_msg, int_msg, bytes_msg, str_msg,
                                  bytes_address_msg)
     tx_hash = sdk.rpc.send_neo_vm_transaction(hex_contract_address, None,
                                               acct1, gas_limit, gas_price,
                                               notify_args, False)
     time.sleep(randint(6, 10))
     event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('testHello', states[0])
     states[1] = ContractDataParser.to_bool(states[1])
     self.assertEqual(bool_msg, states[1])
     states[2] = ContractDataParser.to_int(states[2])
     self.assertEqual(int_msg, states[2])
     states[3] = ContractDataParser.to_bytes(states[3])
     self.assertEqual(bytes_msg, states[3])
     states[4] = ContractDataParser.to_utf8_str(states[4])
     self.assertEqual(str_msg, states[4])
     states[5] = ContractDataParser.to_b58_address(states[5])
     self.assertEqual(acct1.get_address_base58(), states[5])
 def test_test_dict_in_ctx(self):
     bool_value = True
     int_value = 100
     str_value = 'value3'
     dict_value = {'key': 'value'}
     list_value = [1, 10, 1024, [1, 10, 1024, [1, 10, 1024]]]
     dict_msg = {
         'key': dict_value,
         'key1': int_value,
         'key2': str_value,
         'key3': bool_value,
         'key4': list_value
     }
     tx_hash = hello_ontology.test_dict_in_ctx(dict_msg, acct, gas_limit,
                                               gas_price)
     time.sleep(6)
     event = ontology.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('mapInfo', states[0])
     states[1] = ContractDataParser.to_dict(states[1])
     self.assertTrue(isinstance(states[1], dict))
Ejemplo n.º 30
0
 def test_oep4_approve(self):
     hex_contract_address = '1ddbb682743e9d9e2b71ff419e97a9358c5c4ee9'
     func = InvokeFunction('approve')
     bytes_owner_address = acct1.get_address().to_bytes()
     bytes_spender_address = acct2.get_address().to_bytes()
     amount = 10
     func.set_params_value(bytes_owner_address, bytes_spender_address,
                           amount)
     tx_hash = sdk.rpc.send_neo_vm_transaction(hex_contract_address, acct1,
                                               acct2, gas_limit, gas_price,
                                               func, False)
     self.assertEqual(64, len(tx_hash))
     time.sleep(randint(6, 10))
     event = sdk.rpc.get_smart_contract_event_by_tx_hash(tx_hash)
     states = ContractEventParser.get_states_by_contract_address(
         event, hex_contract_address)
     states[0] = ContractDataParser.to_utf8_str(states[0])
     self.assertEqual('approval', states[0])
     states[1] = ContractDataParser.to_b58_address(states[1])
     self.assertEqual(acct1.get_address_base58(), states[1])
     states[2] = ContractDataParser.to_b58_address(states[2])
     self.assertEqual(acct2.get_address_base58(), states[2])
     states[3] = ContractDataParser.to_int(states[3])
     self.assertEqual(amount, states[3])