예제 #1
0
        private StackItem UnregisterCandidate(ApplicationEngine engine, Array args)
        {
            ECPoint pubkey = args[0].GetSpan().AsSerializable <ECPoint>();

            if (!engine.CheckWitnessInternal(Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash()))
            {
                return(false);
            }
            return(UnregisterCandidate(engine.Snapshot, pubkey));
        }
예제 #2
0
        protected internal void RuntimeLog(byte[] state)
        {
            if (state.Length > MaxNotificationSize)
            {
                throw new ArgumentException();
            }
            string message = Utility.StrictUTF8.GetString(state);

            Log?.Invoke(this, new LogEventArgs(ScriptContainer, CurrentScriptHash, message));
        }
예제 #3
0
        public void TestEnumerator_Next()
        {
            var engine = GetEngine();
            var arr    = new VMArray {
                new byte[] { 0x01 },
                new byte[] { 0x02 }
            };

            engine.EnumeratorNext(new ArrayWrapper(arr)).Should().BeTrue();
        }
예제 #4
0
 protected internal IIterator CreateIterator(StackItem item)
 {
     return(item switch
     {
         Array array => new ArrayWrapper(array),
         Map map => new MapWrapper(map, ReferenceCounter),
         VM.Types.Buffer buffer => new ByteArrayWrapper(buffer),
         PrimitiveType primitive => new ByteArrayWrapper(primitive),
         _ => throw new ArgumentException()
     });
예제 #5
0
파일: ContractState.cs 프로젝트: zhmkof/neo
        void IInteroperable.FromStackItem(StackItem stackItem)
        {
            Array array = (Array)stackItem;

            Id            = (int)array[0].GetInteger();
            UpdateCounter = (ushort)array[1].GetInteger();
            Hash          = new UInt160(array[2].GetSpan());
            Nef           = array[3].GetSpan().AsSerializable <NefFile>();
            Manifest      = array[4].ToInteroperable <ContractManifest>();
        }
예제 #6
0
        public void TestIterator_Value()
        {
            var arr = new VMArray {
                new byte[] { 0x01 },
                new byte[] { 0x02 }
            };
            var wrapper = new ArrayWrapper(arr);

            wrapper.Next();
            ApplicationEngine.IteratorValue(wrapper).GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString());
        }
예제 #7
0
        private StackItem Vote(ApplicationEngine engine, Array args)
        {
            UInt160 account = new UInt160(args[0].GetSpan());
            ECPoint voteTo  = args[1].IsNull ? null : args[1].GetSpan().AsSerializable <ECPoint>();

            if (!engine.CheckWitnessInternal(account))
            {
                return(false);
            }
            return(Vote(engine.Snapshot, account, voteTo));
        }
예제 #8
0
        private static (BigInteger numerator, BigInteger denominator) Fraction(decimal d)
        {
            int[]      bits      = decimal.GetBits(d);
            BigInteger numerator = (1 - ((bits[3] >> 30) & 2)) *
                                   unchecked (((BigInteger)(uint)bits[2] << 64) |
                                              ((BigInteger)(uint)bits[1] << 32) |
                                              (uint)bits[0]);
            BigInteger denominator = BigInteger.Pow(10, (bits[3] >> 16) & 0xff);

            return(numerator, denominator);
        }
예제 #9
0
        /// <summary>
        /// The implementation of System.Runtime.CheckWitness.
        /// Determines whether the specified account has witnessed the current transaction.
        /// </summary>
        /// <param name="hashOrPubkey">The hash or public key of the account.</param>
        /// <returns><see langword="true"/> if the account has witnessed the current transaction; otherwise, <see langword="false"/>.</returns>
        protected internal bool CheckWitness(byte[] hashOrPubkey)
        {
            UInt160 hash = hashOrPubkey.Length switch
            {
                20 => new UInt160(hashOrPubkey),
                33 => Contract.CreateSignatureRedeemScript(ECPoint.DecodePoint(hashOrPubkey, ECCurve.Secp256r1)).ToScriptHash(),
                _ => throw new ArgumentException(null, nameof(hashOrPubkey))
            };

            return(CheckWitnessInternal(hash));
        }
