public void TestTransactionInfo() { QBitNinjaClient client = new QBitNinjaClient(Network.Main); var transactionId = uint256.Parse("f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94"); GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; NBitcoin.Transaction transaction = transactionResponse.Transaction; Console.WriteLine(transactionResponse.TransactionId); Console.WriteLine(transaction.GetHash()); Console.WriteLine(); //Received Coins Console.WriteLine("Outputs:"); var outputs = transaction.Outputs; foreach (TxOut output in outputs) { Money amount = output.Value; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = output.ScriptPubKey; Console.WriteLine("ScriptPubKey: " + paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine("address: " + address); Console.WriteLine(); } //Spent Coins Console.WriteLine("Inputs:"); Money receivedAmount = Money.Zero; var inputs = transaction.Inputs; foreach (TxIn input in inputs) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine("Prev Outpoint Hash: " + previousOutpoint.Hash); // hash of prev tx Console.WriteLine("Prev Outpoint Index: " + previousOutpoint.N); // idx of out from prev tx, that has been spent in the current tx Console.WriteLine(); } Console.WriteLine("Amount of inputs: " + transaction.Inputs.Count); var spentCoins = transactionResponse.SpentCoins; foreach (var spentCoin in spentCoins) { receivedAmount = (Money)spentCoin.Amount.Add(receivedAmount); } Console.WriteLine("Bitcoin Received: " + receivedAmount.ToDecimal(MoneyUnit.BTC)); var fee = transaction.GetFee(spentCoins.ToArray()); Console.Write("Fees (in Satoshis): "); Console.WriteLine(fee); }
/// <summary> /// Returns the fee of the transaction being signed /// </summary> /// <param name="fee"></param> /// <returns></returns> public bool TryGetFee(out Money fee) { fee = tx.GetFee(GetAllCoins().ToArray()); return(fee != null); }
public static void BitcoinPractice() { Key privateKey = new Key(); //PubKey publicKey = privateKey.PubKey; //Console.WriteLine(publicKey); //Console.WriteLine(publicKey.GetAddress(Network.Main)); //Console.WriteLine(publicKey.GetAddress(Network.TestNet)); //var publicKeyHash = publicKey.Hash; //Console.WriteLine(publicKeyHash); //var mainNetAddress = publicKeyHash.GetAddress(Network.Main); //var testNetAddress = publicKeyHash.GetAddress(Network.TestNet); //Console.WriteLine(mainNetAddress); //Console.WriteLine(testNetAddress); //var publicKeyHash2 = new KeyId("14836dbe7f38c5ac3d49e8d790af808a4ee9edcf"); // I don't get what's going on here; where does this string come from, what does KeyId do?? //var mainNetAddress2 = publicKeyHash2.GetAddress(Network.Main); //var testNetAddress2 = publicKeyHash2.GetAddress(Network.TestNet); //Console.WriteLine(mainNetAddress2.ScriptPubKey); //Console.WriteLine(testNetAddress2.ScriptPubKey); //var paymentScript = publicKeyHash2.ScriptPubKey; //var sameMainNetAddress = paymentScript.GetDestinationAddress(Network.Main); // going backwards from script and network to get address //Console.WriteLine(sameMainNetAddress); //Console.WriteLine(mainNetAddress2 == sameMainNetAddress); //var samePublicKeyHash = (KeyId)paymentScript.GetDestination(); // going backwards to get same result as line 32 from the script //Console.WriteLine(publicKeyHash2 == samePublicKeyHash); //var sameMainNetAddress2 = new BitcoinPubKeyAddress(samePublicKeyHash, Network.Main); // //Console.WriteLine(mainNetAddress2 == sameMainNetAddress2); //BitcoinSecret mainNetPrivateKey = privateKey.GetBitcoinSecret(Network.Main); // generate WIF Wallet Import Format of privKey //Console.WriteLine(mainNetPrivateKey); //bool wifIsBitcoinSecret = mainNetPrivateKey == privateKey.GetWif(Network.Main); //Console.WriteLine(wifIsBitcoinSecret); //// Exercise: //// 1. Generate a private key on mainnet and note it //Key myKey = new Key(); //BitcoinSecret myKeyWIF = myKey.GetBitcoinSecret(Network.Main); //Console.WriteLine(myKeyWIF); // saved offline so it isn't pushed to github //// 2. Get the corresponding address //PubKey myPubKey = myKey.PubKey; //var myBitcoinAddress = myPubKey.GetAddress(Network.Main); //Console.WriteLine(myBitcoinAddress); //// or... //var myPubKeyHash = myPubKey.Hash; //var myBitcoinAddress2 = myPubKeyHash.GetAddress(Network.Main); //Console.WriteLine(myBitcoinAddress2); // saved offline for privacy // 3. Send bitcoins to it. As much as you can afford to lose, so it will keep you focused and motivated to get them back // during the following lessons. // DONE!!! // Transaction tx = new Transaction(""); QBitNinjaClient client = new QBitNinjaClient(Network.Main); var transactionId = NBitcoin.uint256.Parse(""); // remove tx id and hex before push GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; NBitcoin.Transaction transaction = transactionResponse.Transaction; Console.WriteLine(transactionResponse.TransactionId); Console.WriteLine(transaction.GetHash()); List <ICoin> receivedCoins = transactionResponse.ReceivedCoins; foreach (var coin in receivedCoins) { Money amount = (Money)coin.Amount; // amount of each output in the tx to the address we created above (RECEIVED COINS) Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.TxOut.ScriptPubKey; Console.WriteLine(paymentScript); // ScriptPubKey of each output in the tx var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); // address of each output in the tx } // Exercise: Write out the same info about the SPENT COINS using QBitNinja's GetTransactionResponse class List <ICoin> spentCoins = transactionResponse.SpentCoins; foreach (var spentCoin in spentCoins) { Money amountSpent = (Money)spentCoin.Amount; Console.WriteLine(amountSpent.ToDecimal(MoneyUnit.BTC)); var paymentScript = spentCoin.TxOut.ScriptPubKey; // not sure if this is working... doesn't look like a script, see below Console.WriteLine(paymentScript); // 0 367003b... // ??? '[index of output from prev tx spent in current tx] [hash of prev tx]' == 'Outpoint' ??? var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); // } var outputs = transaction.Outputs; // this does same thing as ReceivedCoins foreach loop above foreach (TxOut output in outputs) { Money amount = output.Value; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = output.ScriptPubKey; Console.WriteLine(paymentScript); var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); } var inputs = transaction.Inputs; foreach (TxIn input in inputs) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine(previousOutpoint.Hash); Console.WriteLine(previousOutpoint.N); } Money twentyOneBitcoin = new Money(21, MoneyUnit.BTC); var scriptPubKey = transaction.Outputs.First().ScriptPubKey; TxOut txOut = new TxOut(twentyOneBitcoin, scriptPubKey); OutPoint firstOutPoint = receivedCoins.First().Outpoint; Console.WriteLine(firstOutPoint.Hash); Console.WriteLine(firstOutPoint.N); Console.WriteLine(transaction.Inputs.Count); OutPoint firstPreviousOutPoint = transaction.Inputs.First().PrevOut; var firstPreviousTransaction = client.GetTransaction(firstPreviousOutPoint.Hash).Result.Transaction; Console.WriteLine(firstPreviousTransaction.IsCoinBase); Money spentAmount = Money.Zero; foreach (var spentCoin in spentCoins) { spentAmount = (Money)spentCoin.Amount.Add(spentAmount); } Console.WriteLine(spentAmount.ToDecimal(MoneyUnit.BTC)); // Exercise: Get the total received amount Money receivedAmount = Money.Zero; foreach (var receivedCoin in receivedCoins) { receivedAmount = (Money)receivedCoin.Amount.Add(receivedAmount); } Console.WriteLine(receivedAmount.ToDecimal(MoneyUnit.BTC)); var fee = transaction.GetFee(spentCoins.ToArray()); Console.WriteLine(fee); Console.WriteLine(fee == (spentAmount - receivedAmount)); // True }
static void Main() { // Create a client QBitNinjaClient client = new QBitNinjaClient(Network.Main); // Parse transaction id to NBitcoin.uint256 so the client can eat it var transactionId = uint256.Parse("f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94"); // Query the transaction QBitNinja.Client.Models.GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; NBitcoin.Transaction transaction = transactionResponse.Transaction; Console.WriteLine(transactionResponse.TransactionId); // f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 Console.WriteLine(transaction.GetHash()); // f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 // RECEIVED COINS List <ICoin> receivedCoins = transactionResponse.ReceivedCoins; foreach (Coin coin in receivedCoins) { Money amount = coin.Amount; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.ScriptPubKey; Console.WriteLine(paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } // RECEIVED COINS var outputs = transaction.Outputs; foreach (TxOut output in outputs) { Coin coin = new Coin(transaction, output); Money amount = coin.Amount; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.GetScriptCode(); Console.WriteLine(paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } // RECEIVED COINS foreach (TxOut output in outputs) { Money amount = output.Value; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = output.ScriptPubKey; Console.WriteLine(paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } // SPENT COINS List <ICoin> spentCoins = transactionResponse.SpentCoins; foreach (Coin coin in spentCoins) { Money amount = coin.Amount; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.ScriptPubKey; Console.WriteLine(paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } // SPENT COINS foreach (Coin coin in spentCoins) { TxOut previousOutput = coin.TxOut; Money amount = previousOutput.Value; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = previousOutput.ScriptPubKey; Console.WriteLine(paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } var fee = transaction.GetFee(spentCoins.ToArray()); Console.WriteLine(fee); var inputs = transaction.Inputs; foreach (TxIn input in inputs) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine(previousOutpoint.Hash); // hash of prev tx Console.WriteLine(previousOutpoint.N); // idx of out from prev tx, that has been spent in the current tx Console.WriteLine(); } // Let's create a txout with 21 bitcoin from the first ScriptPubKey in our current transaction Money twentyOneBtc = new Money(21, MoneyUnit.BTC); var scriptPubKey = transaction.Outputs.First().ScriptPubKey; TxOut txOut = new TxOut(twentyOneBtc, scriptPubKey); OutPoint firstOutPoint = spentCoins.First().Outpoint; Console.WriteLine(firstOutPoint.Hash); // 4788c5ef8ffd0463422bcafdfab240f5bf0be690482ceccde79c51cfce209edd Console.WriteLine(firstOutPoint.N); // 0 Console.WriteLine(transaction.Inputs.Count); // 9 OutPoint firstPreviousOutPoint = transaction.Inputs.First().PrevOut; var firstPreviousTransactionResponse = client.GetTransaction(firstPreviousOutPoint.Hash).Result; Console.WriteLine(firstPreviousTransactionResponse.IsCoinbase); // False NBitcoin.Transaction firstPreviousTransaction = firstPreviousTransactionResponse.Transaction; //while (firstPreviousTransactionResponse.IsCoinbase == false) //{ // Console.WriteLine(firstPreviousTransaction.GetHash()); // firstPreviousOutPoint = firstPreviousTransaction.Inputs.First().PrevOut; // firstPreviousTransactionResponse = client.GetTransaction(firstPreviousOutPoint.Hash).Result; // firstPreviousTransaction = firstPreviousTransactionResponse.Transaction; //} Money spentAmount = Money.Zero; foreach (var spentCoin in spentCoins) { spentAmount = (Money)spentCoin.Amount.Add(spentAmount); } Console.WriteLine(spentAmount.ToDecimal(MoneyUnit.BTC)); // 13.19703492 Money receivedAmount = Money.Zero; foreach (var receivedCoin in receivedCoins) { receivedAmount = (Money)receivedCoin.Amount.Add(receivedAmount); } Console.WriteLine(receivedAmount.ToDecimal(MoneyUnit.BTC)); // 13.19683492 Console.WriteLine((spentAmount - receivedAmount).ToDecimal(MoneyUnit.BTC)); Console.WriteLine(spentAmount.ToDecimal(MoneyUnit.BTC) - receivedAmount.ToDecimal(MoneyUnit.BTC)); //var inputs = transaction.Inputs; //foreach (TxIn input in inputs) //{ // uint256 previousTransactionId = input.PrevOut.Hash; // GetTransactionResponse previousTransactionResponse = client.GetTransaction(previousTransactionId).Result; // NBitcoin.Transaction previousTransaction = previousTransactionResponse.Transaction; // var previousTransactionOutputs = previousTransaction.Outputs; // foreach (TxOut previousTransactionOutput in previousTransactionOutputs) // { // Money amount = previousTransactionOutput.Value; // Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); // var paymentScript = previousTransactionOutput.ScriptPubKey; // Console.WriteLine(paymentScript); // It's the ScriptPubKey // var address = paymentScript.GetDestinationAddress(Network.Main); // Console.WriteLine(address); // Console.WriteLine(); // } //} Console.ReadLine(); }
static void Main() { //======================================================================================== //Section. Transaction //(Mastering Bitcoin) Transactions are the most important part of the bitcoin system. Everything else in bitcoin is designed to ensure that transactions can be created, propagated on the network, validated, and finally added to the global ledger of transactions(the blockchain).Transactions are data structures that encode the transfer of value between participants in the bitcoin system.Each transaction is a public entry in bitcoin’s blockchain, the global double-entry bookkeeping ledger. //A transaction may have no recipient, or it may have several.The same can be said for senders! On the Blockchain, the sender and recipient are always abstracted with a ScriptPubKey, as we demonstrated in previous chapters. //If you use Bitcoin Core, your Transactions tab will show the transaction, like this: //Picture depiction: //For now we are interested in the Transaction ID. In this case, it is: //f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 //Note: The Transaction ID is defined by SHA256(SHA256(txbytes)) //Note: Do NOT use the Transaction ID to handle unconfirmed transactions. The Transaction ID can be manipulated before it is confirmed.This is known as “Transaction Malleability.” //You can review or exmine a specify transaction on a block explorer like Blockchain.info: //https://blockchain.info/tx/f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 //But as a developer you will probably want a service that is easier to query and parse. //As a C# developer and an NBitcoin user Nicolas Dorier's QBit Ninja will definitely be your best choice. It is an open source web service API to query the blockchain and for tracking wallets. //QBit Ninja depends on NBitcoin.Indexer which relies on Microsoft Azure Storage.C# developers are expected to use the NuGet client package instead of developing a wrapper around this API. //If you go to: //http://api.qbit.ninja/transactions/f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 //you will see the raw bytes of your transaction. //Picture depiction: //You can parse the transaction from a Hexadecimal with the following code: //Transaction tx = new Transaction("0100000..."); //Quickly close the tab, before it scares you away. QBit Ninja queries the API and parses the information so go ahead and install QBitNinja.Client NuGet package. //Picture depiction: //Query the transaction by ID: //Create a client. QBitNinjaClient client = new QBitNinjaClient(Network.Main); //Parse transaction ID to NBitcoin.uint256 so the client can eat it. var transactionId = uint256.Parse("f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94"); Console.WriteLine($"transactionId: {transactionId}"); //Query the transaction. QBitNinja.Client.Models.GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; Console.WriteLine($"transactionResponse: {transactionResponse}"); //The type of transactionResponse is GetTransactionResponse. It lives under QBitNinja.Client.Models namespace. //You can get NBitcoin.Transaction type from it: NBitcoin.Transaction transaction = transactionResponse.Transaction; Console.WriteLine($"transaction: {transaction}"); //Let's see an example getting back the transaction ID with both classes(transactionResponse, transaction): Console.WriteLine($"transactionResponse.TransactionId: {transactionResponse.TransactionId}"); //Output: //f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 Console.WriteLine($"transaction.GetHash(): {transaction.GetHash()}"); //Output: //f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 // GetTransactionResponse has additional information about the transaction like the value and scriptPubKey of the inputs being spent in the transaction. //The relevant parts for now are the inputs and outputs. //You can see there is only one output in our transaction. 13.19683492 bitcoins are sent to that ScriptPubKey. //The relevant parts for now are the inputs and outputs. //You can see there is only one output in our transaction. //13.19683492 bitcoins are sent to that ScriptPubKey. //Examine the RECEIVED COINS by using QBitNinja's GetTransactionResponse class List <ICoin> receivedCoins = transactionResponse.ReceivedCoins; Console.WriteLine("=====Examine the RECEIVED COINS by using QBitNinja's GetTransactionResponse class====="); foreach (var coin in receivedCoins) { Money amount = (Money)coin.Amount; Console.WriteLine($"amount.ToDecimal(MoneyUnit.BTC): {amount.ToDecimal(MoneyUnit.BTC)}"); var paymentScript = coin.TxOut.ScriptPubKey; //Print each ScriptPubKey by executing foreach loop. Console.WriteLine(paymentScript); //Get a Bitcoin address. //Recall we can get a Bitcoin address from a ScriptPubKey by specifying a network type by processing backwards. var bitcoinAddressWithQG = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine($"bitcoinAddressWithQG: {bitcoinAddressWithQG}"); //Output: //1HfbwN6Lvma9eDsv7mdwp529tgiyfNr7jc } //Examine the RECEIVED COINS by using NBitcoin's Transaction class var outputs = transaction.Outputs; Console.WriteLine("=====Examine the received coins by using NBitcoin's Transaction class====="); foreach (TxOut output in outputs) { Coin coin = new Coin(transaction, output); Money amount = coin.Amount; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.GetScriptCode(); //It's the ScriptPubKey. Console.WriteLine(paymentScript); var bitcoinAddressWithNT = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine($"bitcoinAddressWithNT: {bitcoinAddressWithNT}"); Console.WriteLine(); } //We have written out some informations about the RECEIVED COINS using QBitNinja's GetTransactionResponse class and NBitcoins's Transaction class. //Exercise: Write out the same informations about the SPENT COINS using QBitNinja's GetTransactionResponse class! //Examine the SPENT COINS by using QBitNinja's GetTransactionResponse class List <ICoin> spentCoins = transactionResponse.SpentCoins; Console.WriteLine("=====Examine the SPENT COINS by using QBitNinja's GetTransactionResponse class====="); foreach (var coin in spentCoins) { Money amount = (Money)coin.Amount; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.TxOut.ScriptPubKey; Console.WriteLine(paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } //Examine the SPENT COINS by using NBitcoin's Transaction class Console.WriteLine("=====Examine the SPENT COINS by using NBitcoin's Transaction class====="); foreach (var coin in spentCoins) { TxOut previousOutput = coin.TxOut; Money amount = previousOutput.Value; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = previousOutput.ScriptPubKey; Console.WriteLine(paymentScript); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } //=============================================================================== //Examine the inputs. //Now let's examine the inputs. If you look at them, you will notice a previous output is referenced. Each input shows you which previous out has been spent in order to fund this transaction. Console.WriteLine("=====Examine the inputs====="); var inputs = transaction.Inputs; foreach (TxIn input in inputs) { //Get each previous output which is referenced to another transaction, from each input. OutPoint previousOutpoint = input.PrevOut; Console.WriteLine($"previousOutpoint: {previousOutpoint}"); //Hash of the previous OutPoint. Console.WriteLine($"previousOutpoint.Hash: {previousOutpoint.Hash}"); //Index number of the previous OutPoint that will be spent in the current transaction. Console.WriteLine($"previousOutpoint.N: {previousOutpoint.N}"); Console.WriteLine(); } //The terms TxOut, Output and out are synonymous. //Not to be confused with OutPoint, but more on this later. //In summary, the TxOut represents an amount of bitcoin and a ScriptPubKey representing a recipient. //As above illustration, let's create a TxOut with 21 bitcoins from the first ScriptPubKey in our current transaction: Money twentyOneBtc = new Money(21, MoneyUnit.BTC); //Get the first ScriptPubKey to specify a recipient. var scriptPubKey = transaction.Outputs.First().ScriptPubKey; //Create a new TxOut with passing twentyOneBtc, scriptPubKey into a constructor arguments. TxOut txOut = new TxOut(twentyOneBtc, scriptPubKey); Console.WriteLine($"Value in txOut: {txOut.Value}"); //Output: //21.00000000 Console.WriteLine($"ScriptPubKey in txOut: {txOut.ScriptPubKey}"); //Output: //OP_DUP OP_HASH160 b6cefbb855cabf6ee45598f518a98011c22961aa OP_EQUALVERIFY OP_CHECKSIG //Every TxOut is uniquely addressed at the blockchain level by the ID of the transaction which includes TxOut(s) and TxOut(s) index number inside this transaction. We call such reference an Outpoint. //Picture depiction: //Transaction ID + Index number of TxOut => OutPoint //For example, the OutPoint of the TxOut with 13.19683492 BTC in our transaction is: //(f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94, 0). //As you can see, OutPoint is composed of 2 values, the transaction ID including a TxOut and index number of the TxOut in the transaction. OutPoint firstOutPoint = receivedCoins.First().Outpoint; Console.WriteLine($"firstOutPoint.Hash {firstOutPoint.Hash}"); //Output: //f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 Console.WriteLine($"firstOutPoint.N: {firstOutPoint.N}"); //Output: //0 //Now let’s take a closer look at the inputs(aka TxIn) of the transaction: //Picture depiction: //OutPoint + ScriptSig => TxIn //The TxIn is composed of the "OutPoint" of the TxOut being spent in the current transaction including this TxIn, which originates in another previous transaction and the "ScriptSig". We can see the ScriptSig as the “Proof of Ownership”. In our transaction there are actually 9 inputs. Console.WriteLine(transaction.Inputs.Count); //Output: //9 //With a transaction ID of the previous transaction including OutPoint, we can review the information associated with that transaction. OutPoint firstPreviousOutPoint = transaction.Inputs.First().PrevOut; Console.WriteLine($"firstPreviousOutPoint {firstPreviousOutPoint}"); //Output: //4788c5ef8ffd0463422bcafdfab240f5bf0be690482ceccde79c51cfce209edd-0 var firstPreviousTransactionResponse = client.GetTransaction(firstPreviousOutPoint.Hash).Result; Console.WriteLine($"firstPreviousTransactionResponse.TransactionId {firstPreviousTransactionResponse.TransactionId}"); //Output: //4788c5ef8ffd0463422bcafdfab240f5bf0be690482ceccde79c51cfce209edd Console.WriteLine($"firstPreviousTransactionResponse.IsCoinbase: {firstPreviousTransactionResponse.IsCoinbase}"); //Output: //False NBitcoin.Transaction firstPreviousTransaction = firstPreviousTransactionResponse.Transaction; Console.WriteLine($"firstPreviousTransaction {firstPreviousTransaction}"); //CoinBase transaction is located in the first transaction, also known as Tx0, in a block. And it includes the newly mined coins and a transaction that the newly mied coins are sent to the miner. //We could continue to trace the transaction IDs back in this manner until we reach a coinbase transaction, the transaction including the newly mined coin by a miner. //Exercise: Follow the first input of this transaction and its ancestor transactions until you find a coinbase transaction! //Hint: After a few minutes and 30-40 transactions, I gave up tracing back. //Yes, you've guessed right, it is not the most efficient way to do this, but a good exercise. //while (firstPreviousTransactionResponse.IsCoinbase == false) //{ // Console.WriteLine(firstPreviousTransaction.GetHash()); // firstPreviousOutPoint = firstPreviousTransaction.Inputs.First().PrevOut; // firstPreviousTransactionResponse = client.GetTransaction(firstPreviousOutPoint.Hash).Result; // firstPreviousTransaction = firstPreviousTransactionResponse.Transaction; //} //In our example, the outputs were for a total of 13.19703492 BTC. Money spentAmount = Money.Zero; foreach (var spentCoin in spentCoins) { spentAmount = (Money)spentCoin.Amount.Add(spentAmount); } Console.WriteLine($"spentAmount.ToDecimal(MoneyUnit.BTC): {spentAmount.ToDecimal(MoneyUnit.BTC)}"); //Output: //13.19703492 //In this transaction, 13.19683492 BTC were received. Money receivedAmount = Money.Zero; foreach (var receivedCoin in receivedCoins) { receivedAmount = (Money)receivedCoin.Amount.Add(receivedAmount); } Console.WriteLine($"receivedAmount.ToDecimal(MoneyUnit.BTC): {receivedAmount.ToDecimal(MoneyUnit.BTC)}"); //Output: //13.19683492 //Exercise: Get the total received amount, as I have been done with the spent amount. //var inputs = transaction.Inputs; //foreach (TxIn input in inputs) //{ // uint256 previousTransactionId = input.PrevOut.Hash; // GetTransactionResponse previousTransactionResponse = client.GetTransaction(previousTransactionId).Result; // NBitcoin.Transaction previousTransaction = previousTransactionResponse.Transaction; // var previousTransactionOutputs = previousTransaction.Outputs; // foreach (TxOut previousTransactionOutput in previousTransactionOutputs) // { // Money amount = previousTransactionOutput.Value; // Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); // var paymentScript = previousTransactionOutput.ScriptPubKey; // Console.WriteLine(paymentScript); // It's the ScriptPubKey // var address = paymentScript.GetDestinationAddress(Network.Main); // Console.WriteLine(address); // Console.WriteLine(); // } //} //That means 0.0002 BTC(or 13.19703492 - 13.19683492) is not accounted for!The difference between the inputs and outputs are called Transaction Fees or Miner’s Fees.This is the money that the miner collects for including a given transaction in a block. Console.WriteLine((spentAmount - receivedAmount).ToDecimal(MoneyUnit.BTC)); Console.WriteLine(spentAmount.ToDecimal(MoneyUnit.BTC) - receivedAmount.ToDecimal(MoneyUnit.BTC)); var fee = transaction.GetFee(spentCoins.ToArray()); Console.WriteLine($"fee : {fee}"); //You should note that a coinbase transaction is the only transaction whose value of output are superior to the value of input. This effectively corresponds to a coin creation. So by definition there is no fee in a coinbase transaction.The coinbase transaction is the first transaction of every block. //The consensus rules enforce that the sum of output's value in the coinbase transaction does not exceed the sum of transaction fees in the block plus the mining reward. Console.ReadLine(); }
public static void Run(string[] args) { Key privateKey = new Key(); PubKey publicKey = privateKey.PubKey; var publicKeyHash = publicKey.Hash; { //print del Base58Check Console.WriteLine("publicKey: " + publicKey); // es 03a40d9841161f5c20c4b67d353248db81d4591a9f221dc2ec113ea6d7d14bcf89 Console.WriteLine("publicKey.GetAddress(Network.Main): " + publicKey.GetAddress(Network.Main)); // es 1PUYsjwfNmX64wS368ZR5FMouTtUmvtmTY Console.WriteLine("publicKey.GetAddress(Network.TestNet): " + publicKey.GetAddress(Network.TestNet)); // es n3zWAo2eBnxLr3ueohXnuAa8mTVBhxmPhq BitcoinAddress mainNetAddress = publicKeyHash.GetAddress(Network.Main); //es 1PUYsjwfNmX64wS368ZR5FMouTtUmvtmTY BitcoinAddress testNetAddress = publicKeyHash.GetAddress(Network.TestNet); //es n3zWAo2eBnxLr3ueohXnuAa8mTVBhxmPhq //print del Base58Check Console.WriteLine("publicKeyHash : " + publicKeyHash); //c06218cdb28034d0fe481471bd0e0c44c4843d12 Console.WriteLine("publicKeyHash.GetAddress(Network.Main) : " + mainNetAddress); Console.WriteLine("publicKeyHash.GetAddress(Network.TestNet): " + testNetAddress); Console.WriteLine("mainNetAddress.ScriptPubKey: " + mainNetAddress.ScriptPubKey); //OP_DUP OP_HASH160 c06218cdb28034d0fe481471bd0e0c44c4843d12 OP_EQUALVERIFY OP_CHECKSIG Console.WriteLine("testNetAdress.ScriptPubKey: " + testNetAddress.ScriptPubKey); //OP_DUP OP_HASH160 c06218cdb28034d0fe481471bd0e0c44c4843d12 OP_EQUALVERIFY OP_CHECKSIG //note that the ScriptPubKey appears to have nothing to do with the Bitcoin Address, but it does show the // hash of the public key. /* * Bitcoin Addresses are composed of a version byte which identifies the network where to use the address and * the hash of a public key. * So we can go backwards and generate a bitcoin address from the ScriptPubKey and the network identifier. */ var paymentScript = publicKeyHash.ScriptPubKey; var sameMainNetAddress = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(mainNetAddress == sameMainNetAddress); // True //It is also possible to retrieve the hash from the ScriptPubKey and generate a Bitcoin Address from it: var samePublicKeyHash = (KeyId)paymentScript.GetDestination(); Console.WriteLine(publicKeyHash == samePublicKeyHash); // True var sameMainNetAddress2 = new BitcoinPubKeyAddress(samePublicKeyHash, Network.Main); Console.WriteLine(mainNetAddress == sameMainNetAddress2); // True /* * Private keys are often represented in Base58Check called a Bitcoin Secret * (also known as Wallet Import Format or simply WIF), like Bitcoin Addresses. */ BitcoinSecret mainNetPrivateKey = privateKey.GetBitcoinSecret(Network.Main); // generate our Bitcoin secret(also known as Wallet Import Format or simply WIF) from our private key for the mainnet BitcoinSecret testNetPrivateKey = privateKey.GetBitcoinSecret(Network.TestNet); // generate our Bitcoin secret(also known as Wallet Import Format or simply WIF) from our private key for the testnet Console.WriteLine(mainNetPrivateKey); // L5B67zvrndS5c71EjkrTJZ99UaoVbMUAK58GKdQUfYCpAa6jypvn Console.WriteLine(testNetPrivateKey); // cVY5auviDh8LmYUW8AfafseD6p6uFoZrP7GjS3rzAerpRKE9Wmuz bool WifIsBitcoinSecret = mainNetPrivateKey == privateKey.GetWif(Network.Main); Console.WriteLine(WifIsBitcoinSecret); // True // *********** section https://programmingblockchain.gitbooks.io/programmingblockchain/content/bitcoin_transfer/transaction.html /* * query of transactions * - https://www.blockchain.com/btc/tx/f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 * - http://api.qbit.ninja/transactions/f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 * - or via QBitNinjaClient */ // Create a client QBitNinjaClient client = new QBitNinjaClient(Network.Main); // Parse transaction id to NBitcoin.uint256 so the client can eat it var transactionId = uint256.Parse("f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94"); // Query the transaction GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; NBitcoin.Transaction transaction = transactionResponse.Transaction; Console.WriteLine(transactionResponse.TransactionId); // f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 Console.WriteLine(transaction.GetHash()); // f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 //browse its output List <ICoin> receivedCoins = transactionResponse.ReceivedCoins; foreach (var coin in receivedCoins) { Money amount = (Money)coin.Amount; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript2 = coin.TxOut.ScriptPubKey; Console.WriteLine(paymentScript2); // It's the ScriptPubKey var address = paymentScript2.GetDestinationAddress(Network.Main); Console.WriteLine(address); // 1HfbwN6Lvma9eDsv7mdwp529tgiyfNr7jc Console.WriteLine(); } //or via transaction.Outputs: var outputs = transaction.Outputs; foreach (TxOut output in outputs) { Money amount = output.Value; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript2 = output.ScriptPubKey; Console.WriteLine(paymentScript2); // It's the ScriptPubKey var address = paymentScript2.GetDestinationAddress(Network.Main); Console.WriteLine(address); Console.WriteLine(); } //now browse its inputs var inputs = transaction.Inputs; foreach (TxIn input in inputs) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine(previousOutpoint.Hash); // hash of prev tx Console.WriteLine(previousOutpoint.N); // idx of out from prev tx, that has been spent in the current tx Console.WriteLine(); } //As illustration let's create a txout with 21 bitcoin from the first ScriptPubKey in our // current transaction: Money twentyOneBtc = new Money(21, MoneyUnit.BTC); var scriptPubKey = transaction.Outputs.First().ScriptPubKey; TxOut txOut = new TxOut(twentyOneBtc, scriptPubKey); //Every TxOut is uniquely addressed at the blockchain level by the ID of the transaction // which include it and its index inside it. We call such reference an Outpoint. //For example, the Outpoint of the TxOut with 13.19683492 BTC in our transaction is // (f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94, 0). OutPoint firstOutPoint = receivedCoins.First().Outpoint; Console.WriteLine(firstOutPoint.Hash); // f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94 Console.WriteLine(firstOutPoint.N); // 0 OutPoint firstPreviousOutPoint = transaction.Inputs.First().PrevOut; var firstPreviousTransaction = client.GetTransaction(firstPreviousOutPoint.Hash).Result.Transaction; Console.WriteLine(firstPreviousTransaction.IsCoinBase); // False /* * Notice: 0.0002 BTC (or 13.19703492 - 13.19683492) is not accounted for! The difference between * the inputs and outputs are called Transaction Fees or Miner’s Fees. This is the money that the * miner collects for including a given transaction in a block. */ //fees: var fee = transaction.GetFee(transactionResponse.SpentCoins.ToArray()); Console.WriteLine(fee); } }
static void Main(string[] args) { //parse tx ID from transactionResponse and transaction.GetHash QBitNinjaClient client = new QBitNinjaClient(Network.TestNet); var transactionId = uint256.Parse("8ce2c18154caa2fa4053a7f8776c662a3216beae344891863b1341ead737239f"); GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; NBitcoin.Transaction transaction = transactionResponse.Transaction; // Console.WriteLine(transactionResponse.TransactionId); // Console.WriteLine(transaction.GetHash()); //show received coin of transaction var receivedCoins = transactionResponse.ReceivedCoins; foreach (var coin in receivedCoins) { Money amount = (Money)coin.Amount; // Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.TxOut.ScriptPubKey; // Console.WriteLine(paymentScript); var address = paymentScript.GetDestinationAddress(Network.TestNet); // Console.WriteLine(address); } //show spent coins of transaction var spentCoins = transactionResponse.SpentCoins; foreach (var coin in spentCoins) { Money amount = (Money)coin.Amount; // Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.TxOut.ScriptPubKey; // Console.WriteLine(paymentScript); var signAddress = paymentScript.GetSignerAddress(Network.TestNet); // Console.WriteLine(signAddress); } //Outputs NBitcoin transaction class var outputs = transaction.Outputs; foreach (TxOut output in outputs) { Money amount = output.Value; // Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = output.ScriptPubKey; // Console.WriteLine(paymentScript); var address = paymentScript.GetDestinationAddress(Network.Main); // Console.WriteLine(address); } //Inputs NBitcoin transaction class var inputs = transaction.Inputs; foreach (TxIn input in inputs) { OutPoint previousOutpoint = input.PrevOut; // Console.WriteLine(previousOutpoint.Hash); // Console.WriteLine(previousOutpoint.N); } //Outpoint = txID + ordering OutPoint firstOutPoint = receivedCoins.First().Outpoint; // Console.WriteLine(firstOutPoint.Hash); // Console.WriteLine(firstOutPoint.N); // Console.WriteLine(transaction.Inputs.Count); OutPoint firstPreviousOutPoint = transaction.Inputs.First().PrevOut; var firstPreviousTransaction = client.GetTransaction(firstPreviousOutPoint.Hash).Result.Transaction; // Console.WriteLine(firstPreviousTransaction.IsCoinBase); //Get spent amount Money spentAmount = Money.Zero; foreach (var spentCoin in spentCoins) { spentAmount = (Money)spentCoin.Amount.Add(spentAmount); } Console.WriteLine(spentAmount.ToDecimal(MoneyUnit.BTC)); //Get received amount Money receivedAmount = Money.Zero; foreach (var receivedCoin in receivedCoins) { receivedAmount = (Money)receivedCoin.Amount.Add(receivedAmount); } Console.WriteLine(receivedAmount.ToDecimal(MoneyUnit.BTC)); //Calculate fee var fee = transaction.GetFee(spentCoins.ToArray()); Console.WriteLine(fee); //Generate key, script, address // Key privateKey = new Key(); // BitcoinSecret testPrivateKey = privateKey.GetBitcoinSecret(Network.TestNet); // PubKey testPublicKey = testPrivateKey.PubKey; // BitcoinAddress testAddress = testPublicKey.GetAddress(Network.TestNet); // Console.WriteLine(testPrivateKey); // Console.WriteLine(testAddress.ScriptPubKey); // Console.WriteLine(testPublicKey); // Console.WriteLine(testAddress); //Test if WIF private key = ECDSA hashed private key // bool WifIsBitcoinSecret = testNetPrivateKey == privateKey.GetWif(Network.TestNet); // Console.WriteLine(WifIsBitcoinSecret); // Key privateKey = new Key(); // BitcoinSecret bitcoinSecret = privateKey.GetWif(Network.Main); // Key samePrivateKey = bitcoinSecret.PrivateKey; // Console.WriteLine(samePrivateKey == privateKey); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please enter a valid question number as commande line argument"); } else if (args.First() == "Question-1") { Key privateKey = new Key(); // generate a random private key PubKey publicKey = privateKey.PubKey; // Get the public key //Console.WriteLine(publicKey); Console.WriteLine(privateKey.ToString(Network.TestNet)); var mainnetAddress = publicKey.GetAddress(Network.Main); //Mainnet address var testnetAddress = publicKey.GetAddress(Network.TestNet); // Testnet address string walletInfo = privateKey.ToString(Network.TestNet) + "@" + mainnetAddress.ToString() + "@" + testnetAddress.ToString(); walletInfo = walletInfo.Replace("@", System.Environment.NewLine); System.IO.File.WriteAllText("C:\\Users\\Mathieu\\Documents\\Blockchain\\wallet2.txt", walletInfo); // Generate QR-code QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode(testnetAddress.ToString(), QRCodeGenerator.ECCLevel.Q); QRCode qrCode = new QRCode(qrCodeData); Bitmap qrCodeImage = qrCode.GetGraphic(11); // Print the bitmap PrintDocument pd = new PrintDocument(); pd.PrintPage += (thesender, ev) => { float x = 230.0F; float y = 320.0F; RectangleF srcRect = new RectangleF(40.0F, 40.0F, 600.0F, 600.0F); GraphicsUnit units = GraphicsUnit.Pixel; ev.Graphics.DrawImage(qrCodeImage, x, y, srcRect, units); }; pd.Print(); } else if (args.First() == "Question-2") { Key privateKey = new Key(); // generate a random private key PubKey publicKey = privateKey.PubKey; // Get the public key var vanityAddress = publicKey.GetAddress(Network.TestNet); //TestNet address string Text = vanityAddress.ToString(); while (Text.Substring(1, 4).Equals("math", StringComparison.CurrentCultureIgnoreCase) == false) { privateKey = new Key(); // generate a random private key publicKey = privateKey.PubKey; // Get the public key vanityAddress = publicKey.GetAddress(Network.TestNet); //TestNet address Text = vanityAddress.ToString(); } Console.WriteLine(vanityAddress.ToString()); string walletInfo = privateKey.ToString(Network.TestNet) + "@" + vanityAddress.ToString(); walletInfo = walletInfo.Replace("@", System.Environment.NewLine); System.IO.File.WriteAllText("C:\\Users\\Mathieu\\Documents\\Blockchain\\vanity2.txt", walletInfo); } else if (args.First() == "Question-3") { // Create a client QBitNinjaClient client = new QBitNinjaClient(Network.Main); string TXID = "12bec2fe21387b60c33f2e766557dfeb8b9f1b75d505745f11100d6b2425cf9f"; // Parse transaction id to NBitcoin.uint256 so the client can eat it var transactionId = uint256.Parse(TXID); // Query the transaction GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; Console.WriteLine(); Console.WriteLine(); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); // Outputs of the transaction = Received Coins Console.WriteLine("Output associated to TX = " + TXID); Console.WriteLine(); List <ICoin> receivedCoins = transactionResponse.ReceivedCoins; Money receivedAmount = Money.Zero; foreach (var coinR in receivedCoins) { Money amount = (Money)coinR.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinR.TxOut.ScriptPubKey; Console.WriteLine("ScriptPubKey = \"" + paymentScript + "\""); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine("Going to address : " + address); receivedAmount = (Money)coinR.Amount.Add(receivedAmount); Console.WriteLine(); } Console.WriteLine("Total output amount = " + receivedAmount.ToDecimal(MoneyUnit.BTC) + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); // Inputs of the transaction Console.WriteLine("Inputs associated to TX = " + TXID); Console.WriteLine(); List <ICoin> spentCoins = transactionResponse.SpentCoins; Money spentAmount = Money.Zero; foreach (var coinS in spentCoins) { Money amount = (Money)coinS.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinS.TxOut.ScriptPubKey; Console.WriteLine("ScriptPubKey = \"" + paymentScript + "\""); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine("Coming from address : " + address); spentAmount = (Money)coinS.Amount.Add(spentAmount); Console.WriteLine(); } Console.WriteLine("Total input amount = " + spentAmount.ToDecimal(MoneyUnit.BTC) + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); // Now looking at the fees NBitcoin.Transaction transaction = transactionResponse.Transaction; var fee = transaction.GetFee(spentCoins.ToArray()); Console.WriteLine("Transaction fees = " + fee.ToString() + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); var inputs = transaction.Inputs; foreach (TxIn input in inputs) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine("Previous TX hash : " + previousOutpoint.Hash); // hash of prev tx Console.WriteLine("Previous TX index : " + previousOutpoint.N); // idx of out from prev tx, that has been spent in the current tx Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(); // Getting the balance from the address string copayAddress = "mz2oHHuMqnJg2grqCrKRDGs2vwG5dwNDRu"; BitcoinAddress WalletAddress = new BitcoinPubKeyAddress(copayAddress, Network.TestNet); QBitNinjaClient testnetClient = new QBitNinjaClient(Network.TestNet); var balanceModel = testnetClient.GetBalance(WalletAddress).Result; var unspentCoins = new List <Coin>(); foreach (var operation in balanceModel.Operations) { unspentCoins.AddRange(operation.ReceivedCoins.Select(coin => coin as Coin)); } var balance = unspentCoins.Sum(x => x.Amount.ToDecimal(MoneyUnit.BTC)); Console.WriteLine(); Console.WriteLine("Copay Address = " + copayAddress); Console.WriteLine("Total balance = " + balance.ToString()); // Get all operations for that address if (balanceModel.Operations.Count > 0) { foreach (var operation in balanceModel.Operations) { // We take the transaction ID var TXIDb = operation.TransactionId; GetTransactionResponse transactionResponseb = testnetClient.GetTransaction(TXIDb).Result; NBitcoin.Transaction transactionb = transactionResponse.Transaction; Console.WriteLine(); Console.WriteLine("Transaction list for the address : "); Console.WriteLine(); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); // Outputs of the transaction = Received Coins Console.WriteLine("Transaction ID : " + TXIDb); Console.WriteLine(); Console.WriteLine("OUTPUTS"); Console.WriteLine(); List <ICoin> receivedCoinsb = transactionResponseb.ReceivedCoins; foreach (var coinR in receivedCoinsb) { Money amount = (Money)coinR.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinR.TxOut.ScriptPubKey; var address = paymentScript.GetDestinationAddress(Network.TestNet); Console.WriteLine("Going to address : " + address); Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); // Inputs of the transaction Console.WriteLine("INPUTS"); Console.WriteLine(); List <ICoin> spentCoinsb = transactionResponseb.SpentCoins; foreach (var coinS in spentCoinsb) { Money amount = (Money)coinS.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinS.TxOut.ScriptPubKey; var address = paymentScript.GetDestinationAddress(Network.TestNet); Console.WriteLine("Coming from address : " + address); Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); // Now looking at the fees var feeb = transactionb.GetFee(spentCoinsb.ToArray()); Console.WriteLine("Transaction fees = " + feeb.ToString() + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); var inputsb = transactionb.Inputs; foreach (TxIn input in inputsb) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine("Previous TX hash : " + previousOutpoint.Hash); // hash of prev tx Console.WriteLine("Previous TX index : " + previousOutpoint.N); // idx of out from prev tx, that has been spent in the current tx Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(); } } // List of UTXO Console.WriteLine(); Console.WriteLine("List of UTXO"); foreach (var c in unspentCoins) { Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(c.Outpoint.ToString()); Console.WriteLine(); } } else if (args.First() == "Question-4") { // Sending a transaction var bitcoinPrivateKey = new BitcoinSecret("cP8UmUrZgiRfQZF9C7VYvJQuPK2Ao9ZTnR1BcZ79hADqn9yNTFXg"); var network = bitcoinPrivateKey.Network; var address = bitcoinPrivateKey.GetAddress(); var client = new QBitNinjaClient(Network.TestNet); var transactionId = uint256.Parse("9e698153d261be07b939ee3e4638b0c09eb466b485f2e09eded5a5eb6fff0519"); var transactionResponse = client.GetTransaction(transactionId).Result; // From where ? var receivedCoins = transactionResponse.ReceivedCoins; OutPoint outPointToSpend = null; foreach (var coin in receivedCoins) { if (coin.TxOut.ScriptPubKey == bitcoinPrivateKey.ScriptPubKey) { outPointToSpend = coin.Outpoint; } } if (outPointToSpend == null) { throw new Exception("TxOut doesn't contain our ScriptPubKey"); } Console.WriteLine("We want to spend {0}. outpoint:", outPointToSpend.N + 1); var transaction = Transaction.Create(network); transaction.Inputs.Add(new TxIn() { PrevOut = outPointToSpend }); // To where ? var CopayAddress = new BitcoinPubKeyAddress("mokLh8W4J4DzZpj2XyEhE1ReZf5BnsSZcs"); // How much we want to spend var CopayAmount = new Money(0.08m, MoneyUnit.BTC); // How much miner fee we want to pay var minerFee = new Money(0.0001m, MoneyUnit.BTC); // How much we want to get back as change var txInAmount = (Money)receivedCoins[(int)outPointToSpend.N].Amount; var changeAmount = txInAmount - CopayAmount - minerFee; TxOut CopayTxOut = new TxOut() { Value = CopayAmount, ScriptPubKey = CopayAddress.ScriptPubKey }; TxOut changeTxOut = new TxOut() { Value = changeAmount, ScriptPubKey = bitcoinPrivateKey.ScriptPubKey }; transaction.Outputs.Add(CopayTxOut); transaction.Outputs.Add(changeTxOut); // We can use the private key to sign transaction.Inputs[0].ScriptSig = bitcoinPrivateKey.ScriptPubKey; transaction.Sign(bitcoinPrivateKey, receivedCoins.ToArray()); BroadcastResponse broadcastResponse = client.Broadcast(transaction).Result; if (!broadcastResponse.Success) { Console.Error.WriteLine("ErrorCode: " + broadcastResponse.Error.ErrorCode); Console.Error.WriteLine("Error message: " + broadcastResponse.Error.Reason); } else { Console.WriteLine("Success! Hash of the transaction :"); Console.WriteLine(transaction.GetHash()); } // Confirmations of the transaction var newTXID = uint256.Parse("4777e829eabd4dd5821153d016e5f3256998e962d0e10af1935bfd7ee95e45d0"); int n = 0; while (n < 10) { GetTransactionResponse newTXResponse = client.GetTransaction(newTXID).Result; Console.WriteLine(); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("Current number of confirmations : " + newTXResponse.Block.Confirmations); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(); System.Threading.Thread.Sleep(10000); n++; } } else if (args.First() == "Question-5") { // We identify the blocks in question // And we create a list of address that have received these coinbase transactions var client = new QBitNinjaClient(Network.Main); var blockHeight = new BlockFeature(2); var blockResponse = client.GetBlock(blockHeight).Result; var TX = blockResponse.Block.Transactions.First(); var reward = TX.Outputs.First(); var nextAddr = reward.ScriptPubKey.GetDestinationAddress(Network.Main); Console.WriteLine(nextAddr); } }
private static void Main(string[] args) { // create client var client = new QBitNinjaClient(Network.Main); // parse tx id to NBitcoin.uint256 for client var transactionId = uint256.Parse("f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94"); // query tx GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; // get NBitcoin.Transaction type NBitcoin.Transaction nBitcoinTransaction = transactionResponse.Transaction; var fromTransactionClass = nBitcoinTransaction.GetHash(); var fromGetTransactionResponseClass = transactionResponse.TransactionId; Console.WriteLine(fromTransactionClass == transactionId && fromGetTransactionResponseClass == transactionId); List <ICoin> receivedCoins = transactionResponse.ReceivedCoins; // received coins Console.WriteLine("Begin received coins"); foreach (var coin in receivedCoins) { Money amount = coin.Amount as Money; Console.WriteLine(amount?.ToDecimal(MoneyUnit.BTC)); var paymentScript = coin.TxOut.ScriptPubKey; Console.WriteLine(paymentScript); var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); } // outputs TxOutList outputs = nBitcoinTransaction.Outputs; Console.WriteLine("Begin outputs"); foreach (var output in outputs) { Money amount = output.Value; Console.WriteLine(amount.ToDecimal(MoneyUnit.BTC)); var paymentScript = output.ScriptPubKey; Console.WriteLine(paymentScript); var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine(address); } // inputs TxInList inputs = nBitcoinTransaction.Inputs; Console.WriteLine("Begin inputs"); foreach (var input in inputs) { OutPoint previousOutPoint = input.PrevOut; Console.WriteLine(previousOutPoint); Console.WriteLine(previousOutPoint.Hash); // hash of prev tx Console.WriteLine(previousOutPoint.N); // index of out from prev tx, that has been spent in current tx } // The terms TxOut, Output and out are synonymous. // create a txout with 21 bitcoin from the first ScriptPubKey in our current transaction: Console.WriteLine("Begin txout"); Money twentyBtc = new Money(21, MoneyUnit.BTC); var scriptPubKey = nBitcoinTransaction.Outputs.FirstOrDefault()?.ScriptPubKey; TxOut txOut = new TxOut(twentyBtc, scriptPubKey); Console.WriteLine(txOut.Value.ToDecimal(MoneyUnit.BTC)); Console.WriteLine(txOut.ScriptPubKey); // every TxOut is uniq addressed by at the blockchain level by the id of the tx, including the index // e.g., OutPoint of TxOut is Console.WriteLine("Begin outpoint"); OutPoint firstOutPoint = receivedCoins.FirstOrDefault()?.Outpoint; Console.WriteLine(firstOutPoint?.Hash); Console.WriteLine(firstOutPoint?.N); Console.WriteLine("Begin txin"); // TxIn is composed of the Outpoint of the TxOut being spent and of the ScriptSig (we can see the ScriptSig as the “Proof of Ownership”). // with the previous transaction ID, we can review the info associated with that tx OutPoint firstPreviousOutPoint = nBitcoinTransaction.Inputs.FirstOrDefault()?.PrevOut; if (firstPreviousOutPoint != null) { var firstPreviousTransaction = client.GetTransaction(firstPreviousOutPoint.Hash).Result.Transaction; Console.WriteLine(firstPreviousTransaction.IsCoinBase); } Console.WriteLine("begin coin base hunt"); //TraceCoinBase(nBitcoinTransaction, client); just done as an exercise, do not use Console.WriteLine("begin total output value count"); var spentCoins = transactionResponse.SpentCoins; var spentAmount = spentCoins.Aggregate(Money.Zero, (money, next) => (Money)next.Amount.Add(money)).ToDecimal(MoneyUnit.BTC); Console.WriteLine(spentAmount); var receivedAmount = receivedCoins.Aggregate(Money.Zero, (money, next) => (Money)next.Amount.Add(money)).ToDecimal(MoneyUnit.BTC); Console.WriteLine(receivedAmount); Console.WriteLine(spentAmount - receivedAmount); // fee var fee = nBitcoinTransaction.GetFee(spentCoins.ToArray()).ToDecimal(MoneyUnit.BTC); Console.WriteLine(fee); // note: there are no fee in a coinbase transaction Console.ReadLine(); }
/// <summary> /// Verify that a transaction is fully signed, have enough fees, and follow the Standard and Miner Transaction Policy rules /// </summary> /// <param name="tx">The transaction to check</param> /// <param name="expectedFees">The expected fees (more or less 10%)</param> /// <param name="errors">Detected errors</param> /// <returns>True if no error</returns> public bool Verify(Transaction tx, Money expectedFees, out TransactionPolicyError[] errors) { if(tx == null) throw new ArgumentNullException("tx"); var coins = tx.Inputs.Select(i => FindCoin(i.PrevOut)).Where(c => c != null).ToArray(); List<TransactionPolicyError> exceptions = new List<TransactionPolicyError>(); var policyErrors = MinerTransactionPolicy.Instance.Check(tx, coins); exceptions.AddRange(policyErrors); policyErrors = StandardTransactionPolicy.Check(tx, coins); exceptions.AddRange(policyErrors); if(expectedFees != null) { var fees = tx.GetFee(coins); if(fees != null) { Money margin = Money.Zero; if(DustPrevention) margin = GetDust() * 2; if(!fees.Almost(expectedFees, margin)) exceptions.Add(new NotEnoughFundsPolicyError("Fees different than expected", expectedFees - fees)); } } errors = exceptions.ToArray(); return errors.Length == 0; }