Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable decode the event #64

Closed
99Kies opened this issue Nov 30, 2021 · 8 comments
Closed

Unable decode the event #64

99Kies opened this issue Nov 30, 2021 · 8 comments

Comments

@99Kies
Copy link

99Kies commented Nov 30, 2021

from substrateinterface import SubstrateInterface, Keypair
from scalecodec import ScaleBytes

substrate=SubstrateInterface(url='ws://127.0.0.1:9944',type_registry_preset='default')
event_data = "0x2000000000000000b0338609000000000200000001000000000080b2e60e0000000002000000020000000003be1957935299d0be2f35b8856751feab95fc7089239366b52b72ca98249b94300000020000000500be1957935299d0be2f35b8856751feab95fc7089239366b52b72ca98249b943000264d2823000000000000000000000000000200000005027a9650a6bd43f1e0b4546affb88f8c14213e1fb60512692c2b39fbfcfc56b703be1957935299d0be2f35b8856751feab95fc7089239366b52b72ca98249b943000264d2823000000000000000000000000000200000013060c4c700700000000000000000000000000000200000005047b8441d5110c178c29be709793a41d73ae8b3119a971b18fbd20945ea5d622f00313dc01000000000000000000000000000002000000000010016b0b00000000000000"
metadata = substrate.get_block_metadata()

system_pallet = [p for p in metadata.pallets if p['name'] == 'System'][0]
event_storage_function = [s for s in system_pallet['storage']['entries'] if s['name'] == "Events"][0]


event = substrate.runtime_config.create_scale_object(
    event_storage_function.get_value_type_string(), data=ScaleBytes(event_data), metadata=metadata
)
print(event)
print(event.decode())

return message:

None
Traceback (most recent call last):
  File "c:\Users\lizhaoyang\Desktop\demo.py", line 711, in <module>
    print(event.decode())
  File "C:\Users\lizhaoyang\AppData\Local\Programs\Python\Python39\lib\site-packages\scalecodec\base.py", line 666, in decode
    self.value_serialized = self.process()
  File "C:\Users\lizhaoyang\AppData\Local\Programs\Python\Python39\lib\site-packages\scalecodec\types.py", line 792, in process
    element = self.process_type(self.sub_type, metadata=self.metadata)
  File "C:\Users\lizhaoyang\AppData\Local\Programs\Python\Python39\lib\site-packages\scalecodec\base.py", line 749, in process_type
    obj.decode(check_remaining=False)
  File "C:\Users\lizhaoyang\AppData\Local\Programs\Python\Python39\lib\site-packages\scalecodec\base.py", line 666, in decode
    self.value_serialized = self.process()
  File "C:\Users\lizhaoyang\AppData\Local\Programs\Python\Python39\lib\site-packages\scalecodec\types.py", line 2545, in process
    self.phase = self.process_type('Phase')
  File "C:\Users\lizhaoyang\AppData\Local\Programs\Python\Python39\lib\site-packages\scalecodec\base.py", line 748, in process_type
    obj = self.runtime_config.create_scale_object(type_string, self.data, **kwargs)
  File "C:\Users\lizhaoyang\AppData\Local\Programs\Python\Python39\lib\site-packages\scalecodec\base.py", line 160, in create_scale_object
    raise NotImplementedError('Decoder class for "{}" not found'.format(type_string))
NotImplementedError: Decoder class for "Phase" not found
@arjanz
Copy link
Member

arjanz commented Nov 30, 2021

The best (and easiest) way to read a storage function in substrateinterface is to use the query() function:

event = substrate.query("System", "Events", block_hash="0x1029553d55f2aa71b164add49282ce56f643bf4ba422cb98278a2e4f32f7c8b4")

But if you for some reason still need to manually decode a SCALE object, you will need to initialize the runtime (to add the type definitions from the metadata to the registry of the library).

You can simply do this by added:

substrate.init_runtime()
event = substrate.runtime_config.create_scale_object(
    event_storage_function.get_value_type_string(), data=ScaleBytes(event_data), metadata=metadata
)

But I see there is a need for a convenience function, so I will add create_scale_object() for SubstrateInterface that will do this automatically for you.

@arjanz
Copy link
Member

arjanz commented Nov 30, 2021

There is in fact already a convenience method, check out: https://polkascan.github.io/py-substrate-interface/#substrateinterface.SubstrateInterface.decode_scale

arjanz added a commit to polkascan/py-substrate-interface that referenced this issue Nov 30, 2021
@99Kies
Copy link
Author

99Kies commented Nov 30, 2021

thanks!

I have encountered a new error here, but I can't track the information. Do you have similar problems?

  /usr/local/lib/python3.9/dist-packages/scalecodec/base.py:732: DeprecationWarning: Use RuntimeConfigurationObject.create_scale_object() instead
    warnings.warn("Use RuntimeConfigurationObject.create_scale_object() instead", DeprecationWarning)

@99Kies
Copy link
Author

99Kies commented Nov 30, 2021

and about ScaleDecoder.get_decoder_class. How should I use it correctly?
image

image

@99Kies
Copy link
Author

99Kies commented Nov 30, 2021

thanks!

I have encountered a new error here, but I can't track the information. Do you have similar problems?

  /usr/local/lib/python3.9/dist-packages/scalecodec/base.py:732: DeprecationWarning: Use RuntimeConfigurationObject.create_scale_object() instead
    warnings.warn("Use RuntimeConfigurationObject.create_scale_object() instead", DeprecationWarning)

https://github.com/polkascan/py-scale-codec/blob/master/scalecodec/base.py#L732
Why need this output here?

@arjanz
Copy link
Member

arjanz commented Dec 1, 2021

@99Kies

I have encountered a new error here, but I can't track the information. Do you have similar problems?

Well I added that notice myself, so I am familiar :) Because all SCALE classes and creation of SCALE objects should run via the RuntimeConfigurationObject, because the ScaleDecoder base class is too global and not context aware.

So see https://github.com/polkascan/py-scale-codec#multiple-runtime-configurations

And an example from the SubstrateInterface perspective:

metadata_decoder = substrate.runtime_config.create_scale_object(
            'MetadataVersioned', ScaleBytes(metadata_node_template_hex)
        )
        metadata_decoder.decode()

@arjanz
Copy link
Member

arjanz commented Dec 1, 2021

https://github.com/polkascan/py-scale-codec/blob/master/scalecodec/base.py#L732
Why need this output here?

Because in future releases this function will be removed, this is a transition stage

@99Kies
Copy link
Author

99Kies commented Dec 3, 2021

Thanks!

@99Kies 99Kies closed this as completed Dec 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants