2

When querying storage functions using Polkascan's py-substrate-interface how do you figure out which parameters are required?

For example, I am trying to discern how much KSM is on Karura via storage functions in the tokens (ORML) pallet.

See below code for example. I tried to substrate.query() Tokens.TotalIssuance storage_function but it requires 6 parameters:

from substrateinterface import SubstrateInterface

substrate = SubstrateInterface(url="wss://karura-rpc-0.aca-api.network/") 

result = substrate.query(module='Tokens',storage_function='TotalIssuance')
        
**ValueError**: Storage function requires 6 parameters, 0 given

Note, I also tried to to use substrate.query_map() for Token.Accounts storage function but that requires 1 parameter which I can't discern.

result = substrate.query_map(
module='Tokens',
storage_function='Accounts',
page_size=10,
max_results = 100)

**ValueError**: Storage function map requires 1 parameters, 0 given

Does anyone have any advice on how to find out which parameters are required for substrate.query() & substrate.query_map()? I have been digging around in the library docs along with substrate storage documentation but I can't figure it out.

Other Note: Through trial and error and comparing with Polkadot.JS queries (see screenshot) I managed to figure out that substrate.query() Tokens.Accounts for a KSM balance of a single Karura account requires two paramaters: params = ['karura_address',{'Token':'KSM'}].

Thanks in advance!

enter image description here enter image description here

1 Answer 1

3

Update: The storage_function.get_param_info() helper function is introduced, see: https://github.com/polkascan/py-substrate-interface#type-information-about-how-to-format-parameters


It is indeed a bit cumbersome to figure out a) what are the parameters for a storage function when this is not a primitive but a complex type and b) how to specify this that is correctly encoded.

I tried to figured this out purely using the library and this resulted in the following example:

# Retrieve storage function to get information about value and param types
storage_function = substrate.get_metadata_storage_function("Tokens", "TotalIssuance")

# Amount of params
print(len(storage_function.get_params_type_string())) # 1

# Retrieve a SCALE object of the param type
param_type = substrate.create_scale_object(storage_function.get_params_type_string()[0])

# Possible options of Enum type
print(param_type.type_mapping)
# [('Token', 'scale_info::42'), ('DexShare', '(scale_info::43, scale_info::43)'), ('Erc20', 'scale_info::44'), ('StableAssetPoolToken', 'scale_info::4'), ('LiquidCrowdloan', 'scale_info::4'), ('ForeignAsset', 'scale_info::35')]

# So if I want to use the 'Token' option: SCALE type is 'scale_info::42'
token_param = substrate.create_scale_object(param_type.type_mapping[0][1])

# Show possible options of Tokens
print(token_param.type_mapping)
# [('ACA', 'Null'), ('AUSD', 'Null'), ('DOT', 'Null'), ('LDOT', 'Null'), (None, 'Null'), (None, 'Null') ....

# So now if I want to show the TotalIssuance of the `Token` `KSM`:
result = substrate.query(
    module='Tokens',
    storage_function='TotalIssuance',
    params=[{'Token': 'KSM'}]
)

# Result is U128 object with value 81190424615873229
print(result.value)
# 81190424615873229

As said, this is not very intuitive.. 😅

It becomes more clear when using the query_map() function (get all results, omitting the param)

# Query the Mapped storage function
result_map = substrate.query_map(module='Tokens', storage_function='TotalIssuance')

print(list(result_map))
# [[<scale_info::41(value={'DexShare': ({'Token': 'KSM'}, {'Token': 'LKSM'})})>, <U128(value=19811150500020714)>], [<scale_info::41(value={'DexShare': ({'Token': 'KUSD'}, {'Token': 'BNC'})})>, <U128(value=2953340214648797607)>], [<scale_info::41(value={'DexShare': ({'Token': 'KSM'}, {'ForeignAsset': 0})})>, <U128(value=5454135724694137)>], ...

Here you will see the key to use immediately. There is clearly a need for an easier way to retrieve this information from the storage function, I will submit an issue for this feature request

4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.