def test_invoke_1(self): # test POST requests contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2' jsn = [ { 'type': str(ContractParameterType.String), 'value': 'name' }, { 'type': str(ContractParameterType.Array), 'value': [] } ] req = self._gen_post_rpc_req("invoke", params=[contract_hash, jsn]) res = json.loads(self.do_test_post("/", json=req)) self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT)) self.assertEqual(res['result']['gas_consumed'], '0.128') results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 1) self.assertEqual(results[0].Type, ContractParameterType.ByteArray) self.assertEqual(results[0].Value, bytearray(b'NEX Template V2')) # test GET requests url = self._gen_get_rpc_req("invoke", params=[contract_hash, jsn]) res = json.loads(self.do_test_get(url)) self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT)) self.assertEqual(res['result']['gas_consumed'], '0.128') results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 1) self.assertEqual(results[0].Type, ContractParameterType.ByteArray) self.assertEqual(results[0].Value, bytearray(b'NEX Template V2'))
def test_6_serialize_full_approve_payload(self): payload = ContractParameter(ContractParameterType.Array, [ ContractParameter(ContractParameterType.String, b'approve'), ContractParameter(ContractParameterType.ByteArray, self.addr_to), ContractParameter(ContractParameterType.ByteArray, self.addr_from), ContractParameter(ContractParameterType.ByteArray, b'x\xe0\x01') ]) sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload, self.contract_hash, 91349, self.event_tx, True, False) stream = StreamManager.GetStream() writer = BinaryWriter(stream) sc.Serialize(writer) out = bytes(stream.getvalue()) StreamManager.ReleaseStream(stream) new_event = SmartContractEvent.FromByteArray(out) self.assertEqual(new_event.event_type, sc.event_type) self.assertEqual(new_event.contract_hash, sc.contract_hash) self.assertEqual(new_event.test_mode, sc.test_mode) self.assertEqual(new_event.tx_hash, sc.tx_hash) self.assertEqual(new_event.block_number, sc.block_number) self.assertEqual(new_event.notify_type, b'approve') self.assertEqual(new_event.AddressFrom, 'AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs') self.assertEqual(new_event.AddressTo, 'ALb8FEhEmtSqv97fuNVuoLmcmrSKckffRf') self.assertEqual(new_event.Amount, 123000) self.assertEqual(new_event.is_standard_notify, True) self.assertEqual(new_event.ShouldPersist, True)
def test_2_serialize_single_notify_payload(self): sc = NotifyEvent( SmartContractEvent.RUNTIME_NOTIFY, ContractParameter( ContractParameterType.Array, [ContractParameter(ContractParameterType.String, b'hello')]), self.contract_hash, 99, self.event_tx, True, False) stream = StreamManager.GetStream() writer = BinaryWriter(stream) sc.Serialize(writer) out = bytes(stream.getvalue()) self.assertEqual( out, b'\x1cSmartContract.Runtime.Notify\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[c\x00\x00\x00\x90\xe4\xf1\xbbb\x8e\xf1\x07\xde\xe9\xf0\xd2\x12\xd1w\xbco\x844\x07=\x1b\xa7\x1f\xa7\x94`\x0b\xb4\x88|K\x05hello' ) StreamManager.ReleaseStream(stream) new_event = SmartContractEvent.FromByteArray(out) self.assertEqual(new_event.event_type, sc.event_type) self.assertEqual(new_event.contract_hash, sc.contract_hash) self.assertEqual(new_event.test_mode, sc.test_mode) self.assertEqual(new_event.tx_hash, sc.tx_hash) self.assertEqual(new_event.block_number, sc.block_number) self.assertEqual(new_event.notify_type, b'hello') self.assertEqual(new_event.AddressFrom, None) self.assertEqual(new_event.AddressTo, None) self.assertEqual(new_event.Amount, 0) self.assertEqual(new_event.is_standard_notify, False)
def test_3_serialize_single_transfer_notify_payload(self): sc = NotifyEvent( SmartContractEvent.RUNTIME_NOTIFY, ContractParameter( ContractParameterType.Array, [ContractParameter(ContractParameterType.String, b'transfer') ]), self.contract_hash, 99, self.event_tx, True, False) stream = StreamManager.GetStream() writer = BinaryWriter(stream) sc.Serialize(writer) out = bytes(stream.getvalue()) StreamManager.ReleaseStream(stream) new_event = SmartContractEvent.FromByteArray(out) self.assertEqual(new_event.event_type, sc.event_type) self.assertEqual(new_event.contract_hash, sc.contract_hash) self.assertEqual(new_event.test_mode, sc.test_mode) self.assertEqual(new_event.tx_hash, sc.tx_hash) self.assertEqual(new_event.block_number, sc.block_number) self.assertEqual(new_event.notify_type, b'transfer') self.assertEqual(new_event.AddressFrom, None) self.assertEqual(new_event.AddressTo, None) self.assertEqual(new_event.Amount, 0) self.assertEqual(new_event.is_standard_notify, False) self.assertEqual(new_event.ShouldPersist, False)
def test_5_serialize_full_refund_payload(self): payload = ContractParameter(ContractParameterType.Array, [ ContractParameter(ContractParameterType.String, b'refund'), ContractParameter(ContractParameterType.ByteArray, self.addr_to), ContractParameter(ContractParameterType.Integer, 123000) ]) sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload, self.contract_hash, 91349, self.event_tx, True, False) stream = StreamManager.GetStream() writer = BinaryWriter(stream) sc.Serialize(writer) out = bytes(stream.getvalue()) StreamManager.ReleaseStream(stream) new_event = SmartContractEvent.FromByteArray(out) self.assertEqual(new_event.event_type, sc.event_type) self.assertEqual(new_event.contract_hash, sc.contract_hash) self.assertEqual(new_event.test_mode, sc.test_mode) self.assertEqual(new_event.tx_hash, sc.tx_hash) self.assertEqual(new_event.block_number, sc.block_number) self.assertEqual(new_event.notify_type, b'refund') self.assertEqual(new_event.AddressTo, 'AKZmSGPD7ytJBbxpRPmobYGLNxdWH3Jiqs') self.assertEqual(new_event.addr_from, sc.contract_hash) self.assertEqual(new_event.Amount, 123000) self.assertEqual(new_event.is_standard_notify, True)
def ExecutionCompleted(self, engine, success, error=None): height = Blockchain.Default().Height + 1 tx_hash = None if engine.ScriptContainer: tx_hash = engine.ScriptContainer.Hash if not tx_hash: tx_hash = UInt256(data=bytearray(32)) entry_script = None try: # get the first script that was executed # this is usually the script that sets up the script to be executed entry_script = UInt160(data=engine.ExecutedScriptHashes[0]) # ExecutedScriptHashes[1] will usually be the first contract executed if len(engine.ExecutedScriptHashes) > 1: entry_script = UInt160(data=engine.ExecutedScriptHashes[1]) except Exception as e: logger.error("Could not get entry script: %s " % e) payload = ContractParameter(ContractParameterType.Array, value=[]) for item in engine.EvaluationStack.Items: payload.Value.append(ContractParameter.ToParameter(item)) if success: # dispatch all notify events, along with the success of the contract execution for notify_event_args in self.notifications: self.events_to_dispatch.append(NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, notify_event_args.State, notify_event_args.ScriptHash, height, tx_hash, success, engine.testMode)) if engine.Trigger == Application: self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.EXECUTION_SUCCESS, payload, entry_script, height, tx_hash, success, engine.testMode)) else: self.events_to_dispatch.append(SmartContractEvent(SmartContractEvent.VERIFICATION_SUCCESS, payload, entry_script, height, tx_hash, success, engine.testMode)) else: payload.Value.append(ContractParameter(ContractParameterType.String, error)) payload.Value.append(ContractParameter(ContractParameterType.String, engine._VMState)) if engine.Trigger == Application: self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.EXECUTION_FAIL, payload, entry_script, height, tx_hash, success, engine.testMode)) else: self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.VERIFICATION_FAIL, payload, entry_script, height, tx_hash, success, engine.testMode)) self.notifications = []
def test_3_should_persist(self): payload = ContractParameter(ContractParameterType.Array, [ ContractParameter(ContractParameterType.String, b'transfer'), ContractParameter(ContractParameterType.ByteArray, self.addr_to), ContractParameter(ContractParameterType.ByteArray, self.addr_from), ContractParameter(ContractParameterType.Integer, 123000) ]) sc = NotifyEvent(SmartContractEvent.RUNTIME_NOTIFY, payload, self.contract_hash, 91349, self.event_tx, True, False) ndb = NotificationDB.instance() ndb.on_smart_contract_event(sc) self.assertEqual(len(ndb.current_events), 1) ndb.on_persist_completed(None)
def test_1_serialize_runtime_log(self): sc = SmartContractEvent( SmartContractEvent.RUNTIME_LOG, ContractParameter(ContractParameterType.Array, []), self.contract_hash, 99999, self.event_tx, True, False) stream = StreamManager.GetStream() writer = BinaryWriter(stream) sc.Serialize(writer) out = bytes(stream.getvalue()) self.assertEqual( out, b'\x19SmartContract.Runtime.Log\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[\x9f\x86\x01\x00\x90\xe4\xf1\xbbb\x8e\xf1\x07\xde\xe9\xf0\xd2\x12\xd1w\xbco\x844\x07=\x1b\xa7\x1f\xa7\x94`\x0b\xb4\x88|K' ) StreamManager.ReleaseStream(stream) new_event = SmartContractEvent.FromByteArray(out) self.assertEqual(new_event.event_type, sc.event_type) self.assertEqual(new_event.contract_hash, sc.contract_hash) self.assertEqual(new_event.test_mode, sc.test_mode) self.assertEqual(new_event.tx_hash, sc.tx_hash) self.assertEqual(new_event.block_number, sc.block_number)
def Contract_Destroy(self, engine): hash = UInt160(data=engine.CurrentContext.ScriptHash()) contract = self.Snapshot.Contracts.TryGet(hash.ToBytes()) if contract is not None: self.Snapshot.Contracts.Delete(hash.ToBytes()) if contract.HasStorage: to_del = [] for k, v in self.Snapshot.Storages.Find(hash.ToArray()): storage_key = StorageKey(script_hash=hash, key=k[20:]) # Snapshot.Storages.Delete() modifies the underlying dictionary of the cache we'd be iterating # over using Storages.Find. We therefore need to postpone deletion to_del.append(storage_key) for storage_key in to_del: self.Snapshot.Storages.Delete(storage_key.ToArray()) self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.CONTRACT_DESTROY, ContractParameter( ContractParameterType.InteropInterface, contract), hash, GetBlockchain().Height + 1, engine.ScriptContainer.Hash if engine.ScriptContainer else None, test_mode=engine.testMode)) return True
def test_invoke_2(self): contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654' jsn = [ { 'type': str(ContractParameterType.String), 'value': 'balanceOf' }, { 'type': str(ContractParameterType.Array), 'value': [ { 'type': str(ContractParameterType.ByteArray), 'value': bytearray(b'\xec\xa8\xfc\xf9Nz*\x7f\xc3\xfdT\xae\x0e\xd3\xd3MR\xec%\x90').hex() } ] } ] req = self._gen_rpc_req("invoke", params=[contract_hash, jsn]) mock_req = mock_request(json.dumps(req).encode("utf-8")) res = json.loads(self.app.home(mock_req)) self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK) results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 1) self.assertEqual(results[0].Type, ContractParameterType.ByteArray) self.assertEqual(results[0].Value, bytearray(b'\xe9\x0f\x80\xbb\x04\x90\x00'))
def DoRun(contract_script, arguments, wallet, path, verbose=True, from_addr=None, min_fee=DEFAULT_MIN_FEE): test = get_arg(arguments, 1) if test is not None and test == 'test': if wallet is not None: f_args = arguments[2:] i_args = arguments[6:] script = GatherLoadedContractParams(f_args, contract_script) tx, result, total_ops, engine = test_deploy_and_invoke( script, i_args, wallet, from_addr, min_fee) i_args.reverse() return_type_results = [] try: rtype = ContractParameterType.FromString(f_args[1]) for r in result: cp = ContractParameter.AsParameterType(rtype, r) return_type_results.append(cp.ToJson()) except Exception as e: logger.error( 'Could not convert result to ContractParameter: %s ' % e) if tx is not None and result is not None: if verbose: print( "\n-----------------------------------------------------------" ) print("Calling %s with arguments %s " % (path, i_args)) print("Test deploy invoke successful") print("Used total of %s operations " % total_ops) print("Result %s " % return_type_results) print("Invoke TX gas cost: %s " % (tx.Gas.value / Fixed8.D)) print( "-------------------------------------------------------------\n" ) return tx, result, total_ops, engine else: if verbose: print("Test invoke failed") print("tx is, results are %s %s " % (tx, result)) else: print("please open a wallet to test built contract") return None, None, None, None
def Contract_Destroy(self, engine): hash = UInt160(data=engine.CurrentContext.ScriptHash()) contract = self._contracts.TryGet(hash.ToBytes()) if contract is not None: self._contracts.Remove(hash.ToBytes()) if contract.HasStorage: for pair in self._storages.Find(hash.ToBytes()): self._storages.Remove(pair.Key) self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.CONTRACT_DESTROY, ContractParameter( ContractParameterType.InteropInterface, contract), hash, Blockchain.Default().Height + 1, engine.ScriptContainer.Hash if engine.ScriptContainer else None, test_mode=engine.testMode)) return True
def test_2_persist_isnt_notify_event(self): sc = SmartContractEvent(SmartContractEvent.RUNTIME_NOTIFY, ContractParameter(ContractParameterType.Array, []), self.contract_hash, 99, self.event_tx, True, False) ndb = NotificationDB.instance() ndb.on_smart_contract_event(sc) self.assertEqual(ndb.current_events, [])
def Runtime_Log(self, engine: ExecutionEngine): item = engine.CurrentContext.EvaluationStack.Pop() # will raise an exception for types that don't support it item.GetByteArray() # if we pass we can call the convenience method to pretty print the data message = item.GetString() hash = UInt160(data=engine.CurrentContext.ScriptHash()) tx_hash = None if engine.ScriptContainer: tx_hash = engine.ScriptContainer.Hash engine.write_log(str(message)) # Build and emit smart contract event self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.RUNTIME_LOG, ContractParameter(ContractParameterType.String, value=message), hash, GetBlockchain().Height + 1, tx_hash, test_mode=engine.testMode)) return True
def Storage_Delete(self, engine: ExecutionEngine): if self.Trigger != TriggerType.Application and self.Trigger != TriggerType.ApplicationR: return False context = engine.CurrentContext.EvaluationStack.Pop().GetInterface( neo.SmartContract.StorageContext.StorageContext) if not self.CheckStorageContext(context): return False if context.IsReadOnly: return False key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray() storage_key = StorageKey(script_hash=context.ScriptHash, key=key) if type(engine) == ExecutionEngine: test_mode = False else: test_mode = engine.testMode self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.STORAGE_DELETE, ContractParameter(ContractParameterType.String, key), context.ScriptHash, GetBlockchain().Height + 1, engine.ScriptContainer.Hash if engine.ScriptContainer else None, test_mode=test_mode)) item = self.Snapshot.Storages.TryGet(storage_key.ToArray()) if item and item.IsConstant: return False self.Snapshot.Storages.Delete(storage_key.ToArray()) return True
def Storage_Delete(self, engine: ExecutionEngine): context = engine.CurrentContext.EvaluationStack.Pop().GetInterface() if not self.CheckStorageContext(context): return False key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray() storage_key = StorageKey(script_hash=context.ScriptHash, key=key) keystr = key if len(key) == 20: keystr = Crypto.ToAddress(UInt160(data=key)) self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.STORAGE_DELETE, ContractParameter(ContractParameterType.String, keystr), context.ScriptHash, Blockchain.Default().Height + 1, engine.ScriptContainer.Hash if engine.ScriptContainer else None, test_mode=engine.testMode)) self._storages.Remove(storage_key.ToArray()) return True
def __init__(self, event_type, event_payload, contract_hash, block_number, tx_hash, execution_success=False, test_mode=False): if event_payload and not isinstance(event_payload, ContractParameter): raise Exception("Event payload must be ContractParameter") self.event_type = event_type self.event_payload = event_payload self.contract_hash = contract_hash self.block_number = block_number self.tx_hash = tx_hash self.execution_success = execution_success self.test_mode = test_mode self.token = None if not self.event_payload: self.event_payload = ContractParameter(ContractParameterType.Array, value=[]) if self.event_type in [ SmartContractEvent.CONTRACT_CREATED, SmartContractEvent.CONTRACT_MIGRATED ]: if self.event_payload.Type == ContractParameterType.InteropInterface: self.contract = self.event_payload.Value
def test_invoke_2(self): contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2' jsn = [ { 'type': str(ContractParameterType.String), 'value': 'balanceOf' }, { 'type': str(ContractParameterType.Array), 'value': [ { 'type': str(ContractParameterType.ByteArray), 'value': bytearray(b'#\xba\'\x03\xc52c\xe8\xd6\xe5"\xdc2 39\xdc\xd8\xee\xe9').hex() } ] } ] req = self._gen_post_rpc_req("invoke", params=[contract_hash, jsn]) res = json.loads(self.do_test_post("/", json=req)) self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT)) results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 1) self.assertEqual(results[0].Type, ContractParameterType.ByteArray) self.assertEqual(results[0].Value, bytearray(b'\x00\x90\x8c\xd4v\xe2\x00'))
def get_invoke_result(self, script, container=None): appengine = ApplicationEngine.Run(script=script, container=container) return { "script": script.decode('utf-8'), "state": VMStateStr(appengine.State), "gas_consumed": appengine.GasConsumed().ToString(), "stack": [ContractParameter.ToParameter(item).ToJson() for item in appengine.EvaluationStack.Items] }
def get_invoke_result(self, script): appengine = ApplicationEngine.Run(script=script) return { "script": script.hex(), "state": appengine.State, "gas_consumed": appengine.GasConsumed().ToString(), "stack": [ContractParameter.ToParameter(item).ToJson() for item in appengine.EvaluationStack.Items] }
def get_invoke_result(self, script): snapshot = GetBlockchain()._db.createSnapshot() appengine = ApplicationEngine.Run(snapshot, script=script) return { "script": script.decode('utf-8'), "state": VMStateStr(appengine.State), "gas_consumed": appengine.GasConsumed().ToString(), "stack": [ContractParameter.ToParameter(item).ToJson() for item in appengine.ResultStack.Items] }
def test_invoke_3(self): contract_hash = 'b9fbcff6e50fd381160b822207231233dd3c56c2' req = self._gen_post_rpc_req("invokefunction", params=[contract_hash, 'symbol']) res = json.loads(self.do_test_post("/", json=req)) self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT)) results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 1) self.assertEqual(results[0].Type, ContractParameterType.ByteArray) self.assertEqual(results[0].Value, bytearray(b'NXT2'))
def Storage_Get(self, engine): context = None try: item = engine.EvaluationStack.Pop() context = item.GetInterface() except Exception as e: logger.error("could not get storage context %s " % e) return False if not self.CheckStorageContext(context): return False key = engine.EvaluationStack.Pop().GetByteArray() storage_key = StorageKey(script_hash=context.ScriptHash, key=key) item = self.Storages.TryGet(storage_key.ToArray()) keystr = key valStr = bytearray(0) if item is not None: valStr = bytearray(item.Value) if len(key) == 20: keystr = Crypto.ToAddress(UInt160(data=key)) try: valStr = int.from_bytes(valStr, 'little') except Exception as e: logger.error("Could not convert %s to number: %s " % (valStr, e)) if item is not None: engine.EvaluationStack.PushT(bytearray(item.Value)) else: engine.EvaluationStack.PushT(bytearray(0)) tx_hash = None if engine.ScriptContainer: tx_hash = engine.ScriptContainer.Hash self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.STORAGE_GET, ContractParameter(ContractParameterType.String, value='%s -> %s' % (keystr, valStr)), context.ScriptHash, Blockchain.Default().Height + 1, tx_hash, test_mode=engine.testMode)) return True
def test_invoke_contract(self, args): if not self.Wallet: print("Please open a wallet") return args, from_addr = get_from_addr(args) args, invoke_attrs = get_tx_attr_from_args(args) args, owners = get_owners_from_params(args) if args and len(args) > 0: tx, fee, results, num_ops = TestInvokeContract( self.Wallet, args, from_addr=from_addr, invoke_attrs=invoke_attrs, owners=owners) if tx is not None and results is not None: parameterized_results = [ ContractParameter.ToParameter(item) for item in results ] print( "\n-------------------------------------------------------------------------------------------------------------------------------------" ) print("Test invoke successful") print("Total operations: %s" % num_ops) print("Results %s" % [item.ToJson() for item in parameterized_results]) print("Invoke TX GAS cost: %s" % (tx.Gas.value / Fixed8.D)) print("Invoke TX fee: %s" % (fee.value / Fixed8.D)) print( "-------------------------------------------------------------------------------------------------------------------------------------\n" ) print( "Enter your password to continue and invoke on the network\n" ) tx.Attributes = invoke_attrs passwd = prompt("[password]> ", is_password=True) if not self.Wallet.ValidatePassword(passwd): return print("Incorrect password") InvokeContract(self.Wallet, tx, fee, from_addr=from_addr, owners=owners) return else: print("Error testing contract invoke") return print("Please specify a contract to invoke")
def test_invoke_3(self): contract_hash = 'd7678dd97c000be3f33e9362e673101bac4ca654' req = self._gen_rpc_req("invokefunction", params=[contract_hash, 'symbol']) mock_req = mock_request(json.dumps(req).encode("utf-8")) res = json.loads(self.app.home(mock_req)) self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK) results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 1) self.assertEqual(results[0].Type, ContractParameterType.ByteArray) self.assertEqual(results[0].Value, bytearray(b'LWTF'))
def test_invoke_5(self): test_script = '00046e616d656754a64cac1b1073e662933ef3e30b007cd98d67d7000673796d626f6c6754a64cac1b1073e662933ef3e30b007cd98d67d70008646563696d616c736754a64cac1b1073e662933ef3e30b007cd98d67d7' req = self._gen_rpc_req("invokescript", params=[test_script]) mock_req = mock_request(json.dumps(req).encode("utf-8")) res = json.loads(self.app.home(mock_req)) self.assertEqual(res['result']['state'], VMState.HALT + VMState.BREAK) results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 3) self.assertEqual(results[0].Value, bytearray(b'LOCALTOKEN')) self.assertEqual(results[1].Value, bytearray(b'LWTF')) self.assertEqual(results[2].Value, 8)
def test_invoke_5(self): test_script = "00046e616d6567c2563cdd3312230722820b1681d30fe5f6cffbb9000673796d626f6c67c2563cdd3312230722820b1681d30fe5f6cffbb90008646563696d616c7367c2563cdd3312230722820b1681d30fe5f6cffbb9" req = self._gen_post_rpc_req("invokescript", params=[test_script]) res = json.loads(self.do_test_post("/", json=req)) self.assertEqual(res['result']['state'], VMStateStr(VMState.HALT)) results = [] for p in res['result']['stack']: results.append(ContractParameter.FromJson(p)) self.assertEqual(len(results), 3) self.assertEqual(results[0].Value, bytearray(b'NEX Template V2')) self.assertEqual(results[1].Value, bytearray(b'NXT2')) self.assertEqual(results[2].Value, 8)
def execute(self, arguments): wallet = PromptData.Wallet if not wallet: print("Please open a wallet") return False arguments, from_addr = PromptUtils.get_from_addr(arguments) arguments, invoke_attrs = PromptUtils.get_tx_attr_from_args(arguments) arguments, owners = PromptUtils.get_owners_from_params(arguments) if len(arguments) < 1: print("Please specify the required parameters") return False hash_string = arguments[0] try: script_hash = UInt160.ParseString(hash_string) except Exception: # because UInt160 throws a generic exception. Should be fixed in the future print("Invalid script hash") return False tx, fee, results, num_ops, engine_success = TestInvokeContract(wallet, arguments, from_addr=from_addr, invoke_attrs=invoke_attrs, owners=owners) if tx and results: parameterized_results = [ContractParameter.ToParameter(item).ToJson() for item in results] print( "\n-------------------------------------------------------------------------------------------------------------------------------------") print("Test invoke successful") print(f"Total operations: {num_ops}") print(f"Results {str(parameterized_results)}") print(f"Invoke TX GAS cost: {tx.Gas.value / Fixed8.D}") print(f"Invoke TX fee: {fee.value / Fixed8.D}") print( "-------------------------------------------------------------------------------------------------------------------------------------\n") print("Enter your password to continue and invoke on the network\n") tx.Attributes = invoke_attrs passwd = prompt("[password]> ", is_password=True) if not wallet.ValidatePassword(passwd): return print("Incorrect password") return InvokeContract(wallet, tx, fee, from_addr=from_addr, owners=owners) else: print("Error testing contract invoke") return False
def Storage_Put(self, engine: ExecutionEngine): context = None try: context = engine.CurrentContext.EvaluationStack.Pop().GetInterface( ) except Exception as e: logger.error("Storage Context Not found on stack") return False if not self.CheckStorageContext(context): return False key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray() if len(key) > 1024: return False value = engine.CurrentContext.EvaluationStack.Pop().GetByteArray() new_item = StorageItem(value=value) storage_key = StorageKey(script_hash=context.ScriptHash, key=key) item = self._storages.ReplaceOrAdd(storage_key.ToArray(), new_item) keystr = key valStr = bytearray(item.Value) if len(key) == 20: keystr = Crypto.ToAddress(UInt160(data=key)) try: valStr = int.from_bytes(valStr, 'little') except Exception as e: pass self.events_to_dispatch.append( SmartContractEvent( SmartContractEvent.STORAGE_PUT, ContractParameter(ContractParameterType.String, '%s -> %s' % (keystr, valStr)), context.ScriptHash, Blockchain.Default().Height + 1, engine.ScriptContainer.Hash if engine.ScriptContainer else None, test_mode=engine.testMode)) return True
def get_invoke_result_balance(self, script): appengine = ApplicationEngine.Run(script=script) val = appengine.EvaluationStack.Items[0].GetBigInteger() balance = Decimal(val) return { "script": script.decode('utf-8'), "state": VMStateStr(appengine.State), "gas_consumed": appengine.GasConsumed().ToString(), "stack": [ ContractParameter.ToParameter(item).ToJson() for item in appengine.EvaluationStack.Items ], "balance": str(balance) }