利用比特币源码打造山寨币教程

日期: 2019-04-21 11:22:33 人气: - 评论: 0

000.jpg


一、选源码

很多山寨币都是开源的,可到github查看。

自Bitcoin之后,好多制作山寨币的源码都是源自Bitcoin。我clone的https://github.com/bitcoin作为模板来DIY属于自己的山寨币。

二、选版本

经过几年,后期版本较之前改动比较多,我尝试过 Bitcoin v0.10、v0.12、v0.16,对LinuxC++开发不熟悉的新手 建议前面两个版本比最新v0.16更容易一些。


三、选操作系统,首选Linux,Windows交叉编译环境更麻烦,比如编译依赖库boost openssl这些都比较耗时

Linux  Ubuntu我用得更顺手,CentOS开始也尝试了一下,后来还是在Ubuntu上感觉环境更容易,我还是用以前常用的LTS ubuntu14.04。

四、装依赖包:

1、编译环境依赖:

sudo apt-get update  更新一下源,发现后面安装太慢,可以系统设置中切换国内的源。

sudo apt-get install git  make  gcc g++   

sudo apt-get install  build-essential libtool autotools-dev autoconf pkg-config libssl-dev

(我已经装过了)

2、源码项目依赖:

libssl       SSL 支持;libboost   C++ Boost库;miniupnpc   通讯穿防火墙支持;libdb4.8    Berkeley DB  钱包会用到;

qt   钱包GUI界面用QT开发的;protobuf    RPC通讯消息支持;libqrencode  二维码支持,比如点请求付款会用到。

sudo add-apt-repository ppa:bitcoin/bitcoin

sudo apt-get update

sudo apt-get install libdb4.8-dev libdb4.8++-dev libminiupnpc-dev libboost-dev  libboost-all-dev   

sudo apt-get install libqt4-dev libprotobuf-dev protobuf-compiler libqrencode-dev

五、编译源码

1、获取源码git clone 或下载 tar压缩包

我受不了Git clone 的下载速度,直接网页下载压缩包,然后tar -xzvf +包路径 来解压


选择0.10版本下载

git clone -b v0.10.5 https://github.com/bitcoin/bitcoin.git

git clone 太慢

2、编译源码

cd bitoin 解压后目录 执行:

./autogen.sh

./configure  #它会检查依赖 如果依赖少的apt-get install

make


./autogen.sh


libdb4.8没装上

遇到libdb4.8  没装上 可以 ./configure –with-incompatible-bdb

conffig 

make

六、运行程序

在刚才bitcion源码目录执行 

