Exemplo n.º 1
0
        /// <summary>
        /// Simple transaction that is locked for x amount of hours before being processed
        /// </summary>
        public static bool SimpleTimeLockContract()
        {
            //Create a client for our QBitNinja API calls
            var client = new QBitNinjaClient(_network);

            var contractorPrivateKey = (_contractorHdRoot.Derive(new KeyPath("m/44'/0'/0'/0/0"))).PrivateKey.GetWif(_network);
            var contractorSecret     = new BitcoinSecret(contractorPrivateKey.ToString(), _network);

            var contracteeAddress = BitcoinAddress.Create("n4bEeKENL9rED2cG31TjSNzPs6T15TCq96", _network);

            //Calculate all payments and fees
            var contracteePaymentAmount = new Money(0.1m, MoneyUnit.BTC);
            var minerFee = new Money(0.00007m, MoneyUnit.BTC);


            int lockTimeMinutes = 5; // <-- Minutes to wait until transaction is allowed to process
            var lockTime        = new LockTime(DateTimeOffset.UtcNow.AddMinutes(5));

            Console.WriteLine("LockTime set to:" + lockTime.ToString());



            //Collect the spendable coins from a previous transction
            GetTransactionResponse transactionResponse = client.GetTransaction(uint256.Parse("e4a06cac11b257908a908e90dda19b4b5e3d5a0f172d6b90ad8b0950878507be")).Result;
            List <ICoin>           receivedCoins       = transactionResponse.ReceivedCoins;

            OutPoint outPointToSpend = null;

            Console.WriteLine("------ Available Coins ------");
            Console.WriteLine();

            foreach (var coin in receivedCoins)
            {
                if (coin.TxOut.ScriptPubKey == contractorPrivateKey.ScriptPubKey)
                {
                    outPointToSpend = coin.Outpoint;

                    Money amount        = (Money)coin.Amount;
                    var   paymentScript = coin.TxOut.ScriptPubKey;
                    var   address       = paymentScript.GetDestinationAddress(_network);

                    Console.WriteLine("Amount: " + amount.ToDecimal(MoneyUnit.BTC) + " | " + paymentScript + " | " + address);
                    Console.WriteLine();
                }
            }


            if (outPointToSpend == null)
            {
                Console.WriteLine("Transaction does not contain our ScriptPubKey!");
                return(false);
            }

            Console.WriteLine("-----------------------------");



            //calculate change amount (not actually used, TransactionBuilder will handle for us):
            var txInAmount   = (Money)receivedCoins[(int)outPointToSpend.N].Amount;
            var changeAmount = txInAmount - contracteePaymentAmount - minerFee;


            #region Console Output (Payment Details)

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("------ Payment Details ------");
            Console.WriteLine();

            Console.WriteLine("Total available: " + txInAmount.ToString() + " btc");
            Console.WriteLine();
            Console.WriteLine("Total payments: " + contracteePaymentAmount.ToString() + " btc");
            Console.WriteLine();
            Console.WriteLine("Total fees: " + minerFee.ToString() + " btc");
            Console.WriteLine();
            Console.WriteLine("Change: " + changeAmount.ToString() + " btc");
            Console.WriteLine();


            Console.WriteLine("-----------------------------");

            Console.WriteLine("");
            Console.WriteLine("Press any key to create transaction...");
            Console.ReadLine();

            #endregion



            try
            {
                //Now we can build a transaction where we send a timelock payment to the contractor
                var txBuilder = new TransactionBuilder();
                var tx        = txBuilder
                                .AddCoins(receivedCoins)
                                .AddKeys(contractorSecret.PrivateKey)
                                .Send(contracteeAddress.ScriptPubKey, contracteePaymentAmount)
                                .SendFees(minerFee)
                                .SetChange(contractorSecret.GetAddress())
                                //.SetLockTime(lockTime)
                                .BuildTransaction(true);

                tx.LockTime = 500123;

                if (txBuilder.Verify(tx))
                {
                    Console.WriteLine(tx.ToString());

                    Console.WriteLine("Timelock contract created, signed and verified!");

                    Console.WriteLine("");
                    Console.WriteLine("Press any key to broadcast...");
                    Console.ReadLine();

                    //Console.WriteLine();
                    //Console.WriteLine(tx.ToString()); //<-- Print out entire transaction as JSON

                    #region Broadcast transaction using NBitcoin with node connection

                    /*
                     * //Use Bitnodes to find a node to connect to: https://bitnodes.earn.com/  |  https://bitnodes.earn.com/nodes/
                     * //For Testnet you may have to find a faucet provider that also provides node information.
                     *
                     *
                     * var node = NBitcoin.Protocol.Node.Connect(_network, "52.10.6.141:18333"); //<-- ReadMe has Terminal commands for looking up available Testnet Nodes. All Testnodes use :18333
                     * node.VersionHandshake();
                     *
                     * // var payload = NBitcoin.Protocol.Payload(tx);
                     *
                     * //inform the server
                     * node.SendMessage(new InvPayload(tx));
                     * Thread.Sleep(1000);
                     *
                     * //send the transaction
                     * node.SendMessage(new TxPayload(tx));
                     * Thread.Sleep(5000);
                     *
                     * node.Disconnect();
                     *
                     * Console.WriteLine("Transaction ID: " + tx.GetHash().ToString());
                     * Console.WriteLine();
                     *
                     */

                    #endregion

                    #region Broadcast transaction using QbitServerClient


                    //Broadcast using QBit server:
                    BroadcastResponse broadcastResponse = client.Broadcast(tx).Result;


                    Console.WriteLine("Transaction ID: " + tx.GetHash().ToString());
                    Console.WriteLine();

                    if (broadcastResponse.Success)
                    {
                        Console.WriteLine("Broadcast succeeded!");
                    }
                    else
                    {
                        Console.WriteLine("Broadcast Error!");
                        Console.WriteLine();
                        Console.WriteLine(broadcastResponse.Error.Reason);
                    }



                    #endregion
                }
                else
                {
                    Console.WriteLine("Timelock contract has some issues.");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }



            Console.WriteLine();
            return(true);
        }
Exemplo n.º 2
0
        public void ToStringTest(LockTime first, string expected)
        {
            string actual = first.ToString();

            Assert.Equal(expected, actual);
        }