Пример #1
0
 public CoinSpend(string from, WalletAddr addr, Coin coin, Key key)
 {
     From = from;
     Addr = addr;
     Coin = coin;
     Key  = key;
 }
Пример #2
0
        void AddFeeInput(WalletAddr address, ChainTx ctx, uint nIn, string sender, BigInteger fee, bool updateInputsAndOutputs)
        {
            // add fee input
            var i = db.TxInputGet(ctx.TxId, nIn);

            if (i == null)
            {
                i         = new TxInput(ctx.TxId, sender, nIn, fee);
                i.ChainTx = ctx;
                if (sender == address.Address)
                {
                    i.WalletAddr = address;
                }
                db.TxInputs.Add(i);
            }
            else if (i.WalletAddr == null && i.Addr == address.Address)
            {
                logger.LogInformation($"Updating input (fee) with no address: {ctx.TxId}, {i.N}, {address.Address}");
                i.WalletAddr = address;
                db.TxInputs.Update(i);
            }
            else if (updateInputsAndOutputs && i.Amount != fee)
            {
                logger.LogInformation($"Updating input (fee) amount: {ctx.TxId}, {i.N}, {address.Address} (from {i.Amount} to {fee}");
                i.Amount = fee;
                db.TxInputs.Update(i);
            }
        }
Пример #3
0
        private void UpdateTxConfirmations(WalletAddr addr)
        {
            var baddr         = BitcoinAddress.Create(addr.Address, GetNetwork());
            var trackedSource = TrackedSource.Create(baddr);
            var txs           = GetClient().GetTransactions(trackedSource);

            UpdateTxConfirmations(txs);
        }
Пример #4
0
        public override WalletAddr NewAddress(string tag)
        {
            // create new address that is unused
            var _tag = db.TagGet(tag);

            Util.WalletAssert(_tag != null, $"Tag '{tag}' does not exist");
            var keypathInfo = GetClient().GetUnused(pubkey, DerivationFeature.Deposit, reserve: true);
            var addr        = keypathInfo.ScriptPubKey.GetDestinationAddress(GetClient().Network.NBitcoinNetwork);
            var address     = new WalletAddr(_tag, keypathInfo.KeyPath.ToString(), 0, addr.ToString());

            // add to address list
            db.WalletAddrs.Add(address);
            return(address);
        }
Пример #5
0
        public override WalletAddr NewAddress(string tag)
        {
            var nonce = db.LastPathIndex;

            db.LastPathIndex++;
            // create new address that is unused
            var _tag = db.TagGet(tag);

            Util.WalletAssert(_tag != null, $"Tag '{tag}' does not exist");
            var acct    = CreateAccount(nonce);
            var address = new WalletAddr(_tag, nonce.ToString(), nonce, acct.Address);

            // add to address list
            db.WalletAddrs.Add(address);
            return(address);
        }
Пример #6
0
        public BitcoinAddress AddChangeAddress(WalletTag tag)
        {
            // get new unused address
            var keypathInfo = GetClient().GetUnused(pubkey, DerivationFeature.Change, reserve: false);
            var addr        = keypathInfo.ScriptPubKey.GetDestinationAddress(GetNetwork());
            // check that address is not already present in the db (we used 'reserve: false')
            var address = db.AddrGet(addr.ToString());

            if (address != null)
            {
                return(addr);
            }
            // add to address list
            address = new WalletAddr(tag, keypathInfo.KeyPath.ToString(), 0, addr.ToString());
            db.WalletAddrs.Add(address);
            return(addr);
        }
Пример #7
0
        public override WalletAddr NewAddress(string tag)
        {
            var pathIndex = db.LastPathIndex + 1;
            // create new address that is unused
            var _tag = db.TagGet(tag);

            Util.WalletAssert(_tag != null, $"Tag '{tag}' does not exist");
            var acct    = wallet.GetAccount(pathIndex);
            var address = new WalletAddr(_tag, PATH.Replace("x", pathIndex.ToString()), pathIndex, acct.Address);

            // regsiter address with gethtxscan
            scanClient.DownloadString(gethTxScanAddress + "/watch_account/" + acct.Address);
            // add to address list
            db.WalletAddrs.Add(address);
            // update last path index and return address
            db.LastPathIndex = pathIndex;
            return(address);
        }
