public void ParseFromBlockain_GenesisBlockchain_TrueParseAmount() { //Arrange EccService.GenerateKey(out var privateKey, out var publicKey); var keyPair = new KeyPair() { PrivateKey = privateKey, PublicKey = publicKey }; var genesisBlock = Genesis.GenerateGenesisBlock(keyPair); var blockchain = new SmartShares.Blockchain() { blocks = new Dictionary <byte[], Block>() { { genesisBlock.Hash, genesisBlock } } }; //Act var amount = CoinPocketManager.ParseFromBlockain(blockchain, keyPair.PublicKey); var recipientHash = BlockchainUtil.ToAddress(keyPair.PublicKey); //Assert Assert.IsTrue(genesisBlock.Transaction.OutEntries[0].RecipientHash.SequenceEqual(recipientHash)); Assert.AreEqual(amount, 10); }
static void Main(string[] args) { var time = new DateTime(2020, 10, 31, 1, 50, 0, DateTimeKind.Utc); var tx = BlockchainUtil.CreateCoinBaseTransaction(0, null, time, engrave: "Haloween - ArCana"); tx.TimeStamp = time; var txs = new List <Transaction>() { tx }; var rootHash = HashUtil.ComputeMerkleRootHash(txs.Select(x => x.Id.Bytes).ToList()); var block = new Block() { Id = new HexString("00006D930177AA974CFBA170357D202AEB22BDA7CEA348F93DF9AD9326776843"), PreviousBlockHash = new HexString(""), Nonce = 8528990852057875687, Transactions = null, MerkleRootHash = rootHash, Timestamp = time, Bits = 17, }; //Always True Console.WriteLine(Miner.HashCheck(block.ComputeId(), Difficulty.ToTargetBytes(block.Bits))); Console.WriteLine(block.Id.Equals(block.ComputeId().ToHexString())); }
public bool Execute(CancellationToken token, out Block block) { block = null; var txs = TransactionPool.GetPool(); var time = DateTime.UtcNow; var subsidy = BlockchainUtil.GetSubsidy(Blockchain.Chain.Count); var txList = txs.Where(tx => { if (token.IsCancellationRequested || !Blockchain.VerifyTransaction(tx, time, false, out var txFee)) { return(false); } subsidy += txFee; return(true); }).ToList(); var coinbaseOut = new Output() { Amount = subsidy, PublicKeyHash = MinerPublicKeyHash }; var tb = new TransactionBuilder(new List <Output>() { coinbaseOut }, new List <Input>()); var coinbaseTx = tb.ToTransaction(time); if (!Blockchain.VerifyTransaction(coinbaseTx, time, true, out var txFee, subsidy)) { return(false); } txList.Insert(0, coinbaseTx); var txIds = txList.Select(x => x.Id.Bytes).ToList(); var mineBlock = new Block() { Id = null, PreviousBlockHash = Blockchain.Chain.Last().Id, Transactions = null, MerkleRootHash = HashUtil.ComputeMerkleRootHash(txIds), Bits = Blockchain.GetDifficulty() }; if (!Mine(mineBlock, token)) { return(false); } mineBlock.Transactions = txList; block = mineBlock; return(true); }
public static ulong ParseFromBlockain(Dictionary <byte[], Block> data, byte[] publicKey) { foreach (var variable in data) { foreach (var outEntry in variable.Value.Transaction.OutEntries) { if (outEntry.RecipientHash.SequenceEqual(BlockchainUtil.ToAddress(publicKey))) { return(outEntry.Value); } } } return(0); }
public void VerifyBlockchainTest() { var list = new List <Block>(); for (var i = 0; i < 10; i++) { Block block; if (i == 0) { block = new Block() { PreviousBlockHash = new byte[] { 0x00 }.ToHexString(), Nonce = (ulong)i }; block.Id = block.ComputeId().ToHexString(); } else { block = new Block() { PreviousBlockHash = list.Last().Id, Nonce = (ulong)i }; block.Id = block.ComputeId().ToHexString(); } list.Add(block); } BlockchainUtil.VerifyBlockchain(list).Is(true); var incorrectBlock = new Block() { PreviousBlockHash = new byte[] { 0x00 }.ToHexString(), Nonce = (ulong)1, }; incorrectBlock.Id = incorrectBlock.ComputeId().ToHexString(); list.Add(incorrectBlock); BlockchainUtil.VerifyBlockchain(list).Is(false); }
private void ButtonToPay_Click(object sender, RoutedEventArgs e) { if (int.Parse(TextBoxAmountAct.Text) > Amount) { MessageBox.Show("Error!", "You haven't avaliable ACT for makking transaction.", MessageBoxButton.OK, MessageBoxImage.Error); return; } var recipientUserHash = HexConvert.ToBytes(TextBoxRecipientId.Text); var inEntry = new InEntry() { PublicKey = _userCoinPocket.KeyPair.PublicKey, Amount = Amount }; var outEntry = new List <OutEntry>(15) { new OutEntry() { RecipientHash = recipientUserHash, Value = int.Parse(TextBoxAmountAct.Text) }, new OutEntry() { RecipientHash = _userCoinPocket.KeyPair.PublicKey, Value = Amount - int.Parse(TextBoxAmountAct.Text) } }; var transaction = new Transaction() { Id = DataManager.UploadBlockchainDictionary().Last().Value.Transaction.Id + 1, InEntries = new List <InEntry>() { inEntry }, OutEntries = outEntry, Signature = EccService.Sign(_userCoinPocket.KeyPair.PublicKey, _userCoinPocket.KeyPair.PrivateKey, _userCoinPocket.KeyPair.PublicKey), Timestamp = DateTime.Now }; var message = BlockchainUtil.SerializeTransaction(transaction); var senderUdpClient = new UdpClient(_userCoinPocket.ReceivePort); try { senderUdpClient.Send( message, message.Length, "127.0.0.1", 9999); } catch { throw new Exception(); } finally { senderUdpClient.Close(); } var receiver = new UdpClient(_userCoinPocket.ReceivePort); IPEndPoint remoteIp = null; var data = receiver.Receive(ref remoteIp); var chain = MessagePackSerializer.Deserialize <KeyValuePair <string, Block> >(data); var json = JsonConvert.SerializeObject(chain, Formatting.Indented); GroupBoxStatus.Header = "You trancsaction has been added"; var blockchain = DataManager.UploadBlockchainDictionary(); TextBlockAct.Text = Executor .GetCashRec(blockchain, _userCoinPocket.KeyPair.PublicKey, blockchain.Last().Key).ToString(); TextBlockStatus.Text = json; receiver.Close(); }
static void Main(string[] args) { var aliceKey = new Key(); var bobKey = new Key(); //Aliceが50コイン所持しているというトランザクションが必要 var coinbaseTx = BlockchainUtil.CreateCoinBaseTransaction(0, aliceKey.PublicKeyHash, engrave: "Alice Coin"); var txBuilder = new TransactionBuilder(); txBuilder.Inputs.Add(new Input() { OutputIndex = 0, TransactionId = coinbaseTx.Id, }); txBuilder.Outputs.Add(new Output() { PublicKeyHash = bobKey.PublicKeyHash, Amount = 10 }); txBuilder.Outputs.Add(new Output() { PublicKeyHash = aliceKey.PublicKeyHash, Amount = 40 }); var tx = txBuilder.ToSignedTransaction(aliceKey.PrivateKey, aliceKey.PublicKey); var hash = tx.GetSignHash(); var input = tx.Inputs[0]; var isAliceTx = Signature.Verify(hash, input.Signature, input.PublicKey, coinbaseTx.Outputs[0].PublicKeyHash); Console.WriteLine($"Is Alice Tx ? : { isAliceTx}"); var preBlock = new Block() { Timestamp = DateTime.UtcNow, Transactions = new List <Transaction>() { coinbaseTx }, Bits = Difficulty.MinDifficultBits }; var block = new Block() { Timestamp = DateTime.UtcNow, Transactions = new List <Transaction>() { tx }, Bits = Difficulty.MinDifficultBits }; preBlock.MerkleRootHash = HashUtil.ComputeMerkleRootHash(preBlock.Transactions); block.MerkleRootHash = HashUtil.ComputeMerkleRootHash(block.Transactions); if (!Miner.Mine(preBlock, CancellationToken.None)) { return; } var blockchain = new Blockchain(); blockchain.BlockVerify(preBlock); var fee = 0ul; foreach (var transaction in block.Transactions) { var isVerified = blockchain.VerifyTransaction(transaction, block.Timestamp, false, out var txFee); if (!isVerified) { return; } fee += txFee; } var noahKey = new Key(); var noahCoinbase = BlockchainUtil.CreateCoinBaseTransaction(blockchain.Chain.Count, noahKey.PublicKeyHash, fee); block.Transactions.Insert(0, noahCoinbase); if (!Miner.Mine(block, CancellationToken.None)) { return; } Console.WriteLine("ブロック追加前----------------"); blockchain.Utxos.ForEach(x => Console.WriteLine($"{x.Output.PublicKeyHash.ToHex()} : {x.Output.Amount}")); //ブロック追加 blockchain.BlockVerify(block); Console.WriteLine("ブロック追加後----------------"); blockchain.Utxos.ForEach(x => Console.WriteLine($"{x.Output.PublicKeyHash.ToHex()} : {x.Output.Amount}")); var inputs = blockchain.Chain .SelectMany(x => x.Transactions) .SelectMany(x => x.Inputs); var outputs = blockchain.Chain .SelectMany(x => x.Transactions) .Select(x => (x.Outputs, x.Id)) .SelectMany(x => ToTxO(x.Outputs, x.Id)); var utxo = outputs.Where(opt => !inputs.Any(ipt => ipt.OutputIndex == opt.OutIndex && ipt.TransactionId.Equals(opt.TransactionId))); var alicePkh = aliceKey.PublicKeyHash; var aliceUtxo = utxo.Select(x => x.Output) .Where(x => x.PublicKeyHash?.SequenceEqual(alicePkh) ?? false) .ToList(); var coinSum = aliceUtxo .Select(x => x.Amount) .Aggregate((a, b) => a + b); Console.WriteLine($"Alice : {coinSum} coin"); //念のためにUTXOを最新にする。 blockchain.UpdateUtxos(); var coinSum2 = blockchain.Utxos .Where(x => x.Output.PublicKeyHash?.SequenceEqual(alicePkh) ?? false) .Select(x => x.Output.Amount) .Aggregate((a, b) => a + b); Console.WriteLine($"Alice : {coinSum2} coin"); var noahCoin = blockchain.Utxos .First(x => x.Output.PublicKeyHash? .SequenceEqual(noahKey.PublicKeyHash) ?? false); var noahInput = new Input() { OutputIndex = noahCoin.OutIndex, TransactionId = noahCoin.TransactionId }; var noahAmount = noahCoin.Output.Amount; var toAliceOutput = new Output() { PublicKeyHash = alicePkh, Amount = noahAmount / 2 }; var toNoahOutput = new Output() { PublicKeyHash = noahKey.PublicKeyHash, Amount = noahAmount - toAliceOutput.Amount }; var tb = new TransactionBuilder(); tb.Inputs.Add(noahInput); tb.Outputs.Add(toAliceOutput); tb.Outputs.Add(toNoahOutput); var noahTx = tb.ToSignedTransaction(noahKey.PrivateKey, noahKey.PublicKey); var node1 = new Server(new CancellationTokenSource()); var node2 = new Server(new CancellationTokenSource()); node1.StartAsync(50001).GetAwaiter().GetResult(); node2.StartAsync(50002).GetAwaiter().GetResult(); node2.MessageReceived += async(msg, ip) => { var newTx = JsonSerializer.Deserialize <NewTransaction>(msg.Payload).Transaction; Console.WriteLine($"New Transaction! : {newTx.Id.String}"); }; var localhost = IPAddress.Parse("127.0.0.1"); var txMessage = new NewTransaction() { Transaction = noahTx }; txMessage.ToMessage() .SendAsync(localhost, 50002, 50001).GetAwaiter().GetResult(); Console.ReadKey(); var target = Difficulty.ToTargetBytes(1); Console.WriteLine(target.ToHex()); byte[] data; ulong nonce = 0; do { data = HashUtil.DoubleSHA256Hash(BitConverter.GetBytes(nonce++)); Console.WriteLine(data.ToHex()); } while (!Miner.HashCheck(data, target)); var aliceNm = new NetworkManager(CancellationToken.None); var bobNm = new NetworkManager(CancellationToken.None); aliceNm.StartServerAsync(50005).GetAwaiter().GetResult(); bobNm.StartServerAsync(50006).GetAwaiter().GetResult(); }
public static SmartShares.Blockchain LoadBlockchain(string path) { var blockchainBytes = File.ReadAllBytes(path); return(BlockchainUtil.DeserializeBlockchain(blockchainBytes)); }
public Blockchain(TransactionPool transactionPool) { TransactionPool = transactionPool; BlockVerify(BlockchainUtil.CreateGenesisBlock()); }