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); }
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; } }