200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 区块链学习(2) 计算区块的哈希值

区块链学习(2) 计算区块的哈希值

时间:2023-04-19 19:54:31

相关推荐

区块链学习(2) 计算区块的哈希值

本文的目的:根据一个区块的信息算出他的哈希值

区块信息:

/zh/btc/block-height/20000

区块头格式:

共80个字节,上图中都是字符串,需要转换为二进制的区块头格式。

程序思路

1、通过区块链浏览器提供的api,获取一个区块的信息。

这里使用,以btc的创世块为例。

curl -s https://chain./v3/block/0{"data": {"height": 0,"version": 1,"mrkl_root": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b","timestamp": 1231006505,"bits": 486604799,"nonce": 2083236893,"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f","prev_block_hash": "0000000000000000000000000000000000000000000000000000000000000000","next_block_hash": "00000000839a8e6886ab5951d76f411475428afc90947ee31bbf18eb6048","size": 285,"pool_difficulty": 2536,"difficulty": 1,"tx_count": 1,"reward_block": 5000000000,"reward_fees": 0,"created_at": 1488909332,"confirmations": 552468,"is_orphan": false,"curr_max_timestamp": 1231006505,"is_sw_block": false,"stripped_size": 285,"weight": 1140,"extras": {"pool_name": "unknown","pool_link": ""}},"err_no": 0,"err_msg": null}

2、解析出区块的头部信息,生成结果block_header_t,注意各种字节序的转换。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++block:0version:1prev_block_hash:0000000000000000000000000000000000000000000000000000000000000000mrkl_root:3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4atimestamp:1231006505bits:486604799nonce:2083236893hash:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3、系统的字节序为小端,80个字节的区块头部信息如下:

0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c

4、对区块头部进行2次哈希得到最终结果。

sha256-1=af42031e805ff493a07341e2f74ff58149d22ab9ba19f61343e2c86c71c5d66dsha256-2=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

完整的代码

// xmain.c// by maxzero#include "xutils.h"#include "xsha256.h"typedef struct _block_header {uint32_t ver;uint32_t hash_prev[8];uint32_t hash_mkrt[8];uint32_t timex;uint32_t bits ;uint32_t nonce;}block_header_t;static int make_block_header(block_header_t *block_header, int block_num){FILE* f = NULL;int n = 0;int r = 0;char url[1024];char* buf = NULL;int len = 1*1024*1024*sizeof(char);;char temp[128];memset(url, 0x00, sizeof(url));sprintf(url, "curl -s https://chain./v3/block/%d", block_num);f = popen(url, "r");buf = (char*)malloc(len);if (NULL == buf) {xprint_err("malloc() failed. len=%d\n", len);pclose(f);return -1;}memset(buf, 0x00, len);n = fread(buf, 1, len, f);if (n <= 0) {xprint_err("fread() failed. n=%d\n", n);goto xexit;}printf("n=%d l=%d\n", n, len);printf("%s\n\n", buf);memset(temp, 0x00, sizeof(temp));if (-1 == xkey_value_parser(buf, "\"version\":", ",", temp, sizeof(temp))) {r = -1;goto xexit;}else {block_header->ver = atoi(temp);}memset(temp, 0x00, sizeof(temp));if (-1 == xkey_value_parser(buf, "\"mrkl_root\":\"", "\",", temp, sizeof(temp))) {r = -1;goto xexit;}else {hex2bin((uint8_t*)block_header->hash_mkrt, temp, strlen(temp));xreverse_dword((uint32_t*)block_header->hash_mkrt, 8, 1);}memset(temp, 0x00, sizeof(temp));if (-1 == xkey_value_parser(buf, "\"timestamp\":", ",", temp, sizeof(temp))) {r = -1;goto xexit;}else {block_header->timex = atoi(temp);}memset(temp, 0x00, sizeof(temp));if (-1 == xkey_value_parser(buf, "\"bits\":", ",", temp, sizeof(temp))) {r = -1;goto xexit;}else {block_header->bits = atoi(temp);}memset(temp, 0x00, sizeof(temp));if (-1 == xkey_value_parser(buf, "\"nonce\":", ",", temp, sizeof(temp))) {r = -1;goto xexit;}else {block_header->nonce = atoi(temp);}memset(temp, 0x00, sizeof(temp));if (-1 == xkey_value_parser(buf, "\"prev_block_hash\":\"", "\",", temp, sizeof(temp))) {r = -1;goto xexit;}else {hex2bin((uint8_t*)block_header->hash_prev, temp, strlen(temp));xreverse_dword((uint32_t*)block_header->hash_prev, 8, 1);}memset(temp, 0x00, sizeof(temp));if (-1 == xkey_value_parser(buf, "\"hash\":\"", "\",", temp, sizeof(temp))) {r = -1;goto xexit;}printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");printf("block:%u\n", block_num);printf(" version:%u\n", block_header->ver);printf("prev_block_hash:"); xdump_byte((uint8_t*)block_header->hash_prev, 32, 32, 0);printf("mrkl_root:"); xdump_byte((uint8_t*)block_header->hash_mkrt, 32, 32, 0);printf("timestamp:%u\n", block_header->timex);printf(" bits:%u\n", block_header->bits);printf("nonce:%u\n", block_header->nonce);printf(" hash:%s\n", temp);printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");printf("\n");xexit:free(buf);pclose(f);return r;}int hash_block_header(int block_num){block_header_t block_header;uint32_t sha1[8];uint32_t sha2[8];int i = 0;memset(&block_header, 0x00, sizeof(block_header));if (0 != make_block_header(&block_header, block_num)) {return -1;}xdump_byte((uint8_t*)&block_header, 80, 80, 0);xsha256((uint8_t*)&block_header, 80, sha1);printf("sha256-1=");for (i=0; i<8; i++) {printf("%08x", sha1[i]);sha1[i] = htonl(sha1[i]);}printf("\n");xsha256((uint8_t*)sha1, sizeof(sha1), sha2);xreverse_dword(sha2, 8, 1);printf("sha256-2=");for (i=0; i<8; i++) {printf("%08x", sha2[i]);}printf("\n");printf("\n");return 0;}int main(int argc, char* argv[]){int block_num = 0;if (argc != 2) {printf("usage: a.out [block number]\n");printf(" ex: a.out 100\n");return -1;}block_num = atoi(argv[1]);hash_block_header(block_num);return 0;}

