Exemplo n.º 1
0
        public string DepositBtc(string btcPubKey, string recipient, decimal amount)
        {
            var address = new BitcoinPubKeyAddress(btcPubKey, Network.TestNet);
            //var address = new BitcoinSecret(btcPubKey);
            var txOperations = QClient.GetBalance(dest: address, unspentOnly: true).Result.Operations;

            var coins = new List <Coin>();

            foreach (var op in txOperations)
            {
                op.ReceivedCoins.ForEach(c => coins.Add((Coin)c));
            }

            coins.Sort(delegate(Coin x, Coin y)
            {
                return(-x.Amount.CompareTo(y.Amount));
            });

            var coinSum = 0m;

            for (int i = 0; coinSum < amount; i++)
            {
                coinSum += coins[i].Amount.ToDecimal(MoneyUnit.BTC);
                if (coinSum >= amount)
                {
                    coins.RemoveRange(i + 1, coins.Count - (i + 1));
                }
            }

            var builder     = new TransactionBuilder();
            var destination = new BitcoinPubKeyAddress(recipient, Network.TestNet);

            NBitcoin.Transaction tx = builder
                                      .AddCoins(coins)
                                      //.AddKeys(testAddress)
                                      .Send(destination, Money.Coins(amount))
                                      .SetChange(address)
                                      .SendFees(Money.Coins(0.0001m))
                                      .BuildTransaction(sign: false);

            tx.Outputs.Add(new TxOut
            {
                Value        = Money.Zero,
                ScriptPubKey = TxNullDataTemplate.Instance.GenerateScriptPubKey(Encoding.UTF8.GetBytes(recipient))
            });

            foreach (var input in tx.Inputs)
            {
                input.ScriptSig = address.ScriptPubKey;
            }

            var txhash = tx.ToHex();

            if (builder.Verify(tx))
            {
                var broadcastResult = QClient.Broadcast(tx).Result;
            }

            return(tx.ToHex());
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public void ProcessTransaction(Transaction transaction, int?blockHeight = null, Block block = null)
        {
            Guard.NotNull(transaction, nameof(transaction));

            var hash = transaction.GetHash();

            this.logger.LogTrace($"transaction received - hash: {hash}, coin: {this.coinType}");

            // load the keys for lookup if they are not loaded yet.
            if (this.keysLookup == null)
            {
                this.LoadKeysLookup();
            }

            // check the outputs
            foreach (TxOut utxo in transaction.Outputs)
            {
                // check if the outputs contain one of our addresses
                if (this.keysLookup.TryGetValue(utxo.ScriptPubKey, out HdAddress pubKey))
                {
                    this.AddTransactionToWallet(transaction.ToHex(), hash, transaction.Time, transaction.Outputs.IndexOf(utxo), utxo.Value, utxo.ScriptPubKey, blockHeight, block);
                }
            }

            // check the inputs - include those that have a reference to a transaction containing one of our scripts and the same index
            foreach (TxIn input in transaction.Inputs.Where(txIn => this.keysLookup.Values.Distinct().SelectMany(v => v.Transactions).Any(trackedTx => trackedTx.Id == txIn.PrevOut.Hash && trackedTx.Index == txIn.PrevOut.N)))
            {
                TransactionData tTx = this.keysLookup.Values.Distinct().SelectMany(v => v.Transactions).Single(trackedTx => trackedTx.Id == input.PrevOut.Hash && trackedTx.Index == input.PrevOut.N);

                // find the script this input references
                var keyToSpend = this.keysLookup.First(v => v.Value.Transactions.Contains(tTx)).Key;

                // get the details of the outputs paid out.
                IEnumerable <TxOut> paidoutto = transaction.Outputs.Where(o =>
                {
                    // if script is empty ignore it
                    if (o.IsEmpty)
                    {
                        return(false);
                    }

                    var found = this.keysLookup.TryGetValue(o.ScriptPubKey, out HdAddress addr);

                    // include the keys we don't hold
                    if (!found)
                    {
                        return(true);
                    }

                    // include the keys we do hold but that are for receiving
                    // addresses (which would mean the user paid itself).
                    return(!addr.IsChangeAddress());
                });

                this.AddSpendingTransactionToWallet(transaction.ToHex(), hash, transaction.Time, paidoutto, tTx.Id, tTx.Index, blockHeight, block);
            }
        }
Exemplo n.º 3
0
    public static void Spend(this Transaction txn, Action <string> a)
    {
        var txnReportRequest = new HTTPRequest(
            new Uri(TxnBroadcastEndpoint), HTTPMethods.Post,
            (txnR, txnResponse) =>
        {
            try
            {
                var response = JsonConvert.DeserializeAnonymousType(txnResponse.DataAsText,
                                                                    new { Success = false, R = "", Message = "" });
                if (!response.Success)
                {
                    Debug.LogError("Spend response was unsuccessful - " + response.Message);
                    Debug.LogError(txnResponse.DataAsText);
                    throw new SpendUTXOException(response.Message);
                }

                var hashRegex = new Regex(@"^([A-Fa-f0-9]{64})$");
                if (hashRegex.IsMatch(response.R))
                {
                    a(response.R);
                }
                else
                {
                    Debug.LogError("Failed spending utxo, return hash wasn't an hash");
                    Debug.LogError(txnResponse.DataAsText);
                    throw new SpendUTXOException(txnResponse.DataAsText);
                }
            }
            catch (Exception e)
            {
                if (txnResponse != null)
                {
                    Debug.LogError("Fatal error: " + txnResponse.DataAsText);
                }
                else
                {
                    Debug.LogError("Failed to spend transaction");
                    Debug.LogError(txnR.Exception.Message);
                }

                Debug.LogError($"{e.GetType()}: {e.Message}");

                ModalDialog.Instance.CallbackYes.AddListener(() => { SceneManager.LoadScene("Main"); });
                ModalDialog.Instance.Show("Failed to spend UTXO",
                                          $"{e.GetType()}: {e.Message}",
                                          "Ok");

                //Debug.LogError(JsonConvert.SerializeObject(txn));
                //Debug.LogError($"{{\"tx\":\"{txn.ToHex()}\"}}");
            }
        });

        txnReportRequest.AddHeader("Content-Type", "application/json");
        txnReportRequest.RawData = Encoding.UTF8.GetBytes($"{{\"tx\":\"{txn.ToHex()}\"}}");
        txnReportRequest.Send();
    }
 public async Task BroadcastAsync(Transaction tx)
 {
     if(tx == null)
         throw new ArgumentNullException("tx");
     var jsonTx = new JObject();
     jsonTx["hex"] = tx.ToHex();
     var content = new StringContent(jsonTx.ToString(), Encoding.UTF8, "application/json");
     using(var response = await Client.PostAsync(BlockrAddress + BroadcastPath, content).ConfigureAwait(false))
     {
         var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
         var json = JObject.Parse(result);
         var status = json["status"];
         var code = json["code"];
         if(status != null && (status.ToString() == "error" || status.ToString() == "fail"))
         {
             throw new BlockrException(json);
         }
     }
 }
Exemplo n.º 5
0
        public UnsignedTransaction SendTransactionToExchage(dynamic transactionDto, string toAddress, string privateKey, string network, string token)
        {
            try
            {
                var      btcnetwork = GetNetwork(network);
                Endpoint endpoint   = Endpoint.BtcTest3;
                if (network.ToUpper() == "MAIN")
                {
                    endpoint = Endpoint.BtcMain;
                }
                Blockcypher          blockCypherLib = new Blockcypher(token, endpoint);
                BitcoinSecret        secret         = new BitcoinSecret(privateKey, btcnetwork);
                NBitcoin.Transaction tx             = NBitcoin.Transaction.Create(btcnetwork);
                TxIn input = new TxIn
                {
                    PrevOut   = new OutPoint(new uint256(transactionDto.TransactionID), transactionDto.Vout),
                    ScriptSig = secret.GetAddress(ScriptPubKeyType.Legacy).ScriptPubKey
                };
                tx.Inputs.Add(input);

                TxOut output      = new TxOut();
                Money fee         = Money.Coins(transactionDto.DefaultFees.GetValueOrDefault());
                Money totalAmount = Money.Coins(transactionDto.Amount);
                output.Value = totalAmount - fee;
                BitcoinAddress toaddress = BitcoinAddress.Create(toAddress, btcnetwork);
                output.ScriptPubKey = toaddress.ScriptPubKey;
                tx.Outputs.Add(output);

                var coins = tx.Inputs.Select(txin => new Coin(txin.PrevOut, new TxOut {
                    ScriptPubKey = txin.ScriptSig
                }));
                tx.Sign(secret, coins.ToArray());
                var response = blockCypherLib.PushTransaction(tx.ToHex()).Result;
                return(response);
            }
            catch (Exception ex)
            {
                throw new Exception();
            }
        }
        public static string GetHexSignedTransaction(TransactionToSign txToSign)
        {
            var walletPrivateKey = ConfigurationManager.AppSettings[METACO_ENV_WALLET_PRIVATE_KEY_HEX_NAME];

            var key = new Key(Encoders.Hex.DecodeData(walletPrivateKey));

            var scriptPubKey = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(key.PubKey);
            var tx = new Transaction(Encoders.Hex.DecodeData(txToSign.Raw));

            foreach(var inputsToSign in txToSign.InputsToSign)
            {
                var sigHash = tx.GetSignatureHash(scriptPubKey, inputsToSign.Index);
                var sig = key.Sign(sigHash);

                var txSign = new TransactionSignature(sig, SigHash.All);
                var inputScript = PayToPubkeyHashTemplate.Instance.GenerateScriptSig(txSign, key.PubKey);

                tx.Inputs[inputsToSign.Index].ScriptSig = inputScript;
                Assert.True(Script.VerifyScript(scriptPubKey, tx, inputsToSign.Index));
            }

            return tx.ToHex();
        }
 public TransactionModel(NBitcoin.Transaction trx)
 {
     hex = trx?.ToHex();
 }
Exemplo n.º 8
0
 public string getHexTransaction()
 {
     return(transaction.ToHex());
 }
        /// <inheritdoc />
        public (string hex, uint256 transactionId, Money fee) BuildTransaction(string walletName, string accountName, string password, string destinationAddress, Money amount, string feeType, int minConfirmations)
        {
            if (amount == Money.Zero)
            {
                throw new WalletException($"Cannot send transaction with 0 {this.coinType}");
            }

            // get the wallet and the account
            Wallet    wallet  = this.GetWalletByName(walletName);
            HdAccount account = wallet.AccountsRoot.Single(a => a.CoinType == this.coinType).GetAccountByName(accountName);

            // get a list of transactions outputs that have not been spent
            var spendableTransactions = account.GetSpendableTransactions().ToList();

            // remove whats under min confirmations
            var currentHeight = this.chain.Height;

            spendableTransactions = spendableTransactions.Where(s => currentHeight - s.BlockHeight >= minConfirmations).ToList();

            // get total spendable balance in the account.
            var balance = spendableTransactions.Sum(t => t.Amount);

            // make sure we have enough funds
            if (balance < amount)
            {
                throw new WalletException("Not enough funds.");
            }

            // calculate which addresses needs to be used as well as the fee to be charged
            var calculationResult = this.CalculateFees(spendableTransactions, amount);

            // get extended private key
            var privateKey = Key.Parse(wallet.EncryptedSeed, password, wallet.Network);
            var seedExtKey = new ExtKey(privateKey, wallet.ChainCode);

            var signingKeys = new HashSet <ISecret>();
            var coins       = new List <Coin>();

            foreach (var transactionToUse in calculationResult.transactionsToUse)
            {
                var           address           = account.FindAddressesForTransaction(t => t.Id == transactionToUse.Id && t.Index == transactionToUse.Index && t.Amount > 0).Single();
                ExtKey        addressExtKey     = seedExtKey.Derive(new KeyPath(address.HdPath));
                BitcoinExtKey addressPrivateKey = addressExtKey.GetWif(wallet.Network);
                signingKeys.Add(addressPrivateKey);

                coins.Add(new Coin(transactionToUse.Id, (uint)transactionToUse.Index, transactionToUse.Amount, transactionToUse.ScriptPubKey));
            }

            // get address to send the change to
            var changeAddress = account.GetFirstUnusedChangeAddress();

            // get script destination address
            Script destinationScript = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(new BitcoinPubKeyAddress(destinationAddress, wallet.Network));

            // build transaction
            var         builder = new TransactionBuilder();
            Transaction tx      = builder
                                  .AddCoins(coins)
                                  .AddKeys(signingKeys.ToArray())
                                  .Send(destinationScript, amount)
                                  .SetChange(changeAddress.ScriptPubKey)
                                  .SendFees(calculationResult.fee)
                                  .BuildTransaction(true);

            if (!builder.Verify(tx))
            {
                throw new WalletException("Could not build transaction, please make sure you entered the correct data.");
            }

            return(tx.ToHex(), tx.GetHash(), calculationResult.fee);
        }
        public async Task <string> WithdrawBtc(string withdrawHash, string recipient, decimal amount)
        {
            var coins        = new List <UTXO>();
            var coinsUsed    = new List <UTXO>();
            var estimatedFee = await client.GetFeeRateAsync(3);

            try
            {
                await locker.WaitAsync();

                while (coinsUsed.Sum(c => c.AsCoin().Amount.ToDecimal(MoneyUnit.BTC)) <= amount)
                {
                    var txOperations = await client.GetUTXOsAsync(TrackedSource.Create(pubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main)));

                    foreach (var op in txOperations.Confirmed.UTXOs)
                    {
                        if (!usedInputs.ContainsKey(op.TransactionHash.ToString() + op.Value.Satoshi.ToString()))
                        {
                            coins.Add(op);
                        }
                    }

                    coins.Sort(delegate(UTXO x, UTXO y)
                    {
                        return(-x.AsCoin().Amount.CompareTo(y.AsCoin().Amount));
                    });

                    foreach (var item in coins)
                    {
                        if (coinsUsed.Sum(c => c.AsCoin().Amount.ToDecimal(MoneyUnit.BTC)) <= amount)
                        {
                            coinsUsed.Add(item);
                            usedInputs.Add(item.TransactionHash.ToString() + item.Value.Satoshi.ToString(), item);
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (coinsUsed.Sum(c => c.AsCoin().Amount.ToDecimal(MoneyUnit.BTC)) < amount)
                    {
                        await Task.Delay(5000);
                    }
                }

                TransactionBuilder   builder     = null;
                BitcoinPubKeyAddress destination = null;
                if (network == NetworkType.Testnet)
                {
                    builder     = Network.TestNet.CreateTransactionBuilder();
                    destination = new BitcoinPubKeyAddress(recipient, Network.TestNet);
                }
                else
                {
                    builder     = Network.Main.CreateTransactionBuilder();
                    destination = new BitcoinPubKeyAddress(recipient, Network.Main);
                }

                NBitcoin.Transaction tx = builder
                                          .AddCoins(coinsUsed.Select(c => c.AsCoin() /* .ScriptPubKey.ToBytes()*/))
                                          .Send(destination, Money.Coins(amount))
                                          .Send(TxNullDataTemplate.Instance.GenerateScriptPubKey(Encoding.UTF8.GetBytes(withdrawHash)), Money.Zero)
                                          .SetChange(pubKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main))
                                          .SendEstimatedFees((await client.GetFeeRateAsync(3)).FeeRate)
                                          .BuildTransaction(sign: false);

                // Specify the path to unmanaged PKCS#11 library provided by the cryptographic device vendor
                string pkcs11LibraryPath = @"/opt/cloudhsm/lib/libcloudhsm_pkcs11_standard.so";

                // Create factories used by Pkcs11Interop library
                Net.Pkcs11Interop.HighLevelAPI.Pkcs11InteropFactories factories = new Net.Pkcs11Interop.HighLevelAPI.Pkcs11InteropFactories();

                // Load unmanaged PKCS#11 library
                using (Net.Pkcs11Interop.HighLevelAPI.IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, pkcs11LibraryPath, AppType.MultiThreaded))
                {
                    // Show general information about loaded library
                    Net.Pkcs11Interop.HighLevelAPI.ILibraryInfo libraryInfo = pkcs11Library.GetInfo();

                    Console.WriteLine("Library");
                    Console.WriteLine("  Manufacturer:       " + libraryInfo.ManufacturerId);
                    Console.WriteLine("  Description:        " + libraryInfo.LibraryDescription);
                    Console.WriteLine("  Version:            " + libraryInfo.LibraryVersion);

                    // Get list of all available slots
                    foreach (Net.Pkcs11Interop.HighLevelAPI.ISlot slot in pkcs11Library.GetSlotList(SlotsType.WithOrWithoutTokenPresent))
                    {
                        // Show basic information about slot
                        Net.Pkcs11Interop.HighLevelAPI.ISlotInfo slotInfo = slot.GetSlotInfo();

                        Console.WriteLine();
                        Console.WriteLine("Slot");
                        Console.WriteLine("  Manufacturer:       " + slotInfo.ManufacturerId);
                        Console.WriteLine("  Description:        " + slotInfo.SlotDescription);
                        Console.WriteLine("  Token present:      " + slotInfo.SlotFlags.TokenPresent);

                        if (slotInfo.SlotFlags.TokenPresent)
                        {
                            // Show basic information about token present in the slot
                            Net.Pkcs11Interop.HighLevelAPI.ITokenInfo tokenInfo = slot.GetTokenInfo();

                            Console.WriteLine("Token");
                            Console.WriteLine("  Manufacturer:       " + tokenInfo.ManufacturerId);
                            Console.WriteLine("  Model:              " + tokenInfo.Model);
                            Console.WriteLine("  Serial number:      " + tokenInfo.SerialNumber);
                            Console.WriteLine("  Label:              " + tokenInfo.Label);

                            // Show list of mechanisms (algorithms) supported by the token
                            Console.WriteLine("Supported mechanisms: ");
                            foreach (CKM mechanism in slot.GetMechanismList())
                            {
                                Console.WriteLine("  " + mechanism);
                            }
                        }

                        using (Net.Pkcs11Interop.HighLevelAPI.ISession session = slot.OpenSession(SessionType.ReadWrite))
                        {
                            session.Login(CKU.CKU_USER, pkcsUser);

                            // Specify signing mechanism
                            Net.Pkcs11Interop.HighLevelAPI.IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_ECDSA);

                            List <Net.Pkcs11Interop.HighLevelAPI.IObjectAttribute> publicKeyAttributes = new List <Net.Pkcs11Interop.HighLevelAPI.IObjectAttribute>();
                            publicKeyAttributes.Add(new Net.Pkcs11Interop.HighLevelAPI80.ObjectAttribute(CKA.CKA_LABEL, hsmKey));
                            publicKeyAttributes.Add(new Net.Pkcs11Interop.HighLevelAPI80.ObjectAttribute(CKA.CKA_SIGN, true));


                            Net.Pkcs11Interop.HighLevelAPI.IObjectHandle key = session.FindAllObjects(publicKeyAttributes).FirstOrDefault();

                            uint i = 0;
                            foreach (var c in tx.Inputs.AsIndexedInputs())
                            {
                                byte[] sourceData = c.GetSignatureHash(coinsUsed.First(cu => cu.Outpoint.Hash == c.PrevOut.Hash).AsCoin()).ToBytes();
                                Console.WriteLine("sourceData: " + tx.ToHex());

                                byte[] signature = session.Sign(mechanism, key, sourceData);
                                Console.WriteLine("signature: " + BitConverter.ToString(signature));
                                var canSig = ECDSASignatureFactory.FromComponents(signature).MakeCanonical();
                                var sig    = new NBitcoin.TransactionSignature(new NBitcoin.Crypto.ECDSASignature(new NBitcoin.BouncyCastle.Math.BigInteger(canSig.R.ToByteArray()), new NBitcoin.BouncyCastle.Math.BigInteger(canSig.S.ToByteArray())), SigHash.Single);
                                builder = builder.AddKnownSignature(pubKey, sig, c.PrevOut);
                                TransactionSignature sig2 = null;
                                if (builder.TrySignInput(tx, i, SigHash.Single, out sig2))
                                {
                                    Console.WriteLine("Input Signed");
                                    Console.WriteLine(BitConverter.ToString(sig2.ToBytes()));
                                }
                                else
                                {
                                    Console.WriteLine("Input Not Signed");
                                }

                                Console.WriteLine("tx: " + tx);
                                i++;

                                tx = builder.SignTransactionInPlace(tx);
                            }


                            Console.WriteLine("tx: " + tx);
                            TransactionPolicyError[] errors = null;
                            if (builder.Verify(tx, out errors))
                            {
                                var broadcastResult = await client.BroadcastAsync(tx);

                                broadcastResult.ToString();
                                Console.WriteLine("broadcast: " + tx.GetHash().ToString());
                                session.Logout();
                                return(tx.GetHash().ToString());
                            }
                            else
                            {
                                Console.WriteLine("Verify transaction failed");
                            }

                            if (errors != null)
                            {
                                foreach (var e in errors)
                                {
                                    Console.WriteLine(e.ToString());
                                }
                            }

                            session.Logout();
                        }
                    }
                }

                return(null);
            }
            catch (Exception e)
            {
                Log.Error("Failed to send BTC Withdraw" + e.ToString());
                throw e;
            }
            finally
            {
                locker.Release();
            }
        }
