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); } }
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); } } }
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); } } }