def totalsupply(conf: dict): """Query total supply of ICX :param conf: totalsupply command configuration """ uri, version = uri_parser(conf['uri']) icon_service = IconService(HTTPProvider(uri, version)) response = icon_service.get_total_supply(True) if "error" in response: print('Got an error response') print(json.dumps(response, indent=4)) else: print(f'Total supply of ICX in hex: {response["result"]}') print(f'Total supply of ICX in decimal: {int(response["result"], 16)}') return response
class Sync: PREPS = TEST_ACCOUNTS[:4] def __init__(self): self.handlers = [ self._set_revision, self._update_governance_score, self._set_step_cost, ] self.revision = 0 self.gs_version = "0.0.0" self.key_wallet = KeyWallet.load(bytes.fromhex(TEST1_PRIVATE_KEY)) self.preps = [] for prep in self.PREPS: self.preps.append(KeyWallet.load(prep)) uri, version = uri_parser("http://127.0.0.1:9000/api/v3") self.icon_service = IconService(HTTPProvider(uri, version)) def apply(self): # get status response = self._get_revision() self.revision = int(response.get("code", "0x0"), 16) # start sync for i, action in enumerate(sync_list): print("") type_: int = action.get("type", -1) params = action.get("params", {}) self.handlers[type_](params) @staticmethod def archive(): root = "./" with tarfile.open('mainnet.tar.gz', 'w:gz') as tar: for dir in [".score", ".statedb"]: for _, _, files in os.walk(os.path.join(root, dir)): for f in files: tar.add(os.path.join(root, dir, f), arcname=f) def _is_network_proposal_enabled(self): return self.revision >= Revision.DECENTRALIZATION.value and self.gs_version >= "1.0.0" def _set_revision(self, params: dict): revision = int(params.get('code'), 16) print(f"## Set revision {revision}") if self.revision > revision: print(f"pass revision {revision}. {revision} < {self.revision}") return if not self._is_network_proposal_enabled(): # send setRevision TX tx_hash = self._call_tx(key_wallet=self.key_wallet, to=GOVERNANCE_ADDRESS, method='setRevision', params=params) print(f"transaction hash: {tx_hash}") else: # register setRevision network proposal and approve it register = self.preps[0] np_id = self._register_proposal_tx( key_wallet=register, title=f"set revision {revision}", desc=f"T-Bears set revision {revision}", type=1, value_dict=params) for prep in self.preps: if prep == register: continue tx_hash = self._vote_proposal_tx(key_wallet=prep, id_=np_id, vote=1) debug_print( f"{prep.get_address()} votes agree to {np_id}. transaction hash: {tx_hash}" ) print(f"Network proposal ID: {np_id}") self.revision = revision if self.revision == Revision.IISS.value: # make 4 P-Reps for network proposal self._make_preps(self.preps) if self.revision == Revision.DECENTRALIZATION.value: response = self._call(to=SYSTEM_ADDRESS, method="getIISSInfo") block_height = int(response.get("blockHeight"), 16) next_calc = int(response.get("nextCalculation"), 16) wait_time = (next_calc - block_height) * 2 print(f"Wait decentralization..... {wait_time} secs") sleep(wait_time) while True: response = self._call(to=SYSTEM_ADDRESS, method="getIISSInfo") print(response.get("nextPRepTerm")) if response.get("nextPRepTerm", "0x0") != "0x0": print(f"Decentralization is done.") break else: sleep(1) def _update_governance_score(self, params: dict): version = params.get('version') print(f"## Update governance SCORE to {version}") path = os.path.join(DIR_PATH, f"data/governance_{version}.zip") self._deploy_score(key_wallet=self.key_wallet, score_address=GOVERNANCE_ADDRESS, path=path) self.gs_version = version def _set_step_cost(self, params: dict): step_type = params.get('stepType') cost = params.get('cost') print(f"## Set stepCost.{step_type} to {cost}") if not self._is_network_proposal_enabled(): # send setStepCost TX tx_hash = self._call_tx(key_wallet=self.key_wallet, to=GOVERNANCE_ADDRESS, method='setStepCost', params=params) print(f"transaction hash: {tx_hash}") else: # TODO send setStepCost network proposal and approve it print(f"Network proposal : ID") def _deploy_score( self, key_wallet: 'KeyWallet', path: str, score_address: str = SYSTEM_ADDRESS, ) -> dict: # Generates an instance of transaction for deploying SCORE. transaction = DeployTransactionBuilder() \ .from_(key_wallet.get_address()) \ .to(score_address) \ .step_limit(100_000_000_000) \ .nid(3) \ .nonce(100) \ .content_type("application/zip") \ .content(gen_deploy_data_content(path)) \ .build() # Returns the signed transaction object having a signature signed_transaction = SignedTransaction(transaction, key_wallet) # send transaction return self.icon_service.send_transaction(signed_transaction) def _call(self, to: str, method: str, params: dict = {}) -> Union[dict, str]: call = CallBuilder() \ .from_(self.key_wallet.get_address()) \ .to(to) \ .method(method) \ .params(params) \ .build() return self.icon_service.call(call) def _tx(self, key_wallet: 'KeyWallet', to: str, value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> str: transaction = TransactionBuilder() \ .from_(key_wallet.get_address()) \ .to(to) \ .value(value) \ .step_limit(step_limit) \ .nid(nid) \ .nonce(nonce) \ .build() # Returns the signed transaction object having a signature signed_transaction = SignedTransaction(transaction, key_wallet) # Send transaction return self.icon_service.send_transaction(signed_transaction) def _call_tx(self, key_wallet: 'KeyWallet', to: str, method: str, params: dict = {}, value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> str: transaction = CallTransactionBuilder() \ .from_(key_wallet.get_address()) \ .to(to) \ .value(value) \ .step_limit(step_limit) \ .nid(nid) \ .nonce(nonce) \ .method(method) \ .params(params) \ .build() # Returns the signed transaction object having a signature signed_transaction = SignedTransaction(transaction, key_wallet) # Send transaction return self.icon_service.send_transaction(signed_transaction) def _get_revision(self) -> dict: try: return self._call(to=GOVERNANCE_ADDRESS, method="getRevision") except JSONRPCException: return {"code": "0x0", "name": "0.0.0"} def _register_proposal_tx(self, key_wallet: 'KeyWallet', title: str, desc: str, type: int, value_dict: dict, value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> str: params = { "title": title, "description": desc, "type": hex(type), "value": "0x" + bytes.hex(json.dumps(value_dict).encode()) } return self._call_tx(key_wallet=key_wallet, to=GOVERNANCE_ADDRESS, method="registerProposal", params=params, value=value, step_limit=step_limit, nid=nid, nonce=nonce) def _vote_proposal_tx(self, key_wallet: 'KeyWallet', id_: str, vote: int, value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'str': params = {"id": id_, "vote": hex(vote)} return self._call_tx(key_wallet=key_wallet, to=GOVERNANCE_ADDRESS, method="voteProposal", params=params, value=value, step_limit=step_limit, nid=nid, nonce=nonce) def _make_preps(self, preps: List[KeyWallet]): print(f"#### make P-Reps") delegate_value = self.icon_service.get_total_supply() * 2 // 1000 transfer_value = delegate_value + 3000 * ICX for prep in preps: # transfer ICX tx_hash = self._tx(key_wallet=self.key_wallet, to=prep.get_address(), value=transfer_value) debug_print( f"transfer {transfer_value} to {prep.get_address()} tx_hash: {tx_hash}" ) while True: sleep(1) balance = self.icon_service.get_balance(preps[0].get_address()) if balance >= transfer_value: break for prep in preps: # register P-Rep name = f"node{prep.get_address()}" params = { ConstantKeys.NAME: name, ConstantKeys.COUNTRY: "KOR", ConstantKeys.CITY: "Unknown", ConstantKeys.EMAIL: f"{name}@example.com", ConstantKeys.WEBSITE: f"https://{name}.example.com", ConstantKeys.DETAILS: f"https://{name}.example.com/details", ConstantKeys.P2P_ENDPOINT: f"{name}.example.com:7100", } tx_hash = self._call_tx(key_wallet=prep, to=SYSTEM_ADDRESS, value=2000 * ICX, method="registerPRep", params=params) debug_print(f"register {prep.get_address()} tx_hash: {tx_hash}") # stake tx_hash = self._call_tx(key_wallet=prep, to=SYSTEM_ADDRESS, method="setStake", params={"value": hex(delegate_value)}) debug_print(f"set stake {prep.get_address()} tx_hash: {tx_hash}") # delegate tx_hash = self._call_tx(key_wallet=prep, to=SYSTEM_ADDRESS, method="setDelegation", params={ "delegations": [{ "address": prep.get_address(), "value": hex(delegate_value) }] }) debug_print(f"delegate {prep.get_address()} tx_hash: {tx_hash}") while True: sleep(1) response = self._call(to=SYSTEM_ADDRESS, method="getPReps") if len(response.get("preps", 0)) > 0: print(f"make 4 P-Reps") for prep in preps: address = prep.get_address() resp = self._call(to=SYSTEM_ADDRESS, method="getPRep", params={"address": address}) print( f" - {address}, delegated: {int(resp.get('delegated'), 16)//ICX:,} ICX" ) print(self._call(to=SYSTEM_ADDRESS, method="getIISSInfo")) break def check_revision(self) -> int: current_revision = int(self._get_revision().get("code"), 16) latest_revision = self._get_latest_revision() return current_revision - latest_revision @staticmethod def _get_latest_revision() -> int: for cmd in reversed(sync_list): if cmd.get("type") == SyncType.REVISION: return int(cmd["params"]["code"], 16) return 0