Archive for April, 2018

作者:AngryFox 分类: Uncategorized April 25th, 2018 暂无评论

ubuntu开启 3306
iptables -I INPUT 4 -p tcp -m state –state NEW -m tcp –dport 3306 -j ACCEPT

1. 安装指令
sudo apt install software-properties-common
sudo apt-key adv –recv-keys –keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
sudo add-apt-repository ‘deb [arch=amd64,i386,ppc64el] http://mirrors.tuna.tsinghua.edu.cn/mariadb/repo/10.2/ubuntu xenial main’

sudo apt update
sudo apt install mariadb-server

2. 查看sourcelist.
sudo vi /etc/apt/sources.list

3. 无法连接Mariadb的问题
Ubuntu 彻底删除 MYSQL 然后重装 MYSQL

sudo apt-get install apt-transport-https
删除 mysql

sudo apt-get autoremove –purge mysql-server-5.0
sudo apt-get remove mysql-server
sudo apt-get autoremove mysql-server
sudo apt-get remove mysql-common //这个很重要
上面的其实有一些是多余的。

清理残留数据
dpkg -l |grep ^rc|awk ‘{print $2}’ |sudo xargs dpkg -P

安装 mysql
sudo apt-get install mysql-server
sudo apt-get install mysql-client
sudo apt-get install php5-mysql
// 安装php5-mysql 是将php和mysql连接起来
一旦安装完成,MySQL 服务器应该自动启动。您可以在终端提示符后运行以下命令来检查 MySQL 服务器是否正在运行:
sudo netstat -tap | grep mysql
当您运行该命令时,您可以看到类似下面的行:

tcp 0 0 localhost.localdomain:mysql *:* LISTEN -

如果服务器不能正常运行,您可以通过下列命令启动它:

sudo /etc/init.d/mysql restart

进入mysql

$mysql -uroot -p 管理员密码

配置 MySQL 的管理员密码:
sudo mysqladmin -u root password newpassword

sudo apt-get update
sudo apt-get install mysql-server mysql-client
sudo apt-get -f install
sudo service mysql restart

作者:AngryFox 分类: Uncategorized April 18th, 2018 暂无评论

#centos升级gcc到4.8.1(支持c++11)步骤

##下载gcc最新版

wget http://ftp.gnu.org/gnu/gcc/gcc-4.8.1/gcc-4.8.1.tar.gz
然后解压到文件夹

tar -xvzf gcc-4.8.1.tar.gz
进入解压缩之后的目录

cd gcc-4.8.1
然后执行下面的运行

./contrib/download_prerequisites
再返回上一层,建立build_gcc_4.8.1目录,这个目录和gcc-4.8.1平行

cd ..
mkdir build_gcc_4.8.1
进入刚建立的目录,并执行编译过程

cd build_gcc_4.8.1
../gcc-4.8.1/configure –enable-checking=release –enable-languages=c,c++ –disable-multilib
make -j23
make install
OK,在build_gcc_4.8.1中将gcc已经安装完成

确定新安装的GCC的路径,之前安装时记下最后mv时的路径即可,我是默认安在了/usr/local/bin

ls /usr/local/bin | grep gcc
看图

执行

/usr/sbin/update-alternatives –install /usr/bin/gcc gcc /usr/local/bin/x86_64-unknown-linux-gnu-gcc-4.8.1 40

gcc –version #查看版本

/usr/sbin/update-alternatives –install /usr/bin/g++ g++ /usr/local/bin/g++ 40

g++ –version #查看版本
来源:http://lonelyprogram.blog.51cto.com/6246243/1355261

作者:AngryFox 分类: Uncategorized April 8th, 2018 暂无评论

