public static JObject?TryGetAppLog(IExpressReadOnlyStore store, UInt256 hash)
        {
            var value = store.TryGet(APP_LOGS_PREFIX, hash.ToArray());

            if (value != null && value.Length != 0)
            {
                return(JObject.Parse(Neo.Utility.StrictUTF8.GetString(value)));
            }

            return(null);
        }
        public static IEnumerable <Nep17Contract> GetNep17Contracts(IExpressReadOnlyStore store)
        {
            var scriptHashes = new HashSet <UInt160>();

            foreach (var(_, _, notification) in GetNep17Transfers(store))
            {
                scriptHashes.Add(notification.ScriptHash);
            }

            scriptHashes.Add(NativeContract.NEO.Hash);
            scriptHashes.Add(NativeContract.GAS.Hash);

            using var snapshot = Blockchain.Singleton.GetSnapshot();
            foreach (var scriptHash in scriptHashes)
            {
                if (Nep17Contract.TryLoad(snapshot, scriptHash, out var contract))
                {
                    yield return(contract);
                }
            }
        }
 static IEnumerable <(uint blockIndex, ushort txIndex, NotificationRecord notification)> GetNep17Transfers(IExpressReadOnlyStore store)
 => ExpressAppLogsPlugin
 public ExpressRpcServer(IExpressReadOnlyStore store, ExpressWalletAccount multiSigAccount)
 {
     this.store           = store;
     this.multiSigAccount = multiSigAccount;
     cacheId = DateTimeOffset.Now.Ticks.ToString();
 }
        public static IEnumerable <(Nep17Contract contract, BigInteger balance, uint lastUpdatedBlock)> GetNep17Balances(IExpressReadOnlyStore store, UInt160 address)
        {
            // assets key is the script hash of the asset contract
            // assets value is the last updated block of the assoicated asset for address
            var assets = new Dictionary <UInt160, uint>();

            foreach (var(blockIndex, _, notification) in GetNep17Transfers(store))
            {
                var from = ToUInt160(notification.State[0]);
                var to   = ToUInt160(notification.State[1]);
                if (from == address || to == address)
                {
                    assets[notification.ScriptHash] = blockIndex;
                }
            }

            if (!assets.ContainsKey(NativeContract.NEO.Hash))
            {
                assets[NativeContract.NEO.Hash] = 0;
            }

            if (!assets.ContainsKey(NativeContract.GAS.Hash))
            {
                assets[NativeContract.GAS.Hash] = 0;
            }

            using var snapshot = Blockchain.Singleton.GetSnapshot();
            foreach (var kvp in assets)
            {
                if (TryGetBalance(kvp.Key, out var balance) &&
                    balance > BigInteger.Zero)
                {
                    var contract = Nep17Contract.TryLoad(snapshot, kvp.Key, out var _contract)
                        ? _contract : Nep17Contract.Unknown(kvp.Key);
                    yield return(contract, balance, kvp.Value);
                }
            }

            bool TryGetBalance(UInt160 asset, out BigInteger balance)
            {
                using var sb = new ScriptBuilder();
                sb.EmitDynamicCall(asset, "balanceOf", address.ToArray());

                using var engine = ApplicationEngine.Run(sb.ToArray(), snapshot);
                if (!engine.State.HasFlag(VMState.FAULT) && engine.ResultStack.Count >= 1)
                {
                    balance = engine.ResultStack.Pop <Neo.VM.Types.Integer>().GetInteger();
                    return(true);
                }

                balance = default;
                return(false);
            }
        }
 public static IEnumerable <(uint blockIndex, ushort txIndex, NotificationRecord notification)> GetNotifications(IExpressReadOnlyStore store)
 {
     return(store.Seek(NOTIFICATIONS_PREFIX, null, SeekDirection.Forward)
            .Select(t =>
     {
         var(blockIndex, txIndex) = ParseNotificationKey(t.Key);
         return (blockIndex, txIndex, t.Value.AsSerializable <NotificationRecord>());
     }));