Exemplo n.º 11
0
        public dynamic SendToTestNet(dynamic transactionDto, string toAddress, string privateKey, string network, string token)
        {
            try
            {
                var btcnetwork = GetNetwork(network);


                BitcoinSecret        secret = new BitcoinSecret(privateKey, btcnetwork);
                NBitcoin.Transaction tx     = NBitcoin.Transaction.Create(btcnetwork);
                TxIn input = new TxIn
                {
                    PrevOut   = new OutPoint(new uint256(transactionDto.TransactionID), transactionDto.Vout),
                    ScriptSig = secret.GetAddress(ScriptPubKeyType.Legacy).ScriptPubKey
                };
                tx.Inputs.Add(input);

                TxOut output      = new TxOut();
                Money fee         = Money.Coins(transactionDto.DefaultFees);
                Money totalAmount = Money.Coins(transactionDto.Amount);
                output.Value = totalAmount - fee;
                BitcoinAddress toaddress = BitcoinAddress.Create(toAddress, btcnetwork);
                output.ScriptPubKey = toaddress.ScriptPubKey;
                tx.Outputs.Add(output);

                var coins = tx.Inputs.Select(txin => new Coin(txin.PrevOut, new TxOut {
                    ScriptPubKey = txin.ScriptSig
                }));
                tx.Sign(secret, coins.ToArray());

                /* Push Data to So Chain*/
                string api            = "https://chain.so/api/v2/send_tx/LTCTEST";
                var    httpWebRequest = (HttpWebRequest)WebRequest.Create(api);
                httpWebRequest.ContentType = "application/json; charset=utf-8";
                httpWebRequest.Method      = HttpMethod.Post.Method;
                dynamic reqObj = new ExpandoObject();
                reqObj.tx_hex = tx.ToHex();
                string payload = JsonConvert.SerializeObject(reqObj);

                using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    streamWriter.Write(payload);
                    var ss = streamWriter.ToString();
                    streamWriter.Flush();
                }
                string responseData = string.Empty;
                var    httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                {
                    responseData = streamReader.ReadToEnd();
                }
                dynamic response = new ExpandoObject();
                if (!string.IsNullOrWhiteSpace(responseData))
                {
                    response = JsonConvert.DeserializeObject(responseData);
                }

                return(response);
            }
            catch (Exception ex)
            {
                throw new Exception();
            }
        }
