def test_send_message(self): # Checks if making an instance of message transaction correctly message_transaction = MessageTransactionBuilder()\ .from_(self.setting["from"])\ .to(self.setting["to"]) \ .step_limit(self.setting["step_limit"])\ .nid(self.setting["nid"]) \ .nonce(self.setting["nonce"])\ .data(self.setting["data"]).build() tx_dict = SignedTransaction.to_dict(message_transaction) self.assertTrue(is_message_transaction(tx_dict)) # Checks if sending transaction correctly signed_transaction_dict = SignedTransaction(message_transaction, self.wallet) result = self.icon_service.send_transaction(signed_transaction_dict) self.assertTrue(is_T_HASH(result)) # When having an optional property, nonce message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction_dict = SignedTransaction(message_transaction, self.wallet) result = self.icon_service.send_transaction(signed_transaction_dict) self.assertTrue(is_T_HASH(result)) # When address is wrong message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"][2:]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction_dict = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction_dict) # When not having a required property, nid message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"][2:]) \ .step_limit(self.setting["step_limit"]).data(self.setting["data"]).build() signed_transaction_dict = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction_dict) # When a sending address is wrong - not the wallet's address message_transaction = MessageTransactionBuilder().from_(self.setting["to"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction_dict = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction_dict)
def test_invalid(self, _make_id): # When data is not hex string with requests_mock.Mocker() as m: message_transaction = MessageTransactionBuilder() \ .from_(self.setting["from"]) \ .to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]) \ .nid(self.setting["nid"]) \ .nonce(self.setting["nonce"]) \ .data("test") # Raise DataTypeException self.assertRaises(DataTypeException, message_transaction.build) response_json = { "jsonrpc": "2.0", "error": { "code": -32602, "message": "Server error" }, "id": 1234 } m.post(self.matcher, json=response_json, status_code=400) # When address is wrong message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"][2:]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction) # When not having a required property, nid message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"][2:]) \ .step_limit(self.setting["step_limit"]).data(self.setting["data"]).build() signed_transaction = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction) # When a sending address is wrong - not the wallet's address message_transaction = MessageTransactionBuilder().from_(self.setting["to"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction)
def test_convert_tx_to_jsonrpc_request_for_message_transaction(self): # Message send msg_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( msg_transaction) self.assertTrue(is_message_transaction(tx_dict))
def test_send_message(self, _make_id): message_transaction = MessageTransactionBuilder() \ .from_(self.setting["from"]) \ .to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]) \ .nid(self.setting["nid"]) \ .nonce(self.setting["nonce"]) \ .data(self.setting["data"]) \ .timestamp(self.setting["timestamp"]) \ .build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( message_transaction) self.assertTrue(is_message_transaction(tx_dict)) signed_transaction = SignedTransaction(message_transaction, self.wallet) with requests_mock.Mocker() as m: tx_hash = "0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238" expected_request = { 'id': 1234, 'jsonrpc': '2.0', 'method': 'icx_sendTransaction', 'params': { 'data': self.setting["data"], 'dataType': 'message', 'from': self.setting["from"], 'nid': hex(self.setting["nid"]), 'nonce': hex(self.setting["nonce"]), 'timestamp': hex(self.setting["timestamp"]), 'signature': signed_transaction.signed_transaction_dict["signature"], 'stepLimit': hex(self.setting["step_limit"]), 'to': self.setting["to"], 'version': hex(3) } } response_json = {'jsonrpc': '2.0', 'result': tx_hash, 'id': 1234} m.post(self.matcher, json=response_json) result = self.icon_service.send_transaction(signed_transaction) self.assertTrue(is_T_HASH(result)) actual_request = json.loads(m._adapter.last_request.text) self.assertEqual(expected_request, actual_request)
def test_estimate_step_with_message_transaction(self): # Checks if making an instance of message transaction correctly message_transaction = MessageTransactionBuilder() \ .from_(self.setting["from"]) \ .to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]) \ .nid(self.setting["nid"]) \ .nonce(self.setting["nonce"]) \ .data(self.setting["data"]).build() self.assertEqual(102400, self.icon_service.estimate_step(message_transaction))
def test_to_dict(self): # Transfer # When having an optional property, nonce icx_transaction = TransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .value(self.setting["value"]).step_limit(self.setting["step_limit"]).nid(self.setting["nid"]) \ .nonce(self.setting["nonce"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( icx_transaction) self.assertTrue(is_icx_transaction(tx_dict)) # When not having an optional property, nonce icx_transaction = TransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .value(self.setting["value"]).step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( icx_transaction) self.assertTrue(is_icx_transaction(tx_dict)) # When not having an required property, value icx_transaction = TransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( icx_transaction) self.assertFalse(is_icx_transaction(tx_dict)) # Update SCORE deploy_transaction = DeployTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).content_type(self.setting["content_type"]) \ .content(self.setting["content_update"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( deploy_transaction) self.assertTrue(is_deploy_transaction(tx_dict)) # Install SCORE deploy_transaction = DeployTransactionBuilder().from_(self.setting["from"]).to(self.setting["to_install"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).nonce(self.setting["nonce"]) \ .content_type(self.setting["content_type"]).content(self.setting["content_install"]) \ .params(self.setting["params_install"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( deploy_transaction) self.assertTrue(is_deploy_transaction(tx_dict)) # SCORE method call call_transaction = CallTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).nonce(self.setting["nonce"]) \ .method(self.setting["method"]).params(self.setting["params_call"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( call_transaction) self.assertTrue(is_call_transaction(tx_dict)) # Message send msg_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request( msg_transaction) self.assertTrue(is_message_transaction(tx_dict))
def test_signed_transaction_with_message_transaction_without_step_limit( self): msg_transaction_without_step_limit = MessageTransactionBuilder() \ .from_(self.setting["from"]) \ .to(self.setting["to"]) \ .nid(self.setting["nid"]) \ .data(self.setting["data"]) \ .build() # fail without step limit self.assertRaises(DataTypeException, SignedTransaction, msg_transaction_without_step_limit, self.wallet)
def timestamp_tweet_body(self): prepared_tweet_body = self.prepare_tweet_body() tweet_body_hex = prepared_tweet_body.encode("utf-8").hex() transaction = MessageTransactionBuilder()\ .from_(wallet.get_address())\ .to(wallet.get_address())\ .data(f"0x{tweet_body_hex}")\ .nid(3)\ .build() estimate_step = icon_service.estimate_step(transaction) step_limit = estimate_step + 10000 signed_transaction = SignedTransaction(transaction, wallet, step_limit) tx_hash = icon_service.send_transaction(signed_transaction) self.check_tx_result(tx_hash) return tx_hash
def test_signed_transaction_with_message_transaction_without_step_limit( self): msg_transaction_without_step_limit = MessageTransactionBuilder().from_(self.setting["from"]).to( self.setting["to"]) \ .nid(self.setting["nid"]).data(self.setting["data"]).build() # fail without step limit self.assertRaises(DataTypeException, SignedTransaction, msg_transaction_without_step_limit, self.wallet) # success with param of step limit signed_transaction_dict = SignedTransaction( msg_transaction_without_step_limit, self.wallet, self.setting["step_limit"]) result = self.icon_service.send_transaction(signed_transaction_dict) self.assertTrue(is_T_HASH(result))
def get_transaction(conf: dict, params: dict): data_type = params.get('dataType') params_data = params.get('data', {}) try: transaction_params = { "from_": params['from'], "to": params['to'], "nid": convert_hex_str_to_int(conf['nid']), "value": convert_hex_str_to_int(params.get('value', "0x0")) } if data_type is None: transaction_builder = TransactionBuilder(**transaction_params) elif data_type == "call": transaction_params['method'] = params_data.get('method') transaction_params['params'] = params_data.get('params') transaction_builder = CallTransactionBuilder( **transaction_params) elif data_type == "deploy": transaction_params['content'] = params_data.get('content') transaction_params['content_type'] = params_data.get( 'contentType') transaction_params['params'] = params_data.get('params') transaction_builder = DeployTransactionBuilder(**params) elif data_type == "message": transaction_params['data'] = params_data transaction_builder = MessageTransactionBuilder( **transaction_params) elif data_type == "deposit": transaction_params['action'] = params_data.get('action') transaction_params['id'] = params_data.get('id') transaction_builder = DepositTransactionBuilder( **transaction_params) else: raise JsonContentsException("Invalid dataType") transaction = transaction_builder.build() except KeyError: raise JsonContentsException( "Invalid json content. check json contents") except TypeError: raise JsonContentsException("Invalid json content. check keys") except DataTypeException: raise JsonContentsException("Invalid json content. check values") else: return transaction
def test_estimate_step_with_message_transaction(self, _make_id): # Checks if making an instance of message transaction correctly message_transaction = MessageTransactionBuilder() \ .from_(self.setting["from"]) \ .to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]) \ .timestamp(self.setting["timestamp"]) \ .nid(self.setting["nid"]) \ .nonce(self.setting["nonce"]) \ .data(self.setting["data"]).build() with requests_mock.Mocker() as m: expected_step = 102_400 expected_request = { 'jsonrpc': '2.0', 'method': 'debug_estimateStep', 'id': 1234, 'params': { 'from': self.setting["from"], 'nid': hex(self.setting["nid"]), 'nonce': hex(self.setting["nonce"]), 'timestamp': hex(self.setting["timestamp"]), 'to': self.setting["to"], 'version': hex(self.version), 'data': self.setting["data"], 'dataType': 'message' } } response_json = { 'jsonrpc': '2.0', 'result': hex(expected_step), 'id': 1234 } m.post(self.matcher, json=response_json) result = self.icon_service.estimate_step(message_transaction) actual_request = json.loads(m._adapter.last_request.text) self.assertEqual(expected_request, actual_request) self.assertEqual(expected_step, result)
def process_message_tx(self, network: IconService = None, msg: str = "dummy", block_confirm_interval: int = -1) -> dict: if self._network_only and network is None: raise URLException("Set network URL") if block_confirm_interval == -1: block_confirm_interval = self._block_confirm_interval msg_byte = msg.encode('utf-8') # build message tx transaction = MessageTransactionBuilder() \ .from_(self._test1.get_address()) \ .to(self._test1.get_address()) \ .step_limit(10000000000) \ .nid(3) \ .nonce(100) \ .data(f"0x{msg_byte.hex()}") \ .build() # signing message tx request = SignedTransaction(transaction, self._test1) try: if network is not None: # Send the transaction to network tx_hash = network.send_transaction(request) sleep(block_confirm_interval) # Get transaction result tx_result = network.get_transaction_result(tx_hash) else: # process the transaction in local tx_results = self._process_transaction_in_local( request.signed_transaction_dict) except IconServiceBaseException as e: tx_result = e.message return tx_result
network: IconService, from_: 'KeyWallet', to_: Union['KeyWallet', str], step_limit: int = 10_000_000_000, msg: str = "dummy") -> list: if isinstance(to_, KeyWallet): to_ = to_.get_address() msg_byte = msg.encode('utf-8') # build message tx transaction = MessageTransactionBuilder() \ .from_(from_.get_address()) \ .to(to_) \ .step_limit(step_limit) \ .nid(3) \ .nonce(100) \ .data(f"0x{msg_byte.hex()}") \ .build() # signing message tx request = SignedTransaction(transaction, from_) tx_hashes: list = [network.send_transaction(request)] sleep(self._block_confirm_interval) return tx_hashes def get_txresults(self, network: IconService, tx_hashes: list) -> list: tx_results: list = [] for h in tx_hashes: tx_result = network.get_transaction_result(h)
header = "This timestamp of " + str(url) + " was taken at " + str(utc_datetime) + " UTC." + "\n\n" header_hex = header.encode("utf-8").hex() tx_message = header_hex + html_hex #Calculate transaction message length tx_message_length = len(tx_message) if tx_message_length > 509950: print("Sorry, this HTML page is too large to timestamp in an ICX transaction.") exit() elif tx_message_length <= 509950: keystore_location = input("What is the file path of your keystore file? ") keystore_password = input("What is your keystore password? ") keystore_location_str = keystore_location.rstrip() keystore_password_str = keystore_password.rstrip() #Create ICX transaction wallet = KeyWallet.load(keystore_location_str, keystore_password_str) transaction = MessageTransactionBuilder()\ .from_(wallet.get_address())\ .to(wallet.get_address())\ .step_limit(100000000)\ .data("0x" + tx_message)\ .nid(1)\ .build() icon_service = IconService(HTTPProvider("https://wallet.icon.foundation/api/v3")) signed_transaction = SignedTransaction(transaction, wallet) tx_hash = icon_service.send_transaction(signed_transaction) #Print success message with link to transaction on ICON tracker print("\nSuccess! View your timestamped HTML at the URL below.\nhttps://tracker.icon.foundation/transaction/" + tx_hash + "\n")
def test_send_message(self): sleep_time = 2 # Checks if making an instance of message transaction correctly message_transaction = MessageTransactionBuilder()\ .from_(self.setting["from"])\ .to(self.setting["to"]) \ .step_limit(self.setting["step_limit"])\ .nid(self.setting["nid"]) \ .nonce(self.setting["nonce"])\ .data(self.setting["data"]).build() tx_dict = SignedTransaction.convert_tx_to_jsonrpc_request(message_transaction) self.assertTrue(is_message_transaction(tx_dict)) # Checks if sending transaction correctly signed_transaction = SignedTransaction(message_transaction, self.wallet) result = self.icon_service.send_transaction(signed_transaction) self.assertTrue(is_T_HASH(result)) # When having an optional property, nonce sleep(sleep_time) message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction = SignedTransaction(message_transaction, self.wallet) result = self.icon_service.send_transaction(signed_transaction) self.assertTrue(is_T_HASH(result)) # When the data is hex string sleep(sleep_time) tx_result = self.icon_service.get_transaction_result(result) tx = self.icon_service.get_transaction(result) # Checks the transaction self.assertEqual(tx["data"], self.setting["data"]) block = self.icon_service.get_block(int(tx_result["blockHeight"])) # Checks the block's transaction self.assertEqual(block["confirmed_transaction_list"][0]["data"], self.setting["data"]) # When data is not hex string message_transaction = MessageTransactionBuilder() \ .from_(self.setting["from"]) \ .to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]) \ .nid(self.setting["nid"]) \ .nonce(self.setting["nonce"]) \ .data("test") # Raise DataTypeException self.assertRaises(DataTypeException, message_transaction.build) # When address is wrong message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"][2:]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction) # When not having a required property, nid message_transaction = MessageTransactionBuilder().from_(self.setting["from"]).to(self.setting["to"][2:]) \ .step_limit(self.setting["step_limit"]).data(self.setting["data"]).build() signed_transaction = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction) # When a sending address is wrong - not the wallet's address message_transaction = MessageTransactionBuilder().from_(self.setting["to"]).to(self.setting["to"]) \ .step_limit(self.setting["step_limit"]).nid(self.setting["nid"]).data(self.setting["data"]).build() signed_transaction = SignedTransaction(message_transaction, self.wallet) self.assertRaises(JSONRPCException, self.icon_service.send_transaction, signed_transaction)
def test_transaction_builder_from_dict(self): """Test for all kind of transaction builders to support for making each transaction from dict""" # case 0 for icx transaction : successful case with every fields of basic transaction input_transaction_as_dict = { "from_": self.transaction_as_setting["from_"], "to": self.transaction_as_setting["to"], "value": self.transaction_as_setting["value"], "step_limit": self.transaction_as_setting["step_limit"], "nid": self.transaction_as_setting["nid"], "nonce": self.transaction_as_setting["nonce"], "version": self.transaction_as_setting["version"], "timestamp": self.transaction_as_setting["timestamp"] } transaction = TransactionBuilder.from_dict( input_transaction_as_dict).build() transaction_as_dict = transaction.to_dict() self.assertTrue(self._is_icx_transaction(transaction_as_dict)) self.assertEqual(input_transaction_as_dict, transaction_as_dict) # case 1 for icx transaction : successful case without the optional field same as nid input_transaction_as_dict2 = deepcopy(input_transaction_as_dict) del input_transaction_as_dict2["nid"] transaction = TransactionBuilder.from_dict( input_transaction_as_dict2).build() transaction_as_dict = transaction.to_dict() self.assertTrue(self._is_icx_transaction(transaction_as_dict)) self.assertEqual(None, transaction_as_dict["nid"]) # case 2 for icx transaction : successful case without the 'step_limit' field for estimate step input_transaction_as_dict3 = deepcopy(input_transaction_as_dict) del input_transaction_as_dict3["step_limit"] transaction = TransactionBuilder.from_dict( input_transaction_as_dict3).build() transaction_as_dict = transaction.to_dict() self.assertTrue(self._is_icx_transaction(transaction_as_dict)) # case 0 for call transaction : successful case with every fields of call transaction input_call_transaction_as_dict = deepcopy(input_transaction_as_dict) tmp_other_fields = { "method": self.transaction_as_setting["method"], "params": { "key1": "value1" } } input_call_transaction_as_dict.update(tmp_other_fields) call_transaction = CallTransactionBuilder.from_dict( input_call_transaction_as_dict).build() call_transaction_as_dict = call_transaction.to_dict() self.assertTrue(self._is_call_transaction(call_transaction_as_dict)) # case 1 for call transaction : successful case without the optional field same as params input_call_transaction_as_dict2 = deepcopy( input_call_transaction_as_dict) del input_call_transaction_as_dict2["params"] call_transaction = CallTransactionBuilder.from_dict( input_call_transaction_as_dict2).build() call_transaction_as_dict = call_transaction.to_dict() self.assertTrue( isinstance( CallTransactionBuilder.from_dict( input_call_transaction_as_dict2), CallTransactionBuilder)) self.assertTrue(self._is_call_transaction(call_transaction_as_dict)) # case 2 for call transaction : failed case without the required field same as method input_call_transaction_as_dict3 = deepcopy( input_call_transaction_as_dict) del input_call_transaction_as_dict3["method"] self.assertRaises(DataTypeException, CallTransactionBuilder.from_dict, input_call_transaction_as_dict3) # case 0 for message transaction : failed case without the required field same as data input_message_transaction_as_dict = deepcopy(input_transaction_as_dict) self.assertRaises(DataTypeException, MessageTransactionBuilder.from_dict, input_message_transaction_as_dict) # case 1 for message transaction : successful case with every fields of message transaction tmp_other_fields = {'data': self.transaction_as_setting['data']} input_message_transaction_as_dict.update(tmp_other_fields) message_transaction = MessageTransactionBuilder.from_dict( input_message_transaction_as_dict).build() message_transaction_as_dict = message_transaction.to_dict() self.assertTrue( isinstance( MessageTransactionBuilder.from_dict( input_message_transaction_as_dict), MessageTransactionBuilder)) self.assertTrue( self._is_message_transaction(message_transaction_as_dict)) # case 0 for deploy transaction : successful case with every fields of deploy transaction input_deploy_transaction_as_dict = deepcopy(input_transaction_as_dict) tmp_other_fields = { 'content': self.transaction_as_setting['content_install'], 'content_type': self.transaction_as_setting['content_type'], 'params': { 'key1': 'value1' } } input_deploy_transaction_as_dict.update(tmp_other_fields) deploy_transaction = DeployTransactionBuilder.from_dict( input_deploy_transaction_as_dict).build() deploy_transaction_as_dict = deploy_transaction.to_dict() self.assertTrue( isinstance( DeployTransactionBuilder.from_dict( input_deploy_transaction_as_dict), DeployTransactionBuilder)) self.assertTrue( self._is_deploy_transaction(deploy_transaction_as_dict))