头文件就是库
使用者最常问的问题就是“我该怎么安装Boost”,这个也是我一开始最关心的问题,Boost这点做的很好,将大部分实现都封装在头文件里,所以对于一些基本的Boost库,其实是不需要安装的,只需要将头文件include到自己的程序里,当然前提是你把Boost的所有用到的头文件都拷贝了一份。
Boost是如何做到这点的?
这是因为Boost的头文件(*.hpp)包含了模板和内联函数,这点随便找一个hpp文件来看你就明白了,所以不需要去静态链接活动态链接二进制lib库了。
不过Boost的某些库还是需要生成二进制的库的,如果你要使用他们,必须编译安装哦,他们是:
Boost.Filesystem
Boost.IOStreams
Boost.ProgramOptions
Boost.Python
Boost.Regex
Boost.Serialization
Boost.Signals
Boost.Thread
Boost.Wave
命名规则
libboost_filesystem-vc80-mt-sgdp-1_42.lib
前缀:统一为lib,但在Windows下只有静态库有lib前缀;
库名称:以”boost一”开头的库名称,在这里是boost_filesystem;
编译器标识:编译该库文件的编译器名称和版本,在这里是-vc80;
多线程标识:支持多线程使用-mt,没有表示不支持多线程;
ABI标识:这个标识比较复杂,标识了Boost库的几个编译链接选项;
s: 静态库标识;
gd:debug版标识;
p: 使用STlport而不是编译器自带STL实现;
版本号:Boost库的版本号,小数点用下画线代替,在这里是1_42;
扩展名:在Windows上是lib,在Linux等类Unix操作系统上是a或者.so。
几个常用宏
#define BOOST_ALL_DYN_LINK
同样,此时boost也会默认帮我们包含对应的lib。如果不想使用boost提供的auto-link机制,或者对它的自动链接不太放心的话(其实大可不必担心),可以预先定义宏:
#define BOOST_ALL_NO_LIB
然后使用以下方法链接:
#pragma comment(lib, “boost_thread-vc100-mt-1_46.lib”)或
#pragma comment(lib, “boost_thread-vc100-mt.lib”)
这两个lib其实是一样的,实在不明白boost编译时为什么每个库都要复制一份,难道是因为后者在升级boost版本后不用改代码?另外还有一个比较有用的宏:
#define BOOST_LIB_DIAGNOSTIC
它可以让VC在编译时的output窗口中输出程序具体链接了哪些boost库以及链接顺序。
加快Boost编译的方法
可以采用预编译头来解决这个问题。

update 三个命令的区别

apt-get update 更新软件源中的所有软件列表。
apt-get upgrade 更新软件。
apt-get dist-upgrade 更新系统版本。如果你对新版本软件的需求不是那么迫切,可以不执行

作者:AngryFox 分类: Uncategorized April 8th, 2018 暂无评论

不小心删除了lib库 终极恢复命令
apt-get坏掉了,dpkg也说错误太多
如果这个也不行 那只能重装了

