Programar una cadena de bloques sencilla en C# no es excesivamente complicado si tienes una comprensión básica de programación orientada a objetos y los conceptos fundamentales detrás de las blockchains. El proceso implica crear una estructura de datos para los bloques, implementar un sistema de hashing, y encadenar los bloques juntos para formar una blockchain. Aquí te explico los principales pasos:
1. Definir la Estructura del Bloque
Cada bloque de la cadena debe contener:
- Un índice o identificador único.
- Una marca de tiempo.
- Datos transaccionales o información que quieras almacenar.
- El hash del bloque anterior para mantener la integridad de la cadena.
- Un hash propio, que se calcula en base a los datos del bloque.
public class Block{public int Index { get; set; }public DateTime Timestamp { get; set; }public string Data { get; set; }public string PreviousHash { get; set; }public string Hash { get; set; }public Block(int index, DateTime timestamp, string data, string previousHash){Index = index;Timestamp = timestamp;Data = data;PreviousHash = previousHash;Hash = CalculateHash();}public string CalculateHash(){using (SHA256 sha256 = SHA256.Create()){var inputString = $"{Index}-{Timestamp}-{Data}-{PreviousHash}";var inputBytes = Encoding.UTF8.GetBytes(inputString);var hashBytes = sha256.ComputeHash(inputBytes);return Convert.ToBase64String(hashBytes);}}}
En este código, el método CalculateHash
genera un hash en base a los datos del bloque. Usamos SHA-256, un algoritmo de hashing muy común en blockchain.
2. Crear la Cadena de Bloques (Blockchain)
Una vez que tienes los bloques definidos, debes construir la cadena que enlaza estos bloques.
El código que se muestra debajo va dentro de la clase pública Block
public class Blockchain
{ public List<Block> Chain { get; set; }
public Blockchain() {
Chain = new List<Block>();
Chain.Add(CreateGenesisBlock());
}
public Block CreateGenesisBlock() {
return new Block(0, DateTime.Now, "Genesis Block", "0");
}
public Block GetLatestBlock() {
return Chain[Chain.Count - 1];
}
public void AddBlock(Block newBlock) {
newBlock.PreviousHash = GetLatestBlock().Hash;
newBlock.Hash = newBlock.CalculateHash();
Chain.Add(newBlock);
}
public bool IsChainValid() {
for (int i = 1; i < Chain.Count; i++)
{
Block currentBlock = Chain[i];
Block previousBlock = Chain[i - 1];
if (currentBlock.Hash != currentBlock.CalculateHash())
{ return false; // El bloque ha sido alterado
}
if (currentBlock.PreviousHash != previousBlock.Hash)
{ return false; // La cadena no es consistente
}
}
return true;
}
}
Aquí, la clase Blockchain contiene una lista de bloques, comenzando con un bloque génesis. El método AddBlock
agrega nuevos bloques a la cadena, y IsChainValid
verifica si la cadena es válida comprobando los hashes de cada bloque.
3. Prueba del Blockchain
Finalmente, puedes probar la blockchain agregando algunos bloques y verificando su integridad:
static void Main(string[] args)
{ Blockchain myBlockchain = new Blockchain();
Console.WriteLine("Añadiendo Bloques...");
myBlockchain.AddBlock(new Block(1, DateTime.Now, "Transaccion 1 bloque 2", myBlockchain.GetLatestBlock().Hash));
myBlockchain.AddBlock(new Block(2, DateTime.Now, "Transaccion 2 bloque 3", myBlockchain.GetLatestBlock().Hash));
myBlockchain.AddBlock(new Block(3, DateTime.Now, "Transaccion 3 bloque 4", myBlockchain.GetLatestBlock().Hash));
Console.WriteLine($"¿La cadena es válida?: {myBlockchain.IsChainValid()}");
foreach (var block in myBlockchain.Chain)
{
Console.WriteLine($"Bloque {block.Index} [Hash: {block.Hash}, PrevHash: {block.PreviousHash}, Data: {block.Data}]");
}
// Guardar blockchain en disco
BlockchainSerializer.SaveBlockchainToFile(myBlockchain, "blockchain.json");
// Modificar los datos del segundo bloque
Console.WriteLine("\nModificando los datos del segundo bloque...");
myBlockchain.Chain[1].Data = "Datos alterados"; // Alteramos los datos
// Verificar si la cadena es válida después de modificar los datos
Console.WriteLine($"¿La cadena es válida después de la modificación?: {myBlockchain.IsChainValid()}");
// Imprimir la cadena de bloques nuevamente
foreach (var block in myBlockchain.Chain)
{
Console.WriteLine($"Bloque {block.Index} [Hash: {block.Hash}, PrevHash: {block.PreviousHash}, Data: {block.Data}]");
}
// Mantener la consola abierta hasta que se presione una tecla
Console.WriteLine("Presiona cualquier tecla para salir...");
Console.ReadKey();
}
Esta implementación es local y sencilla. Para que sea una blockchain real, necesitas implementar un mecanismo de consenso distribuido, donde múltiples nodos verifiquen y acuerden sobre los bloques.
Aquí puedes ver la salida del programa en la consola:

- Como puedes ver después de imprimir el contenido de la cadena orignal se altera el contenido del Data de uno de los bloques y la verificación de la integridad del blockchain falla.
- Aquí puedes ver el contenido de la cadena de bloques original en un archivo serializado con la instrucción BlockchainSerializer.SaveBlockchainToFile(myBlockchain, "blockchain.json");
Crear una cadena de bloques sencilla en C# es factible con un conocimiento básico de programación y criptografía (hashing). La implementación básica puede llevar algunas horas, pero agregar características avanzadas como PoW, PoS o una red distribuida puede aumentar significativamente la complejidad.
Comentarios
Publicar un comentario