static void Main(string[] args) { Chain mainChain = new Chain(); //Test add block mainChain.AddBlock(new Block { data = "test", date_stamp = DateTime.Now.ToString(), owner = "nero" }); mainChain.AddBlock(new Block { data = "test", date_stamp = DateTime.Now.ToString(), owner = "nero" }); mainChain.AddBlock(new Block { data = "test", date_stamp = DateTime.Now.ToString(), owner = "nero" }); //End Test add block Console.WriteLine(); }
public void TestThatValidateCanBeCalledUsingSubsetOfBlocks() { var fakeDateTimeOffsetProvider = A.Fake <IDateTimeOffsetProvider>(); A.CallTo(() => fakeDateTimeOffsetProvider.GetDateTimeOffset()).Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 32, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 33, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 34, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 35, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 36, 00))).Once(); var chain = new Chain(fakeDateTimeOffsetProvider); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=sd7g8578s5g78d56s87g5"))); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=d8976fd876f8d7689f76d"))); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=34j5hg45jhgjh5gjh4g5h"))); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=684db68d4r6b84rd68bdd"))); Assert.That(chain.Validate(), Is.EqualTo(true)); Assert.That(chain.Blocks.Count, Is.EqualTo(5)); Assert.That(chain.Validate(100), Is.EqualTo(true)); Assert.That(chain.Validate(5), Is.EqualTo(true)); Assert.That(chain.Validate(4), Is.EqualTo(true)); Assert.That(chain.Validate(3), Is.EqualTo(true)); Assert.That(chain.Validate(2), Is.EqualTo(true)); Assert.That(chain.Validate(1), Is.EqualTo(true)); }
public void CanFindBlock() { var blocks = new Chain <MyData> (new ProofOfWork()); blocks.AddBlock(new MyData(108, "Message - 108")); blocks.AddBlock(new MyData(109, "Message - 109")); blocks.AddBlock(new MyData(110, "Message - 110")); Assert.True(blocks.IsValid()); var block0 = blocks.Blocks.First(x => x.Value.Data.Value.Message == "Message - 108"); Assert.Equal("Message - 108", block0.Value.Data.Value.Message); }
public void ChainIsInvalidatedAfterChange() { var blocks = new Chain <MyData> (new ProofOfWork()); blocks.AddBlock(new MyData(108, "Message - 108")); blocks.AddBlock(new MyData(109, "Message - 109")); var blockJSON = blocks.ToString().Replace("Message - 108", "CHANGED"); blocks = DeserializeObject <Chain <MyData> > (blockJSON, new ProofOfWorkConverter()); Assert.False(blocks.IsValid()); }
public void TestThatPreviousBlockWithThreeBlocksInChainReturnsPreviousBlock() { var fakeDateTimeOffsetProvider = A.Fake <IDateTimeOffsetProvider>(); A.CallTo(() => fakeDateTimeOffsetProvider.GetDateTimeOffset()).Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 32, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 33, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 34, 00))).Once(); var chain = new Chain(fakeDateTimeOffsetProvider); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=sd7g8578s5g78d56s87g5"))); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=65ouybo6ouy45bo6yub56"))); Assert.That(chain.GetPreviousBlock().Index, Is.EqualTo(2)); Assert.That(chain.GetPreviousBlock().Hash.Substring(0, 3), Is.EqualTo("5WZ")); }
private void SendMessage(string message) { var hash = chain.CreateBlock(message); var blockMessage = new BlockMessage() { Message = message, Hash = hash }; chatClient.SendMessage(new Message() { Command = "Text", Parameters = JsonConvert.SerializeObject(blockMessage) }).Wait(); chain.AddBlock(message, hash); }
public void CreateValidChain() { // Arrange var chain = new Chain(); // Act var firstBlock = new PocBlock("test"); chain.AddBlock(firstBlock); var secondBlock = new PocBlock("test2"); chain.AddBlock(secondBlock); // Assert Assert.IsTrue(chain.IsChainValid()); }
public void IsValidIsNotNullWhenChainExists() { var sut = new Chain <object> (); sut.AddBlock(new MyData(108, "Message - 108")); Assert.True(sut.IsValid() != null); }
public void GetLatestBlock_GetsLatestBlock() { // Arrange var chain = new Chain(); // Act var firstBlock = new PocBlock("test"); chain.AddBlock(firstBlock); var secondBlock = new PocBlock("test2"); chain.AddBlock(secondBlock); // Assert Assert.IsTrue(chain.IsChainValid()); Assert.AreEqual(secondBlock, chain.GetLatestBlock()); }
public void TestThatChainWithTwoBlocksIsValid() { var fakeDateTimeOffsetProvider = A.Fake <IDateTimeOffsetProvider>(); A.CallTo(() => fakeDateTimeOffsetProvider.GetDateTimeOffset()).Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 32, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 33, 00))).Once() .Then.Returns(new DateTimeOffset(new DateTime(2018, 12, 01, 14, 34, 00))).Once(); var chain = new Chain(fakeDateTimeOffsetProvider); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=sd7g8578s5g78d56s87g5"))); chain.AddBlock(chain.CreateBlock(new Transaction("nodeA", "Add", "Id=d8976fd876f8d7689f76d"))); Assert.That(chain.GetLatestBlock().Hash, Is.Not.Empty); Assert.That(chain.GetLatestBlock().Hash.Length, Is.EqualTo(44)); Assert.That(chain.GetLatestBlock().Hash.Substring(0, 3), Is.EqualTo("jIG")); Assert.That(chain.GetPreviousBlock().Hash.Substring(0, 3), Is.EqualTo("jIG")); Assert.That(chain.Validate(), Is.EqualTo(true)); }
public void MustPointToLastHash() { var blockchain = new Chain(StrategyEnum.ProofOfWork, 2); var block = blockchain.MineBlock(blockchain.LastHash, "first block"); blockchain.AddBlock(block); Assert.Equal(blockchain.LastHash, block.Hash); }
public static void ConnectToNode(string address) { HubConnection connection = new HubConnectionBuilder() .WithUrl(address + "/chain") .Build(); connection.On <string>("Blockchain", (chain) => { _blockchain = JsonConvert.DeserializeObject <Chain>(chain); }); connection.On <Block>("Block", (block) => { _blockchain.AddBlock(block); }); connection.StartAsync().Wait(); _nodes.Add(connection); }
public void MustAddBlock() { var blockchain = new Chain(StrategyEnum.ProofOfWork, 2); var block = blockchain.MineBlock(blockchain.LastHash, "first block"); blockchain.AddBlock(block); Assert.Equal(blockchain.Blocks[blockchain.Blocks.Length - 1], block); Assert.Equal(blockchain.Blocks[blockchain.Blocks.Length - 1].Hash, block.Hash); }
private void MineButton_Click(object sender, EventArgs e) { mainingLabel.Text = "Mining"; Block block = Miner.GetBlock(Chain.GetLastBlock()); if (Chain.IsValidNewBlock(block, Chain.GetLastBlock())) { mainingLabel.Text = "Success"; Chain.AddBlock(block); } UpdateChainInfo(); }
public void ChainCanBeSerializedAndDeSerialized(bool proofOfWork) { var blocks = new Chain <MyData> (proofOfWork ? new ProofOfWork() : null); blocks.AddBlock(new MyData(108, "Amount is 108")); blocks.AddBlock(new MyData(109, "Amount is 109")); blocks.AddBlock(new MyData(110, "Amount is 110")); Assert.True(blocks.IsValid()); var blockJSON = blocks.ToString(); blocks = null; blocks = DeserializeObject <Chain <MyData> > (blockJSON, new ProofOfWorkConverter()); Assert.True(blocks.IsValid()); Assert.Equal(blockJSON, blocks.ToString()); blocks.AddBlock(new MyData(111, "Amount is 111")); Assert.Equal(4, blocks.Blocks.Count); }
static void Main(string[] args) { var blockchain = new Chain(StrategyEnum.ProofOfWork, 3); Console.WriteLine(blockchain.Blocks[0].ToString()); for (int i = 0; i < 10; i++) { var newBlock = blockchain.MineBlock(blockchain.Blocks[i].Hash, $"{i+1}nth block in the chain"); blockchain.AddBlock(newBlock); Console.WriteLine(newBlock.ToString()); } }
public void TemperCreatesInvalidChain() { // Arrange var chain = new Chain(); // Act var firstBlock = new PocBlock("test"); chain.AddBlock(firstBlock); var secondBlock = new PocBlock("test2"); chain.AddBlock(secondBlock); var thirdBlock = new PocBlock("test3"); chain.AddBlock(thirdBlock); chain.Blocks[0] = thirdBlock; // Assert Assert.IsFalse(chain.IsChainValid()); }
private static void AddBlock() { Console.Clear(); Console.Write("Data: "); string str = Console.ReadLine(); object data = new BlockData { BlockValue = str }; Console.Clear(); Console.WriteLine("Mining Block..."); var block = new Block <object>(DateTime.Now, data, ""); var c = _chain.AddBlock(block); Console.WriteLine("Block mined."); }
private bool HandleBlock(Chain chain, Block block, IList <Transaction> transactions) { try { var oracle = new BlockOracleReader(Nexus, block); var changeSet = chain.ProcessTransactions(block, transactions, oracle, 1, false); // false, because we don't want to modify the block chain.AddBlock(block, transactions, 1, changeSet); } catch (Exception e) { Logger.Error(e.ToString()); throw new Exception("block add failed"); } Logger.Message($"Added block #{block.Height} to {chain.Name}"); return(true); }
public void MiningUpdate(bool forceMineBlock = false) { // Enter critical section _chainUpdateLock.WaitOne(); // Process blocks that were queued because of future timestamps. Chain.ProcessQueuedBlocks(); // Verify we have transactions in our pool. if (TransactionPool.Count > 0 || forceMineBlock) { // Determine if we're skipping miner coverage bool skipMinerCoverageAndTracing = !TrustMinerStates; // Backup our coverage enabled state and disable it if necessary. bool oldCoverageState = Chain.Configuration.CodeCoverage.Enabled; bool oldTracingState = Chain.Configuration.DebugConfiguration.IsTracing; if (skipMinerCoverageAndTracing) { Chain.Configuration.CodeCoverage.Enabled = false; Chain.Configuration.DebugConfiguration.IsTracing = false; } // Create a new head candidate. var candidateResult = Chain.State.CreateNewHeadCandidate(Chain, TransactionPool, Chain.State.PreviousHeaders[0], Chain.Configuration.CurrentTimestamp, Coinbase, ExtraData, MinimumGasPrice); // Restore our coverage state and tracing state. Chain.Configuration.CodeCoverage.Enabled = oldCoverageState; Chain.Configuration.DebugConfiguration.IsTracing = oldTracingState; // We mine our block and do our proof of work to reach desired nonce/mix hash which satisfies our difficulty condition. (byte[] Nonce, byte[] MixHash)miningResult = Chain.Configuration.IgnoreEthashVerification ? (new byte[8], new byte[32]) : MiningPoW.Mine(candidateResult.newBlock.Header, 0, ulong.MaxValue); // Set our nonce and mix hash for this block candidateResult.newBlock.Header.MixHash = miningResult.MixHash; candidateResult.newBlock.Header.Nonce = miningResult.Nonce; // Add it to our chain Chain.AddBlock(candidateResult.newBlock, TrustMinerStates ? candidateResult.newState : null); } // Exit critical section _chainUpdateLock.Release(); }
static void Main(string[] args) { Console.WriteLine("Ondrej Balas - Building a Blockchain"); Console.WriteLine("Twitter: @ondrejbalas"); Console.WriteLine("Website: https://ondrejbalas.com"); Console.WriteLine("Github: https://github.com/ondrejbalas/blockchain"); Console.WriteLine(); Console.WriteLine(); var blockchain = new Chain(); // Create the blockchain blockchain.AddGenesisBlock(); // Add the genesis block var genesisBlock = (blockchain.LastBlock as GenesisBlock); var pub1 = genesisBlock.Transactions.Single().Recipients.Single().Address; var priv1 = genesisBlock.SpendKey; // Get the genesis spend key (private key needed to spend coins from the genesis transaction) // Make a key for ourselves so we can send coins to it. CryptoProvider.GenerateKeyPair(out byte[] myPrivateKey, out byte[] myPublicKey); // Make a couple blocks var block1 = new Block(blockchain.LastBlock); var b1tx1 = new Transaction() { SourceAddress = pub1, Recipients = new List <TransactionTarget>() { new TransactionTarget() { Address = myPublicKey, Amount = 50m } } }; b1tx1.Sign(priv1); // Comment this line and the transaction will be rejected by the blockchain. block1.Transactions.Add(b1tx1); blockchain.AddBlock(block1); var ledger = blockchain.GetLedger(); ledger.Print(); Console.ReadLine(); }
private bool HandleBlock(Chain chain, Block block, IList <Transaction> transactions) { if (block.Height != chain.Height + 1) { throw new NodeException("unexpected block height"); } try { var oracle = new BlockOracleReader(Nexus, block); Transaction inflationTx; var changeSet = chain.ProcessTransactions(block, transactions, oracle, 1, out inflationTx, null); // null, because we don't want to modify the block chain.AddBlock(block, transactions, 1, changeSet); } catch (Exception e) { Logger.Error(e.ToString()); throw new NodeException($"Failed to add block {block.Height} to {chain.Name} chain"); } return(true); }
private void Mine(Chain chain, int i) { Program.CryptoProvider.GenerateKeyPair(out byte[] priv0, out byte[] pub0); Program.CryptoProvider.GenerateKeyPair(out byte[] priv1, out byte[] pub1); Program.PrivateKeyLookup.Add(pub1, priv1); while (true) { var work = chain.GetWork(); decimal?result = null; int nonce = 0; Block block = null; while (result == null) { Thread.Sleep(100); lock (obj) { block = new Block(chain.LastBlock) { Type = BlockType.ProofOfWork }; // Increment nonce block.Nonce = nonce++; // add mining reward transaction var miningRewardTransaction = new Transaction() { SourceAddress = pub0, Recipients = new List <TransactionTarget>() { new TransactionTarget() { Amount = 100.0m, Address = pub1 } }, Type = BlockType.ProofOfWork }; miningRewardTransaction.Sign(priv0); block.Transactions.Add(miningRewardTransaction); foreach (var pendingTransactions in Program.PendingTransactions) { block.Transactions.Add(pendingTransactions); } result = work.AttemptHash(block.Hash()); if (result != null) { chain.AddBlock(block); nonce = 0; // success. reset nonce. } } } } }
public void Run() { var dateTimeProvider = new DateTimeOffsetProvider(); var chain = new Chain(dateTimeProvider); Server server = new Server { Services = { P2PGrpc.BindService(new P2PReceiverImpl(OnRemoteBlockReceived)) }, Ports = { new ServerPort(_localAddress.Host, _localAddress.Port, ServerCredentials.Insecure) } }; server.Start(); Console.WriteLine("P2PGrpc server listening on port " + _localAddress.Port); // client connection to servers var manager = new P2POutboundConnectionManager(); var allPortsInCluster = new List<NodeAddress> { new NodeAddress("localhost", 6000), new NodeAddress("localhost", 6001), new NodeAddress("localhost", 6002) }; manager.Connect(allPortsInCluster, _localAddress); manager.InitialiseNode(reply => { var seedChain = JsonConvert.DeserializeObject<Chain>(reply.Data); seedChain.DateTimeOffsetProvider = dateTimeProvider; chain = seedChain; }); DisplayHelp(); while (true) { var command = Console.ReadLine(); switch (command) { case "send": Console.WriteLine("enter a name..."); var user = Console.ReadLine(); manager.Broadcast(new Request { From = $"node{_localAddress}", Mode = "Hello", Data = user }, reply => { Console.WriteLine($"{reply.Data} from {reply.From}"); }); break; case "add": Console.WriteLine("enter data:"); var data = Console.ReadLine(); var newTransaction = new Transaction($"node{_localAddress}", "Add", data); var newBlock = chain.CreateBlock(newTransaction); chain.AddBlock(newBlock); manager.Broadcast(new Request { From = $"node{_localAddress}", Mode = "Add", Data = JsonConvert.SerializeObject(chain.GetLatestBlock()) }, reply => { Console.WriteLine($"{reply.Data} from {reply.From}"); if (reply.Mode == "FailureToAddBlockResponse") { chain.UndoLastBlock(); Console.WriteLine($"Removed last block!"); } }); // TODO manage failed message coming back... break; case "addlocal": Console.WriteLine("enter data:"); var dataLocal = Console.ReadLine(); var newTransactionLocal = new Transaction($"node{_localAddress}", "Add", dataLocal); var newBlockLocal = chain.CreateBlock(newTransactionLocal); chain.AddBlock(newBlockLocal); // This would simulate what would happen if this node was truncated? break; case "challenge": manager.ChallengeLatestBlockHashAcrossCluster(chain.GetLatestBlock(), reply => { Console.WriteLine($"node {reply.From} has mismatched latest hash of {reply.Data}"); }); break; case "display": Console.WriteLine(JsonConvert.SerializeObject(chain.GetChain(), Formatting.Indented)); break; case "help": DisplayHelp(); break; case "exit": server.ShutdownAsync().Wait(); manager.CloseAllConnections(); Environment.Exit(0); break; } } }