예제 #10
0
        private StackItem Vote(ApplicationEngine engine, VMArray args)
        {
            UInt160 account = new UInt160(args[0].GetByteArray());

            ECPoint[] pubkeys = ((VMArray)args[1]).Select(p => p.GetByteArray().AsSerializable <ECPoint>()).ToArray();
            if (!InteropService.CheckWitness(engine, account))
            {
                return(false);
            }
            StorageKey key_account = CreateAccountKey(account);

            if (engine.Snapshot.Storages.TryGet(key_account) is null)
            {
                return(false);
            }
            StorageItem  storage_account = engine.Snapshot.Storages.GetAndChange(key_account);
            AccountState state_account   = new AccountState(storage_account.Value);

            foreach (ECPoint pubkey in state_account.Votes)
            {
                StorageItem    storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Validator, pubkey.ToArray()));
                ValidatorState state_validator   = ValidatorState.FromByteArray(storage_validator.Value);
                state_validator.Votes  -= state_account.Balance;
                storage_validator.Value = state_validator.ToByteArray();
            }
            pubkeys = pubkeys.Distinct().Where(p => engine.Snapshot.Storages.TryGet(CreateStorageKey(Prefix_Validator, p.ToArray())) != null).ToArray();
            if (pubkeys.Length != state_account.Votes.Length)
            {
                StorageItem storage_count = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_ValidatorsCount), () => new StorageItem
                {
                    Value = new ValidatorsCountState().ToByteArray()
                });
                ValidatorsCountState state_count = ValidatorsCountState.FromByteArray(storage_count.Value);
                if (state_account.Votes.Length > 0)
                {
                    state_count.Votes[state_account.Votes.Length - 1] -= state_account.Balance;
                }
                if (pubkeys.Length > 0)
                {
                    state_count.Votes[pubkeys.Length - 1] += state_account.Balance;
                }
                storage_count.Value = state_count.ToByteArray();
            }
            state_account.Votes   = pubkeys;
            storage_account.Value = state_account.ToByteArray();
            foreach (ECPoint pubkey in state_account.Votes)
            {
                StorageItem    storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Validator, pubkey.ToArray()));
                ValidatorState state_validator   = ValidatorState.FromByteArray(storage_validator.Value);
                state_validator.Votes  += state_account.Balance;
                storage_validator.Value = state_validator.ToByteArray();
            }
            return(true);
        }
예제 #11
0
 /// <summary>
 /// The implementation of System.Runtime.Notify.
 /// Sends a notification.
 /// </summary>
 /// <param name="eventName">The name of the event.</param>
 /// <param name="state">The arguments of the event.</param>
 protected internal void RuntimeNotify(byte[] eventName, Array state)
 {
     if (eventName.Length > MaxEventName)
     {
         throw new ArgumentException(null, nameof(eventName));
     }
     using MemoryStream ms     = new(MaxNotificationSize);
     using BinaryWriter writer = new(ms, Utility.StrictUTF8, true);
     BinarySerializer.Serialize(writer, state, MaxNotificationSize);
     SendNotification(CurrentScriptHash, Utility.StrictUTF8.GetString(eventName), state);
 }
        public void TestIterator_Key()
        {
            var engine = GetEngine();
            var arr    = new VMArray {
                new byte[] { 0x01 },
                new byte[] { 0x02 }
            };
            var wrapper = new ArrayWrapper(arr);

            wrapper.Next();
            engine.IteratorKey(wrapper).GetInteger().Should().Be(0);
        }
        public void TestEnumerator_Value()
        {
            var engine = GetEngine();
            var arr    = new VMArray {
                new byte[] { 0x01 },
                new byte[] { 0x02 }
            };
            var wrapper = new ArrayWrapper(arr);

            wrapper.Next();
            engine.EnumeratorValue(wrapper).GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString());
        }
        public void TestEnumerator_Create()
        {
            var engine = GetEngine();
            var arr    = new VMArray {
                new byte[] { 0x01 },
                new byte[] { 0x02 }
            };
            var ret = engine.CreateEnumerator(arr);

            ret.Next();
            ret.Value().GetSpan().ToHexString().Should().Be(new byte[] { 0x01 }.ToHexString());
        }
