private void BuildMethodTable() { var type = this.GetType(); var srcMethods = type.GetMethods(BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance); var methods = new List <ContractMethod>(); var ignore = new HashSet <string>(new string[] { "ToString", "GetType", "Equals", "GetHashCode", "CallMethod", "SetTransaction" }); foreach (var srcMethod in srcMethods) { var parameters = new List <ContractParameter>(); var srcParams = srcMethod.GetParameters(); var methodName = srcMethod.Name; if (methodName.StartsWith("get_")) { methodName = methodName.Substring(4); } if (ignore.Contains(methodName)) { continue; } var isVoid = srcMethod.ReturnType == typeof(void); var returnType = isVoid ? VMType.None : VMObject.GetVMType(srcMethod.ReturnType); bool isValid = isVoid || returnType != VMType.None; if (!isValid) { continue; } foreach (var srcParam in srcParams) { var paramType = srcParam.ParameterType; var vmtype = VMObject.GetVMType(paramType); if (vmtype != VMType.None) { parameters.Add(new ContractParameter(srcParam.Name, vmtype)); } else { isValid = false; break; } } if (isValid) { _methodTable[methodName] = srcMethod; var method = new ContractMethod(methodName, returnType, parameters.ToArray()); methods.Add(method); } } this.ABI = new ContractInterface(methods); }
private static VMObject ExecuteScript(Chain chain, byte[] script, ContractInterface abi, string methodName, params object[] args) { var method = abi.FindMethod(methodName); if (method == null) { throw new Exception("ABI is missing: " + method.name); } var changeSet = new StorageChangeSetContext(chain.Storage); var oracle = chain.Nexus.GetOracleReader(); var vm = new RuntimeVM(-1, script, (uint)method.offset, chain, Address.Null, Timestamp.Now, null, changeSet, oracle, ChainTask.Null, true); //var vm = new GasMachine(script, (uint)method.offset); // TODO maybe this needs to be in inverted order? foreach (var arg in args) { vm.Stack.Push(VMObject.FromObject(arg)); } var result = vm.Execute(); if (result == ExecutionState.Halt) { return(vm.Stack.Pop()); } throw new Exception("Script execution failed for: " + method.name); }
private static ExecutionState Map_Has(RuntimeVM vm) { vm.ExpectStackSize(3); var contractName = vm.PopString("contract"); var field = vm.PopString("field"); var mapKey = SmartContract.GetKeyForField(contractName, field, false); var entryKey = vm.Stack.Pop().AsByteArray(); vm.Expect(entryKey.Length > 0, "invalid entry key"); var type_obj = vm.Stack.Pop(); var vmType = type_obj.AsEnum <VMType>(); var map = new StorageMap(mapKey, vm.Storage); var keyExists = map.ContainsKey(entryKey); var val = new VMObject(); val.SetValue(keyExists); vm.Stack.Push(val); return(ExecutionState.Running); }
private static ExecutionState Data_Get(RuntimeVM vm) { vm.ExpectStackSize(3); var contractName = vm.PopString("contract"); vm.Expect(vm.ContractDeployed(contractName), $"contract {contractName} is not deployed"); var field = vm.PopString("field"); var key = SmartContract.GetKeyForField(contractName, field, false); var type_obj = vm.Stack.Pop(); var vmType = type_obj.AsEnum <VMType>(); if (vmType == VMType.Object) { vmType = VMType.Bytes; } var value_bytes = vm.Storage.Get(key); var val = new VMObject(); val.SetValue(value_bytes, vmType); vm.Stack.Push(val); return(ExecutionState.Running); }
public async Task <object> InvokeContractGeneric( PhantasmaKeys keyPair, string chain, string contract, string method, object[] paramArray) { try { var script = ScriptUtils .BeginScript() .AllowGas(keyPair.Address, Address.Null, MinimumFee, 800) .CallContract(contract, method, paramArray) .SpendGas(keyPair.Address) .EndScript(); var result = await _phantasmaRpcService.InvokeRawScript.SendRequestAsync(chain, script.Encode()); byte[] decodedResult = Base16.Decode((string)result.GetValue("result")); VMObject output = Serialization.Unserialize <VMObject>(decodedResult); return(output.ToObject()); } catch (RpcResponseException rpcEx) { Debug.WriteLine($"RPC Exception occurred: {rpcEx.RpcError.Message}"); return(null); } catch (Exception ex) { Debug.WriteLine($"Exception occurred: {ex.Message}"); return(null); } }
private static ExecutionState Map_Get(RuntimeVM vm) { vm.ExpectStackSize(4); var contractName = vm.PopString("contract"); var field = vm.PopString("field"); var mapKey = SmartContract.GetKeyForField(contractName, field, false); var entryKey = vm.Stack.Pop().AsByteArray(); vm.Expect(entryKey.Length > 0, "invalid entry key"); var type_obj = vm.Stack.Pop(); var vmType = type_obj.AsEnum <VMType>(); var map = new StorageMap(mapKey, vm.Storage); var value_bytes = map.GetRaw(entryKey); var val = new VMObject(); if (value_bytes == null) { val.SetDefaultValue(vmType); } else { val.SetValue(value_bytes, vmType); } vm.Stack.Push(val); return(ExecutionState.Running); }
private static ExecutionState Runtime_MintToken(RuntimeVM vm) { vm.ExpectStackSize(4); var source = vm.PopAddress(); var destination = vm.PopAddress(); var symbol = vm.PopString("symbol"); var rom = vm.PopBytes("rom"); var ram = vm.PopBytes("ram"); BigInteger seriesID; if (vm.ProtocolVersion >= 4) { seriesID = vm.PopNumber("series"); } else { seriesID = 0; } var tokenID = vm.MintToken(symbol, source, destination, rom, ram, seriesID); var result = new VMObject(); result.SetValue(tokenID); vm.Stack.Push(result); return(ExecutionState.Running); }
private static ExecutionState Runtime_MintToken(RuntimeVM Runtime) { ExpectStackSize(Runtime, 4); VMObject temp; var source = PopAddress(Runtime); var destination = PopAddress(Runtime); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.String, "expected string for symbol"); var symbol = temp.AsString(); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.Bytes, "expected bytes for rom"); var rom = temp.AsByteArray(); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.Bytes, "expected bytes for ram"); var ram = temp.AsByteArray(); var tokenID = Runtime.MintToken(symbol, source, destination, rom, ram); var result = new VMObject(); result.SetValue(tokenID); Runtime.Stack.Push(result); return(ExecutionState.Running); }
private static ExecutionState Runtime_CreatePlatform(RuntimeVM Runtime) { ExpectStackSize(Runtime, 3); VMObject temp; var source = PopAddress(Runtime); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.String, "expected string for name"); var name = temp.AsString(); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.String, "expected string for pubaddress"); var externalAddress = temp.AsString(); var interopAddress = PopAddress(Runtime); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.String, "expected string for symbol"); var symbol = temp.AsString(); var target = Runtime.CreatePlatform(source, name, externalAddress, interopAddress, symbol); var result = new VMObject(); result.SetValue(target); Runtime.Stack.Push(result); return(ExecutionState.Running); }
/* * private static ExecutionState Oracle_Register(RuntimeVM vm) * { * if (vm.Stack.Count < 2) * { * return ExecutionState.Fault; * } * * VMObject temp; * * temp = vm.Stack.Pop(); * if (temp.Type != VMType.Object) * { * return ExecutionState.Fault; * } * * var address = temp.AsInterop<Address>(); * * temp = vm.Stack.Pop(); * if (temp.Type != VMType.String) * { * return ExecutionState.Fault; * } * * var name = temp.AsString(); * * return ExecutionState.Running; * } * * // should return list of all registered oracles * private static ExecutionState Oracle_List(RuntimeVM vm) * { * throw new NotImplementedException(); * }*/ #endregion private static ExecutionState Runtime_IsWitness(RuntimeVM vm) { try { var tx = vm.Transaction; Throw.IfNull(tx, nameof(tx)); if (vm.Stack.Count < 1) { return(ExecutionState.Fault); } var temp = vm.Stack.Pop(); if (temp.Type != VMType.Object) { return(ExecutionState.Fault); } var address = temp.AsInterop <Address>(); var success = tx.IsSignedBy(address); var result = new VMObject(); result.SetValue(success); vm.Stack.Push(result); } catch { return(ExecutionState.Fault); } return(ExecutionState.Running); }
public VMObject CallContext(string contextName, string methodName, params object[] args) { var previousContext = CurrentContext; var context = LoadContext(contextName); Expect(context != null, "could not call context: " + contextName); for (int i = args.Length - 1; i >= 0; i--) { var obj = VMObject.FromObject(args[i]); this.Stack.Push(obj); } this.Stack.Push(VMObject.FromObject(methodName)); CurrentContext = context; var temp = context.Execute(this.CurrentFrame, this.Stack); Expect(temp == ExecutionState.Halt, "expected call success"); CurrentContext = previousContext; if (this.Stack.Count > 0) { var result = this.Stack.Pop(); return(result); } else { return(new VMObject()); } }
private static ExecutionState Runtime_TransferToken(RuntimeVM Runtime) { Runtime.Expect(Runtime.Stack.Count >= 4, "not enough arguments in stack"); VMObject temp; var source = PopAddress(Runtime); var destination = PopAddress(Runtime); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.String, "expected string for symbol"); var symbol = temp.AsString(); temp = Runtime.Stack.Pop(); Runtime.Expect(temp.Type == VMType.Number, "expected number for amount"); var tokenID = temp.AsNumber(); var success = Runtime.TransferToken(symbol, source, destination, tokenID); var result = new VMObject(); result.SetValue(success); Runtime.Stack.Push(result); return(ExecutionState.Running); }
private static ExecutionState Runtime_IsWitness(RuntimeVM vm) { try { var tx = vm.Transaction; Throw.IfNull(tx, nameof(tx)); vm.ExpectStackSize(1); var address = vm.PopAddress(); //var success = tx.IsSignedBy(address); // TODO check if this was just a bug or there was a real reason var success = vm.IsWitness(address); var result = new VMObject(); result.SetValue(success); vm.Stack.Push(result); } catch (Exception e) { throw new VMException(vm, e.Message); } return(ExecutionState.Running); }
private static ExecutionState Runtime_IsMinter(RuntimeVM vm) { try { var tx = vm.Transaction; Throw.IfNull(tx, nameof(tx)); vm.ExpectStackSize(1); var address = vm.PopAddress(); var symbol = vm.PopString("symbol"); bool success = vm.IsMintingAddress(address, symbol); var result = new VMObject(); result.SetValue(success); vm.Stack.Push(result); } catch (Exception e) { throw new VMException(vm, e.Message); } return(ExecutionState.Running); }
private void BuildMethodTable() { var type = this.GetType(); var srcMethods = type.GetMethods(BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.DeclaredOnly); var methods = new List <ContractMethod>(); foreach (var srcMethod in srcMethods) { var parameters = new List <ContractParameter>(); var srcParams = srcMethod.GetParameters(); var methodName = srcMethod.Name; if (methodName.StartsWith("get_")) { methodName = methodName.Substring(4); } if (methodName == "Kind") { continue; } var isVoid = srcMethod.ReturnType == typeof(void); var returnType = isVoid ? VMType.None : VMObject.GetVMType(srcMethod.ReturnType); bool isValid = isVoid || returnType != VMType.None; if (!isValid) { continue; } foreach (var srcParam in srcParams) { var paramType = srcParam.ParameterType; var vmtype = VMObject.GetVMType(paramType); if (vmtype != VMType.None) { parameters.Add(new ContractParameter(srcParam.Name, vmtype)); } else { isValid = false; break; } } if (isValid) { _methodTable[methodName] = srcMethod; var method = new ContractMethod(methodName, returnType, -1, parameters.ToArray()); methods.Add(method); } } this.ABI = new ContractInterface(methods, Enumerable.Empty <ContractEvent>()); }
private static ExecutionState Task_Current(RuntimeVM vm) { var result = new VMObject(); result.SetValue(vm.CurrentTask); vm.Stack.Push(result); return(ExecutionState.Running); }
/* * private static ExecutionState Oracle_Register(RuntimeVM vm) * { * ExpectStackSize(vm, 2); * * VMObject temp; * * temp = vm.Stack.Pop(); * if (temp.Type != VMType.Object) * { * return ExecutionState.Fault; * } * * var address = temp.AsInterop<Address>(); * * temp = vm.Stack.Pop(); * if (temp.Type != VMType.String) * { * return ExecutionState.Fault; * } * * var name = temp.AsString(); * * return ExecutionState.Running; * } * * // should return list of all registered oracles * private static ExecutionState Oracle_List(RuntimeVM vm) * { * throw new NotImplementedException(); * }*/ #endregion private static ExecutionState Runtime_Time(RuntimeVM vm) { var result = new VMObject(); result.SetValue(vm.Time); vm.Stack.Push(result); return(ExecutionState.Running); }
public void DecodeStruct() { var bytes = Base16.Decode("010E04076372656174656405C95AC15F040763726561746F720823220100279FB052FA82D619FB33581321E3A5F592507EAC995907B504876ABF6F62421F0409726F79616C746965730302160004046E616D65041C61736461736461617364617364616173646173646161736461736461040B6465736372697074696F6E041C61736461736461617364617364616173646173646161736461736461040474797065030202000408696D61676555524C04096173646173646173640407696E666F55524C0400040E61747472696275746554797065310400040F61747472696275746556616C7565310400040E61747472696275746554797065320400040F61747472696275746556616C7565320400040E61747472696275746554797065330400040F61747472696275746556616C7565330400"); var obj = VMObject.FromBytes(bytes); Assert.IsTrue(obj.Type == VMType.Struct); }
private static ExecutionState Runtime_Context(RuntimeVM vm) { var result = new VMObject(); result.SetValue(vm.CurrentContext.Name); vm.Stack.Push(result); return(ExecutionState.Running); }
public static ExecutionState Constructor_AddressV2(RuntimeVM vm) { var addr = vm.PopAddress(); var temp = new VMObject(); temp.SetValue(addr); vm.Stack.Push(temp); return(ExecutionState.Running); }
private static ExecutionState Runtime_ReadTokenROM(RuntimeVM Runtime) { var content = Runtime_ReadTokenInternal(Runtime); var result = new VMObject(); result.SetValue(content.ROM, VMType.Bytes); Runtime.Stack.Push(result); return(ExecutionState.Running); }
private static ExecutionState Oracle_Price(RuntimeVM vm) { vm.ExpectStackSize(1); var symbol = vm.PopString("price"); var price = vm.GetTokenPrice(symbol); vm.Stack.Push(VMObject.FromObject(price)); return(ExecutionState.Running); }
private static ExecutionState Data_Get(RuntimeVM vm) { var key = vm.Stack.Pop(); var key_bytes = key.AsByteArray(); var value_bytes = vm.ChangeSet.Get(key_bytes); var val = new VMObject(); val.SetValue(value_bytes, VMType.Bytes); vm.Stack.Push(val); return(ExecutionState.Running); }
private static ExecutionState Task_Get(RuntimeVM vm) { vm.ExpectStackSize(1); var taskID = vm.PopNumber("task"); var task = (ChainTask)vm.GetTask(taskID); var result = new VMObject(); result.SetValue(task); vm.Stack.Push(result); return(ExecutionState.Running); }
public static IEnumerable <string> ExtractContractNames(Disassembler disassembler) { var instructions = disassembler.Instructions.ToArray(); var result = new List <string>(); int index = 0; var regs = new VMObject[16]; while (index < instructions.Length) { var instruction = instructions[index]; switch (instruction.Opcode) { case Opcode.LOAD: { var dst = (byte)instruction.Args[0]; var type = (VMType)instruction.Args[1]; var bytes = (byte[])instruction.Args[2]; regs[dst] = new VMObject(); regs[dst].SetValue(bytes, type); break; } case Opcode.CTX: { var src = (byte)instruction.Args[0]; var dst = (byte)instruction.Args[1]; regs[dst] = new VMObject(); regs[dst].Copy(regs[src]); break; } case Opcode.SWITCH: { var src = (byte)instruction.Args[0]; var contractName = regs[src].AsString(); result.Add(contractName); break; } } index++; } return(result.Distinct()); }
private VMObject GenerateTestObject(VarType type) { VMObject obj; switch (type.Kind) { case VarKind.Number: obj = VMObject.FromObject(new BigInteger(123)); break; case VarKind.String: obj = VMObject.FromObject("test"); break; case VarKind.Bool: obj = VMObject.FromObject(true); break; case VarKind.Struct: var fields = new Dictionary <VMObject, VMObject>(); var structInfo = type as StructVarType; foreach (var field in structInfo.decl.fields) { fields[VMObject.FromObject(field.name)] = GenerateTestObject(field.type); } obj = new VMObject(); obj.SetValue(fields); using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { obj.SerializeData(writer); } var bytes = stream.ToArray(); obj.SetValue(bytes); } break; default: throw new CompilerException($"Can't initialize test object with type: {type}"); } return(obj); }
private static ExecutionState Runtime_ReadToken(RuntimeVM vm) { if (vm.ProtocolVersion < 4) { return(Runtime_ReadTokenRAM(vm)); } var content = Runtime_ReadTokenInternal(vm); var fieldList = vm.PopString("fields").Split(','); var result = new VMObject(); var fields = new Dictionary <VMObject, VMObject>(); foreach (var field in fieldList) { object obj; switch (field) { case "chain": obj = content.CurrentChain; break; case "owner": obj = content.CurrentOwner.Text; break; case "creator": obj = content.Creator.Text; break; case "ROM": obj = content.ROM; break; case "RAM": obj = content.RAM; break; case "tokenID": obj = content.TokenID; break; case "seriesID": obj = content.SeriesID; break; case "mintID": obj = content.MintID; break; default: throw new VMException(vm, "unknown nft field: " + field); } var key = VMObject.FromObject(field); fields[key] = VMObject.FromObject(obj); } result.SetValue(fields); vm.Stack.Push(result); return(ExecutionState.Running); }
private static ExecutionState Oracle_Quote(RuntimeVM vm) { vm.ExpectStackSize(3); var amount = vm.PopNumber("amount"); var quoteSymbol = vm.PopString("quoteSymbol"); var baseSymbol = vm.PopString("baseSymbol"); var price = vm.GetTokenQuote(baseSymbol, quoteSymbol, amount); vm.Stack.Push(VMObject.FromObject(price)); return(ExecutionState.Running); }
private static ExecutionState Runtime_GasTarget(RuntimeVM vm) { if (vm.GasTarget.IsNull) { new VMException(vm, "Gas target is now available yet"); } var result = new VMObject(); result.SetValue(vm.GasTarget); vm.Stack.Push(result); return(ExecutionState.Running); }
private static ExecutionState Data_Get(RuntimeVM runtime) { var key = runtime.Stack.Pop(); var key_bytes = key.AsByteArray(); runtime.Expect(key_bytes.Length > 0, "invalid key"); var value_bytes = runtime.Storage.Get(key_bytes); var val = new VMObject(); val.SetValue(value_bytes, VMType.Bytes); runtime.Stack.Push(val); return(ExecutionState.Running); }