-
Notifications
You must be signed in to change notification settings - Fork 19
/
how_to_query.py
129 lines (96 loc) · 3.6 KB
/
how_to_query.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import argparse
import asyncio
import os
import pathlib
import pycspr
from pycspr import NodeRpcClient as NodeClient
from pycspr import NodeRpcConnectionInfo as NodeConnectionInfo
from pycspr.types.crypto import PrivateKey
from pycspr.types.crypto import PublicKey
from pycspr.types.cl import CLV_Key
# Path to CCTL assets.
_PATH_TO_CCTL_ASSETS = pathlib.Path(os.getenv("CCTL")) / "assets"
# CLI argument parser.
_ARGS = argparse.ArgumentParser("Demo illustrating how to qeury an ERC-20 smart contract.")
# CLI argument: path to contract operator public key - defaults to CCTL faucet.
_ARGS.add_argument(
"--operator-public-key-path",
default=_PATH_TO_CCTL_ASSETS / "faucet" / "public_key_hex",
dest="path_to_operator_public_key",
help="Path to operator's public_key_hex file.",
type=str,
)
# CLI argument: name of target chain - defaults to CCTL chain.
_ARGS.add_argument(
"--chain",
default="cspr-dev-cctl",
dest="chain_name",
help="Name of target chain.",
type=str,
)
# CLI argument: host address of target node - defaults to CCTL node 1.
_ARGS.add_argument(
"--node-host",
default="localhost",
dest="node_host",
help="Host address of target node.",
type=str,
)
# CLI argument: Node API JSON-RPC port - defaults to 11101 @ CCTL node 1.
_ARGS.add_argument(
"--node-port-rpc",
default=11101,
dest="node_port_rpc",
help="Node API JSON-RPC port. Typically 7777 on most nodes.",
type=int,
)
async def _main(args: argparse.Namespace):
"""Main entry point.
:param args: Parsed command line arguments.
"""
print("-" * 74)
print("PYCSPR :: How To Query For A Smart Contract Named Key")
print("-" * 74)
# Set node client.
client: NodeClient = _get_client(args)
# Set contract operator key.
operator = _get_operator_key(args)
# Set contract hash.
contract_hash: CLV_Key = await _get_contract_hash(client, operator)
# Issue queries.
token_decimals = await _get_contract_data(client, contract_hash, "decimals")
token_name = await _get_contract_data(client, contract_hash, "name")
token_symbol = await _get_contract_data(client, contract_hash, "symbol")
token_supply = await _get_contract_data(client, contract_hash, "total_supply")
print("-" * 72)
print(f"Token Decimals: {token_decimals}")
print(f"Token Name: {token_name}")
print(f"Token Symbol: {token_symbol}")
print(f"Token Supply: {token_supply}")
print("-" * 72)
def _get_client(args: argparse.Namespace) -> NodeClient:
"""Returns a pycspr client instance.
"""
return NodeClient(NodeConnectionInfo(args.node_host, args.node_port_rpc))
async def _get_contract_data(client: NodeClient, contract_hash: CLV_Key, key: str) -> bytes:
"""Queries chain for data associated with a contract.
"""
state_key = f"hash-{contract_hash.identifier.hex()}"
value = await client.get_state_item(state_key, key)
return value["CLValue"]["parsed"]
async def _get_contract_hash(client: NodeClient, operator: PrivateKey) -> CLV_Key:
"""Returns on-chain contract identifier.
"""
named_key = await client.get_account_named_key(operator.account_key, "ERC20")
if named_key is None:
raise ValueError("ERC-20 uninstalled ... see how_tos/how_to_install_a_contract.py")
return named_key
def _get_operator_key(args: argparse.Namespace) -> PublicKey:
"""Returns the smart contract operator's public key.
"""
return pycspr.parse_public_key(
args.path_to_operator_public_key,
)
# Entry point.
if __name__ == "__main__":
asyncio.run(_main(_ARGS.parse_args()))