Пример #8
0
        void AddOutputInputAndWalletTx(WalletAddr address, ChainTx ctx, uint nOut, string sender, string recipient, BigInteger amount)
        {
            // add output
            var o = db.TxOutputGet(ctx.TxId, nOut);

            if (o == null)
            {
                o         = new TxOutput(ctx.TxId, recipient, nOut, amount);
                o.ChainTx = ctx;
                if (recipient == address.Address)
                {
                    o.WalletAddr = address;
                }
                db.TxOutputs.Add(o);
            }
            else if (o.WalletAddr == null && o.Addr == address.Address)
            {
                logger.LogInformation($"Updating output with no address: {ctx.TxId}, {o.N}, {address.Address}");
                o.WalletAddr = address;
                db.TxOutputs.Update(o);
            }
            // add input (so we can see who its from)
            var i = db.TxInputGet(ctx.TxId, nOut);

            if (i == null)
            {
                i         = new TxInput(ctx.TxId, sender, nOut, amount);
                i.ChainTx = ctx;
                db.TxInputs.Add(i);
            }
            // add / update wallet tx
            var dir = recipient == address.Address ? WalletDirection.Incomming : WalletDirection.Outgoing;
            var wtx = db.TxGet(address, ctx, dir);

            if (wtx == null)
            {
                wtx = new WalletTx {
                    ChainTx = ctx, Address = address, Direction = dir, State = WalletTxState.None
                };
                db.WalletTxs.Add(wtx);
            }
        }
Пример #9
0
 public WalletTx TxGet(WalletAddr addr, ChainTx tx, WalletDirection dir)
 {
     return(WalletTxs.SingleOrDefault(t => t.WalletAddrId == addr.Id && t.ChainTxId == tx.Id && t.Direction == dir));
 }
Пример #10
0
 public CoinCandidate(WalletAddr addr, Coin coin, UTXO utxo)
 {
     Addr = addr;
     Coin = coin;
     Utxo = utxo;
 }
Пример #11
0
 public BigInteger GetAddrBalance(WalletAddr addr, int minConfs = 0)
 {
     return(addr.Balance(minConfs));
 }