Exemplo n.º 12
0
        public static String Submit(Transaction tx)
        {
            //Info.Blockchain.API.PushTx.PushTx bcInfo = new Info.Blockchain.API.PushTx.PushTx();
            //http://btc.blockr.io/api/v1/tx/push

            var cli = new WebClient();
            cli.Headers[HttpRequestHeader.ContentType] = "application/json";

            RawTx t = new RawTx();
            t.hex = tx.ToHex();

            String json = Newtonsoft.Json.JsonConvert.SerializeObject(t);

            String response = cli.UploadString("http://tbtc.blockr.io/api/v1/tx/push", json);

            //IList<String> nodes = new List<String>(3);
            //nodes.Add("54.149.133.4:18333");
            ////SOME TEST NET NODES
            ////54.149.133.4:18333
            ////52.69.206.155:18333
            ////93.114.160.222:18333
            //string url = "93.114.160.222:18333"; //nic
            ////url = "52.4.156.236:18333";
            ////string url = "54.149.133.4:18333";

            //using (var node = NBitcoin.Protocol.Node.ConnectToLocal(NBitcoin.Network.TestNet))
            //{
            //    node.VersionHandshake();

            //    NBitcoin.Transaction[] transactions = new Transaction[1];
            //    transactions[0] = tx;

            //    node.SendMessage(new NBitcoin.Protocol.InvPayload(transactions));
            //    node.SendMessage(new NBitcoin.Protocol.TxPayload(tx));
            //}

            //using(var node = NBitcoin.Protocol.Node.Connect(NBitcoin.Network.TestNet, url))
            //{
            //    node.VersionHandshake();

            //    System.Threading.Thread.Sleep(100);

            //    NBitcoin.Transaction[] transactions = new Transaction[1];
            //    transactions[0] = tx;

            //    node.SendMessage(new NBitcoin.Protocol.InvPayload(transactions));
            //    node.SendMessage(new NBitcoin.Protocol.TxPayload(tx));
            //}

            var r = Newtonsoft.Json.JsonConvert.DeserializeObject<Response>(response);

            return r.data;
        }
