Simepl blockchain

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
2.6 kB
2
Indexable
Never
#include <iostream>

#define DATA_MAX_SIZE 800
#define BLOCKS_LEN 1024

using namespace std;

typedef struct block {
    uint16_t hash;
    uint16_t prev_hash;
    uint16_t id;
    uint16_t nonce;
    char data[DATA_MAX_SIZE];
} block;

block blocks[BLOCKS_LEN];
int minedBlockNumber = 0;

bool has_ones(uint16_t hash, int n);

/**
 * Add block to the blockchain
 * @param data
 * @return
 */
bool add_block(const char *data) {

    // check if data is too large
    if (strlen(data) > DATA_MAX_SIZE) {
        return false;
    }

    // assign previous hash
    if (minedBlockNumber == 0) {
        // this is a genesis block
        blocks[0].prev_hash = 0;
    } else {
        blocks[minedBlockNumber].prev_hash = blocks[minedBlockNumber - 1].hash;
    }

    // assign block id
    blocks[minedBlockNumber].id = minedBlockNumber;

    // assign data
    strcpy(blocks[minedBlockNumber].data, data);

    // calculate nonce and hash
    // the condition of the valid block: "hash"'s last digit must be equal to 1
    blocks[minedBlockNumber].nonce = 0;
    do {
        blocks[minedBlockNumber].nonce++;
        blocks[minedBlockNumber].hash = blocks[minedBlockNumber].id + blocks[minedBlockNumber].nonce;
        uint16_t *ptr = &(blocks[minedBlockNumber].hash);
        // add all data to pointer - it is some sort of the pseudo-hash function :D
        for (int i = 0; i < sizeof(data); i++) {
            blocks[minedBlockNumber].hash += *ptr;
            ptr++;
        }
    } while (!has_ones(blocks[minedBlockNumber].hash, 4));
    minedBlockNumber++;
    return true;
}

/**
 * Print block @block_number of the blockchain
 * @param block_number
 */
void print_data(int block_number) {
    printf("Block %d [hash=%d, prev_hash=%d, nonce=%d, data=%s]\n",
           blocks[block_number].id, blocks[block_number].hash, blocks[block_number].prev_hash,
           blocks[block_number].nonce, blocks[block_number].data);
}

/**
 * Check if @hash begins with @n ones
 * @param hash
 * @param n
 * @return
 */
bool has_ones(uint16_t hash, int n) {
    uint16_t hashDigits[100];
    memset(hashDigits, 0, sizeof(hashDigits));
    int count = 0;
    while (hash >= 10) {
        hashDigits[count] = hash % 10;
        hash /= 10;
        count++;
    }
    hashDigits[count] = hash;

    for (int i = 0; i < n; i++) {
        if (hashDigits[count - i] != 1) return false;
    }
    return true;
}

int main() {
    add_block("Hello");
    add_block("How are you");
    add_block("Ok");
    for (int i = 0; i < minedBlockNumber; i++) {
        print_data(i);
    }
    return 0;
}