sudo dpkg -i /var/cache/apt/archives/*.deb
sudo dpkg –configure -a

cenos上安装 apt-get

http://www.rpm-find.net/linux/rpm2html/search.php?query=rpmforge-release

#!/bin/bash
#这个脚本最后都加了-y代表直接输入y的意思,效果相当于一个回车
#安装gnome3、ubuntu-tweak和歌词osdlyrics,添加源并更新
sudo add-apt-repository ppa:tualatrix/ppa -y
sudo add-apt-repository ppa:gnome3-team/gnome3 -y
sudo add-apt-repository ppa:osd-lyrics/ppa
sudo apt-get update
#在终端中打开
sudo apt-get install nautilus-open-terminal -y
#gnome-do
sudo apt-get install gnome-do -y
#必须的第三方软件
sudo apt-get install ubuntu-restricted-extras -y

#编程必须
sudo apt-get install build-essential scons -y
#编程工具codelite和codeblocks
sudo apt-get install codelite -y
sudo apt-get install codeblocks -y

#stardict
sudo apt-get install stardict -y

#浏览器
sudo apt-get install chromium-browser -y
#wireshark
sudo apt-get install wireshark -y
#iptux信使,相当于飞鸽飞秋
sudo apt-get install iptux -y
#显示天气、系统温度和系统负载情况
sudo apt-get install indicator-weather -y
sudo apt-get install indicator-multiload -y
sudo apt-get install psensor -y
#gnome3、tweak和osdlyrics的真正安装部分
sudo apt-get dist-upgrade -y
sudo apt-get install gnome-shell -y
sudo apt-get install ubuntu-tweak -y
#肯定系统需要更新一些软件包
sudo apt-get upgrade -y
#重启
sudo reboot

Ubuntu配置文件系统初始化

1. /etc/timezone 时区
2. /etc/inetd.conf 超级进程

Ubuntu配置文件文件系统

1. /etc/fstab 开机时挂载的文件系统
2. /etc/mtab 当前挂载的文件系统

Ubuntu配置文件用户系统

1. /etc/passwd 用户信息
2. /etc/shadow 用户密码
3. /etc/group 群组信息
4. /etc/gshadow 群组密码
5. /etc/sudoers Sudoer列表(请使用“visudo”命令修改此文件,而不要直接编辑)

Ubuntu配置文件Shell

1. /etc/shell 可用Shell列表
2. /etc/inputrc ReadLine控件设定
3. /etc/profile 用户首选项
4. /etc/bash.bashrc bash配置文件

Ubuntu配置文件系统环境

1. /etc/environment 环境变量
2. /etc/updatedb.conf 文件检索数据库配置信息
3. /etc/issue 发行信息
4. /etc/issue.net
5. /etc/screenrc 屏幕设定

Ubuntu配置文件网络

1. /etc/iftab 网卡MAC地址绑定
2. /etc/hosts 主机列表
3. /etc/hostname 主机名
4. /etc/resolv.conf 域名解析服务器地址
5. /etc/network/interfaces 网卡配置文件

Ubuntu配置文件via 来自Ubuntu部落的教程

用DD命令生成引导文件方法:
dd if=/dev/hdax of=/mnt/fat32/bootsect.lnx bs=512 count=1 并口硬盘
dd if=/dev/sdax of=/mnt/fat32/bootsect.lnx bs=512 count=1 串口硬盘
命令解释:
hdax/sdax上面已经解释过了~~~~生成的引导文件名字就是bootsect.lnx
弄好之后进入Windows把生成的引导文件COPY进C盘,在boot.ini加C:”bootsect.lnx=”Ubuntu”,OK!

//最终解决问题O(∩_∩)O哈哈~
$ sudo apt-get install apt-transport-https
$ sudo apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
$ sudo bash -c “echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list”
$ sudo apt-get update
$ sudo apt-get install lxc-docker

作者:AngryFox 分类: Uncategorized April 4th, 2018 暂无评论

mongodb replSet

一般启动

/opt/mongodb/bin/mongod –dbpath=/data/mongodata/ –fork –logpath=/data/mongodata/logs/mongodb.log
replSet 启动

/opt/mongodb/bin/mongod –dbpath=/data/mongodata/ –fork –logpath=/data/mongodata/logs/mongodb.log –replSet rs0 27017
/opt/mongodb/bin/mongod –dbpath=/data/mongodata/rs1/ –fork –logpath=/data/mongodata/rs1/mongodb.log –replSet rs0 –port 27018

###在安装文件下有README,描述了常用的mongodb相关命令行工具
# more /usr/local/mongodb/README
MongoDB README
Welcome to MongoDB!
COMPONENTS

bin/mongod – The database process.
bin/mongos – Sharding controller.
bin/mongo – The database shell (uses interactive javascript).

UTILITIES

bin/mongodump – MongoDB dump tool – for backups, snapshots, etc..
bin/mongorestore – MongoDB restore a dump
bin/mongoexport – Export a single collection to test (JSON, CSV)
bin/mongoimport – Import from JSON or CSV
bin/mongofiles – Utility for putting and getting files from MongoDB GridFS
bin/mongostat – Show performance statistics

作者:AngryFox 分类: Uncategorized April 4th, 2018 暂无评论

VirtualBox 配置虚拟网卡(桥接),实现主机-虚拟机网络互通

环境:
  在Oracle VM VirtualBox中安装的Ubuntu,具体版本名是:ubuntu-14.10-server-amd64

Step1:
VirtualBox在虚拟机关机状态下 设置桥接

Step 2:
虚拟机开机,输入命令:sudo ifconfig或者sudo ifconfig -a查看当前网卡配置

查看当前ip地址
Step3:

  输入命令:vim /etc/network/interfaces

  打开网卡配置文件,添加eth1,保存修改。修改后的文件内容,如下:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
#本机当前ip地址,通过Step2中ifconfig查询出来的即可
address 192.168.56.11
netmask 255.255.255.0

Step4:
  重启虚拟机(必要时重启主机电脑),命令ifconfig查看当前网卡设置。能看到eth1,并且有值,即可。

Step5:
  1) Windows的cmd中,命令:ipconfig查看当前ip
结果:

至此,虚拟机与主机桥接网卡成功,ip互通,且虚拟机成功通过主机网络访问外网。
四、启动ssh服务

安装ssh-server

sudo apt-get install openssh-server

然后重启虚拟机

确认sshserver是否安装好

ps -e | grep ssh

16224 ? 00:00:00 sshd

如果看到sshd那说明ssh-server已经启动了。

可以使用下述命令查看是否有进程在22端口上监听,即是否已启动:

netstat -nat | grep 22

扩展配置(未尝试)

ssh的配置文件位置:/etc/ssh/sshd_config

设置允许root登录:

注释这一行:PermitRootLogin without-password

在修改完配置之后记得保存并重启SSH 服务:

sudo/etc/init.d/ssh restart 或者 service ssh restart

作者:AngryFox 分类: Uncategorized April 3rd, 2018 暂无评论

可以总结出4个实体:区块、交易、输入、输出。而其中的关系是,一个区块对应多个交易,一个交易对应多个输入和多个输出。除了Coinbase的输入外,一笔输入对应另一笔交易中的输出。于是我们可以得出这样的数据模型:

需要特别说明几点的是:

1.TxId是自增的int,我没有用TxHash做Transaction的PK,那是因为TxHash根本就不唯一啊!有好几个不同区块里面的第一笔交易,也就是Coinbase交易是相同的。这其实应该是异常数据,因为相同的TxHash将导致只能花费一次,所以这个矿工杯具了。

2.对于一笔Coinbase 的Transaction,其输入的PreOutTxId是0000000000000000000000000000000000000000000000000000000000000000,而其PreOutIndex是-1,这是一条不存在的TxOutput,所以我并没有建立TXInput和TxOutput的外键关联。

3.对于Block,PreId就是上一个Block的ID,而创世区块的PreId是0000000000000000000000000000000000000000000000000000000000000000,也是一个不存在的BlockId,所以我没有建立Block的自引用外键。

4.有很多字段其实并不是区块链数据结构中的,这些字段是我添加为了接下来方便分析用的。在导入的时候并没有值,需要经过一定的SQL运算才能得到。比如Trans里面的TotalInAmount,TransFee等。

create table Block (
   Height               int                  not null,
   BlkId                char(64)             not null,
   TxCount              int                  not null,
   Size                 int                  not null,
   PreId                char(64)             not null,
   Timestamp            datetime             not null,
   Nonce                bigint               not null,
   Difficulty           double precision     not null,
   Bits                 char(64)             not null,
   Version              int                  not null,
   TxMerkleRoot         char(64)             not null,
   constraint PK_BLOCK primary key nonclustered (BlkId)
)
go

/*==============================================================*/
/* Index: Block_Height                                          */
/*==============================================================*/
create unique clustered index Block_Height on Block (
Height ASC
)
go