src/qt/bitcoin-qt打开钱包GUI界面(初次运行会提示目录设置

src/bitcoind 运行coin的无界面后台进程,然后另开一个Bash,cd 到同一目录,执行 src/bitcoin-cli getmininginfo等客户端命令,命令可到钱包界面查看


钱包GUI界面


以上,写得很详细,对Linux不太熟同学也更容易看懂,截图是我改bitcoin为自己山寨币tinycoin后的截图,注意对应。

编译环境搭好了,下一步就可以开始动手制作山寨币了,开始体验我们DIY山寨币的乐趣吧。



一、工欲善其事,必先利其器

        修改源码用文本编辑器也能完成,不过选择一个顺手的开发工具能提高你的工作效率,Java系的朋友可能倾向Eclipse、IDEA之类,BitCion的项目是Linnuxc++,且钱包界面是QT所建,曾经玩过QTCreater,机器上有现成的,就用QTCreater来年读源码,后来……emm感觉还不错,全局查找、定义实现切换、查看所有引用等功能 可以提高啃源码的效率。


都知道c++的程序入口是int main(……)

那么就从Main开始下手:

使用快捷键 Ctrl+Shift+F 打开全局搜索功能:

Ctrl+Shift+F



源码中main()函数入口

二、项目大致组成

从上面的Main函数搜索,大致也能看到有哪几个主要功能部分

bitcoind ---->看到xxxd基本都是后台守护进程

bitcoin-cli ---->Client 客户端(无界面)

bitcoin-tx  ----> TranceAction 交易

bitcoin-qt ----> QT开发的界面钱包

test_bitcoinXXX  ---->测试部分

三、啃源码

顺着Main下去,看个人兴趣咯,慢慢看吧,反正这么多不是1、2天能看得完的

src/init.cpp 里面是程序初始化主要流程,bitcoind 、bitcoin-qt 共用的初始化功能,有注释的step1 、step2 ……

        好了,源码也有大致认识了,下面正式改源码造自己的Token。


      我们要把BitCoin改成自己的Token,最少要修改Src/chainparams.cpp,这里面主要是para参数,改了不与Bitcoin(包括其它山寨币)冲突就行。不过运行出来还看着还是比特币,你需要设计个图标,改个名称,源码对应的名称也要改。

        当然要做一个深度定制个性化的代币,就要花很多功夫了。比如,先想一个Token的中英文名字,我想了2个:

tinyCoin——TNC——泰立币

testCoin——TYC——体验币。

感觉不太好听,不过自己拿来玩玩而已。在我大蓉城,也曾联想到有一个巴蜀特色的名字PandaCoin——PDC——盼猫币,不过PandaCoin有人用过了。也许你可以取个火锅币,哈哈哈哈哈哈

        不吹水,干正事:

一、改名字、端口等

Linux下使用 grep sed命令很方便

打开 bitcoin v0.10 目录

cd bitcoin

grep -ir 比特币 #看一下有多少个比特币待替换 

sed -i 's/比特币/体验币/' src/qt/locale/testcoin_zh*.ts  #执行替换

find . -type f -print0 | xargs -0 sed -i 's/bitcoin/testcoin/g'

find . -type f -print0 | xargs -0 sed -i 's/Bitcoin/Testcoin/g'

find . -type f -print0 | xargs -0 sed -i 's/BitCoin/TestCoin/g'

find . -type f -print0 | xargs -0 sed -i 's/BITCOIN/TESTCOIN/g'

find . -type f -print0 | xargs -0 sed -i 's/BTC/TNC/g'

find . -type f -print0 | xargs -0 sed -i 's/btc/TNC/g'

find . -type f -print0 | xargs -0 sed -i 's/Btc/TNC/g'

find . -exec rename 's/bitcoin/testcoin/' {} ";"

find . -exec rename 's/btc/TNC/' {} ";"

sed -i 's/bitcon/testcoin/' src/qt/locale/testcoin_da.ts

sed -i 's/Bitconi/Testcoin/' src/qt/locale/testcoin_et.ts

find . -type f -print0 | xargs -0 sed -i '/opyright/ s/Testcoin/Bitcoin/' {} ";"

sed -i 's/testcoin/bitcoin/g' doc/release-notes/*

sed -i 's/Testcoin/Bitcoin/g' doc/release-notes/*

find . -type f -print0 | xargs -0 sed -i 's/8332/12345/' {} ";" #替换P2P的连结端口

find . -type f -print0 | xargs -0 sed -i 's/8333/54321/' {} ";"

二、替换你的图片、图标

src/qt下面 你看着办

三、编译源码

编译过的直接make,没有的先./autogen.sh ./configure  


接下来就跃跃欲试,执行src/bitcoind 或src/qt/bitcoin-qt 打开看看效果……

燃鹅,以为胜利就在眼前,你会发现你会讶异

你是我最压抑最深处的秘密……

接近换来期望 期望带来失望的恶性循环

这就是好奇心,连问三个为什么,即使不睡觉也想把它搞明白,洗洗睡吧,其实,后面还有一波参数

那就是传说中的创世块与POW,就快要揭开区块链技术的神秘面纱了。


现在离程序运行起来,就差创世块的参数设置了

一、删除或注释点bitcoin的链中区块校验Hash,增加一条 ( 0, uint256("0x1")) //这个0x1后面创世块Hash算出来时再改过来 ,mapCheckpoints、mapCheckpointsTestnet、mapCheckpointsRegtest 同样处理。

二、修改参数 CMainParams、CTestNetParams、CRegTestParams

先准备几个Hash

openssl ecparam -genkey -name secp256k1 -out alertkey.pem

openssl ec -in alertkey.pem -text > alertkey.hex

openssl ecparam -genkey -name secp256k1 -out testnetalert.pem

openssl ec -in testnetalert.pem -text > testnetalert.hex

openssl ecparam -genkey -name secp256k1 -out genesiscoinbase.pem

openssl ec -in testnetalert.pem -text > genesiscoinbase.hex


1、cat alertkey.hex   -->vAlertPubKey = ParseHex(“…”);

然后读出Hash,填到vAlertPubKey,testnetalert同理

2、4字节的消息ID,每个字节填你喜欢的Ascii码对应的16进制数:


3、        const char* pszTimestamp = "The Times 24/Feb/2018 The rebirth starts"; 当前日期 消息文本按你喜欢改,不过不要太长,毕竟消息传输太大不好,多大不宜我没有测过

4、cat genesiscoinbase.hex  -->txNew.vout[0].scriptPubKey = CScript() << ParseHex("...") << OP_CHECKSIG;

5、 genesis.nTime    = 当前Unix时间戳;

6、设置工作量证明POW的 难度,没明白就不动它,具体意义看pow.cpp,看懂了再去调整

genesis.nBits    = 0x1d00ffff;//这是8个0的难度,CPU大概平均10分钟找出Hash解的参谋

7、 genesis.nNonce  = 0;//我们常听说挖矿浪费那么多算力电力就去找一个随机数,没错,传说中的随机数就是它

实事上求解满足以上难度Hash时, “随机数”我们是依次递增,当然你也可以用Radom函数去生产随机数来碰撞也没问题,不过敲代码用For或While 然后Nonce++更快捷。

8、删除Bitcoin的创世块Hash值,在如下位置:

        hashGenesisBlock = genesis.GetHash();

        assert(hashGenesisBlock == uint256("0x1"));//

        assert(genesis.hashMerkleRoot == uint256("0x1"));

9、设置种子服务器域名或IP,如果你在公网有7*24小时的机器,那就可以用上,没有就暂时先Clear掉,后面运行Client时用Addnode命名去连结节点

vFixedSeeds.clear();

vSeeds.clear();


三、添加代码来生成创世块Hash,在刚才改过Hash的位置,加入如下代码:


        hashGenesisBlock = uint256("0x01");

        if (true && genesis.GetHash() != hashGenesisBlock)

                {

                    printf("bnProofOfWorkLimit:  %u \n", bnProofOfWorkLimit);

                    printf("CMainParams recalculating params for mainnet.\n");

                    printf("old mainnet genesis nonce:  %u \n", genesis.nNonce);

                    printf("old mainnet genesis hash:  %s\n", hashGenesisBlock.ToString().c_str());

                    // deliberately empty for loop finds nonce value.

                    for(genesis.nNonce == 0; genesis.GetHash() > bnProofOfWorkLimit; genesis.nNonce++){ }

                    printf("new mainnet genesis merkle root: %s\n", genesis.hashMerkleRoot.ToString().c_str());

                     printf("new mainnet genesis nonce:  %u \n", genesis.nNonce);

                    printf("new mainnet genesis hash: %s\n", genesis.GetHash().ToString().c_str());

                }

        当“随机数改变到”块Hash值满足难度要求时,循环退出就出打印出来我们的需要的参数了。

四、make 后执行 src/qt/bitcoin-qt 或src/bitcoind 运行程序,等待Hash结果,8个0估计会有10分钟左右,看运气吧。

genesis.nNonce =算出来时的nNonce;

 assert(hashGenesisBlock == uint256("0x填刚算出来的Hash"));//

 assert(genesis.hashMerkleRoot == uint256("0x填刚算出来的Hash"));

        if (false && genesis.GetHash() != hashGenesisBlock) //留下这段代码,或许你还会回来再重算创世块。

别忘了 最开始第一步 mapCheckpoints 那里(0,XX)  也要填上,0就是创世发块Index。

五、再Make 再src/qt/bitcoin-qt 或src/bitcoind 运行程序,就可以开始心情享受你的虚拟币了


        至此,好奇心得到了满足,想深入区块的实现细节,也不难了。emm~玩玩还是将就,然后你想发布到公网然后筹点资金做做ICO?