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

example for get_storage(module, function, params) please #3

Closed
drandreaskrueger opened this issue Nov 20, 2019 · 8 comments
Closed
Assignees

Comments

@drandreaskrueger
Copy link

I have been going through all the functions:

Connected to: https://dev-node.substrate.dev:9933/

[no parameters]
          get_system_name : substrate-node
              get_version : 2.0.0
 get_chain_finalised_head : 0x189dafe56cf99d25ddf6a8a6eec2e08834d3435d721a91b898c633573e8ba7a0
           get_chain_head : 0xd41eade474e58b90bbe7d7b490c0306da66dc1b36cdd4d6595aeda847a03ef8f

[param block_hash=0xd41eade474e58b90bbe7d7b490c0306da66dc1b36cdd4d6595aeda847a03ef8f]
          get_chain_block : dict_keys(['block', 'justification'])  -->  block : dict_keys(['extrinsics', 'header']) 
         get_block_header : dict_keys(['digest', 'extrinsicsRoot', 'number', 'parentHash', 'stateRoot'])  -->  digest : dict_keys(['logs']) 
         get_block_events : dict_keys(['jsonrpc', 'result', 'id']) 
get_block_runtime_version : dict_keys(['apis', 'authoringVersion', 'implName', 'implVersion', 'specName', 'specVersion']) 
         get_block_number : 905 

[param block_hash=0xd41eade474e58b90bbe7d7b490c0306da66dc1b36cdd4d6595aeda847a03ef8f]
       get_block_metadata : dict_keys(['magicNumber', 'metadata'])
                         -->
                  magicNumber : 1635018093
                          key : MetadataV8
      MetadataV8-->modules[0] : dict_keys(['name', 'prefix', 'storage', 'calls', 'events', 'constants', 'errors'])

[param block_id=905]
          get_chain_block : dict_keys(['block', 'justification'])  -->  block : dict_keys(['extrinsics', 'header']) 
           get_block_hash : 0xd41eade474e58b90bbe7d7b490c0306da66dc1b36cdd4d6595aeda847a03ef8f 

[params: storage_key=xxh6464('Sudo Key')='0x50a63a871aced22e88ee6466fe5aa5d9', block_hash=0xd41eade474e58b90bbe7d7b490c0306da66dc1b36cdd4d6595aeda847a03ef8f]
get_storage_by_key(storage_key='0x50a63a871aced22e88ee6466fe5aa5d9', block_hash=0xd41eade474e58b90bbe7d7b490c0306da66dc1b36cdd4d6595aeda847a03ef8f)
'0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d'

Now that worked all very well. Thanks a lot. Makes my life much easier.
The last one could benefit from one small improvement, see that feature request.

However, this remaining 1, I could not yet get working:

get_storage(module='Balances', function='FreeBalance', params='d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d', block_hash=0xd41eade474e58b90bbe7d7b490c0306da66dc1b36cdd4d6595aeda847a03ef8f)

results in

None

Which is better than an exception, so the query seems to be well-formed at least; it is just asking for the wrong thing probably? Following Shawn's tutorial, it should accept a list of parameters, right? But it doesn't want to take a list.

I have tried some permutations of possible parameters, using the instructions over there; but obviously I have't understood the role of the arguments (module, function, params) yet.

For most of your other functions in this library, we can live well without unittests - but please you give one or two working examples for get_storage(). Perhaps connecting to "https://dev-node.substrate.dev:9933/" because then I can easily replicate it here.

Thanks. A lot.

@emielsebastiaan
Copy link
Contributor

Hi @drandreaskrueger

Yeah thank you. We won't be merging that.
We are working on a generalized solution for exactly this.
You can find the spec here: https://github.com/w3f/Web3-collaboration/blob/master/grants/speculative/python_substrate_api.md

We hope to finish that by the end of the year.
Therefore, I am closing this issue.

@drandreaskrueger
Copy link
Author

This was not about a pull request to be merged. Please reopen this issue, thanks.

@drandreaskrueger
Copy link
Author

drandreaskrueger commented Nov 26, 2019

However, this remaining 1, I could not yet get working:

I cannot get this beast

def get_storage(self, block_hash, module, function, params=None, return_scale_type=None, hasher=None,
spec_version_id='default', metadata=None):

working to replicate that simple example