/*==============================================================*/
/* Table: Trans                                                 */
/*==============================================================*/
create table Trans (
   TxId                 int                  not null,
   BlkId                char(64)             not null,
   TxHash               char(64)             not null,
   Version              int                  not null,
   InputCount           int                  not null,
   OutputCount          int                  not null,
   TotalOutAmount       bigint               not null,
   TotalInAmount        bigint               not null,
   TransFee             bigint               not null,
   IsCoinbase           bit                  not null,
   IsHeightLock         bit                  not null,
   IsTimeLock           bit                  not null,
   LockTimeValue        int                  not null,
   Size                 int                  not null,
   TransTime            datetime             not null,
   constraint PK_TRANS primary key (TxId)
)
go

/*==============================================================*/
/* Index: Relationship_1_FK                                     */
/*==============================================================*/
create index Relationship_1_FK on Trans (
BlkId ASC
)
go

/*==============================================================*/
/* Index: Trans_Hash                                            */
/*==============================================================*/
create index Trans_Hash on Trans (
TxHash ASC
)
go

/*==============================================================*/
/* Table: TxInput                                               */
/*==============================================================*/
create table TxInput (
   TxId                 int                  not null,
   Idx                  int                  not null,
   Amount               bigint               not null,
   PrevOutTxId          char(64)             not null,
   PrevOutIndex         int                  not null,
   PaymentScriptLen     int                  not null,
   PaymentScript        varchar(8000)        not null,
   Address              char(58)             null,
   constraint PK_TXINPUT primary key (TxId, Idx)
)
go