Пример #12
0
        void UpdateTxs(WalletAddr address)
        {
            //TODO - add attachment
            // - read the 'data' field (https://ethereum.stackexchange.com/questions/2466/how-do-i-send-an-arbitary-message-to-an-ethereum-address)

            var blockNumTask = web3.Eth.Blocks.GetBlockNumber.SendRequestAsync();

            blockNumTask.Wait();
            var blockNum = (long)blockNumTask.Result.Value;
            var json     = scanClient.DownloadString(gethTxScanAddress + "/list_transactions/" + address.Address);
            var scantxs  = JsonConvert.DeserializeObject <List <scantx> >(json);

            foreach (var scantx in scantxs)
            {
                long confirmations = 0;
                if (scantx.block_num > 0)
                {
                    confirmations = blockNum - scantx.block_num;
                }
                // add/update chain tx
                var ctx = db.ChainTxGet(scantx.txid);
                if (ctx == null)
                {
                    ctx = new ChainTx(scantx.txid, scantx.date, -1, scantx.block_num, confirmations);
                    db.ChainTxs.Add(ctx);
                }
                else
                {
                    ctx.Height        = scantx.block_num;
                    ctx.Confirmations = confirmations;
                    db.ChainTxs.Update(ctx);
                }
                var status = confirmations > 0 ? ChainTxStatus.Confirmed : ChainTxStatus.Unconfirmed;
                if (ctx.NetworkStatus == null)
                {
                    //TODO: we need txdata from scantx, to be able to rebroadcast if necessary
                    //var networkStatus = new ChainTxNetworkStatus(ctx, status, 0, scantx.txdata/*TODO*/);
                    //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(scantx.txid, 0);
                if (o == null)
                {
                    o         = new TxOutput(scantx.txid, scantx.to, 0, BigInteger.Parse(scantx.value));
                    o.ChainTx = ctx;
                    if (scantx.to == address.Address)
                    {
                        o.WalletAddr = address;
                    }
                    db.TxOutputs.Add(o);
                }
                else if (o.WalletAddr == null && o.Addr == address.Address)
                {
                    logger.LogInformation($"Updating output with no address: {scantx.txid}, {o.N}, {address.Address}");
                    o.WalletAddr = address;
                    db.TxOutputs.Update(o);
                }
                // add input (so we can see who its from)
                var i = db.TxInputGet(scantx.txid, 0);
                if (i == null)
                {
                    i         = new TxInput(scantx.txid, scantx.from_, 0, BigInteger.Parse(scantx.value) /*+ fee*/); //TODO: add fee
                    i.ChainTx = ctx;
                    db.TxInputs.Add(i);
                }
                // add / update wallet tx
                var dir = scantx.to == address.Address ? WalletDirection.Incomming : WalletDirection.Outgoing;
                var wtx = db.TxGet(address, ctx, dir);
                if (wtx == null)
                {
                    wtx = new WalletTx {
                        ChainTx = ctx, Address = address, Direction = dir, State = WalletTxState.None
                    };
                    db.WalletTxs.Add(wtx);
                }
            }
        }
Пример #13
0
        void UpdateTxs(WalletAddr address, long blockHeight, bool updateInputsAndOutputs)
        {
            var    sufficientTxsQueried = false;
            var    processedTxs         = new Dictionary <string, Transaction>();
            var    limit = 100;
            string after = null;

            while (!sufficientTxsQueried)
            {
                var nodeTxs = node.GetTransactions(address.Address, limit, after);
                logger.LogDebug($"UpdateTxs ({address.Address}) count: {nodeTxs.Count()}, limit: {limit}, after: {after}, processedCount: {processedTxs.Count()}");

                // if less txs are returned then we requested we have all txs for this account
                if (nodeTxs.Count() < limit)
                {
                    sufficientTxsQueried = true;
                }

                foreach (var nodeTx in nodeTxs)
                {
                    after = nodeTx.GenerateId();
                    // get common waves tx params
                    var id    = nodeTx.GenerateId();
                    var date  = ((DateTimeOffset)nodeTx.Timestamp).ToUnixTimeSeconds();
                    var confs = nodeTx.Height > 0 ? (blockHeight - nodeTx.Height) + 1 : 0;
                    // skip any txs we have already processed
                    if (processedTxs.ContainsKey(id))
                    {
                        continue;
                    }
                    if (nodeTx is TransferTransaction)
                    {
                        var trans = (TransferTransaction)nodeTx;
                        if (trans.Asset.Id == assetId)
                        {
                            var amount     = trans.Asset.AmountToLong(trans.Amount);
                            var fee        = trans.FeeAsset.AmountToLong(trans.Fee);
                            var attachment = trans.Attachment;

                            // add/update chain tx
                            var ctx = AddUpdateChainTx(trans, id, date, confs, nodeTx.Height, fee, attachment, ref sufficientTxsQueried);
                            // add output, input and wallet tx
                            AddOutputInputAndWalletTx(address, ctx, 0, trans.Sender, trans.Recipient, amount, updateInputsAndOutputs);
                            // add fee input
                            AddFeeInput(address, ctx, 1, trans.Sender, fee, updateInputsAndOutputs);

                            // record the transactions we have processed already
                            processedTxs[id] = trans;
                        }
                    }
                    else if (nodeTx is MassTransferTransaction)
                    {
                        var massTx = (MassTransferTransaction)nodeTx;
                        if (massTx.Asset.Id == assetId)
                        {
                            var attachment = massTx.Attachment;
                            var fee        = Assets.WAVES.AmountToLong(massTx.Fee);

                            // add/update chain tx
                            var ctx = AddUpdateChainTx(massTx, id, date, confs, nodeTx.Height, fee, attachment, ref sufficientTxsQueried);
                            // process transfers
                            uint n = 0;
                            foreach (var trans in massTx.Transfers)
                            {
                                var amount = massTx.Asset.AmountToLong(trans.Amount);
                                // add output, input and wallet tx
                                AddOutputInputAndWalletTx(address, ctx, n, massTx.Sender, trans.Recipient, amount, updateInputsAndOutputs);
                                n++;
                            }
                            // add fee input
                            AddFeeInput(address, ctx, n, massTx.Sender, fee, updateInputsAndOutputs);

                            // record the transactions we have processed already
                            processedTxs[id] = massTx;
                        }
                    }
                }
            }
        }