https://www.shawntabrizi.com/substrate/querying-substrate-storage-via-rpc/#storage-map-query
--> Storage Map Query

I would think for one from your team, it would be a quick thing to just write down a Python threeliner example ... how to do the exact same but with your library substrateinterface. Please help.

Thanks a million.

@arjanz
Copy link
Member

arjanz commented Nov 26, 2019

Hi @drandreaskrueger,

Here a quick example for the latest Kusama dev node (run with --dev), I used the same account as Shawn did (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY, which result in the public key 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d)

If you use hex values as params, you need to omit the '0x', so a quick example will be:

substrate = SubstrateInterface("http://127.0.0.1:9933")
result = substrate.get_storage(
            block_hash=None,
            module='Balances',
            function='FreeBalance',
            params='d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d',
            return_scale_type='Balance',
            hasher='Blake2_256'
        )
print(result)

Note that when None is passed as block_hash, it will retrieve the most recent state.

Moreover there is a more sophisticated Substrate interface in the making, which will make our life easier by extracting and autofill the 'hasher' and 'return_scale_type' from the runtime metadata and will do the account decoding to public key automatically.

@drandreaskrueger
Copy link
Author

drandreaskrueger commented Nov 26, 2019

Ohhhh, thank you sooooooo much. You won't believe how much I tried. And then it was so easy:

 hasher='Blake2_256'

THAT was it. Hoooray, finally the result is not None anymore :-)

by extracting and autofill the 'hasher' and 'return_scale_type' from the runtime metadata

NOW other things start to make sense too. I can see this in the metadata:

'type': {'MapType': {'hasher': 'Blake2_256', ...

Oh cool, that's useful too:

return_scale_type='Balance',

Thanks, well done. And the "more sophisticated Substrate interface in the making" sounds great.


Now my next challenge is to read and write my own storage objects. In Python.

I would expect to be able to use the same API function at least for reading the data, no?
So far no success though.

How would I access this through your library?

PUT MyModule.store_value(42)
GET MyModule.SomeValue()

The metadata section says this:

metadata --> Module 'mymodule':

{'calls': [{'args': [{'name': 'somevalue', 'type': 'u32'}],
            'docs': [],
            'name': 'store_value'}],
 'constants': [],
 'errors': [],
 'events': [{'args': ['u32', 'AccountId'],
             'docs': [],
             'name': 'SomeValueStored'}],
 'name': 'mymodule',
 'prefix': 'MyModule',
 'storage': [{'docs': [],
              'fallback': '0x00',
              'modifier': 'Optional',
              'name': 'SomeValue',
              'type': {'PlainType': 'u32'}}]}

via https://polkadot.js.org/apps/ I can write that extrinsics mymodule.store_value(42), and read the chain state mymodule.SomeValue(), no problem. Now how to get that into Python code? Any hints?
.


Meta: All the tutorials, e.g. the substratekitties tutorial, are targeted at JavaScript only. What I am really missing here is one supersimple tutorial, which creates the simplemost substrate node (by now, I understood how to do that, but it took ages), which can only do 1 thing: just read and store/overwrite one integer - without fancy GUI and stuff, just showing the whole procedure from scratch, possibly even only with curl, because simple GET/POST requests can then be translated into ANY language.

Of course, what you are doing here, for us Pythonians, is super valuable. Hide the low levels. Great. Really looking forward to when it's ready. But for now the above would be everything I need short term. So if you could give me one more hint, that would be great.

Thanks!

@drandreaskrueger
Copy link
Author

drandreaskrueger commented Nov 26, 2019

Hah! I got it, result 42 is:

'0x2a000000'

Yipppieh.

And ... wow, I see the light ...

return_scale_type='U32'

turns it into:

42

Great.
.


What solved it:

  • module= must be the capital letter thing called "prefix" (different from https://polkadot.js.org/apps/ which has the small letter "name" in the dropdown)
  • and in this case NOT using hasher='Blake2_256'

then it worked. Great.


Now I have to learn how to store values, talking to MyModule.store_value(42)

But that is NOT part of the current py-substrate-interface yet, right? Any hints that might help me?

@drandreaskrueger
Copy link
Author

Anyways, just want to say thanks again. Traveling now, continue probably end of next week. Thanks.

CanClose.

@emielsebastiaan
Copy link
Contributor

Sure np!

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

3 participants