/*==============================================================*/
/* Index: Relationship_2_FK                                     */
/*==============================================================*/
create index Relationship_2_FK on TxInput (
TxId ASC
)
go

/*==============================================================*/
/* Table: TxOutput                                              */
/*==============================================================*/
create table TxOutput (
   TxId                 int                  not null,
   Idx                  int                  not null,
   Amount               bigint               not null,
   ScriptPubKeyLen      int                  not null,
   ScriptPubKey         varchar(8000)        not null,
   Address              char(58)             null,
   IsUnspendable        bit                  not null,
   IsPayToScriptHash    bit                  not null,
   IsValid              bit                  not null,
   IsSpent              bit                  not null,
   constraint PK_TXOUTPUT primary key (TxId, Idx)
)
go

/*==============================================================*/
/* Index: Relationship_3_FK                                     */
/*==============================================================*/
create index Relationship_3_FK on TxOutput (
TxId ASC
)
go

alter table Trans
   add constraint FK_TRANS_RELATIONS_BLOCK foreign key (BlkId)
      references Block (BlkId)
go

alter table TxInput
   add constraint FK_TXINPUT_RELATIONS_TRANS foreign key (TxId)
      references Trans (TxId)
go

alter table TxOutput
   add constraint FK_TXOUTPUT_RELATIONS_TRANS foreign key (TxId)
      references Trans (TxId)
go
作者:AngryFox 分类: Uncategorized April 1st, 2018 暂无评论

在以前某个项目上竟然用-w把gcc的警告给关闭了,怪不得编译代码完全没警告,多漂亮的代码!

1、未使用变量、未使用函数返回值,
未使用变量:

warning: unused variable ‘ret’ [-Wunused-variable] int ret;

–>修改:删之。

没有达到函数末尾:

warning: control reaches end of non-void function [-Wreturn-type] int open(const char* file) { if(foo==11) { return ok; } // --> 修改:此处要加上返回值 }

没有返回值:

warning: no return statement in function returning non-void [-Wreturn-type] int Open(char* file){}

–> 修改:加上返回值

2、参数一致性,参数类型检查
空字符串:

warning: zero-length gnu_printf format string [-Wformat-zero-length] sprintf(buffer, "");

类型不对:

warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘char*’ [-Wformat=] warning: format ‘%d’ expects argument of type ‘int*’, but argument 4 has type ‘short int*’ [-Wformat=] --> 修改:按printf格式来修改,unsigned long使用%lu。不要用%d来打印字符串指针。

有符号和无符号:

warning: pointer targets in passing argument 2 of ‘ll_foobar’ differ in signedness [-Wpointer-sign] expected ‘unsigned char *’ but argument is of type ‘char *’

有符号和无符号比较:

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

–> 修改:强制转换类型

参数类型:

warning: passing NULL to non-pointer argument 2 of ‘void* memset(void*, int, size_t)’ [-Wconversion-null] memset(foobar, NULL, sizeof(foobar)); (C++中,NULL是指针,不是数值,而memset要求的是数值0)

–> 修改:用0来代替,或将NULL强转为INT。

比较诡异:

warning: argument to ‘sizeof’ in ‘char* strncpy(char*, const char*, size_t)’ call is the same expression as the destination; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess] strncpy(ptr, buffer, sizeof(ptr));