// xsha256.h// by maxzero#ifndef _M_XSHA256_H#define _M_XSHA256_H#include "xutils.h"#ifdef __cplusplus extern "C" { #endif int xsha256(const uint8_t *src, uint32_t len, uint32_t *hash);#ifdef __cplusplus }#endif #endif// xsha256.c// by maxzero#include "xsha256.h"#define XSHA_DBG 0#define SHFR(x, n) (((x) >> (n)))#define ROTR(x, n) (((x) >> (n)) | ((x) << ((sizeof(x) << 3) - (n))))#define ROTL(x, n) (((x) << (n)) | ((x) >> ((sizeof(x) << 3) - (n))))#define CHX(x, y, z) (((x) & (y)) ^ (~(x) & (z)))#define MAJ(x, y, z) (((x) & (y)) ^ ( (x) & (z)) ^ ((y) & (z)))#define BSIG0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))#define BSIG1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))#define SSIG0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))#define SSIG1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))#define SHA256_BLOCK_SIZE (512/8)#define SHA256_COVER_SIZE (SHA256_BLOCK_SIZE*2)static uint32_t k[64] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};static int xtransform(const uint8_t *msg, uint32_t *h){uint32_t w[64];uint32_t a0, b1, c2, d3, e4, f5, g6, h7;uint32_t t1, t2;int i = 0;int j = 0;for (i=0; i<16; i++) {w[i] = msg[j]<<24 | msg[j+1]<<16 | msg[j+2]<<8 | msg[j+3];j += 4;}for(i=16; i<64; i++){w[i] = SSIG1(w[i-2])+w[i-7]+SSIG0(w[i-15])+w[i-16];}#if XSHA_DBGxdump_byte((uint8_t*)w, 64*4, 32);#endifa0 = h[0];b1 = h[1];c2 = h[2];d3 = h[3];e4 = h[4];f5 = h[5];g6 = h[6];h7 = h[7];for (i= 0; i<64; i++) {t1 = h7 + BSIG1(e4) + CHX(e4, f5, g6) + k[i] + w[i];t2 = BSIG0(a0) + MAJ(a0, b1, c2);h7 = g6;g6 = f5;f5 = e4;e4 = d3 + t1;d3 = c2;c2 = b1;b1 = a0;a0 = t1 + t2;}h[0] += a0;h[1] += b1;h[2] += c2;h[3] += d3;h[4] += e4;h[5] += f5;h[6] += g6;h[7] += h7;return 0;}int xsha256(const uint8_t *src, uint32_t len, uint32_t *hash){uint8_t *tmp = (uint8_t*)src;uint8_t cover_data[SHA256_COVER_SIZE];uint32_t cover_size = 0;uint32_t i = 0;uint32_t n = 0;uint32_t m = 0;uint32_t h[8];h[0] = 0x6a09e667;h[1] = 0xbb67ae85;h[2] = 0x3c6ef372;h[3] = 0xa54ff53a;h[4] = 0x510e527f;h[5] = 0x9b05688c;h[6] = 0x1f83d9ab;h[7] = 0x5be0cd19;memset(cover_data, 0x00, sizeof(uint8_t)*SHA256_COVER_SIZE);n = len / SHA256_BLOCK_SIZE;m = len % SHA256_BLOCK_SIZE;if (m < 56 ) {cover_size = SHA256_BLOCK_SIZE;}else {cover_size = SHA256_BLOCK_SIZE*2;}if (m !=0) {memcpy(cover_data, tmp + (n * SHA256_BLOCK_SIZE), m);}cover_data[m] = 0x80;cover_data[cover_size-4] = ((len*8)&0xff000000) >> 24;cover_data[cover_size-3] = ((len*8)&0x00ff0000) >> 16;cover_data[cover_size-2] = ((len*8)&0x0000ff00) >> 8;cover_data[cover_size-1] = ((len*8)&0x000000ff);#if XSHA_DBGxdump_hex(tmp, len-m, 32);xdump_hex(cover_data, cover_size, 32);#endiffor (i=0; i<n; i++) {xtransform(tmp, h);tmp += SHA256_BLOCK_SIZE;}tmp = cover_data;n = cover_size / SHA256_BLOCK_SIZE;for (i=0; i<n; i++) {xtransform(tmp, h);tmp += SHA256_BLOCK_SIZE;}if (NULL != hash) {memcpy(hash, h, sizeof(uint32_t)*8);}return 0;}

