2
\$\begingroup\$

I'm creating a new open-source blockchain framework for .NET Core and .NET Standard. But I have some questions about how to make block structure to be customizable and look beautiful.

Let's begin from basic block which I created:

public class Block
{
  //header part
  public string Hash;
  public long Index;
  public long TimeStamp;
  public string PreviousHash;
  //data part
  public string Data;
}

I want the user to be able to store anything in Block, so I've created generic version of Block:

public class Block<TData>
{
  //header part
  public string Hash;
  public long Index;
  public long TimeStamp;
  public string PreviousHash;
  //data part
  public TData Data;
}

It is a good solution, but if I want the user to be able to create any good cryptocurrencies and, which is more necessary, blockchains for business, I need to support some limitations. What about hashing data? Or storing it in some file, not in a memory? Or what if the user wants to modify header parts and/or add more fields? We compute the block hash from this fields and data hash(if data is complex), so I've created interfaces and split them:

public interface IHashable
{
  string Hash { get; set;} 
  byte[] GetDataForHash();
}
public interface IBlock: IHashable
{
  long Index { get; set;} 
  long TimeStamp { get; set;} 
  string PreviousHash { get; set;} 
}
public interface IWithData<TData>
{
  TData Data { get; set;} 
}
public interface IWithStoredData<TData>: IWithData<TData>
{
  string DataHash {get;set;}
  string FileName {get;set;}
}
public interface IFullBlock<TData>: IBlock, IWithData<TData> {}

And there will be generic Block class, which implements IFullBlock and basic interfaces. If the user wants to modify the data type, he can modify the type parameter.

If the user wants to modify header fields, he can create a new ICustomBlock: IBlock, and add more fields, then derive from Block class and implement the new interface:

public class Block<TData>: IFullBlock<TData>
{
  //..implementation
}
// for example
public interface IBitcoinBlock: IBlock
{
   long Nonce {get;set;}
   long Bits {get;set;}
   int Version {get;set;}
}
public class MyBitcoinBlock: Block<List<Transaction>>, IBitcoinBlock
{
   //..implementation
}

And if the user wants to use more fields in hashing the block, he just overrides the GetDataForHash method.

But is this solution good? Can it be simpler? And is there any possibility to make block deconstructable into the header part and data part ( via c# 7 Deconstruct method) ?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.