Add sources
This commit is contained in:
210
test/compute_hash.cpp
Normal file
210
test/compute_hash.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
#include "Blockchain.h"
|
||||
|
||||
#include "Hash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef HashSha256 HASH_HEADER;
|
||||
typedef HashMd5 HASH_DATA;
|
||||
|
||||
typedef Block<1024, HASH_HEADER, HASH_DATA> BLOCK;
|
||||
typedef Blockchain<BLOCK> BLOCKCHAIN;
|
||||
|
||||
const unsigned int DIFFICULTY = 2;
|
||||
|
||||
static inline uint32_t getCurrentTimestamp()
|
||||
{
|
||||
time_t unix_timestamp = time(nullptr);
|
||||
|
||||
if (-1 == unix_timestamp)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
uint32_t timestamp = unix_timestamp & 0xFFFFFFFF; // should be ok for now
|
||||
|
||||
return(timestamp);
|
||||
}
|
||||
|
||||
struct MiningBlockHeader
|
||||
{
|
||||
uint32_t version;
|
||||
uint32_t timestamp;
|
||||
HASH_HEADER previousHash;
|
||||
HASH_DATA dataHash;
|
||||
uint32_t nonce;
|
||||
|
||||
MiningBlockHeader(const BLOCK::HASH & previousBlockHash, byte * data, unsigned int size)
|
||||
{
|
||||
version = 1;
|
||||
timestamp = getCurrentTimestamp();
|
||||
previousHash = previousBlockHash;
|
||||
if (data != nullptr)
|
||||
{
|
||||
dataHash.initFromData(data, size);
|
||||
}
|
||||
nonce = 0;
|
||||
}
|
||||
};
|
||||
|
||||
static void print_hash(unsigned char * data, unsigned int size)
|
||||
{
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
printf("%02x", (unsigned)(*(data+i)));
|
||||
}
|
||||
}
|
||||
|
||||
static bool print_block_info(const BLOCK & block)
|
||||
{
|
||||
BLOCK::HASH H;
|
||||
bool success = block.computeHash(H);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
printf("Block ");
|
||||
print_hash((unsigned char*)&H, BLOCK::HASH::SIZE);
|
||||
printf(" : \n");
|
||||
|
||||
printf("\t Version : %d\n", block.getHeader().getVersion());
|
||||
printf("\t Timestamp : %d\n", block.getHeader().getTimestamp());
|
||||
|
||||
printf("\t Previous Block : ");
|
||||
print_hash((unsigned char*)&block.getHeader().getPreviousHash(), HASH_HEADER::SIZE);
|
||||
printf(" \n");
|
||||
|
||||
printf("\t Data Hash : ");
|
||||
print_hash((unsigned char*)&block.getHeader().getDataHash(), HASH_DATA::SIZE);
|
||||
printf(" \n");
|
||||
|
||||
printf("\t Nonce : %d\n", block.getHeader().getNonce());
|
||||
|
||||
printf("\n");
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
static inline bool isHashValidForBlockchain(BLOCKCHAIN & blockchain, const BLOCK::HASH & H)
|
||||
{
|
||||
for (int i = 0; i < blockchain.getCurrentDifficulty(); ++i)
|
||||
{
|
||||
if (H[i] != 0)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
static bool ComputeNonce(BLOCKCHAIN & blockchain, MiningBlockHeader & parameters)
|
||||
{
|
||||
BLOCK::HASH H;
|
||||
H.initFromData((byte*)¶meters, sizeof(parameters));
|
||||
|
||||
while (!isHashValidForBlockchain(blockchain, H))
|
||||
{
|
||||
++parameters.nonce;
|
||||
if (!H.initFromData((byte*)¶meters, sizeof(parameters)))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool CreateGenesisBlock(BLOCKCHAIN & blockchain, byte * data, unsigned int size)
|
||||
{
|
||||
BLOCK::HASH empty_hash;
|
||||
MiningBlockHeader parameters(empty_hash, data, size);
|
||||
ComputeNonce(blockchain, parameters);
|
||||
|
||||
BLOCK block;
|
||||
if (!blockchain.CreateGenesisBlock(parameters.version, parameters.timestamp, parameters.nonce, data, size, block))
|
||||
{
|
||||
printf("Block creation failed !\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
BLOCK::HASH H;
|
||||
bool success = block.computeHash(H);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
print_block_info(block);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool CreateEmptyGenesisBlock(BLOCKCHAIN & blockchain)
|
||||
{
|
||||
byte no_data [BLOCK::SIZE];
|
||||
memset(no_data, 0, BLOCK::SIZE);
|
||||
|
||||
return(CreateGenesisBlock(blockchain, no_data, BLOCK::SIZE));
|
||||
}
|
||||
|
||||
bool AddDataToBlockChain(BLOCKCHAIN & blockchain, const BLOCK::HASH & previousBlockHash, byte * data, unsigned int size)
|
||||
{
|
||||
MiningBlockHeader parameters(previousBlockHash, data, size);
|
||||
ComputeNonce(blockchain, parameters);
|
||||
|
||||
BLOCK block;
|
||||
if (!blockchain.CreateBlock(parameters.version, parameters.timestamp, parameters.previousHash, parameters.nonce, data, size, block))
|
||||
{
|
||||
printf("Block creation failed !\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
BLOCK::HASH H;
|
||||
bool success = block.computeHash(H);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
print_block_info(block);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
BLOCKCHAIN blockchain(DIFFICULTY);
|
||||
|
||||
//
|
||||
// Create Genesis Block
|
||||
if (!CreateEmptyGenesisBlock(blockchain))
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
BLOCK::HASH H;
|
||||
|
||||
const BLOCK & genesis = blockchain.getGenesisBlock();
|
||||
genesis.computeHash(H);
|
||||
|
||||
//
|
||||
// Create some Block
|
||||
byte random_data [BLOCK::SIZE];
|
||||
memset(random_data, 0, BLOCK::SIZE);
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
AddDataToBlockChain(blockchain, H, random_data, BLOCK::SIZE);
|
||||
|
||||
const BLOCK & current = blockchain.getCurrentBlock();
|
||||
current.computeHash(H);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
Reference in New Issue
Block a user