Ejemplo n.º 1
0
        public Task <IReadOnlyList <(RpcNep17Balance balance, Nep17Contract contract)> > ListBalancesAsync(UInt160 address)
        {
            try
            {
                if (disposedValue)
                {
                    return(Task.FromException <IReadOnlyList <(RpcNep17Balance, Nep17Contract)> >(new ObjectDisposedException(nameof(OfflineNode))));
                }

                var contractMap = ExpressRpcServer.GetNep17Contracts(neoSystem, rocksDbStorageProvider).ToDictionary(c => c.ScriptHash);
                var results     = ExpressRpcServer.GetNep17Balances(neoSystem, rocksDbStorageProvider, address)
                                  .Select(b => (
                                              balance: new RpcNep17Balance
                {
                    Amount = b.balance,
                    AssetHash = b.contract.ScriptHash,
                    LastUpdatedBlock = b.lastUpdatedBlock
                },
                                              contract: contractMap.TryGetValue(b.contract.ScriptHash, out var value)
                            ? value
                            : Nep17Contract.Unknown(b.contract.ScriptHash)));

                return(Task.FromResult <IReadOnlyList <(RpcNep17Balance, Nep17Contract)> >(results.ToArray()));
            }
            catch (Exception ex)
            {
                return(Task.FromException <IReadOnlyList <(RpcNep17Balance, Nep17Contract)> >(ex));
            }
        }
Ejemplo n.º 2
0
        public static IEnumerable <(Nep17Contract contract, BigInteger balance, uint lastUpdatedBlock)> GetNep17Balances(NeoSystem neoSystem, IStorageProvider storageProvider, 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(storageProvider))
            {
                var from = ToUInt160(notification.State[0]);
                var to   = ToUInt160(notification.State[1]);

                var fromAddress = notification.State[0].IsNull ? "<null>" : from.ToAddress(neoSystem.Settings.AddressVersion);
                var toAddress   = notification.State[1].IsNull ? "<null>" : to.ToAddress(neoSystem.Settings.AddressVersion);

                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 = neoSystem.GetSnapshot();
            foreach (var kvp in assets)
            {
                if (TryGetBalance(kvp.Key, out var balance) &&
                    balance > BigInteger.Zero)
                {
                    var contract = Nep17Contract.TryLoad(neoSystem.Settings, 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 = sb.Invoke(neoSystem.Settings, 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);
            }
        }
Ejemplo n.º 3
0
        public async Task <(Neo.Network.RPC.Models.RpcNep17Balance balance, Nep17Contract contract)[]> GetBalancesAsync(UInt160 address)
        {
            var contracts = ((Neo.IO.Json.JArray) await rpcClient.RpcSendAsync("expressgetnep17contracts"))
                            .Select(json => Nep17Contract.FromJson(json))
                            .ToDictionary(c => c.ScriptHash);
            var balances = await rpcClient.GetNep17BalancesAsync(address.ToAddress()).ConfigureAwait(false);

            return(balances.Balances
                   .Select(b => (
                               balance: b,
                               contract: contracts.TryGetValue(b.AssetHash, out var value)
                        ? value
                        : Nep17Contract.Unknown(b.AssetHash)))
                   .ToArray());
        }
Ejemplo n.º 4
0
        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);
                }
            }
        }
Ejemplo n.º 5
0
        public static IEnumerable <Nep17Contract> GetNep17Contracts(NeoSystem neoSystem, IStorageProvider storageProvider)
        {
            var scriptHashes = new HashSet <UInt160>();

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

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

            using var snapshot = neoSystem.GetSnapshot();
            foreach (var scriptHash in scriptHashes)
            {
                if (Nep17Contract.TryLoad(neoSystem.Settings, snapshot, scriptHash, out var contract))
                {
                    yield return(contract);
                }
            }
        }