예제 #15
0
        private StackItem SetFeePerByte(ApplicationEngine engine, Array args)
        {
            if (!CheckValidators(engine))
            {
                return(false);
            }
            long        value   = (long)args[0].GetBigInteger();
            StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_FeePerByte));

            storage.Value = BitConverter.GetBytes(value);
            return(true);
        }
예제 #16
0
 protected internal void InvokeCallback(CallbackBase callback, Array args)
 {
     if (args.Count != callback.ParametersCount)
     {
         throw new InvalidOperationException();
     }
     callback.LoadContext(this, args);
     if (callback is SyscallCallback syscallCallback)
     {
         OnSysCall(syscallCallback.Method);
     }
 }
예제 #17
0
        public void FromStackItem(StackItem stackItem)
        {
            Array array = (Array)stackItem;

            OriginalTxid     = new UInt256(array[0].GetSpan());
            GasForResponse   = (long)array[1].GetInteger();
            Url              = array[2].GetString();
            Filter           = array[3].GetString();
            CallbackContract = new UInt160(array[4].GetSpan());
            CallbackMethod   = array[5].GetString();
            UserData         = array[6].GetSpan().ToArray();
        }
예제 #18
0
        protected StorageKey CreateStorageKey(byte prefix, byte[] key = null)
        {
            StorageKey storageKey = new StorageKey
            {
                Id  = Id,
                Key = new byte[sizeof(byte) + (key?.Length ?? 0)]
            };

            storageKey.Key[0] = prefix;
            key?.CopyTo(storageKey.Key.AsSpan(1));
            return(storageKey);
        }
예제 #19
0
        private StackItem SetMaxTransactionsPerBlock(ApplicationEngine engine, Array args)
        {
            if (!CheckValidators(engine))
            {
                return(false);
            }
            uint        value   = (uint)args[0].GetBigInteger();
            StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxTransactionsPerBlock));

            storage.Value = BitConverter.GetBytes(value);
            return(true);
        }
예제 #20
0
        public void TestIterator_Keys()
        {
            var engine = GetEngine();
            var arr    = new VMArray {
                new byte[] { 0x01 },
                new byte[] { 0x02 }
            };
            var wrapper = new ArrayWrapper(arr);
            var ret     = engine.IteratorKeys(wrapper);

            ret.Next();
            ret.Value().GetBigInteger().Should().Be(0);
        }
예제 #21
0
        public void AddTransferNotification(ExecutionEngine engine, UIntBase assetId, UInt160 from, UInt160 to, Fixed8 value)
        {
            VMArray array = new VMArray();

            array.Add("transfer");
            array.Add(new ByteArray(from.ToArray()));
            array.Add(new ByteArray(to.ToArray()));
            array.Add(new ByteArray(new BigInteger(value.GetData()).ToByteArray()));

            NotifyEventArgs notification = new NotifyEventArgs(engine.ScriptContainer, assetId, array);

            InvokeNotification(notification);
        }
예제 #22
0
        public void TestOnPersistWithArgs()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot();
            ApplicationEngine engine1 = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
            VMArray args = new VMArray();

            VM.Types.Boolean result1 = new VM.Types.Boolean(false);
            testNativeContract.TestOnPersist(engine1, args).Should().Be(result1);

            ApplicationEngine engine2 = new ApplicationEngine(TriggerType.System, null, snapshot, 0);
            VM.Types.Boolean result2 = new VM.Types.Boolean(true);
            testNativeContract.TestOnPersist(engine2, args).Should().Be(result2);
        }
