question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Question] How to use encoded parameters?

See original GitHub issue

Hi, I am migrating a scripts from polkadot-js-api to python library I have command:

polkadot-js-api --ws ws://127.0.0.1:9944 --seed <seed> tx.session.setKeys <session_key: 0x...> None

It also works in polkadot.js.org: image

But same steps in python does not work: Error:

ValueError: Element "grandpa" of struct is missing in given value

Script:

substrate_client = SubstrateInterface(
    url="ws://127.0.0.1:9944"
)

rotate_keys = substrate_client.rpc_request(method="author_rotateKeys", params=[])['result']
print(rotate_keys)
# 0x55cd921526c42e90e26d2680a4bf0968b393cb4847...
keypair = Keypair.create_from_uri("bottom drive obey lake curtain smoke basket hold race lonely fit walk//Alice")
call = substrate_client.compose_call(  # <- scrip fails here
    call_module='Session',
    call_function='set_keys',
    call_params={
        'keys': rotate_keys,
        'proof': 'None'
    }
)
extrinsic = substrate_client.create_signed_extrinsic(
    call=call,
    keypair=keypair,
)

try:
    receipt = substrate_client.submit_extrinsic(extrinsic, wait_for_inclusion=True)
    print("Extrinsic '{}' sent".format(receipt.extrinsic_hash))
except Exception as e:
    print("Failed to send call: {}, Error: {}".format(call, e))

As I understand library tries to encode already encoded parameter , so if I replace hex string with map of keys all works.

call_params={
  'keys': {'grandpa':'0x7e4230880436450bc1cc3d65039d83a6a728bd5f7d0364499afaab7a16e79c3d',
            'babe':'0x50105b266cd9e427a634d332c26b7d37df8844570a2b5e867d54fa0b1da7771e',
            'im_online':'0x723fd195e5a8b60f3f637f5a65840e09dd3e1a2ec1bd2495278783e673b68c29',
            'para_validator':'0x323710e92ac2b8068445b6a3bf75fee366e12370a7e365b492dd719b7057954c',
            'para_assignment':'0xa8123ed90963ba5f698a3ac230d70d50393dfc9a29d6d07175ed382aaf60fc54',
            'authority_discovery':'0x9041e95e6705e800db99caaf787acaadfa7879f9fb979ce44a778e50cb79eb47',
            'beefy':'0x035e4cb4dcda61d44cd6107e966e680723f7d5ac6cf8762cff7a35da21a32eb94e'
            },

Questions

  1. Is it possible to use encoded value as parameter?
  2. Can you please provide example how to decode/encode results from rpc call?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
BulatSaifcommented, Mar 8, 2022

@arjanz, Thank you for helping!

In case someone needs my workaround:

rotate_keys = substrate_client.rpc_request(method="author_rotateKeys", params=[])['result']

# Get type name (rococo_runtime::SessionKeys) from runtime by id
type_id = substrate_client.get_metadata_call_function('Session', 'set_keys')['fields'][0]['type']
print(type_id)  # 199
metadata = substrate_client.get_runtime_metadata()['result'][1]
runtime_version = list(metadata.keys())[0]
types = metadata[runtime_version]['types']['types']
type_dict = next(item for item in types if item["id"] == type_id)
print(type_dict)  # {'id': 199, 'type': {'path': ['rococo_runtime', 'SessionKeys'], 'params': [], 'def': {'composite': {'fields': [{'name': 'grandpa', 'type': 34,...
type_string = "::".join(type_dict['type']['path'])

# decode rotate_keys
print(substrate_client.decode_scale(type_string, rotate_keys))
# {'grandpa': '0x760cc41f74fd549e8bba788c7202a14eb61e8087b4405e2e1bbd5a68c6fa417a', 'babe': '0x12fc0...

I believe mapping between RPC metod and value type returned should exist somewhere, because in some cases RPC meted returns JSON (example: chain_getHeader), in another it returns hex (Example: author_rotateKeys). But I was not able to find such information.

0reactions
BulatSaifcommented, Mar 9, 2022

Wanted to add that if you know the type_id, you can also easily reconstruct the type_string with scale_info::<type_id>, in this case scale_info::199

That’s what I was looking for, Thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to encode URL parameters? - javascript - Stack Overflow
With PHP echo urlencode("http://www.image.com/?username=unknown&password=unknown");. Result
Read more >
URL encoding - Documentation for Action Request System ...
Open the AR URL Encoder utility by using the following URL: ... You can encode parameter values, but do not code the entire...
Read more >
Using URL encoding to handle special characters in a ...
Consider the example where a parameter is supplied in a URL and parameter value has a special character in it, such as,
Read more >
encodeURIComponent() - JavaScript - MDN Web Docs
The encodeURIComponent() function encodes a URI by replacing each instance of certain characters by one, two, three, or four escape ...
Read more >
URL Encoding | Google Maps Platform
All characters to be URL-encoded are encoded using a '%' character and a two-character hex value corresponding to their UTF-8 character. For example,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found