Example #1
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 #2
0
        public void Execute(CancellationToken token)
        {
            var txs     = BlockchainManager.GetPool();
            var time    = DateTime.UtcNow;
            var subsidy = BlockchainManager.GetSubsidy(BlockchainManager.Chain.Count);

            var txList = txs.Where(tx =>
            {
                try
                {
                    token.ThrowIfCancellationRequested();
                    BlockchainManager.VerifyTransaction(tx, time);
                    subsidy += tx.TransactionFee;
                    return(true);
                }
                catch
                {
                    return(false);
                }
            }).ToList();

            var cbOut = new Output()
            {
                Amount        = subsidy,
                PublicKeyHash = MinerKeyHash.Bytes
            };
            var tb = new TransactionBuilder(new List <Output>()
            {
                cbOut
            }, new List <Input>());
            var coinbaseTx = tb.ToTransaction(time);

            BlockchainManager.VerifyTransaction(coinbaseTx, time, subsidy);
            txList.Insert(0, coinbaseTx);

            var txIds = txList.Select(x => x.Id).ToList();

            var block = new Block()
            {
                PreviousBlockHash = BlockchainManager.Chain.Last().Id,
                Transactions      = txList,
                MerkleRootHash    = HashUtil.ComputeMerkleRootHash(txIds),
                Bits = Difficulty.DifficultyBits
            };

            if (!Mining(block, token))
            {
                return;
            }

            _logger.LogInformation($"Mined");
            _logger.LogInformation($"{JsonSerializer.PrettyPrint(JsonSerializer.Serialize(block))}");

            //Broadcast Block
        }
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 Block MakeBlock(ulong nonce, List <Transaction> transactions)
        {
            var merkleHash = HashUtil.ComputeMerkleRootHash(transactions.Select(x => x.Id).ToList());
            var lastBlock  = JsonSerializer.Serialize(Chain.Last());

            return(new Block()
            {
                MerkleRootHash = merkleHash,
                Nonce = nonce,
                PreviousBlockHash = new HexString(HashUtil.DoubleSHA256(lastBlock)),
                Timestamp = DateTime.UtcNow,
                Transactions = transactions
            });
        }
Example #5
0
        public static Block CreateGenesisBlock()
        {
            var time = new DateTime(2020, 10, 31, 1, 50, 0, DateTimeKind.Utc);
            var tx = 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());

            return new Block()
            {
                Id = new HexString("00006D930177AA974CFBA170357D202AEB22BDA7CEA348F93DF9AD9326776843"),
                PreviousBlockHash = new HexString(""),
                Nonce = 8528990852057875687,
                Transactions = txs,
                MerkleRootHash = rootHash,
                Timestamp = time,
                Bits = 17,
            };
        }
        public static Block CreateGenesis()
        {
            var tx = CreateCoinBaseTransaction(0, null, "ArC - A Little BlockChain by C#");

            tx.TimeStamp = GenesisTime;
            var txs = new List <Transaction> {
                tx
            };
            var rootHash = HashUtil.ComputeMerkleRootHash(txs.Select(x => x.Id).ToList());

            return(new Block()
            {
                PreviousBlockHash = new HexString(""),
                Nonce = 2083236893,
                Transactions = txs,
                MerkleRootHash = rootHash,
                Timestamp = GenesisTime,
                Bits = 5
            });
        }
        public void Mining()
        {
            var(privateKey, publicKey) = SignManager.GenerateKeys();
            var publickKeyHash = new HexString(HashUtil.RIPEMD_SHA256(publicKey));
            //Genesis Mining
            var genesis = BlockchainManager.CreateGenesis();
            var miner   = new Miner
            {
                MinerKeyHash = publickKeyHash
            };

            Console.WriteLine("Mining");
            miner.Mining(genesis, Context.CancellationToken);
            BlockchainManager.Chain.Add(genesis);


            for (var i = 0; i < 10; i++)
            {
                var gg = BlockchainManager.CreateCoinBaseTransaction(i + 1, publickKeyHash.Bytes, $"まかろに{i}");
                gg.TimeStamp = DateTime.UtcNow;
                var txs = new List <Transaction>()
                {
                    gg
                };
                var rootHash = HashUtil.ComputeMerkleRootHash(txs.Select(x => x.Id).ToList());

                var b = new Block()
                {
                    PreviousBlockHash = BlockchainManager.Chain.Last().Id,
                    Transactions      = txs,
                    MerkleRootHash    = rootHash,
                    Timestamp         = DateTime.UtcNow,
                    Bits = 1
                };
                miner.Mining(b, Context.CancellationToken);
                BlockchainManager.Chain.Add(b);
                Task.Delay(10).GetAwaiter().GetResult();
            }

            //Second Block Mining
            Console.WriteLine($"{genesis.Transactions.Count}");
            var tb  = new TransactionBuilder();
            var ttx = BlockchainManager.Chain.SelectMany(x => x.Transactions).First(x => x.Engraving == "まかろに0");

            var input = new Input()
            {
                TransactionId = ttx.Id,
                OutputIndex   = 0,
            };
            var output = new Output()
            {
                Amount        = 10,
                PublicKeyHash = publickKeyHash.Bytes
            };

            tb.Inputs.Add(input);
            tb.Outputs.Add(output);
            var tx = tb.ToSignedTransaction(privateKey, publicKey);

            BlockchainManager.TransactionPool.Add(tx);
            miner.Start();

            Console.WriteLine($"{BlockchainManager.VerifyBlockchain()} : OK");
            Console.ReadLine();
        }
Example #8
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();
        }