Когда я проверяю действительность моего блокчейна после майнинга, я получаю неверную цепочку. Я думаю, что это может быть проблема с моими методами майнинга, а не методом verifyChain, но я не уверен.
класс блока
public class Block
{
public string Hash { get; set; }
public string PreviousHash { get; set; }
public List<Transaction> Transactions {get; set;}
private DateTime _timestamp;
private long _nonce;
public Block(DateTime timestamp, List<Transaction> transactions, string previousHash = "")
{
_timestamp = timestamp;
_nonce = 0;
Transactions = transactions;
PreviousHash = previousHash;
Hash = GenerateHash();
}
public void MineBlock(int proofOfWorkDifficulty)
{
string hashValidationTemplate = new String('0', proofOfWorkDifficulty);
while (Hash.Substring(0, proofOfWorkDifficulty) != hashValidationTemplate)
{
_nonce++;
Hash = GenerateHash();
}
Console.WriteLine("Blocked with HASH={0} successfully mined!", Hash);
}
public string GenerateHash()
{
string hashString = PreviousHash + Transactions + _timestamp + _nonce; ;
using (SHA256 sha256Hash = SHA256.Create())
{
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(hashString));
// Convert byte array to a string
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}
}
транзакция класс
public class Transaction
{
public string Sender { get; set; }
public string Receiver { get; set; }
public double Amount { get; set; }
public DateTime Timestamp { get; set; }
public Transaction(string sender, string receiver, double amount)
{
this.Sender = sender;
this.Receiver = receiver;
this.Amount = amount;
this.Timestamp = DateTime.Now;
}
}
блокчейн-класс Редактирование: изменен метод MineBlock () - теперь я получаю больше проходов, но все равно получаю ошибку, где Я не должен быть
public class Blockchain
{
private readonly int _difficulty;
private readonly double _rewardAmount;
public List<Block> Blocks { get; set; }
private List<Transaction> Transactions { get; set; }
public Blockchain(int difficulty, int rewardAmount)
{
_difficulty = difficulty;
_rewardAmount = rewardAmount;
Transactions = new List<Transaction>();
Blocks = new List<Block> { CreateGenesisBlock() };
// SOME KIND OF NODES LIST BELONGS HERE?
//Socket IO? something to emit to other nodes?
}
public Block GetLastBlock()
{
return this.Blocks[this.Blocks.Count - 1];
}
public long GetChainLength()
{
return this.Blocks.Count;
}
public void NewTransaction(Transaction transaction)
{
this.Transactions.Add(transaction);
}
public bool VerifyChain()
{
Block previousBlock = Blocks[0];
for (int i = 1; i < Blocks.Count; i++)
{
Block currentBlock = Blocks[i];
var testHashCurrentBlock = currentBlock.GenerateHash();
var testHashPreviousBlock = previousBlock.GenerateHash();
if (currentBlock.PreviousHash != previousBlock.GenerateHash())
{
return false;
}
previousBlock = currentBlock;
}
return true;
}
public void MineBlock(string minerAddress)
{
Transaction minerRewardTransaction = new Transaction(null, minerAddress, _rewardAmount);
NewTransaction(minerRewardTransaction);
Block block = new Block(DateTime.Now, Transactions);
block.MineBlock(_difficulty);
block.PreviousHash = Blocks.Last().Hash;
VerifyChain();
Blocks.Add(block);
Transactions = new List<Transaction>();
}
public double GetBalance(string address)
{
double balance = 0;
foreach(Block block in Blocks)
{
foreach(Transaction transaction in block.Transactions)
{
if (transaction.Sender == address)
{
balance -= transaction.Amount;
}
if(transaction.Receiver == address)
{
balance += transaction.Amount;
}
}
}
return balance;
}
private Block CreateGenesisBlock()
{
List<Transaction> transactions = new List<Transaction> { new Transaction("", "", 0) };
return new Block(DateTime.Now, transactions, "0");
}
}
program.cs
в этом первом тесте проверки проходов цепи, но после майнинга я получить сбой
static void Main(String []args)
{
const string minerAddress = "miner1";
const string user1Address = "A";
const string user2Address = "B";
Blockchain blockChain = new Blockchain(2, 10);
blockChain.NewTransaction(new Transaction(user1Address, user2Address, 200));
blockChain.NewTransaction(new Transaction(user2Address, user1Address, 10));
Console.WriteLine("Is valid: {0}", blockChain.VerifyChain());
Console.WriteLine();
Console.WriteLine("--------- Start mining ---------");
blockChain.MineBlock(minerAddress);
Console.WriteLine("after MineBlock()");
Console.WriteLine(blockChain.Blocks.ToString());
Console.WriteLine("Is valid: {0}", blockChain.VerifyChain());
Console.WriteLine("BALANCE of the miner: {0}", blockChain.GetBalance(minerAddress));
blockChain.NewTransaction(new Transaction(user1Address, user2Address, 5));
Console.WriteLine("Is valid: {0}", blockChain.VerifyChain());
}