예제 #23
0
        public static StackItem StackItemFromJson(JObject json)
        {
            StackItemType type = json["type"].TryGetEnum <StackItemType>();

            switch (type)
            {
            case StackItemType.Boolean:
                return(new Boolean(json["value"].AsBoolean()));

            case StackItemType.Buffer:
                return(new Buffer(Convert.FromBase64String(json["value"].AsString())));

            case StackItemType.ByteString:
                return(new ByteString(Convert.FromBase64String(json["value"].AsString())));

            case StackItemType.Integer:
                return(new Integer(new BigInteger(json["value"].AsNumber())));

            case StackItemType.Array:
                Array array = new Array();
                foreach (var item in (JArray)json["value"])
                {
                    array.Add(StackItemFromJson(item));
                }
                return(array);

            case StackItemType.Struct:
                Struct @struct = new Struct();
                foreach (var item in (JArray)json["value"])
                {
                    @struct.Add(StackItemFromJson(item));
                }
                return(@struct);

            case StackItemType.Map:
                Map map = new Map();
                foreach (var item in (JArray)json["value"])
                {
                    PrimitiveType key = (PrimitiveType)StackItemFromJson(item["key"]);
                    map[key] = StackItemFromJson(item["value"]);
                }
                return(map);

            case StackItemType.Pointer:
                return(new Pointer(null, (int)json["value"].AsNumber()));

            case StackItemType.InteropInterface:
                return(new InteropInterface(new object()));    // See https://github.com/neo-project/neo/blob/master/src/neo/VM/Helper.cs#L194
            }
            return(json["value"] is null ? StackItem.Null : json["value"].AsString());
        }
예제 #24
0
        public JObject GetNep17Balances(JArray _params)
        {
            UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString());

            JObject json     = new();
            JArray  balances = new();

            json["address"] = userScriptHash.ToAddress(_neoSystem.Settings.AddressVersion);
            json["balance"] = balances;

            int count = 0;

            byte[] prefix = Key(Nep17BalancePrefix, userScriptHash);
            foreach (var(key, value) in _db.FindPrefix <Nep17BalanceKey, TokenBalance>(prefix))
            {
                if (NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key.AssetScriptHash) is null)
                {
                    continue;
                }

                try
                {
                    using var script = new ScriptBuilder();
                    script.EmitDynamicCall(key.AssetScriptHash, "decimals");
                    script.EmitDynamicCall(key.AssetScriptHash, "symbol");

                    var engine   = ApplicationEngine.Run(script.ToArray(), _neoSystem.StoreView, settings: _neoSystem.Settings);
                    var symbol   = engine.ResultStack.Pop().GetString();
                    var decimals = engine.ResultStack.Pop().GetInteger();
                    var name     = NativeContract.ContractManagement.GetContract(_neoSystem.StoreView, key.AssetScriptHash).Manifest.Name;

                    balances.Add(new JObject
                    {
                        ["assethash"]        = key.AssetScriptHash.ToString(),
                        ["name"]             = name,
                        ["symbol"]           = symbol,
                        ["decimals"]         = decimals.ToString(),
                        ["amount"]           = value.Balance.ToString(),
                        ["lastupdatedblock"] = value.LastUpdatedBlock
                    });
                    count++;
                    if (count >= _maxResults)
                    {
                        break;
                    }
                }
                catch { }
            }
            return(json);
        }
