public async Task <Error> GenerateFees(BitcoinSecret sourceSecret, BitcoinSecret destinationSecret, int feeCount)
        {
            var feeAmount = Settings.Constants.BTCToSathoshiMultiplicationFactor / 100;
            var coins     = await explorerHelper.GetCoinsForWallet(sourceSecret.GetAddress().ToString(), 10, 0, null, null,
                                                                   null, true) as GetOrdinaryCoinsForWalletReturnType;

            if (coins.Error == null)
            {
                var selectedCoin = coins.Coins.Where(c => c.Amount >= (ulong)feeCount
                                                     * Settings.Constants.BTCToSathoshiMultiplicationFactor).FirstOrDefault();
                if (selectedCoin == null)
                {
                    Error retError = new Error();
                    retError.Message = "Could not find the proper coin to spend.";
                    return(retError);
                }

                try
                {
                    TransactionBuilder builder = new TransactionBuilder();
                    builder.AddKeys(sourceSecret).AddCoins(selectedCoin);
                    for (int i = 0; i < feeCount; i++)
                    {
                        builder.Send(destinationSecret.GetAddress(),
                                     new Money(feeAmount));
                    }
                    builder.SetChange(sourceSecret.GetAddress());
                    builder.SendFees(new Money(feeCount * 100000));

                    var tx = builder.BuildTransaction(true);
                    await transactionBroadcaster.BroadcastTransactionToBlockchain(tx.ToHex());

                    using (BlockchainStateManagerContext context = new BlockchainStateManagerContext())
                    {
                        IList <Fee> fees   = new List <Fee>();
                        var         txHash = tx.GetHash().ToString();
                        for (uint i = 0; i < feeCount; i++)
                        {
                            if (tx.Outputs[i].Value != feeAmount)
                            {
                                continue;
                            }

                            fees.Add(new Fee
                            {
                                Consumed      = false,
                                TransactionId = txHash,
                                OutputNumber  = (int)i,
                                Satoshi       = (long)feeAmount,
                                PrivateKey    = destinationSecret.ToString(),
                                Script        = tx.Outputs[i].ScriptPubKey.ToString()
                            });
                        }
                        context.Fees.AddRange(fees);

                        await context.SaveChangesAsync();
                    }
                }
                catch (Exception exp)
                {
                    Error retError = new Error();
                    retError.Message = string.Format("An exception occured {0}.", exp.ToString());
                    return(retError);
                }

                return(null); // No error
            }

            return(coins.Error);
        }
