Ejemplo n.º 1
0
        public IBitcoinBasedTransaction CreateHtlcP2PkhSwapPaymentTx(BitcoinBasedCurrency currency)
        {
            var       initTx = BitcoinBasedCommon.CreateFakeTx(currency, Common.Alice.PubKey, 1_0000_0000, 1_0000_0000);
            const int amount = 1_0000_0000;
            const int fee    = 1_0000;
            //const int change = 9999_0000;

            var tx = currency.CreateHtlcP2PkhSwapPaymentTx(
                unspentOutputs: initTx.Outputs,
                aliceRefundAddress: Common.Alice.PubKey.GetAddress(currency),
                bobAddress: Common.Bob.PubKey.GetAddress(currency),
                lockTime: DateTimeOffset.UtcNow.AddHours(1),
                secretHash: Common.SecretHash,
                secretSize: Common.Secret.Length,
                amount: amount,
                fee: fee);

            Assert.NotNull(tx);
            Assert.True(tx.Check());
            Assert.Equal(initTx.TotalOut - fee, tx.TotalOut);
            Assert.Equal(fee, tx.GetFee(initTx.Outputs));

            return(tx);
        }
Ejemplo n.º 2
0
        public async Task <IBitcoinBasedTransaction> CreateSwapPaymentTxAsync(
            BitcoinBasedCurrency currency,
            ClientSwap swap,
            IEnumerable <string> fromWallets,
            string refundAddress,
            string toAddress,
            DateTimeOffset lockTime,
            byte[] secretHash,
            int secretSize,
            ITxOutputSource outputsSource)
        {
            var availableOutputs = (await outputsSource
                                    .GetAvailableOutputsAsync(currency, fromWallets)
                                    .ConfigureAwait(false))
                                   .ToList();

            var fee         = 0L;
            var orderAmount = (long)(AmountHelper.QtyToAmount(swap.Side, swap.Qty, swap.Price) *
                                     currency.DigitsMultiplier);

            var requiredAmount = orderAmount + fee;

            long usedAmount;
            IList <ITxOutput>        usedOutputs;
            IBitcoinBasedTransaction tx;

            do
            {
                usedOutputs = availableOutputs
                              .SelectOutputsForAmount(requiredAmount)
                              .ToList();

                usedAmount = usedOutputs.Sum(o => o.Value);

                if (usedAmount < requiredAmount)
                {
                    throw new Exception($"Insufficient funds. Available {usedAmount}, required {requiredAmount}");
                }

                var estimatedSigSize = EstimateSigSize(usedOutputs);

                tx = currency.CreateHtlcP2PkhSwapPaymentTx(
                    unspentOutputs: usedOutputs,
                    aliceRefundAddress: refundAddress,
                    bobAddress: toAddress,
                    lockTime: lockTime,
                    secretHash: secretHash,
                    secretSize: secretSize,
                    amount: orderAmount,
                    fee: fee);

                var txSize = tx.VirtualSize();

                fee = (long)(currency.FeeRate * (txSize + estimatedSigSize));

                requiredAmount = orderAmount + fee;
            } while (usedAmount < requiredAmount);

            tx = currency.CreateHtlcP2PkhSwapPaymentTx(
                unspentOutputs: usedOutputs,
                aliceRefundAddress: refundAddress,
                bobAddress: toAddress,
                lockTime: lockTime,
                secretHash: secretHash,
                secretSize: secretSize,
                amount: orderAmount,
                fee: fee);

            return(tx);
        }