用意本身是好的,用法却是错的,ptr是指针,sizeof指针只能得到4。
类似的有:

warning: argument to ‘sizeof’ in ‘void* memset(void*, int, size_t)’ call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess] memset(this, 0, sizeof(this));

–> 修改:strncpy、memset第三个参数按实际给数值。

C++类构造函数初始化顺序问题:

warning: CFoobar::m_nInit will be initialized after [-Wreorder] int m_nInit; ^ warning: ‘int CFoobar::m_nTime’ [-Wreorder] int m_nTime’;

–> 修改:按声明的顺序排列。

常量字符串:

warning: deprecated conversion from string constant to ‘CHAR* {aka char*}’ [-Wwrite-strings]

–> 修改:字符串要加const。

3、打印格式化

warning: too few arguments for format warning: too many arguments for format

如本身要打印2个参数,但只有一个%。
myprintf(“hello world %d!\n”, count, getname());
–> 修改:认真检查参数。

4、类型一致性,类型转换

整数溢出:

warning: integer overflow in expression [-Woverflow] #define BIG_SIZE 800*1024*1024*1024

转换转换:

warning: narrowing conversion of ‘height’ from ‘DWORD {aka unsigned int}’ to ‘int’ inside { } is ill-formed in C++11 [-Wnarrowing] my_dst_size foo = {width, height};

my_dst_size类型为int,但width和height为DWORD
–> 修改:强制转换类型,保持一致。

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default] my_pos.pos = {0,0};

my_pos.pos为坐标。
–> 修改:一一赋值。

my_pos.pos.x = 0; my_pos.pos.y = 0;

5、括号、优先级

warning: suggest parentheses around arithmetic in operand of '^' [-Wparentheses] #define HELLO ((((z>>51)^(y<<32))+((y>>23)^(z<<5)))^((sum^y)+(k[p&7^e]^z)))

–> 添加括号

#define HELLO ((((z>>51)^(y<<32))+((y>>23)^(z<<5)))^((sum^y)+(k[(p&7)^e]^z)))

另一个例子:

warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses] return id == foo::Get() || foo::Get() != bar::Get() && bar::Go();

6、switch

warning: enumeration value ‘LL_FOO’ not handled in switch [-Wswitch]

–>枚举类型没有完全使用,如没有default语句。添加之

7、

warning: the address of ‘filename’ will always evaluate as ‘true’ [-Waddress] #define LL_STR(foo) foo ? foo : ""

其它

error: function declaration isn’t a prototype -->函数声明如无参数,要加上void

 

作者:AngryFox 分类: Uncategorized April 1st, 2018 暂无评论

主要修改内容在chainparams.cpp源码文件中。

关于比特币家族的新的币种修改方法主要有以下几点

创世块
创世块时间戳
私钥地址的开头
块分割的魔法四字节
难度、出块时间
币的总量
欲挖币数量
  • 创世块 创世块时间戳 私钥地址的开头 块分割的魔法四字节 难度、出块时间 币的总量 欲挖币数量

算法难度

算法难度是指,在哈希的过程中,哈希后的值匹配的格式命中难度。

例:0 必须匹配 0f 匹配任意字符。

因此,算法难度取决于哈希匹配格式中 0 的数量,0 越多,匹配命中率越低,即算法难度高。

在 Qtum 中使用了两种共识机制的算法,分别是 PoW 工作量证明与 PoS 权益证明

此处将两者的算法难度分离,以更好的让官方 Qtum 实施预挖。

consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.posLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");

创世块

创世块是指整个区块中的第一个块。