예제 #25
0
        public void TestOnPersistWithArgs()
        {
            ApplicationEngine  engine1            = new ApplicationEngine(TriggerType.Application, null, Store.GetSnapshot(), 0);
            TestNativeContract testNativeContract = new TestNativeContract();
            VMArray            args = new VMArray();

            VM.Types.Boolean result1 = new VM.Types.Boolean(false);
            testNativeContract.TestOnPersist(engine1, args).Should().Be(result1);

            ApplicationEngine engine2 = new ApplicationEngine(TriggerType.System, null, Store.GetSnapshot(), 0);

            VM.Types.Boolean result2 = new VM.Types.Boolean(true);
            testNativeContract.TestOnPersist(engine2, args).Should().Be(result2);
        }
예제 #26
0
        /// <summary>
        /// The implementation of System.Runtime.GetNotifications.
        /// Gets the notifications sent by the specified contract during the execution.
        /// </summary>
        /// <param name="hash">The hash of the specified contract. It can be set to <see langword="null"/> to get all notifications.</param>
        /// <returns>The notifications sent during the execution.</returns>
        protected internal NotifyEventArgs[] GetNotifications(UInt160 hash)
        {
            IEnumerable <NotifyEventArgs> notifications = Notifications;

            if (hash != null) // must filter by scriptHash
            {
                notifications = notifications.Where(p => p.ScriptHash == hash);
            }
            NotifyEventArgs[] array = notifications.ToArray();
            if (array.Length > Limits.MaxStackSize)
            {
                throw new InvalidOperationException();
            }
            return(array);
        }
예제 #27
0
        protected StorageKey CreateStorageKey(byte prefix, byte[] key = null)
        {
            StorageKey storageKey = new StorageKey
            {
                ScriptHash = Hash,
                Key        = new byte[sizeof(byte) + (key?.Length ?? 0)]
            };

            storageKey.Key[0] = prefix;
            if (key != null)
            {
                Buffer.BlockCopy(key, 0, storageKey.Key, 1, key.Length);
            }
            return(storageKey);
        }
예제 #28
0
        /// <summary>
        /// Converts the event from a JSON object.
        /// </summary>
        /// <param name="json">The event represented by a JSON object.</param>
        /// <returns>The converted event.</returns>
        public static ContractEventDescriptor FromJson(JObject json)
        {
            ContractEventDescriptor descriptor = new()
            {
                Name       = json["name"].GetString(),
                Parameters = ((JArray)json["parameters"]).Select(u => ContractParameterDefinition.FromJson((JObject)u)).ToArray(),
            };

            if (string.IsNullOrEmpty(descriptor.Name))
            {
                throw new FormatException();
            }
            _ = descriptor.Parameters.ToDictionary(p => p.Name);
            return(descriptor);
        }
예제 #29
0
        /// <summary>
        /// check script if it contains wrong Opcode
        /// </summary>
        /// <param name="script"></param>
        /// <returns></returns>
        private async Task CheckBadOpcode(byte[] script)
        {
            Script scriptCodes = new Script(script);

            for (var i = 0; i < scriptCodes.Length;)
            {
                // Check bad opcodes
                Instruction inst = scriptCodes.GetInstruction(i);
                if (inst is null || !Enum.IsDefined(typeof(OpCode), inst.OpCode))
                {
                    throw new FormatException($"OpCode not found at {i}-{((byte)inst.OpCode):x2}");
                }
                i += inst.Size;
            }
        }
예제 #30
0
        public void TestEnumerator_Next()
        {
            var engine = GetEngine();
            var arr    = new VMArray {
                new byte[] { 0x01 },
                new byte[] { 0x02 }
            };

            engine.CurrentContext.EvaluationStack.Push(new InteropInterface <ArrayWrapper>(new ArrayWrapper(arr)));
            InteropService.Invoke(engine, InteropService.Neo_Enumerator_Next).Should().BeTrue();
            engine.CurrentContext.EvaluationStack.Pop().ToBoolean().Should().BeTrue();

            engine.CurrentContext.EvaluationStack.Push(1);
            InteropService.Invoke(engine, InteropService.Neo_Enumerator_Next).Should().BeFalse();
        }