public async Task AddTransfer_Test() { var transfer = new TransferInfo() { BlockHeight = 0, From = UInt160.Parse("0xf9df308b7bb380469354062f6b73f9cb0124317b"), FromBalance = 0, To = UInt160.Parse("0x18c52425debcc3c76c06c3368044b8c60609a904"), ToBalance = 1, Asset = NativeContract.NEO.Hash, Amount = 1, TxId = UInt256.Parse(""), TimeStamp = DateTime.Now.ToTimestamp(), AssetInfo = new AssetInfo() { Asset = NativeContract.NEO.Hash, Name = "NEO", Symbol = "neo", Decimals = NativeContract.NEO.Decimals, }, }; _db.AddTransfer(transfer); //_db.Commit(); }
/// <summary> /// try to find "Transfer" event, then add record to db /// </summary> /// <param name="notification"></param> /// <param name="transaction"></param> /// <param name="block"></param> /// <param name="snapshot"></param> /// <returns></returns> private bool HasTransfer(NotificationInfo notification, Transaction transaction, Block block, SnapshotView snapshot) { var assetHash = UInt160.Parse(notification.Contract); var asset = AssetCache.GetAssetInfo(assetHash, snapshot); if (asset == null) { //not nep5 asset return(false); } var notify = JStackItem.FromJson(notification.State); if (!(notify.Value is IList <JStackItem> notifyArray) || notifyArray.Count < 4) { return(false); } if (!"transfer".Equals(notifyArray[0].ValueString, StringComparison.OrdinalIgnoreCase)) { return(false); } var from = notifyArray[1].Value as byte[]; var to = notifyArray[2].Value as byte[]; if (from == null && to == null) { return(false); } if (!ConvertBigInteger(notifyArray[3], out var amount)) { return(false); } var record = new TransferInfo { BlockHeight = block.Index, From = from == null ? null : new UInt160(from), To = to == null ? null : new UInt160(to), Asset = asset.Asset, Amount = amount, TxId = transaction.Hash, TimeStamp = block.Timestamp, AssetInfo = asset, }; _db.AddTransfer(record); if (record.From != null) { var fromBalance = record.From.GetBalanceOf(assetHash, snapshot); _db.UpdateBalance(record.From, asset, fromBalance.Value, snapshot.Height); } if (record.To != null && record.To != record.From) { var toBalance = record.To.GetBalanceOf(assetHash, snapshot); _db.UpdateBalance(record.To, asset, toBalance.Value, snapshot.Height); } return(true); }
/// <summary> /// analysis block transaction execute result logs /// </summary> /// <param name="blockHeight"></param> /// <returns></returns> public async Task <bool> Sync(uint blockHeight) { if (blockHeight > this.GetCurrentHeight()) { return(false); } if (_db.HasSyncIndex(blockHeight)) { return(true); } var block = blockHeight.GetBlock(); var blockTime = block.Timestamp.FromTimestampMS(); //var balanceChanges = new HashSet<(UInt160 account, UInt160 asset)>(); foreach (var transaction in block.Transactions) { _db.AddTransaction(new TransactionInfo() { TxId = transaction.Hash, BlockHeight = blockHeight, Sender = transaction.Sender, Time = blockTime, }); //balanceChanges.Add((transaction.Sender, NativeContract.GAS.Hash)); var invokeMethods = GetInvokeMethods(transaction); if (invokeMethods.NotEmpty()) { foreach (var invokeMethod in invokeMethods) { _db.AddInvokeTransaction(transaction.Hash, invokeMethod.contract, string.Join(',', invokeMethod.methods)); } } } SyncContracts(blockHeight, blockTime); var transfers = new List <TransferInfo>(); var transferItems = _levelDb.GetTransfers(blockHeight); if (transferItems.NotEmpty()) { foreach (var item in transferItems) { transfers.Add(new TransferInfo() { BlockHeight = blockHeight, TimeStamp = block.Timestamp, TxId = item.TxId, From = item.From, To = item.To, Amount = item.Amount, Asset = item.Asset, Trigger = item.Trigger, }); } } foreach (var transferInfo in transfers) { _db.AddTransfer(transferInfo); } var balanceChanges = _levelDb.GetBalancingAccounts(blockHeight); if (balanceChanges.NotEmpty()) { var snapshot = this.GetDefaultSnapshot(); foreach (var balanceChange in balanceChanges) { UpdateBalance(balanceChange.Account, balanceChange.Asset, snapshot); } } _db.AddSyncIndex(blockHeight); _db.Commit(); Console.WriteLine($"Synced:{_scanHeight}"); if (_db.LiveTime.TotalSeconds > 15) { //release memory _db.Dispose(); _db = new TrackDB(); } return(true); }