// 创建创世块函数原型
// @params: nTime 发起时间 (Unix 时间戳)
// @params: nNonce 创世块的合理随机数 该随机数得到的结果必须符合协议的难度
// @params: nBits
// @params: nVersion 版本号
// @params: genesisReward 创世块奖励
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce,
                uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) {
    // 当时的头条事件
    const char* pszTimestamp = "Sep 02, 2017 Bitcoin breaks $5,000 in latest price frenzy";
    // 公钥的十六进制
    // 拥有创世块真正私钥的人,才是这个链的主人。
    const CScript genesisOutputScript =
                    CScript() << ParseHex("040d61d8653448c98731ee5fffd303c15e71ec"\
                    "2057b77f11ab3601979728cdaff2d68afbba14e4fa0bc44f2072b0b23ef63"\
                    "717f8cdfbe58dcd33f32b6afe98741a") << OP_CHECKSIG;
    return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}

创世块的生成是整个主链的基础,接下来主链的所有块都是创世块的延伸。

genesis = CreateGenesisBlock(1504695029, 8026361, 0x1f00ffff, 1, 50 * COIN);
genesis.GetHash();

魔法四字节

这里的四字节用于比特币网络中二进制数据传输过程中,作为数据分隔作用。

以该四字节作为分隔标准,这里可以修改成任意约定字节内容。

pchMessageStart[0] = 0xfd;
pchMessageStart[1] = 0xdd;
pchMessageStart[2] = 0xc6;
pchMessageStart[3] = 0xe1;

默认同步主机

服务器起来时,程序会向主机拉去其它节点的信息。

由该中心节点,完成 P2P 网络基础传输地址建设。

此处的中心节点,可以向上添加。

// CDNSSeedData @param 1: 列表名称
// CDNSSeedData @param 2: 服务器地址
vSeeds.push_back(CDNSSeedData("qtum3.dynu.net", "qtum3.dynu.net", false)); // Qtum mainnet

确认数

确认数是指该笔交易第一次记录到区块中后,后面的延伸块的长度。

例如当前块高为1000,则创世块的确认数为:1000个。

节点检验

节点检验是指在同步块的过程中,将已发生的块哈希写死在代码中。

在同步过程中检验对应高度的块,若块哈希不同,直接停止块同步。

此处的节点检验,可以向上添加。

checkpointData = (CCheckpointData) {
    boost::assign::map_list_of
    ( 0, uint256S("000075aef83cf2853580f8ae8ce6f8c3096cfa21d98334d6e3f95e5582ed986c"))
    ( 5000, uint256S("00006a5338e5647872bd91de1d291365e941e14dff1939b5f16d1804d1ce61cd")) //last PoW block
};

问题分析

在修改源码参数的过程中,可能会遇到一些问题。

第5000个块过度 PoW 过度 PoS

该问题可以查看源码

StakeQtums(true, pwalletMain);
// 摘自 init.cpp (1740)
// @brief : 矿机的主要操作函数
// @param : 当前钱包
void ThreadStakeMiner(CWallet *pwallet)

PoS的运行前提

  1. 正在同步块的时候,不会执行 PoS 挖矿操作
  2. 当前无其它在线节点时,不会执行PoS挖矿操作
  3. 拥有钱包功能( ENABLE_WALLET 宏被声明)
//don't disable PoS mining for no connections if in regtest mode
if(!regtestMode && !GetBoolArg("-emergencystaking", false)) {
    while (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0 || IsInitialBlockDownload()) {
        nLastCoinStakeSearchInterval = 0;
        fTryToSync = true;
        MilliSleep(1000);
    }
    if (fTryToSync) {
        fTryToSync = false;
        if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) < 3 ||
            pindexBestHeader->GetBlockTime() < GetTime() - 10 * 60) {
            MilliSleep(60000);
            continue;
        }
    }
} // 摘自 miner.cpp - ThreadStakeMiner(1093)

ThreadStakeMiner

函数原型:void ThreadStakeMiner(CWallet *pwallet);

函数功能:该函数负责主要的 PoS 挖矿操作,涉及所有挖矿的任务流操作

由 bitcoind.cpp 的 main 函数发起运行在线程池中

  1. 检查钱包状态是否可用
  2. 检测是否满足 PoS 协议的运行前提
  3. 检验是否存在可兑换币龄

附言

若出现同步到第五千个块后,无法继续同步,在测试情况下,一般是由于在线节点数量不够的原因