Exemplo n.º 13
0
        private async Task <BtcTxnSignature> getBtcTxnSignaturesAsync(
            ECurrency currency,
            string address,
            string amount,
            string fee,
            string target,
            string reserve,
            string reservedFundsRedeemScript,
            string privateKey
            )
        {
            GluwaClient client = new GluwaClient(mEnv);

            Result <BalanceResponse, ErrorResponse> getUnspentOutput = await client.GetBalanceAsync(currency, address, true);

            List <UnspentOutput> unspentOutputs = getUnspentOutput.Data.UnspentOutputs.OrderByDescending(u => u.Amount).ToList();

            Money amountValue              = Money.Parse(amount);
            Money feeValue                 = Money.Parse(fee);
            Money reserveAmount            = amountValue + feeValue;
            Money totalRequiredAmountMoney = reserveAmount + feeValue;

            BigInteger totalRequiredAmount = new BigInteger(totalRequiredAmountMoney.Satoshi);

            BitcoinAddress sourceAddress  = BitcoinAddress.Create(address, mEnv.Network);
            BitcoinAddress targetAddress  = BitcoinAddress.Create(target, mEnv.Network);
            BitcoinAddress reserveAddress = BitcoinAddress.Create(reserve, mEnv.Network);

            BitcoinSecret secret = new BitcoinSecret(privateKey, mEnv.Network);

            List <UnspentOutput> usingUnspentOutputs      = new List <UnspentOutput>();
            BigInteger           unspentOutputTotalAmount = BigInteger.Zero;

            for (int i = 0; i < unspentOutputs.Count; i++)
            {
                if (unspentOutputTotalAmount < totalRequiredAmount && i >= MAX_UNSPENTOUTPUTS_COUNT)
                {
                    throw new InvalidOperationException($"Could not find up to {MAX_UNSPENTOUTPUTS_COUNT} BTC unspent outputs that can cover the amount and fee.");
                }

                if (unspentOutputTotalAmount >= totalRequiredAmount)
                {
                    break;
                }

                usingUnspentOutputs.Add(unspentOutputs[i]);
                Money sumAmount = Money.Parse(unspentOutputs[i].Amount);
                unspentOutputTotalAmount += new BigInteger(sumAmount.Satoshi);
            }

            List <Coin> coins = new List <Coin>();

            for (int i = 0; i < usingUnspentOutputs.Count; i++)
            {
                coins.Add(new Coin(
                              fromTxHash: new uint256(usingUnspentOutputs[i].TxHash),
                              fromOutputIndex: (uint)usingUnspentOutputs[i].Index,
                              amount: usingUnspentOutputs[i].Amount,
                              scriptPubKey: Script.FromHex(sourceAddress.ScriptPubKey.ToHex())
                              ));
            }

            TransactionBuilder builder = mEnv.Network.CreateTransactionBuilder();

            NBitcoin.Transaction reserveTxSignature = builder
                                                      .AddKeys(secret)
                                                      .AddCoins(coins)
                                                      .Send(reserveAddress, reserveAmount)
                                                      .SetChange(sourceAddress)
                                                      .SendFees(fee)
                                                      .BuildTransaction(true);

            IEnumerable <Coin> reserveTxCoins = reserveTxSignature.Outputs.AsCoins();
            Coin reserveTxCoin = reserveTxCoins.First(
                c => c.TxOut.ScriptPubKey.GetDestinationAddress(mEnv.Network) == reserveAddress);
            Script     reservedFundsRedeemScriptValue = new Script(reservedFundsRedeemScript);
            ScriptCoin reservedCoin = new ScriptCoin(reserveTxCoin, reservedFundsRedeemScriptValue);

            builder = mEnv.Network.CreateTransactionBuilder();
            PSBT executePsbt = builder
                               .AddKeys(secret)
                               .AddCoins(reservedCoin)
                               .Send(targetAddress, amount)
                               .SendFees(feeValue)
                               .SetChange(reserveAddress)
                               .BuildPSBT(true);

            builder = mEnv.Network.CreateTransactionBuilder();
            PSBT reclaimPsbt = builder
                               .AddKeys(secret)
                               .AddCoins(reservedCoin)
                               .Send(sourceAddress, amount)
                               .SendFees(feeValue)
                               .SetChange(reserveAddress)
                               .BuildPSBT(true);

            BtcTxnSignature bTCTxnSignature = new BtcTxnSignature()
            {
                ReserveTxnSignature = reserveTxSignature.ToHex(),
                ExecuteTxnSignature = executePsbt.ToHex(),
                ReclaimTxnSignature = reclaimPsbt.ToHex()
            };

            return(bTCTxnSignature);
        }
