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);
        }
Example #2
0
        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()));
        }
Example #3
0
        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();
        }
Example #7
0
        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();
        }
Example #8
0
        public static SmartShares.Blockchain LoadBlockchain(string path)
        {
            var blockchainBytes = File.ReadAllBytes(path);

            return(BlockchainUtil.DeserializeBlockchain(blockchainBytes));
        }
Example #9
0
 public Blockchain(TransactionPool transactionPool)
 {
     TransactionPool = transactionPool;
     BlockVerify(BlockchainUtil.CreateGenesisBlock());
 }