WalletTx AddOutgoingTx(string from, string signedTx, WalletTag tagFor) { var address = db.AddrGet(from); var tx = new Transaction(signedTx.HexToByteArray()); var date = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var fee = HexBigIntegerConvertorExtensions.HexToBigInteger(tx.GasLimit.ToHex(), false) * HexBigIntegerConvertorExtensions.HexToBigInteger(tx.GasPrice.ToHex(), false); var amount = HexBigIntegerConvertorExtensions.HexToBigInteger(tx.Value.ToHex(), false); logger.LogDebug("outgoing tx: amount: {0}, fee: {1}", amount, fee); // create chain tx var ctx = new ChainTx(tx.Hash.ToHex(true), date, fee, -1, 0); db.ChainTxs.Add(ctx); var networkStatus = new ChainTxNetworkStatus(ctx, ChainTxStatus.Unconfirmed, date, signedTx.HexToByteArray()); db.ChainTxNetworkStatus.Add(networkStatus); // create tx input var i = new TxInput(tx.Hash.ToHex(true), from, 0, amount + fee); i.ChainTx = ctx; i.WalletAddr = address; db.TxInputs.Add(i); // create tx output var o = new TxOutput(tx.Hash.ToHex(true), tx.ReceiveAddress.ToHex(true), 0, amount); o.ChainTx = ctx; db.TxOutputs.Add(o); if (tagFor != null) { db.TxOutputsForTag.Add(new TxOutputForTag { TxOutput = o, Tag = tagFor }); } // create wallet tx var wtx = new WalletTx { ChainTx = ctx, Address = address, Direction = WalletDirection.Outgoing }; db.WalletTxs.Add(wtx); return(wtx); }
ChainTx AddUpdateChainTx(Transaction trans, string id, long date, long confs, long height, BigInteger fee, byte[] attachment, ref bool sufficientTxsQueried) { // add/update chain tx var ctx = db.ChainTxGet(id); if (ctx == null) { ctx = new ChainTx(id, date, fee, height, confs); db.ChainTxs.Add(ctx); } else { ctx.Height = height; ctx.Confirmations = confs; db.ChainTxs.Update(ctx); // if we are replacing txs already in our wallet we have queried sufficent txs for this account sufficientTxsQueried = true; } var status = confs > 0 ? ChainTxStatus.Confirmed : ChainTxStatus.Unconfirmed; if (ctx.NetworkStatus == null) { var networkStatus = new ChainTxNetworkStatus(ctx, status, 0, trans.GetBytes()); db.ChainTxNetworkStatus.Add(networkStatus); } else { // transaction update comes from our trusted node so we will override any status we have set manually ctx.NetworkStatus.Status = status; db.ChainTxNetworkStatus.Update(ctx.NetworkStatus); } if (ctx.Attachment == null && attachment != null && attachment.Length > 0) { var att = new ChainAttachment(ctx, attachment); db.ChainAttachments.Add(att); } return(ctx); }
IEnumerable <WalletTx> AddOutgoingTx(Transaction tx, List <CoinSpend> spents, List <CoinOutput> outputs, BigInteger fee, WalletTag tagFor) { var txid = tx.GetHash().ToString(); logger.LogDebug("outgoing tx: outputs: {0}, fee: {1}", outputs.Select(o => o.Amount), fee); var date = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); // create chain tx var ctx = db.ChainTxGet(txid); if (ctx == null) { ctx = new ChainTx(txid, date, fee, -1, 0); db.ChainTxs.Add(ctx); } if (ctx.NetworkStatus == null) { var networkStatus = new ChainTxNetworkStatus(ctx, ChainTxStatus.Unconfirmed, date, tx.ToBytes()); db.ChainTxNetworkStatus.Add(networkStatus); } // create tx inputs uint n = 0; foreach (var spent in spents) { if (db.TxInputGet(txid, n) == null) { var i = new TxInput(txid, spent.From, n, spent.Coin.Amount.Satoshi); i.ChainTx = ctx; i.WalletAddr = spent.Addr; db.TxInputs.Add(i); } n++; } // create tx outputs n = 0; foreach (var output in outputs) { if (db.TxOutputGet(txid, n) == null) { var o = new TxOutput(txid, output.To, n, output.Amount); o.ChainTx = ctx; db.TxOutputs.Add(o); if (tagFor != null) { db.TxOutputsForTag.Add(new TxOutputForTag { TxOutput = o, Tag = tagFor }); } } n++; } // create wallet txs var wtxs = new List <WalletTx>(); foreach (var spent in spents) { if (spent.Addr == null) { continue; } var wtx = db.TxGet(spent.Addr, ctx, WalletDirection.Outgoing); if (wtx == null) { wtx = new WalletTx { ChainTx = ctx, Address = spent.Addr, Direction = WalletDirection.Outgoing, State = WalletTxState.None }; db.WalletTxs.Add(wtx); } wtxs.Add(wtx); } return(wtxs); }
private void processUtxo(NBXplorer.Models.UTXO utxo, int currentHeight) { //TODO - add attachment // - read OP_RETURN ? //var addr = AddressOf(pubkey.Root, utxo.KeyPath); var to = utxo.ScriptPubKey.GetDestinationAddress(GetNetwork()); var id = utxo.Outpoint.Hash.ToString(); var date = utxo.Timestamp.ToUnixTimeSeconds(); var height = utxo.Confirmations > 0 ? currentHeight - (utxo.Confirmations - 1) : -1; logger.LogInformation($"processing UTXO - txid {id} - destination addr {to} - value {utxo.Value}"); var address = db.AddrGet(to.ToString()); if (address == null) { logger.LogError($"Address not found for {to}"); return; } // add/update chain tx var ctx = db.ChainTxGet(id); if (ctx == null) { ctx = new ChainTx(id, date, -1, height, utxo.Confirmations); db.ChainTxs.Add(ctx); } else { ctx.Height = height; ctx.Confirmations = utxo.Confirmations; db.ChainTxs.Update(ctx); } var status = utxo.Confirmations > 0 ? ChainTxStatus.Confirmed : ChainTxStatus.Unconfirmed; if (ctx.NetworkStatus == null) { var txResult = GetClient().GetTransaction(utxo.Outpoint.Hash); var networkStatus = new ChainTxNetworkStatus(ctx, status, 0, txResult.Transaction.ToBytes()); db.ChainTxNetworkStatus.Add(networkStatus); } else { // transaction update comes from our trusted node so we will override any status we have set manually ctx.NetworkStatus.Status = status; db.ChainTxNetworkStatus.Update(ctx.NetworkStatus); } // add output var o = db.TxOutputGet(id, utxo.Outpoint.N); if (o == null) { o = new TxOutput(id, address.Address, utxo.Outpoint.N, utxo.Value.Satoshi); o.ChainTx = ctx; o.WalletAddr = address; db.TxOutputs.Add(o); } else if (o.WalletAddr == null) { logger.LogInformation($"Updating output with no address: {id}, {o.N}, {address.Address}"); o.WalletAddr = address; db.TxOutputs.Update(o); } // add/update wallet tx var wtx = db.TxGet(address, ctx, WalletDirection.Incomming); if (wtx == null) { wtx = new WalletTx { ChainTx = ctx, Address = address, Direction = WalletDirection.Incomming, State = WalletTxState.None }; db.WalletTxs.Add(wtx); } }