Exemplo n.º 14
0
        private async Task <string> getBtcTransactionSignatureAsync(ECurrency currency, string address, string amount, string fee, string target, string privateKey)
        {
            Result <BalanceResponse, ErrorResponse> getUnspentOutput = await GetBalanceAsync(currency, address, true);

            List <UnspentOutput> unspentOutputs = getUnspentOutput.Data.UnspentOutputs.OrderByDescending(u => u.Amount).ToList();

            Money      amountValue            = Money.Parse(amount);
            Money      feeValue               = Money.Parse(fee);
            Money      totalAmountAndFeeValue = amountValue + feeValue;
            BigInteger totalAmountAndFee      = new BigInteger(totalAmountAndFeeValue.Satoshi);

            BitcoinAddress sourceAddress = BitcoinAddress.Create(address, mEnv.Network);
            BitcoinAddress targetAddress = BitcoinAddress.Create(target, mEnv.Network);
            BitcoinSecret  secret        = new BitcoinSecret(privateKey, mEnv.Network);

            List <UnspentOutput> usingUnspentOutputs      = new List <UnspentOutput>();
            BigInteger           unspentOutputTotalAmount = BigInteger.Zero;

            for (int i = 0; i < unspentOutputs.Count; i++)
            {
                if (unspentOutputTotalAmount < totalAmountAndFee && i >= MAX_UNSPENTOUTPUTS_COUNT)
                {
                    throw new InvalidOperationException($"Could not find up to {MAX_UNSPENTOUTPUTS_COUNT} BTC unspent outputs that can cover the amount and fee.");
                }

                if (unspentOutputTotalAmount >= totalAmountAndFee)
                {
                    break;
                }

                usingUnspentOutputs.Add(unspentOutputs[i]);
                Money sumAmount = Money.Parse(unspentOutputs[i].Amount);
                unspentOutputTotalAmount += new BigInteger(sumAmount.Satoshi);
            }

            List <Coin> coins = new List <Coin>();

            for (int i = 0; i < usingUnspentOutputs.Count; i++)
            {
                coins.Add(new Coin(
                              fromTxHash: new uint256(usingUnspentOutputs[i].TxHash),
                              fromOutputIndex: (uint)usingUnspentOutputs[i].Index,
                              amount: usingUnspentOutputs[i].Amount,
                              scriptPubKey: Script.FromHex(sourceAddress.ScriptPubKey.ToHex())
                              ));
            }

            TransactionBuilder builder = mEnv.Network.CreateTransactionBuilder();

            NBitcoin.Transaction txn = builder
                                       .AddKeys(secret)
                                       .AddCoins(coins)
                                       .Send(targetAddress, amount)
                                       .SetChange(sourceAddress)
                                       .SendFees(fee)
                                       .BuildTransaction(true);

            if (!builder.Verify(txn, out NBitcoin.Policy.TransactionPolicyError[] error))
            {
                throw new InvalidOperationException(string.Join(System.Environment.NewLine, error.Select(e => e.ToString())));
            }

            string signature = txn.ToHex();

            return(signature);
        }