Queries 1ΒΆ
This tutorial will showcase the following topics:
Smart-contract queries
Scenario data
Smart values
The entire source code can be find in the MxOps github
ContextΒΆ
Letβs say that we want to fetch some data from a smart-contract, either for informative purposes or because we will reuse it later on in. To do that we will execute queries, which will call read-only functions (also called views) on the targeted smart-contracts. It is always recommended to use the ABI of the contract you are going to interact with, as the ABI provided the definition of what views are available, how to use them and how the process the resulting data.
For our tutorial, we will take a look at the mainnet swap contract of OneDex, we will call it onedex-swap and we will try to get information on the current state of the pair pool ONE/WEGLD.
A second tutorial, queries 2, will go one step further and show how to make more complex queries and manipulate the received data.
PrerequisitesΒΆ
You will need to have the following installed:
MxOps: installation steps
Tutorial planΒΆ
ABI download
Simple state query
theoretical price estimation
Swap estimation
To prepare for the tutorial, create a new folder
mkdir queries_tutorial
cd queries_tutorial
export MXOPS_SOURCE_BRANCH=main
ABI DownloadΒΆ
The first thing we need is the ABI of the onedex-swap contract. You can download it from using the command below:
mkdir data
curl https://raw.githubusercontent.com/Catenscia/MxOps/refs/heads/${MXOPS_SOURCE_BRANCH}/examples/queries/data/onedex-sc.abi.json > data/onedex-sc.abi.json
Simple State QueryΒΆ
We want to query the state of a single pool, namely the pool ONE/WEGLD which has the id 9 on Onedex. First create a new scene file:
mkdir mxops_scenes
touch mxops_scenes/single_pair_queries.yaml
Network and AccountΒΆ
In our use-case, we want to interact with the mainnet, so we will add this to the beginning of the scene:
allowed_networks:
- mainnet
Note
By default, for security measure, scenes can be executed on all networks except mainnet. This is why we have to specify the allowed networks in our tutorial.
Then, we will declare the onedex-swap contract by giving it an account id and by providing the path to the abi file we downloaded previously:
accounts:
- account_id: onedex-swap
address: erd1qqqqqqqqqqqqqpgqqz6vp9y50ep867vnr296mqf3dduh6guvmvlsu3sujc
abi_path: ./abis/onedex-sc.abi.json
ViewΒΆ
If you look at the ABI file, you will see the following definition of the endpoint viewPair:
{
"name": "viewPair",
"mutability": "readonly",
"inputs": [
{
"name": "pair_id",
"type": "u32"
}
],
"outputs": [
{
"type": "Pair"
}
]
}
This is the endpoint that interests us, it returns a custom Pair structure, of which you can also find the definition in the ABI file. As we are providing the ABI, MxOps will be able to automatically decode the output data into this Pair structure.
To query the pair nΒ°9 of the onedex-swap contract, add the following to your scene:
steps:
- type: ContractQuery
contract: onedex-swap
endpoint: viewPair
arguments:
- 9
results_save_keys:
- pair_9
We save the result (a Pair structure) into the key onedex-swap.pair_9. This will make us able to reuse this data.
Full SceneΒΆ
Your scene mxops_scenes/single_pair_queries.yaml should look like this:
allowed_networks:
- mainnet
accounts:
- account_id: onedex-swap
address: erd1qqqqqqqqqqqqqpgqqz6vp9y50ep867vnr296mqf3dduh6guvmvlsu3sujc
abi_path: ./data/onedex-sc.abi.json
steps:
- type: ContractQuery
contract: onedex-swap
endpoint: viewPair
arguments:
- 9
results_save_keys:
- pair_9
To execute it, use the following command:
mxops execute -n mainnet -s queries_tutorial mxops_scenes/single_pair_queries.yaml
Command results
[2025-04-02 15:12:38,622 INFO] MxOps Copyright (C) 2025 Catenscia
This program comes with ABSOLUTELY NO WARRANTY [general in main_cli.py:65]
[2025-04-02 15:12:38,640 INFO] scenario queries_tutorial loaded for network mainnet [data in execution_data.py:836]
[2025-04-02 15:12:38,640 INFO] Executing scene mxops_scenes/single_pair_queries.yaml [execution in scene.py:148]
[2025-04-02 15:12:38,665 INFO] Query viewPair on erd1qqqqqqqqqqqqqpgqqz6vp9y50ep867vnr296mqf3dduh6guvmvlsu3sujc (onedex-swap) [execution in smart_contract.py:362]
[2025-04-02 15:12:38,808 INFO] Query results: {
"pair_9": {
"pair_id": 9,
"state": {
"__discriminant__": 1,
"__name__": "Active"
},
"enabled": true,
"owner": "erd1xkflzkx3hp52szy26zh9m5ts3v3j4dxhqkpxzj9npzp7wyp6qeysfpqz2m",
"first_token_id": "ONE-f9954f",
"second_token_id": "WEGLD-bd4d79",
"lp_token_id": "ONEWEGLD-892244",
"lp_token_decimal": 18,
"first_token_reserve": 1495664529430316346685003,
"second_token_reserve": 4450294287790899643561,
"lp_token_supply": 1304000317043535522230,
"lp_token_roles_are_set": true,
"unkown": 0,
"fees": 100
}
} [execution in smart_contract.py:390]
Saved DataΒΆ
You can use the the command mxops data get to play around with the values saved by MxOps. Try to use it to recover some data about the pair nΒ°9.
Examples
mxops data get -n mainnet -s queries_tutorial "%onedex-swap.pair_9.lp_token_id"
Command results
[2025-04-02 15:20:39,679 INFO] MxOps Copyright (C) 2025 Catenscia
This program comes with ABSOLUTELY NO WARRANTY [general in main_cli.py:65]
[2025-04-02 15:20:39,697 INFO] scenario queries_tutorial loaded for network mainnet [data in execution_data.py:836]
ONEWEGLD-892244
mxops data get -n mainnet -s queries_tutorial "Pair 9 LP has a supply of ={%{onedex-swap.pair_9.lp_token_supply} / 10**%{onedex-swap.pair_9.lp_token_decimal}} %{onedex-swap.pair_9.lp_token_id}"
Command results
[2025-04-02 15:26:02,515 INFO] MxOps Copyright (C) 2025 Catenscia
This program comes with ABSOLUTELY NO WARRANTY [general in main_cli.py:65]
[2025-04-02 15:26:02,532 INFO] scenario queries_tutorial loaded for network mainnet [data in execution_data.py:836]
Pair 9 LP has a supply of 1304.000317043535522230 ONEWEGLD-892244
Price EstimationΒΆ
We managed to get the current state of the pool ONE/WEGLD on OneDex. Using this data, we are going to perform some calculation: we will compute the current theoretical price of ONE versus WEGLD.
This theoretical price is simply the ratio between the WEGLD reserve and the ONE reserve of the pool and we already have this data thanks to the previous query. To compute the theoretical price with MxOps, add the following to the scene:
- type: SetVars
variables:
one_reserve: "%onedex-swap.pair_9.first_token_reserve"
wegld_reserve: "%onedex-swap.pair_9.second_token_reserve"
pair_9_th_price: "={%{wegld_reserve} / %{one_reserve}}"
This will create variables and most importantly, compute the theoretical price of ONE versus WEGLD and store it under the key pair_9_th_price.
Swap estimationΒΆ
To be more complete, we will compare the theoretical price we just obtained to the actual amount of WEGLD we would get if we where to swap 1 ONE for WEGLD. For that, we are going to use the view getAmountOut of the contract onedex-swap:
{
"name": "getAmountOut",
"mutability": "readonly",
"inputs": [
{
"name": "token_in",
"type": "TokenIdentifier"
},
{
"name": "token_out",
"type": "TokenIdentifier"
},
{
"name": "amount_in",
"type": "BigUint"
}
],
"outputs": [
{
"type": "BigUint"
}
]
}
To call it within MxOps, add this step to your scene:
- type: ContractQuery
contract: onedex-swap
endpoint: getAmountOut
arguments:
- "%onedex-swap.pair_9.first_token_id" # ONE -> token in
- "%onedex-swap.pair_9.second_token_id" # WEGLD -> token out
- "=10**18" # -> 1 ONE (18 decimals)
results_save_keys:
- pair_9_amount_out
Lastly, to make it easier to compare to the theoretical price, we will compute the output amount as a float by dividing the result by 10**18 (ONE token has 18 decimals):
- type: SetVars
variables:
pair_9_float_amount_out: "={%{onedex-swap.pair_9_amount_out} / 10**18}"
Final SceneΒΆ
Your scene mxops_scenes/single_pair_queries.yaml should look like this:
allowed_networks:
- mainnet
accounts:
- account_id: onedex-swap
address: erd1qqqqqqqqqqqqqpgqqz6vp9y50ep867vnr296mqf3dduh6guvmvlsu3sujc
abi_path: ./data/onedex-sc.abi.json
steps:
- type: ContractQuery
contract: onedex-swap
endpoint: viewPair
arguments:
- 9
results_save_keys:
- pair_9
- type: SetVars
variables:
one_reserve: "%onedex-swap.pair_9.first_token_reserve"
wegld_reserve: "%onedex-swap.pair_9.second_token_reserve"
pair_9_th_price: "={%{wegld_reserve} / %{one_reserve}}"
- type: ContractQuery
contract: onedex-swap
endpoint: getAmountOut
arguments:
- "%onedex-swap.pair_9.first_token_id"
- "%onedex-swap.pair_9.second_token_id"
- "=10**18"
results_save_keys:
- pair_9_amount_out
- type: SetVars
variables:
pair_9_float_amount_out: "={%{onedex-swap.pair_9_amount_out} / 10**18}"
To execute it, use the following command:
mxops execute -n mainnet -s queries_tutorial mxops_scenes/single_pair_queries.yaml
Command results
[2025-04-03 16:04:09,064 INFO] MxOps Copyright (C) 2025 Catenscia
This program comes with ABSOLUTELY NO WARRANTY [general in main_cli.py:65]
[2025-04-03 16:04:09,082 INFO] scenario queries_tutorial loaded for network mainnet [data in execution_data.py:836]
[2025-04-03 16:04:09,083 INFO] Executing scene mxops_scenes/single_pair_queries.yaml [execution in scene.py:148]
[2025-04-03 16:04:09,098 INFO] Query viewPair on erd1qqqqqqqqqqqqqpgqqz6vp9y50ep867vnr296mqf3dduh6guvmvlsu3sujc (onedex-swap) [execution in smart_contract.py:362]
[2025-04-03 16:04:09,208 INFO] Query results: {
"pair_9": {
"pair_id": 9,
"state": {
"__discriminant__": 1,
"__name__": "Active"
},
"enabled": true,
"owner": "erd1xkflzkx3hp52szy26zh9m5ts3v3j4dxhqkpxzj9npzp7wyp6qeysfpqz2m",
"first_token_id": "ONE-f9954f",
"second_token_id": "WEGLD-bd4d79",
"lp_token_id": "ONEWEGLD-892244",
"lp_token_decimal": 18,
"first_token_reserve": 1515337284792026638369995,
"second_token_reserve": 4338610389278931476333,
"lp_token_supply": 1295607106382727806181,
"lp_token_roles_are_set": true,
"unkown": 0,
"fees": 100
}
} [execution in smart_contract.py:390]
[2025-04-03 16:04:09,220 INFO] Setting variable `one_reserve` with the value `1515337284792026638369995` [execution in msc.py:137]
[2025-04-03 16:04:09,221 INFO] Setting variable `wegld_reserve` with the value `4338610389278931476333` [execution in msc.py:137]
[2025-04-03 16:04:09,224 INFO] Setting variable `pair_9_th_price` with the value `0.002863131814165311` [execution in msc.py:137]
[2025-04-03 16:04:09,237 INFO] Query getAmountOut on erd1qqqqqqqqqqqqqpgqqz6vp9y50ep867vnr296mqf3dduh6guvmvlsu3sujc (onedex-swap) [execution in smart_contract.py:362]
[2025-04-03 16:04:09,349 INFO] Query results: {
"pair_9_amount_out": 2834498644189293
} [execution in smart_contract.py:390]
[2025-04-03 16:04:09,361 INFO] Setting variable `pair_9_float_amount_out` with the value `0.002834498644189293` [execution in msc.py:137]
We obtained a theoretical price of 1 ONE = 0.00286 WEGLD and a swap estimation of 1 ONE -> 0.00283 WEGLD.
Note
There will always be a difference between the theoretical price and a swap estimation as the swap estimation will take into account the fees and the price impact of the swap.
π ConclusionΒΆ
Congratulation, you learned how to do simple queries a third party contract using its ABI definition and how to inspect the resulting data.
A second tutorial will help you to take things a bit further, by making more complex queries and by doing more advanced data manipulation. To follow it, head over to the queries 2 tutorial.
Do not hesitate to give us your feedback on this tutorial π