public void WhenGetUnspentTransactionsTwoBlocks() { RemoveBlockChain(); var serviceProvider = BuildServiceProvider(); var blockChainFactory = serviceProvider.GetService <IBlockChainFactory>(); var blockChain = blockChainFactory.Build(_network); var genesisBlock = blockChain.GetCurrentBlock(); var firstTransaction = genesisBlock.Transactions.First() as BcBaseTransaction; var firstTransactionOut = firstTransaction.TransactionOut.First(); var genesisKey = KeyStore.GetGenesisKey(); var genesisAdr = new BlockChainAddress(_scriptTypes, _network, genesisKey); // Create block chain address. var destinationBlockChainAddress = GenerateBlockChainAddress(); var minerBlockChainAddress = GenerateBlockChainAddress(); var signature = genesisKey.GetSignature(); // Create the script. var scriptBuilder = new ScriptBuilder(); var genesisScript = scriptBuilder .New() .AddToStack(signature) .AddToStack(genesisKey.GetPublicKey()) .Build(); var destinationScript = Script.CreateP2PKHScript(destinationBlockChainAddress.PublicKeyHash); var minerScript = Script.CreateP2PKHScript(minerBlockChainAddress.PublicKeyHash); var genesisScriptDest = Script.CreateP2PKHScript(genesisKey.GetPublicKeyHashed()); var transactionBuilder = new TransactionBuilder(); var coinBaseTransaction = transactionBuilder // Add COIN-BASE TRANSACTION. .NewCoinbaseTransaction() .SetBlockNumber(1) .AddOutput(1, minerScript) .Build(); var noneCoinBaseTransaction = transactionBuilder // ADD GENESIS (10 BTC) => DESTINATION TRANSACTION. .NewNoneCoinbaseTransaction() .Spend(firstTransaction, 0, genesisScript.Serialize()) .AddOutput(10, destinationScript) .Build(); var otherCoinBaseTransaction = transactionBuilder .NewNoneCoinbaseTransaction() .Spend(firstTransaction, 0, genesisScript.Serialize()) .AddOutput(39, genesisScriptDest) .Build(); var nonce = NonceHelper.GetNonceUInt32(); // CREATE A BLOCK. var block = new Block(genesisBlock.GetHashHeader(), Constants.DEFAULT_NBITS, nonce); block.Transactions.Add(coinBaseTransaction); block.Transactions.Add(noneCoinBaseTransaction); block.Transactions.Add(otherCoinBaseTransaction); var a = noneCoinBaseTransaction.Serialize().ToArray(); var b = BcBaseTransaction.Deserialize(a); block.UpdateMerkleRoot(); blockChain.AddBlock(block); var unspentTransactions = blockChain.GetUnspentTransactions(); Assert.IsNotNull(unspentTransactions); Assert.IsTrue(unspentTransactions.Count() == 3); Assert.IsTrue(unspentTransactions.Sum(t => t.Value) == 50); }
private static BlockChainAddress GenerateBlockChainAddress() { var key = Key.Genererate(); var adr = new BlockChainAddress(_scriptTypes, _network, key); return(adr); }
public void CheckClientSignature() { var clientKey = KeyStore.GetClientKey(); var clientWallet = BlockChainAddress.Deserialize("12K5LnVWKCu9QGyB39uGAgVSAfBs33PKS96HSL93"); var scriptBuilder = new ScriptBuilder(); var inputScript = scriptBuilder.New() .AddToStack(clientKey.GetSignature()) .AddToStack(clientKey.GetPublicKey()) .Build(); var outputScript = scriptBuilder.New() .AddOperation(OpCodes.OP_DUP) .AddOperation(OpCodes.OP_HASH160) .AddToStack(clientWallet.PublicKeyHash) .AddOperation(OpCodes.OP_EQUALVERIFY) .AddOperation(OpCodes.OP_CHECKSIG) .Build(); var serializedInputScript = inputScript.Serialize(); var serializedOutputScript = outputScript.Serialize(); var deserializedInputScript = Script.Deserialize(serializedInputScript); var deserializedOutputScript = Script.Deserialize(serializedOutputScript); var interpreter = new ScriptInterpreter(); bool isCorrect = interpreter.Check(deserializedInputScript, deserializedOutputScript); Assert.IsTrue(isCorrect); }
private JObject GetUnconfirmedBalance(string id, JObject response) { var transactions = MemoryPool.Instance().GetTransactions(); var wallet = WalletStore.Instance().GetAuthenticatedWallet(); if (wallet == null) { return(CreateErrorResponse(id, (int)RpcErrorCodes.RPC_WALLET_NOT_FOUND, "No authenticated wallet")); } long unconfirmedBalance = 0; if (wallet.Addresses != null) { var bcAddrs = wallet.Addresses.Select(addr => BlockChainAddress.Deserialize(addr.Hash)); foreach (var memTx in transactions) { var mBcTx = memTx.Transaction as BcBaseTransaction; if (mBcTx == null) { continue; } var balance = _transactionHelper.CalculateBalance(mBcTx, bcAddrs, _network); unconfirmedBalance += balance; } } response["result"] = unconfirmedBalance; return(response); }
/* * [TestMethod] * public void WhenBuildSmartContractTransaction() * { * var code = @" * using System; * public class SimpleTest * { * private string y {get; set;} * private string z; * public string Test2(string parameter) * { * return parameter; * } * private string Test() * { * return ""1""; * } * }"; * var compiler = new DotnetCompiler(); * var smartContract = compiler.Compile(code); * var ba = BuildBlockChainAddress(); * var builder = new TransactionBuilder(); * var script = Script.CreateP2PKHScript(ba.PublicKeyHash); * var nonce = BitConverter.GetBytes(NonceHelper.GetNonceUInt64()); * var transaction = builder * .NewSmartContractTransaction().CreateSmartContract(smartContract, script, "thabart", "test", 0, nonce) * .Build(); * var serializedTransaction = transaction.Serialize(); * var deserializedTx = BaseTransaction.Deserialize(serializedTransaction, TransactionTypes.SmartContract); * string s = ""; * } */ private static BlockChainAddress BuildBlockChainAddress() { var network = Networks.MainNet; var key = Key.Genererate(); var blockChainAddress = new BlockChainAddress(ScriptTypes.P2PKH, network, key); var hash = blockChainAddress.GetSerializedHash(); var deserializedBA = BlockChainAddress.Deserialize(hash); return(deserializedBA); }
public TransactionOut GetTransactionOut(string encodedBcAddr) { if (string.IsNullOrWhiteSpace(encodedBcAddr)) { throw new ArgumentNullException(nameof(encodedBcAddr)); } var bcAddr = BlockChainAddress.Deserialize(encodedBcAddr); var publicKeyHash = bcAddr.PublicKeyHash; return(GetTransactionOut(publicKeyHash)); }
private static BlockChainAddress BuildBlockChainAddress() { var network = Networks.MainNet; var key = Key.Deserialize(new BigInteger("66661394595692466950200829442443674598224300882267065208709422638481412972116609477112206002430829808784107536250360432119209033266013484787698545014625057"), new BigInteger("43102461949956883352376427470284148089747996528740865531180015053863743793176")); //Key.Genererate(); var k2 = Key.Genererate(); var publicKey = new BigInteger(k2.GetPublicKey().ToArray()); var privateKey = k2.GetPrivateKey(); var keyHash = new BigInteger(k2.GetPublicKeyHashed().ToArray()); var blockChainAddress2 = new BlockChainAddress(ScriptTypes.P2PKH, network, k2); var hh = blockChainAddress2.GetSerializedHash(); var h = new BigInteger(key.GetPublicKeyHashed()); var blockChainAddress = new BlockChainAddress(ScriptTypes.P2PKH, network, key); var s = blockChainAddress.GetJson().ToString(); var hash = blockChainAddress.GetSerializedHash(); var deserializedBA = BlockChainAddress.Deserialize(hash); return(deserializedBA); }
public BlockChainAddress FindByAddressAndPrivateKey(string address, string privateKey) { var cmd = new MySqlCommand("select * from address where address = @address and privateKey = @privateKey", ConnectionHelper.GetConnection()); cmd.Parameters.AddWithValue("@address", address); cmd.Parameters.AddWithValue("@privateKey", privateKey); var reader = cmd.ExecuteReader(); var blockchainAddress = new BlockChainAddress(); if (reader.Read()) { blockchainAddress.Address = reader.GetString("address"); blockchainAddress.PrivateKey = reader.GetString("privateKey"); blockchainAddress.Balance = reader.GetDouble("balance"); } ConnectionHelper.CloseConnection(); return(blockchainAddress); }
public void WhenCalculateBalance48PTCSLeft() { RemoveBlockChain(); var serviceProvider = BuildServiceProvider(); var transactionHelper = serviceProvider.GetService <ITransactionHelper>(); var blockChainFactory = serviceProvider.GetService <IBlockChainFactory>(); var blockChainStore = serviceProvider.GetService <IBlockChainStore>(); blockChainStore.Switch(_network); var blockChain = blockChainStore.GetBlockChain(); // Get the genesis block. var genesisBlock = blockChain.GetCurrentBlock(); var firstTransaction = genesisBlock.Transactions.First() as BcBaseTransaction; var firstTransactionOut = firstTransaction.TransactionOut.First(); var genesisKey = KeyStore.GetGenesisKey(); var genesisAdr = new BlockChainAddress(_scriptTypes, _network, genesisKey); // Create block chain address. var destinationBlockChainAddress = GenerateBlockChainAddress(); var signature = genesisKey.GetSignature(); // Create the script. var scriptBuilder = new ScriptBuilder(); var genesisScript = scriptBuilder .New() .AddToStack(signature) .AddToStack(genesisKey.GetPublicKey()) .Build(); var destinationScript = Script.CreateP2PKHScript(destinationBlockChainAddress.PublicKeyHash); var destGenesisScript = Script.CreateP2PKHScript(genesisKey.GetPublicKeyHashed()); var transactionBuilder = new TransactionBuilder(); var noneCoinBaseTransaction = transactionBuilder // ADD GENESIS (10 BTC) => DESTINATION TRANSACTION. .NewNoneCoinbaseTransaction() .Spend(firstTransaction, 0, genesisScript.Serialize()) .AddOutput(2, destinationScript) .AddOutput(48, destGenesisScript) .Build(); var genesisBalance = transactionHelper.CalculateBalance(noneCoinBaseTransaction, new[] { genesisAdr }, _network); var receiverBalance = transactionHelper.CalculateBalance(noneCoinBaseTransaction, new[] { destinationBlockChainAddress }, _network); Assert.IsTrue(genesisBalance == 48); Assert.IsTrue(receiverBalance == 2); }
public static void GenerateMenu(Transaction transaction) { currentLoggedInAddress = null; currentLoggedInAccount = null; Console.Clear(); Console.WriteLine("Please choose the type of transaction: "); Console.WriteLine("1. Withdraw."); Console.WriteLine("2. Deposit."); Console.WriteLine("3. Transfer."); Console.WriteLine("Please enter your choice: "); var choice = int.Parse(Console.ReadLine()); while (true) { switch (choice) { case 1: transaction.Withdraw(); break; case 2: transaction.Deposit(); break; case 3: transaction.Transfer(); break; default: Console.WriteLine("Choose the wrong type of transaction."); break; } if (choice == 4) { break; } } }
public Key CreateNewAddress() { var walletStore = WalletStore.Instance(); var authenticatedWallet = walletStore.GetAuthenticatedWallet(); if (authenticatedWallet == null) { return(null); } var key = Key.Genererate(); var blockChainAdr = new BlockChainAddress(ScriptTypes.P2PKH, authenticatedWallet.Network, key); authenticatedWallet.Addresses.Add(new WalletAggregateAddress { Hash = blockChainAdr.GetSerializedHash(), Key = key, Network = authenticatedWallet.Network }); var password = walletStore.GetPassword(); _walletRepository.Update(authenticatedWallet, walletStore.GetPassword()); return(key); }
private void SendMoney(object sender, EventArgs e) { var authenticatedWallet = WalletStore.Instance().GetAuthenticatedWallet(); if (authenticatedWallet == null) { MainWindowStore.Instance().DisplayError("You're not authenticated"); return; } var receiverValue = _viewModel.SendValue; var addr = _viewModel.SendAddress; var selectedTransaction = _viewModel.SelectedTransaction; if (selectedTransaction == null) { MainWindowStore.Instance().DisplayError("A transaction must be selected"); return; } if (receiverValue > selectedTransaction.Amount) { return; } var txFee = _transactionHelper.GetMinFee(); var senderValue = selectedTransaction.Amount - receiverValue - txFee; var walletAddr = authenticatedWallet.Addresses.FirstOrDefault(a => a.Hash == selectedTransaction.Hash); if (walletAddr == null) { MainWindowStore.Instance().DisplayError("The selected tranasction is not linked to your wallet"); return; } BlockChainAddress bcAddr = null; try { bcAddr = BlockChainAddress.Deserialize(addr); } catch (Exception) { MainWindowStore.Instance().DisplayError("The address is not correct"); } if (bcAddr == null) { MainWindowStore.Instance().DisplayError("The address is not correct"); return; } var newKey = _walletHelper.CreateNewAddress(); var kh = new BigInteger(newKey.GetPublicKeyHashed()); var script = _scriptBuilder.New() .AddToStack(walletAddr.Key.GetSignature()) .AddToStack(walletAddr.Key.GetPublicKey()) .Build(); var pp = walletAddr.Key.GetPublicKeyHashed(); var senderSript = _scriptBuilder.New() // SEND MONEY TO MY WALLET. .AddOperation(OpCodes.OP_DUP) .AddOperation(OpCodes.OP_HASH160) .AddToStack(newKey.GetPublicKeyHashed()) .AddOperation(OpCodes.OP_EQUALVERIFY) .AddOperation(OpCodes.OP_CHECKSIG) .Build(); var receiverScript = _scriptBuilder.New() // SEND MONEY TO THE SELLER. .AddOperation(OpCodes.OP_DUP) .AddOperation(OpCodes.OP_HASH160) .AddToStack(bcAddr.PublicKeyHash) .AddOperation(OpCodes.OP_EQUALVERIFY) .AddOperation(OpCodes.OP_CHECKSIG) .Build(); var txBuilder = _transactionBuilder.NewNoneCoinbaseTransaction() .Spend(selectedTransaction.TxId.FromHexString(), (uint)selectedTransaction.Vout, script.Serialize()) .AddOutput((long)receiverValue, receiverScript); if (senderValue > 0) { txBuilder.AddOutput((long)senderValue, senderSript); } var tx = txBuilder.Build(); var s = tx.Serialize().Count(); var rpcClient = new RpcClient(authenticatedWallet.Network); rpcClient.SendRawTransaction(tx).ContinueWith((r) => { try { var res = r.Result; } catch (AggregateException ex) { var exx = ex.InnerExceptions; } }); }
/// <summary> /// Deserializing the JSON object /// </summary> /// <param name="result"></param> /// <returns></returns> private BlockChainAddress GetAddrfromJSON(string result) { BlockChainAddress address = new BlockChainAddress(); address = JsonConvert.DeserializeObject<BlockChainAddress>(result); return address; }
public bool UpdateBalance(BlockChainAddress currentLoggedInAddress, TransactionBlockChain transactionBc) { var trans = ConnectionHelper.GetConnection().BeginTransaction(); try { var cmd = new MySqlCommand("select balance from address where address = @address", ConnectionHelper.GetConnection()); cmd.Parameters.AddWithValue("@address", currentLoggedInAddress.Address); var reader = cmd.ExecuteReader(); double currentBalance = 0; if (reader.Read()) { currentBalance = reader.GetDouble("balance"); } reader.Close(); if (transactionBc.Type == TransactionBlockChain.TransactionType.Withdraw && currentBalance < transactionBc.Amount) { throw new Exception("Not enough money in the account."); } if (transactionBc.Type == TransactionBlockChain.TransactionType.Withdraw) { currentBalance -= transactionBc.Amount; } if (transactionBc.Type == TransactionBlockChain.TransactionType.Deposit) { currentBalance += transactionBc.Amount; } var cmd1 = new MySqlCommand( "update address set balance = @balance WHERE address = @address", ConnectionHelper.GetConnection()); cmd1.Parameters.AddWithValue("@balance", currentBalance); cmd1.Parameters.AddWithValue("@address", currentLoggedInAddress.Address); var updateResult = cmd1.ExecuteNonQuery(); var cmd2 = new MySqlCommand( "insert into blockchaintransactions (transactionId, senderAddress, receiverAddress, type, amount, createdAt, updatedAt, status) values ( @transactionId, @senderAddress, @receiverAddress, @type, @amount, @createdAt, @updatedAt, @status) ", ConnectionHelper.GetConnection()); cmd2.Parameters.AddWithValue("@transactionId", transactionBc.TransactionId); cmd2.Parameters.AddWithValue("@senderAddress", transactionBc.SenderAddress); cmd2.Parameters.AddWithValue("@receiverAddress", transactionBc.ReceiveAddress); cmd2.Parameters.AddWithValue("@type", transactionBc.Type); cmd2.Parameters.AddWithValue("@amount", transactionBc.Amount); cmd2.Parameters.AddWithValue("@createdAt", transactionBc.CreatedAtMls); cmd2.Parameters.AddWithValue("@updatedAt", transactionBc.UpdatedAtMls); cmd2.Parameters.AddWithValue("@status", transactionBc.Status); var transactionResult = cmd2.ExecuteNonQuery(); if (updateResult != 1 || transactionResult != 1) { throw new Exception("Cannot add transactions or update accounts."); } trans.Commit(); return(true); } catch (Exception e) { trans.Rollback(); Console.WriteLine(e); return(false); } finally { ConnectionHelper.CloseConnection(); } }
/// <summary> /// Extracts all transactions from the BlockChain JSON response /// </summary> /// <param name="address">The address of the report</param> /// <param name="rawData">Serialized JSON data for invalidly serialized data</param> private List<Transaction> GetTransactionsList(BlockChainAddress address, string rawData, Transaction lastTrx, int order, out bool lastTrxFound) { // List of transaction, will be ordered and use as a data source for charts List<Transaction> trx = new List<Transaction>(); // value for balance calculation long balance = address.final_balance; lastTrxFound = false; // Get all relevant transactions foreach (Tx transaction in address.txs) { if (lastTrx != null && transaction.tx_index == lastTrx.Index) { lastTrxFound = true; break; } long tempValOut = 0; long tempValIn = 0; long fee = 0; // Use the extended out object to add a time stamp Transaction newItemOut = new Transaction(); Transaction newItemIn = new Transaction(); // Get outgoing transactions foreach (Input input in transaction.inputs) { if (input.prev_out.addr == address.address) { // multiple outbound transaction are possible? tempValOut += input.prev_out.value; } fee -= input.prev_out.value; } if (tempValOut != 0) { newItemOut = InitializeTrx(transaction, TransactionType.OUT, rawData, tempValOut, balance, order); trx.Add(newItemOut); } // Get incoming transactions foreach (Out output in transaction.@out) { if (output.addr == address.address) { // multiple inbound transaction are possible tempValIn += output.value; } fee += output.value; } if (tempValIn != 0) { newItemIn = InitializeTrx(transaction, TransactionType.IN, rawData, tempValIn, balance, order); trx.Add(newItemIn); } trx[trx.Count - 1].Fee = fee < 0 ? fee * -1 : fee; } // initialize the original transaction order (will be reversed later) for (int i =trx.Count - 1; i >=0 ; i--) { trx[i].ItemOrder += trx[i].ItemOrder + i; } // Order the list based on the timestamp return trx; }
private static void ExecuteConnectedWallet(int number) { if (number < 0 && number > 6) { MenuHelper.DisplayError("Please enter an option between [1-6]"); } switch (number) { case 1: // BROADCAST A UTXO TRANSACTION. Console.WriteLine("Please enter the address"); var receivedHash = Console.ReadLine(); var deserializedAdr = BlockChainAddress.Deserialize(receivedHash); Console.WriteLine("How much do-you want to send ?"); var value = MenuHelper.EnterNumber(); var blockChain = BlockChainStore.Instance().GetBlockChain(); var builder = new TransactionBuilder(); var transaction = builder.NewNoneCoinbaseTransaction() // .Spend(0, ) .AddOutput(value, Script.CreateP2PKHScript(deserializedAdr.PublicKeyHash)) .Build(); var serializedTransaction = transaction.Serialize(); // SEND UTXO. _nodeLauncher.Broadcast(transaction); ExecuteMenu(); return; case 2: // GENERATE A NEW BITCOIN ADDRESS. var key = Key.Genererate(); var h = new BigInteger(key.GetPublicKeyHashed()); var blockChainAddress = new BlockChainAddress(ScriptTypes.P2PKH, _nodeLauncher.GetNetwork(), key); var hash = blockChainAddress.GetSerializedHash(); Console.WriteLine($"Give the bitcoin address to the person {hash}"); Console.WriteLine("Please enter a password to protect your wallet"); var password = Console.ReadLine(); _keyRepository.Load(password); _keyRepository.Keys.Add(key); _keyRepository.Save(password); break; case 3: DisplayWalletInformation(); ExecuteMenu(); return; case 4: _nodeLauncher.RefreshBlockChain(); ExecuteMenu(); break; case 5: _nodeLauncher.RefreshConnectedPeers(); ExecuteMenu(); break; case 6: Console.WriteLine("Bye bye"); Console.ReadLine(); return; } ExecuteMenu(); }
private JObject ListUnspent(IEnumerable <string> parameters, JObject response, string id) { var transactions = MemoryPool.Instance().GetTransactions(); var blockChain = _blockChainStore.GetBlockChain(); var wallet = WalletStore.Instance().GetAuthenticatedWallet(); int confirmationScore = 1; var maxConfirmations = 9999999; IEnumerable <string> addrs = new List <string>(); if (parameters.Any()) { if (int.TryParse(parameters.First().ToString(), out confirmationScore)) { } if (parameters.Count() >= 2 && int.TryParse(parameters.ElementAt(1), out maxConfirmations)) { } if (parameters.Count() >= 3) { var jArr = JArray.Parse(parameters.ElementAt(2)); if (jArr != null) { addrs = jArr.Select(j => j.ToString()); } } } if (wallet == null) { return(CreateErrorResponse(id, (int)RpcErrorCodes.RPC_WALLET_NOT_FOUND, "No authenticated wallet")); } var res = new JArray(); if (addrs == null || !addrs.Any()) { addrs = wallet.Addresses.Select(a => a.Hash); } var walletBlockChainAddrs = addrs.Select(a => new { bca = BlockChainAddress.Deserialize(a), hash = a }); if (maxConfirmations >= 0) // CONFIRMATION 0. { if (transactions != null && transactions.Any()) { foreach (var unconfirmedTransaction in transactions) { if (unconfirmedTransaction.Transaction != null) { var lBcTx = unconfirmedTransaction.Transaction as BcBaseTransaction; if (lBcTx == null) { continue; } foreach (var unconfirmedUTXO in lBcTx.TransactionOut.Where(t => t is TransactionOut).Select(t => t as TransactionOut)) { var bcAdr = walletBlockChainAddrs.FirstOrDefault(wph => unconfirmedUTXO.Script.ContainsPublicKeyHash(wph.bca.PublicKeyHash)); if (bcAdr == null) { continue; } var record = new JObject(); record.Add("txid", unconfirmedTransaction.Transaction.GetTxId().ToHexString()); record.Add("vout", lBcTx.TransactionOut.IndexOf(unconfirmedUTXO)); record.Add("amount", unconfirmedUTXO.Value); record.Add("address", bcAdr.hash); record.Add("scriptPubKey", unconfirmedUTXO.Script.Serialize().ToHexString()); record.Add("confirmations", 0); record.Add("spendable", true); record.Add("solvable", true); res.Add(record); } } } } } if (maxConfirmations >= 1) // CONFIRMATION 1. { var utxos = blockChain.GetUnspentTransactions(); foreach (var utxo in utxos) { var bcAdr = walletBlockChainAddrs.FirstOrDefault(wph => utxo.Script.ContainsPublicKeyHash(wph.bca.PublicKeyHash)); if (bcAdr == null) { continue; } var record = new JObject(); record.Add("txid", utxo.TxId.ToHexString()); record.Add("vout", utxo.Index); record.Add("address", bcAdr.hash); record.Add("scriptPubKey", utxo.Script.Serialize().ToHexString()); record.Add("amount", utxo.Value); record.Add("confirmations", 1); record.Add("spendable", true); record.Add("solvable", true); res.Add(record); } } response["result"] = res; return(response); }