예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
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);
        }
예제 #7
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);
        }
예제 #8
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);
        }
예제 #9
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);
        }
예제 #10
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);
        }
예제 #11
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);
        }
예제 #12
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);
        }
예제 #13
0
        private static ExecutionState Task_Current(RuntimeVM vm)
        {
            var result = new VMObject();

            result.SetValue(vm.CurrentTask);
            vm.Stack.Push(result);
            return(ExecutionState.Running);
        }
예제 #14
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);
        }
예제 #15
0
        private static ExecutionState Runtime_Context(RuntimeVM vm)
        {
            var result = new VMObject();

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

            return(ExecutionState.Running);
        }
예제 #16
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);
        }
예제 #17
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);
        }
예제 #18
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);
        }
예제 #19
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);
        }
예제 #20
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);
        }
예제 #21
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);
        }
예제 #22
0
        private static ExecutionState Runtime_DeployContract(RuntimeVM Runtime)
        {
            var tx = Runtime.Transaction;

            Throw.IfNull(tx, nameof(tx));

            if (Runtime.Stack.Count < 1)
            {
                return(ExecutionState.Fault);
            }

            VMObject temp;

            var owner = Runtime.Nexus.GetChainOwnerByName(Runtime.Chain.Name);

            Runtime.Expect(owner.IsUser, "address must be user");

            if (Runtime.Nexus.HasGenesis)
            {
                Runtime.Expect(Runtime.IsStakeMaster(owner), "needs to be master");
            }

            Runtime.Expect(Runtime.IsWitness(owner), "invalid witness");

            temp = Runtime.Stack.Pop();

            bool success;

            switch (temp.Type)
            {
            case VMType.String:
            {
                var name = temp.AsString();
                success = Runtime.Chain.DeployNativeContract(Runtime.Storage, SmartContract.GetAddressForName(name));
            }
            break;

            default:
                success = false;
                break;
            }

            var result = new VMObject();

            result.SetValue(success);
            Runtime.Stack.Push(result);
            return(ExecutionState.Running);
        }
예제 #23
0
        private static ExecutionState Runtime_AESEncrypt(RuntimeVM vm)
        {
            vm.ExpectStackSize(2);

            var data = vm.PopBytes("data");
            var key  = vm.PopBytes("key");

            var encryptedData = CryptoExtensions.AESGCMEncrypt(data, key);

            var result = new VMObject();

            result.SetValue(encryptedData);
            vm.Stack.Push(result);

            return(ExecutionState.Running);
        }
예제 #24
0
        private static ExecutionState Runtime_GetBalance(RuntimeVM vm)
        {
            vm.ExpectStackSize(2);

            var source = vm.PopAddress();
            var symbol = vm.PopString("symbol");

            var balance = vm.GetBalance(symbol, source);

            var result = new VMObject();

            result.SetValue(balance);
            vm.Stack.Push(result);

            return(ExecutionState.Running);
        }
예제 #25
0
        private static ExecutionState Runtime_Random(RuntimeVM vm)
        {
            try
            {
                var number = vm.GenerateRandomNumber();

                var result = new VMObject();
                result.SetValue(number);
                vm.Stack.Push(result);
            }
            catch (Exception e)
            {
                throw new VMException(vm, e.Message);
            }

            return(ExecutionState.Running);
        }
예제 #26
0
        private static ExecutionState Runtime_TokenExists(RuntimeVM vm)
        {
            vm.ExpectStackSize(1);

            var temp = vm.Stack.Pop();

            vm.Expect(temp.Type == VMType.String, "expected string for symbol");
            var symbol = temp.AsString();

            var success = vm.TokenExists(symbol);

            var result = new VMObject();

            result.SetValue(success);
            vm.Stack.Push(result);

            return(ExecutionState.Running);
        }
예제 #27
0
        private static ExecutionState Runtime_TransactionHash(RuntimeVM vm)
        {
            try
            {
                var tx = vm.Transaction;
                Throw.IfNull(tx, nameof(tx));

                var result = new VMObject();
                result.SetValue(tx.Hash);
                vm.Stack.Push(result);
            }
            catch (Exception e)
            {
                throw new VMException(vm, e.Message);
            }

            return(ExecutionState.Running);
        }
예제 #28
0
        private static ExecutionState Runtime_TransferTokens(RuntimeVM vm)
        {
            try
            {
                var tx = vm.Transaction;
                Throw.IfNull(tx, nameof(tx));

                if (vm.Stack.Count < 4)
                {
                    return(ExecutionState.Fault);
                }

                VMObject temp;

                var source      = PopAddress(vm);
                var destination = PopAddress(vm);

                temp = vm.Stack.Pop();
                if (temp.Type != VMType.String)
                {
                    return(ExecutionState.Fault);
                }
                var symbol = temp.AsString();

                temp = vm.Stack.Pop();
                if (temp.Type != VMType.Number)
                {
                    return(ExecutionState.Fault);
                }
                var amount = temp.AsNumber();

                var success = vm.TransferTokens(vm, symbol, source, destination, amount);

                var result = new VMObject();
                result.SetValue(success);
                vm.Stack.Push(result);
            }
            catch
            {
                return(ExecutionState.Fault);
            }

            return(ExecutionState.Running);
        }
예제 #29
0
        private static ExecutionState Constructor_Object <IN, OUT>(RuntimeVM vm, Func <IN, OUT> loader)
        {
            var type  = VMObject.GetVMType(typeof(IN));
            var input = vm.Stack.Pop().AsType(type);

            try
            {
                OUT obj  = loader((IN)input);
                var temp = new VMObject();
                temp.SetValue(obj);
                vm.Stack.Push(temp);
            }
            catch
            {
                return(ExecutionState.Fault);
            }

            return(ExecutionState.Running);
        }
예제 #30
0
        private static ExecutionState Nexus_CreatePlatform(RuntimeVM vm)
        {
            vm.ExpectStackSize(5);

            var source          = vm.PopAddress();
            var name            = vm.PopString("name");
            var externalAddress = vm.PopString("external address");
            var interopAddress  = vm.PopAddress();
            var symbol          = vm.PopString("symbol");

            var target = vm.CreatePlatform(source, name, externalAddress, interopAddress, symbol);

            var result = new VMObject();

            result.SetValue(target);
            vm.Stack.Push(result);

            return(ExecutionState.Running);
        }