// xutils.h// by maxzero#ifndef _M_XUTILS_H#define _M_XUTILS_H#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <stdint.h>#include <unistd.h>#include <memory.h>#include <string.h>#include <time.h>#include <arpa/inet.h>#include <stdbool.h>#ifdef __cplusplus extern "C" { #endif #define xdbg 1#if xdbg#define xprint_log(fmt, ...) \printf("[%s:%04d] %s() "fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)#define xprint_err(fmt, ...) \printf("[%s:%04d] %s() err: " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)#else#define xprint_log(fmt, ...)#define xprint_err(fmt, ...)#endif#define XDUMP_LINEN 0x01 #define XDUMP_SPACE 0x02#define XDEMP_DEFAULT (XDUMP_SPACE|XDUMP_LINEN)int xdump_byte(const uint8_t *data, int size, int line, int flag);uint8_t crc5(uint8_t *data, uint8_t size);bool hex2bin(unsigned char *binstr, const char *hexstr, size_t len);void xreverse_byte(unsigned char *s, size_t n);void xreverse_dword(uint32_t *s, size_t n, int f);int xkey_value_parser(char *data, char *key, char *end, char *value, int len);#ifdef __cplusplus }#endif #endif/// xutils.c// by maxzero#include "xutils.h"static const int hex2bin_tbl[256] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,};int xdump_byte(const uint8_t *data, int size, int line, int flag){int i;int l = line;if (size <= 0) { return 0; }for (i=0; i<size; i++) {if (((i%l)==0) && ((flag&XDUMP_LINEN)==XDUMP_LINEN)) {printf( "[%02x] ", i/l );}printf( "%02x", data[i] );if ((flag&XDUMP_SPACE) == XDUMP_SPACE) {printf(" ");}if(((i+1)%l) == 0) {printf( "\n" );}}if (size%line != 0) { printf("\n"); }return 0;}uint8_t crc5(uint8_t *data, uint8_t size){uint8_t i, j, k;uint8_t crc = 0x1f;uint8_t crcin [5] = {1, 1, 1, 1, 1};uint8_t crcout[5] = {1, 1, 1, 1, 1};uint8_t din = 0;j = 0x80;k = 0;for (i=0; i<size; i++) {if (*data & j) {din = 1;} else {din = 0;}crcout[0] = crcin[4] ^ din;crcout[1] = crcin[0];crcout[2] = crcin[1] ^ crcin[4] ^ din;crcout[3] = crcin[2];crcout[4] = crcin[3];j = j >> 1;k++;if (k == 8) {j = 0x80;k = 0;data++;}memcpy(crcin, crcout, 5);}crc = 0;if(crcin[4]) crc |= 0x10;if(crcin[3]) crc |= 0x08;if(crcin[2]) crc |= 0x04;if(crcin[1]) crc |= 0x02;if(crcin[0]) crc |= 0x01;return crc;}bool hex2bin(unsigned char *bin, const char *hexstr, size_t len){int nibble1, nibble2;unsigned char idx;bool ret = false;while (*hexstr && len) {if (!hexstr[1]) {xprint_err("hex string truncated.\n");return ret;}idx = *hexstr++;nibble1 = hex2bin_tbl[idx];idx = *hexstr++;nibble2 = hex2bin_tbl[idx];if ((nibble1<0) || (nibble2<0)) {xprint_err("hex string scan failed.\n");return ret;}*bin++ = (((unsigned char)nibble1)<<4) | ((unsigned char)nibble2);--len;}if (len == 0 && *hexstr == 0) {ret = true;}return ret;}void xreverse_byte(unsigned char *s, size_t n){size_t i = 0;size_t j = 0;for (i=0, j=n-1; i<j; i++, j--) {s[i] = s[i] ^ s[j];s[j] = s[j] ^ s[i];s[i] = s[i] ^ s[j];}return ;}void xreverse_dword(uint32_t *s, size_t n, int f){size_t i = 0;size_t j = 0;for (i=0, j=n-1; i<j; i++, j--) {s[i] = s[i] ^ s[j];s[j] = s[j] ^ s[i];s[i] = s[i] ^ s[j];if (1 == f) {s[i] = htonl(s[i]);s[j] = htonl(s[j]);}}return ;}/*解析规则1、查找关键字 key,key不存在返回失败2、查找结束符 end value取值 key到end之间3、end不存在 尝试空格当结束符 value取值 key到空格之间4、空格不存在 value取值 key到data结束*/int xkey_value_parser(char *data, char *key, char *end, char *value, int len){char *a = NULL;char *b = NULL; int n = 0; int r = 0;a = strstr(data, key);if (NULL != a) {a += strlen(key);b = strstr(a, end);if (NULL != b) {n = b - a;n = (n > len) ? len : n;memcpy(value, a, n);r = b - data;}else {b = strstr(a, " ");if (NULL == b) {b = data + strlen(data);}n = b - a;n = (n > len) ? len : n;memcpy(value, a, n);r = b - data;}}else {r = -1;}if (-1 == r) {xprint_err("%s not find. pls check uri\n %s \n", key, data);}return r;}

编译运行

ubuntu 14.04gcc 5.5.0

[root@ubuntu:src]# gcc xmain.c xsha256.c xutils.c[root@ubuntu:src]# ./a.out 0{"data":{"height":0,"version":1,"mrkl_root":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b","timestamp":1231006505,"bits":486604799,"nonce":2083236893,"hash":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f","prev_block_hash":"0000000000000000000000000000000000000000000000000000000000000000","next_block_hash":"00000000839a8e6886ab5951d76f411475428afc90947ee31bbf18eb6048","size":285,"pool_difficulty":2536,"difficulty":1,"tx_count":1,"reward_block":5000000000,"reward_fees":0,"created_at":1488909332,"confirmations":553612,"is_orphan":false,"curr_max_timestamp":1231006505,"is_sw_block":false,"stripped_size":285,"weight":1140,"extras":{"pool_name":"unknown","pool_link":""}},"err_no":0,"err_msg":null}++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++block:0version:1prev_block_hash:0000000000000000000000000000000000000000000000000000000000000000mrkl_root:3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4atimestamp:1231006505bits:486604799nonce:2083236893hash:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7csha256-1=af42031e805ff493a07341e2f74ff58149d22ab9ba19f61343e2c86c71c5d66dsha256-2=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。