Beispiel #2
0
        public static async Task <bool> PutBlockchainInAKnownState(string[] privateKeys)
        {
            var settings = settingsProvider.GetSettings();

            try
            {
                var  clientPrivateKey         = new BitcoinSecret(privateKeys[0]);
                var  hubPrivateKey            = new BitcoinSecret(privateKeys[1]);
                var  clientSelfRevokeKey      = new BitcoinSecret(privateKeys[2]);
                var  hubSelfRevokKey          = new BitcoinSecret(privateKeys[3]);
                var  feeSourcePrivateKey      = new BitcoinSecret(new Key(), settings.Network);
                var  feeDestinationPrivateKey = new BitcoinSecret(new Key(), settings.Network);
                uint feeCount = 100;

                AssetDefinition usdAsset = null;
                foreach (var item in (settings as IBlockchainStateManagerSettings).Assets)
                {
                    if (item.Name == "TestExchangeUSD")
                    {
                        usdAsset = item;
                        break;
                    }
                }

                if (!await StartRequiredJobs(true))
                {
                    return(false);
                }

                var bitcoinRPCCLient = GetRPCClient(settings as IBlockchainStateManagerSettings);

                IEnumerable <string> blkIds = null;

                for (int i = 0; i < 201; i++)
                {
                    var blkCount = 1;

                    blkIds = await bitcoinRPCCLient.GenerateBlocksAsync(blkCount);

                    await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                        (blockchainExplorerHelper.HasBlockIndexed, blkIds);
                }

                /*
                 * for (int i = 0; i < 11; i++)
                 * {
                 *  var blkCount = 20;
                 *  if (i == 10)
                 *  {
                 *      blkCount = 1;
                 *  }
                 *
                 *  blkIds = await bitcoinRPCCLient.GenerateBlocksAsync(blkCount);
                 *  await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                 *      (blockchainExplorerHelper.HasBlockIndexed, blkIds);
                 * }
                 */
                await bitcoinRPCCLient.ImportPrivKeyAsync(new BitcoinSecret(usdAsset.PrivateKey));

                var txId = await bitcoinRPCCLient.SendToAddressAsync(new BitcoinSecret(usdAsset.PrivateKey).GetAddress(),
                                                                     new Money(100 * Constants.BTCToSathoshiMultiplicationFactor));

                await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                    (blockchainExplorerHelper.HasTransactionIndexed, new string[] { txId.ToString() });

                txId = await bitcoinRPCCLient.SendToAddressAsync(feeSourcePrivateKey.GetAddress(),
                                                                 new Money((feeCount + 1) * Constants.BTCToSathoshiMultiplicationFactor));

                blkIds = await bitcoinRPCCLient.GenerateBlocksAsync(1);

                await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                    (blockchainExplorerHelper.HasBlockIndexed, blkIds);

                await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                    (blockchainExplorerHelper.HasTransactionIndexed, new string[] { txId.ToString() });

                await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                    (blockchainExplorerHelper.HasBalanceIndexed, new string[] { txId.ToString() }, feeSourcePrivateKey.GetAddress().ToString());

                var error = await feeManager.GenerateFees(feeSourcePrivateKey, feeDestinationPrivateKey, (int)feeCount);

                if (error != null)
                {
                    return(false);
                }

                var signedResp = await GetOffchainSignedSetup(privateKeys);

                await transactionBroadcaster.BroadcastTransactionToBlockchain
                    (signedResp.FullySignedSetupTransaction);

                await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                    (blockchainExplorerHelper.HasTransactionIndexed, new string[] { new Transaction(signedResp.FullySignedSetupTransaction).GetHash().ToString() });

                /*
                 * // Not used
                 * var unsignedCommitment = await offchainHelper.CreateUnsignedCommitmentTransactions(signedResp.FullySignedSetupTransaction, clientPrivateKey.PubKey,
                 *  hubPrivateKey.PubKey, 40, 65, ASSET, hubSelfRevokKey.PubKey, 10, true);
                 */

                var clientSignedCommitment = await Helper.SignTransactionWorker(new TransactionSignRequest
                {
                    TransactionToSign = signedResp.UnsignedClientCommitment0,
                    PrivateKey        = clientPrivateKey.ToString()
                }, SigHash.All | SigHash.AnyoneCanPay);

                var commitmentToLog = clientSignedCommitment;

                /*
                 * var commitmentSpendingResp = await offchainHelper.CreateCommitmentSpendingTransactionForTimeActivatePart(txSendingResult.ToHex(), hubPrivateKey.ToString(),
                 *  clientPrivateKey.PubKey, hubPrivateKey.PubKey, "TestExchangeUSD", hubSelfRevokKey.PubKey, 144, true);
                 */
                var commitmentSpendingResp = await offchainHelper.CreateCommitmentSpendingTransactionForMultisigPart(clientSignedCommitment, clientPrivateKey.PubKey, hubPrivateKey.PubKey,
                                                                                                                     ASSET, 75, hubSelfRevokKey.PubKey, 144, true, clientPrivateKey, hubSelfRevokKey);

                //  Fee is now directly paid from output for bitcoin
                //  txSendingResult = await AddEnoughFeesToTransaction
                //       (new Transaction(commitmentSpendingResp.TransactionHex));

                var hubSignedCommitment = await Helper.SignTransactionWorker(new TransactionSignRequest
                {
                    TransactionToSign = clientSignedCommitment,
                    PrivateKey        = hubPrivateKey.ToString()
                }, SigHash.All | SigHash.AnyoneCanPay);

                // var txSendingResult = await AddEnoughFeesToTransaction
                // (new Transaction(hubSignedCommitment));
                //var txSendingResult = new Transaction(hubSignedCommitment);
                //await transactionBroadcaster.BroadcastTransactionToBlockchain
                //    (txSendingResult.ToHex());
                //await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                //    (blockchainExplorerHelper.HasTransactionIndexed, new string[] { txSendingResult.GetHash().ToString() });
                //await blockchainExplorerHelper.WaitUntillBlockchainExplorerHasIndexed
                //    (blockchainExplorerHelper.HasBalanceIndexedZeroConfirmation, new string[] { txSendingResult.GetHash().ToString() },
                //    clientPrivateKey.PubKey.WitHash.ScriptPubKey.GetScriptAddress(settings.Network).ToString());


                // bool v = await VerifyTransaction(txSendingResult);
                var punishmentToLog = commitmentSpendingResp.TransactionHex;

                using (StreamWriter writer = new StreamWriter("log.txt"))
                {
                    StringBuilder builder = new StringBuilder();
                    builder.AppendLine("HubUnsignedCommitment:");
                    builder.AppendLine(commitmentToLog);

                    builder.AppendLine("HubSignedCommitment");
                    builder.AppendLine(hubSignedCommitment);

                    builder.AppendLine("Punishment:");
                    builder.AppendLine(punishmentToLog);

                    await writer.WriteAsync(builder.ToString());
                }

                return(true);
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }