11 months ago

1、我们需要指定储存卷宗(文件夹)
2、我们需要指定端口
3、指定别的节点的地址和端口
4、指定创世区块的摘要(每个区块的merkle tree)

存储区块的方式:


指向区块内容的指针:可以理解成图书馆中某一本书存放在书架上的具体位置。

没有注释的地方请看上一篇如何写创世区块的代码

#define TFM_DESC

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/socket.h" //这个是套接字的函数库
#include "arpa/inet.h"//这个是专门面对互联网的套接字函数库
#include "tfm.h"
#include "tomcrypt.h"

char *get_rmd160(char *buffer, int size)
{
   hash_state resource;
   char *digest;

   digest = malloc(20);
   rmd160_init(&resource);
   rmd160_process(&resource, buffer, size);
   rmd160_done(&resource, digest);

   return digest;
}

char *get_sha256(char *buffer, int size)
{
   hash_state resource;
   char *digest;

   digest = malloc(32);
   sha256_init(&resource);
   sha256_process(&resource, buffer, size);
   sha256_done(&resource, digest);

   return digest;
}

static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

// Thanks to Luke Dashjr.

int b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
{
   const uint8_t *bin = data;
   int carry;
   ssize_t i, j, high, zcount = 0;
   size_t size;
   
   while (zcount < binsz && !bin[zcount])
      ++zcount;
   
   size = (binsz - zcount) * 138 / 100 + 1;
   uint8_t buf[size];
   memset(buf, 0, size);
   
   for (i = zcount, high = size - 1; i < binsz; ++i, high = j)
   {
      for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
      {
         carry += 256 * buf[j];
         buf[j] = carry % 58;
         carry /= 58;
      }
   }
   
   for (j = 0; j < size && !buf[j]; ++j);
   
   if (*b58sz <= zcount + size - j)
   {
      *b58sz = zcount + size - j + 1;
      return 0;
   }
   
   if (zcount)
      memset(b58, '1', zcount);
   for (i = zcount; j < size; ++i, ++j)
      b58[i] = b58digits_ordered[buf[j]];
   b58[i] = '\0';
   *b58sz = i + 1;
   
   return 1;
}

int scan(char *source)
{
   int *size;

   size = (int *) source;

   return *size;
}

unsigned char *get_private(unsigned int *length)
{
   prng_state random;
   ecc_key key;
   unsigned char *buffer;

   buffer = malloc(*length = 1000);
   ecc_make_key(&random, find_prng("sprng"), 32, &key);
   ecc_export(buffer, length, PK_PRIVATE, &key);

   return buffer;
}

unsigned char *get_public(unsigned int *length, unsigned char *private)
{
   ecc_key key;
   unsigned char *buffer;

   ecc_import(private, *length, &key);
   buffer = malloc(*length = 1000);
   ecc_export(buffer, length, PK_PUBLIC, &key);

   return buffer;
}

char *read_file(char *path, int *length) {

   FILE *file;
   char *contents;

   file = fopen(path, "r+");
   fseek(file, 0, SEEK_END);
   *length = ftell(file);
   fseek(file, 0, SEEK_SET);

   contents = malloc(*length + 1);
   fread(contents, 1, *length, file);
   fclose(file);

   return contents;
}

//void是返回空值,即没有返回值。否则需返回0或者1表示失败或者成功
void write_file(char *path, char *substance, int length)
{
   FILE *file;

   file = fopen(path, "w");
   fwrite(substance, 1, length, file);
   fclose(file);
}

char *string_create(char *old, int length)
{
   char *new;
   int *_6157;

   new = malloc(length + 4) + 4;
   memcpy(new, old, length);

   _6157 = (int *) (new - 4);
   *_6157 = length;

   return new;
}

char *string_create_improper(char *old)
{
   char *new;
   int *_7193;

   new = malloc(strlen(old) + 4) + 4;
   memcpy(new, old, strlen(old));

   _7193 = (int *) (new - 4);
   *_7193 = strlen(old);

   return new;
}

int string_measure(char *buffer)
{
   int *_4721;

   _4721 = (int *) (buffer - 4);

   return *_4721;
}

uint8_t *create_input(uint32_t index, uint8_t *public, uint8_t *signature, uint8_t *transaction)
{
   uint8_t *result;
   uint32_t a, b, c;

   result = malloc(48 + string_measure(public) + string_measure(signature));

   a = 48 + string_measure(public) + string_measure(signature);
   b = string_measure(public);
   c = string_measure(signature);

   memcpy(result, &a, 4);
   memcpy(result + 4, &index, 4);
   memcpy(result + 8, &b, 4);
   memcpy(result + 12, public, b);
   memcpy(result + 12 + b, &c, 4);
   memcpy(result + 16 + b, signature, c);
   memcpy(result + 16 + b + c, transaction, 32);
   return result;
}

uint8_t *create_output(uint8_t *address, uint64_t amount)
{
   uint8_t *result;
   uint32_t a, b;

   result = malloc(16 + string_measure(address));

   a = 16 + string_measure(address);
   b = string_measure(address);

   memcpy(result, &a, 4);
   memcpy(result + 4, &b, 4);
   memcpy(result + 8, address, b);
   memcpy(result + 8 + b, &amount, 8);

   return result;
}

uint8_t *create_head(uint8_t *current, uint32_t nonce, uint8_t *previous, uint8_t *target, uint32_t time, uint32_t valence)
{
   uint8_t *result;

   result = malloc(108);

   memcpy(result, current, 32);
   memcpy(result + 32, &nonce, 4); 
   memcpy(result + 36, previous, 32);
   memcpy(result + 68, target, 32);
   memcpy(result + 100, &time, 4);
   memcpy(result + 104, &valence, 4);

   return result;
}

//创建一个新的能放limit个区块的容量
char *storage_create(int limit)
{
   char *A;
   int *B;

   A = malloc(40 * limit + 8);
   B = (int *) A;
   *B = 0;
   B = (int *) (A + 4);
   *B = limit;

   return A;
}

//得到容量值
int storage_get_limit(char *storage)
{
   int *B;
   B = (int *) (storage + 4);

   return *B;
}

//得到实际存放的区块数量
int storage_get_attainment(char *storage)
{
   int *B;
   B = (int *) storage;

   return *B;
}

//通过遍历配对的方式找到需要的那个指向区块内容的指针
char *storage_search(char *storage, char *target)
{
   int *A, X;
   char *B, **C, *digest;

   A = (int *) storage;
   X = 0;

   while (X < *A) {

      B = (char *) (storage + 8 + X * 40);//如果X为0则从第一个区块开始与目标区块相比较
      C = (char **) (storage + 8 + X * 40 + 36); //将内存中的指针移动到(指向区块内容的指针)的位置

   digest = B;
   printf("comparing: %02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%c", digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15], digest[16], digest[17], digest[18], digest[19], digest[20], digest[21], digest[22], digest[23], digest[24], digest[25], digest[26], digest[27], digest[28], digest[29], digest[30], digest[31], 10);
   digest = target;
   printf("against: %02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%c", digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15], digest[16], digest[17], digest[18], digest[19], digest[20], digest[21], digest[22], digest[23], digest[24], digest[25], digest[26], digest[27], digest[28], digest[29], digest[30], digest[31], 10);

      if (memcmp(B, target, 32) == 0) { //从指针B的的第一个字节开始与指针target的第一个字节开始比较,直到第32个字节完全相等,那么表示找到我们需要的目标区块了
         printf("found%c", 10);
         return *C;//返回指向目标区块内容的指针
      }

      X++;
   }

   return 0;
}

//在storage中依次增加区块,根据图片来理解
int storage_add(char *storage, char *digest, int length, char *substance)
{
   int *A, *B, *D;
   char *C, **E;

   A = (int *) storage;
   B = (int *) (storage + 4);

   if (*A == *B)//当存放的区块达到最高容量时,则存储失败
      return 0;

   C = (char *) (storage + 8 + *A * 40);//依次存放区块
   D = (int *) (C + 32);//在摘要的后面存放区块的大小
   E = (char **) (C + 32 + 4);//在区块大小的后面存放(指向区块内容的指针)

   memcpy(C, digest, 32);//将摘要放在区块最开始的位置
   *D = length;
   *E = substance;
   *A = *A + 1;//随着区块依次存放,实际存放的数量则会依次加1

   return 1;//返回1表示成功
}

//每一个节点都会维持住一个Table(关系型数据库是以Table的方式来存储数据的),所以我们需要构建一个有IP地址、端口、最新通讯和指望通讯的Table。
char *table_create(int limit)
{
   char *A;
   int *B;

   A = malloc(16 * limit + 8);
   B = (int *) A;
   *B = 0;
   B = (int *) (A + 4);
   *B = limit;

   return A;
}

int table_add(char *table, int address, int port, int recent, int expectation)
{
   int *A, *B, *C, *D, *E, *F;

   A = (int *) table;
   B = (int *) (table + 4);
   C = (int *) (table + 8 + *A * 16);
   D = (int *) (table + 8 + *A * 16 + 4);
   E = (int *) (table + 8 + *A * 16 + 8);
   F = (int *) (table + 8 + *A * 16 + 12);

   *C = address;
   *D = port;
   *E = recent;
   *F = expectation;

   *A = *A + 1;

   return 1;
}

//获得需要的数据
int table_get_row(char *table, int sequence, int *address, int *port)
{
   int *A, *B, *C, *D;

   A = (int *) table;
   B = (int *) (table + 4);

   if (sequence >= *A)
      return 0;

   C = (int *) (table + 8 + 16 * sequence);
   D = (int *) (table + 8 + 16 * sequence + 4);

   *address = *C;
   *port = *D;

   return 1;
}

int table_get_attainment(char *table)
{
   int *B;
   B = (int *) table;

   return *B;
}

int table_get_limit(char *table)
{
   int *B;
   B = (int *) (table + 4);

   return *B;
}

//构建监听者的节点
int get_socket_alt(int address, int port)
{
   int s;
   struct sockaddr_in address;

   address.sin_family = 2;
   address.sin_port = htons(port);
   address.sin_addr.s_addr = address;

   s = socket(2, 1, 0);

   if (s == -1)
      return -1;
      
//这一步出现了问题,老师也不知道原因
   if (connect(s, (struct sockaddr *) &address, sizeof (address)) == -1)
      return -1;

   return s;
}

//构建连接者的节点
int get_socket(int port)
{
   int s;
   struct sockaddr_in address;

   address.sin_family = 2;
   address.sin_port = htons(port);
   address.sin_addr.s_addr = inet_addr("0.0.0.0");

   s = socket(2, 1, 0);

   if (s == -1)
      return -1;

   if (bind(s, (struct sockaddr *) &address, sizeof (address)) == -1)
      return -1;

   if (listen(s, 1024) == -1)
      return -1;

   return s;
}

//这里是主代码
int main(int count, char **arguments)
{
   ltc_mp = tfm_desc;
   register_prng(&sprng_desc);
   register_hash(&sha256_desc);

   int other, self, length, alternate;
   char byte;

   if ((self = get_socket(atoi(arguments[1]))) == -1)
      exit(1);

//这一步是连接上种子服务器,主动的把我的信息告诉种子服务器,但是卡在了connect那一步上面。
   if (count == 4) {

      printf("attempting to contact seed server%c", 10);
      byte = 97;
      alternate = get_socket_alt(inet_addr(arguments[2]), atoi(arguments[3]));
      printf("connection: %d%c", alternate, 10);

      send(alternate, &byte, 1, 0);
   }

   printf("listening has begun%c", 10);

   while (1) {

      if ((other = accept(self, 0, 0)) == -1)
         exit(1);

      printf("a new connection has been made%c", 10);

      int state = 0;//造一个限制状态机,还没有开始传输的状态是0,在传输中的状态是1
      int transfer = 0;

      while (1) {

         length = recv(other, &byte, 1, 0);
   
         if (length == 0 || length == -1)//接收到的长度错误或者没有,连接会断开
            break;
            
         //当接收到的ASCII码为97时,即我们输入a时,监听者会开始接收信息
         if (state == 0 && byte == 97) {
            printf("a ping was received%c", 10);
            state = 1;
            continue;
         }
         
         //将每一个收到的字符累加打印出来
         if (state == 1) {
            transfer++;
            printf("%d bytes received%c", transfer, 10);
            continue;
         }
         
         //当累加到200个字符时,则传输中断
          if (state == 1 && transfer == 200) {
            printf("transfer complete%c", 10);
            exit(1);
         }
      }
   }
}
← nano编辑器常用快捷键 限制状态机 →
 
comments powered by Disqus