Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        /*
         * 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);
        }
Esempio n. 11
0
        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());
            }
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
        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>());
        }
Esempio n. 16
0
        private static ExecutionState Task_Current(RuntimeVM vm)
        {
            var result = new VMObject();

            result.SetValue(vm.CurrentTask);
            vm.Stack.Push(result);
            return(ExecutionState.Running);
        }
Esempio n. 17
0
        /*
         * 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);
        }
Esempio n. 18
0
        public void DecodeStruct()
        {
            var bytes = Base16.Decode("010E04076372656174656405C95AC15F040763726561746F720823220100279FB052FA82D619FB33581321E3A5F592507EAC995907B504876ABF6F62421F0409726F79616C746965730302160004046E616D65041C61736461736461617364617364616173646173646161736461736461040B6465736372697074696F6E041C61736461736461617364617364616173646173646161736461736461040474797065030202000408696D61676555524C04096173646173646173640407696E666F55524C0400040E61747472696275746554797065310400040F61747472696275746556616C7565310400040E61747472696275746554797065320400040F61747472696275746556616C7565320400040E61747472696275746554797065330400040F61747472696275746556616C7565330400");

            var obj = VMObject.FromBytes(bytes);

            Assert.IsTrue(obj.Type == VMType.Struct);
        }
Esempio n. 19
0
        private static ExecutionState Runtime_Context(RuntimeVM vm)
        {
            var result = new VMObject();

            result.SetValue(vm.CurrentContext.Name);
            vm.Stack.Push(result);

            return(ExecutionState.Running);
        }
Esempio n. 20
0
        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);
        }
Esempio n. 21
0
        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);
        }
Esempio n. 22
0
        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);
        }
Esempio n. 23
0
        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);
        }
Esempio n. 24
0
        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);
        }
Esempio n. 25
0
        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());
        }
Esempio n. 26
0
        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);
        }
Esempio n. 27
0
        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);
        }
Esempio n. 28
0
        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);
        }
Esempio n. 29
0
        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);
        }
Esempio n. 30
0
        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);
        }