PPC CLONE GUIDE by YarkoL v.0.1 Extremely quick n dirty. But should work :) Prerequisites – some programming knowledge and some skill with ubuntu linux. Disclaimer Disclaimer this is !or learning purposes only " so i! # hear that you ha$e been using my guide !or some !unny business business # swear #%ll come and slap your sorry little ears &til you cry !or mummy. mummy. #n case you%re lost check out my blog where # intend to go through all this 'a(( step by step holding hands and spoon !eeding whene$er # ha$e the time. https:yarkol.github.io *r ask me on the practicecoin !orum. #%m $ery economical with words here these are 'ust the rough notes and you need to search !or rele$ant parts in the code. #%m not intentionally trying to mysti!y you but this is complex stu!! and you need to do your homework. Dedicated to +innamon carter , -hake(ula Bitrick +ryddit ite/0 the spirit li$es on. *1 let%s roll.
Build dependencies let%s install sudo apt-get install git nano build-essential build-essential autoconf libssl-dev libboost-all-dev libboost-all-dev libdb++-dev libdb-dev --yes
Get the source files and test your build system go to your home dir or whene$er you want the coin source to be and $ git clone https://github.com/peercoin/peer https://github.com/peercoin/peercoin coin ewer coins use autotools introduced in Bitcoin 2.0. 3owe$er Peercoin is based on older builds and they still ha$e make!iles. read build instructions in docbuild"unix.txt ow you can check that you can build the headless client cd stanislawsrc then
$ make -f makefile.unix USE_UPNP4ot the ppcoind client5 6hen $ ./ppcoin! -printtoconsole -!ebug "printtoconsole will print out what the node is doing and "debug will show some special messages that can be use!ul 7!ter getting up and opening databases it will exit with this message about missing con! !ile *pen nano or some other text editor $ nano /home/"arkko/.ppcoin/ppcoin.conf and think o! a password -ince we are testing we can do with rpcuser=rpc rpcpassword=pwd testnet=1
8ust remember to replace the password with something reasonable 9like a random string ) when you run a node out there in the wild 7gain run the node ow it ought to be running nicely
Install Q Creator e need ;t +reator !or the graphical wallet. 4et installer here http:download.qt.ioo!!icial
!or the build then pro'ects ? build steps and add @A-E
!ac" the coin Cet=s start modi!ying the source.
#our Ne$ Identity Ase !ind,replace and search Peercoin Cea$e Peercoin De$elopers as they are but change others to your coin=s name +hange the currency units srcqtbitcoinunits ;-tring BitcoinAnits::name9int unit) { switch(unit) { case BTC return !"tring(#$$C#)% case &BTC return !"tring(#&$$C#)% case uBTC return !"tringfro&'tf(#$$C#)% default return !"tring(#***#)% !"tring Bitcoin'nitsdescription(int unit) { switch(unit) { case BTC return !"tring(#$$Coins#)% case &BTC return !"tring(#,illi-$$Coins (1 1.///)#)% case uBTC return !"tring(#,icro-$$Coins (1 1.///.///)#)% default return !"tring(#***#)%
ow the coin pre!ix -ee list o! pre!ixes and this will make sense https:en.bitcoin.itwikiCistF.h is not showing up in the !ile window o! qt creator -earch !or +Base>FData and it should open that class CBitcoin0ddress public CBase2ata { public enu& { $'B345602274"" = . ppcoin addresses begin with 8$8 "C79$T602274"" = 11:. ppcoin addresses begin with 8p8 $'B345602274""6T4"T = 111. "C79$T602274""6T4"T = 1;<. %
hen let%s loo" at some net$or" stuff 2" seeds 4ach pair gives a source na&e and a seed na&e> The first na&e is used as infor&ation source for addr&an> The second na&e should resolve to a list of seed addresses> testnet dns seed begins with 8t8. all else are ppcoin dns seeds> static const char ?str2""eed@A@A = { {#seed#. #seed>fencoin>net#. %
srcnet.cpp 9#! you want to con!igure a dns seed you add a D- Gecord on your hosts settings – !or example seed.Hyourcoinname?.net 7 Gecord IJJ22 H#P o! your node? ) +hange pKp and Gpc ports in protocol.h define define define define
$$CD96$D7T ;;/1 7$C6$D7T ;;/ T4"T4T6$D7T ;;/E T4"T4T67$C6$D7T ;;/F
ow search !or these in protocol.cpp $ublic testnet &essage start unsigned char pch,essage"tartTestBitcoin@FA = { /Gfa. /Gbf. /Gb. /Gda % static unsigned char pch,essage"tartTestDld@FA = { /Gdb. /Ge1. /Gf. /Gf< % static unsigned char pch,essage"tartTestew@FA = { /Gcb. /Gf. /Gc/. /Gef % static unsigned int n,essage"tartTest"witchTi&e = 1EF</////% $$Coin &essage start (switch fro& Bitcoin8s in v/>) static unsigned char pch,essage"tartBitcoin@FA = { /Gf;. /Gbe. /GbF. /Gd; %
static unsigned char pch,essage"tart$$Coin@FA = { /Ge<. /Ge. /Ge;. /Ge % static unsigned int n,essage"tart"witchTi&e = 1EF:E/////%
there is a lot o! PeercoinBitcoin history in the source code that is totally super!luous but since we%re only learning stu!! it doesn%t matter. 3owe$er regarding these network identi!iers replace with something like this. 9Don%t use these $alues though they are taken !rom Lencoin a coin that #%m de$eloping now and # don%t want it to collide with your coin out there. 6hink up some hex $alues o! your own *15) static unsigned char pch,essage"tart,ain@FA = { /G;. /G;. /G<. /G1F % static unsigned char pch,essage"tartTest@FA = { /G1F. /G;. /G;. /G< %
6hen replace void Het,essage"tart(unsigned char pch,essage"tart@A. bool f$ersistent) { if (fTestet) &e&cpy(pch,essage"tart. (f$ersistent II Het0dJustedTi&e() K n,essage"tartTest"witchTi&e)* pch,essage"tartTestew pch,essage"tartTestDld. siLeof(pch,essage"tartTestew))% else &e&cpy(pch,essage"tart. (f$ersistent II Het0dJustedTi&e() K n,essage"tart"witchTi&e)* pch,essage"tart$$Coin pch,essage"tartBitcoin. siLeof(pch,essage"tart$$Coin))%
with void Het,essage"tart(unsigned char pch,essage"tart@A. bool f$ersistent) { if (fTestet) &e&cpy(pch,essage"tart. pch,essage"tartTest. siLeof(pch,essage"tartTest))% else &e&cpy(pch,essage"tart. pch,essage"tart,ain. siLeof(pch,essage"tart,ain))%
6hen delete the second argument !Persistent and do so in declaration in the header !ile too -earch !or usage o! 4etMessage-tart and remo$e the boolean where it occurs
Let%s reset the &ersion to somethin' else $ersion cpp include #version>h# a&e of client reported in the 8version8 &essage> 7eport the sa&e na&e
for both bitcoind and bitcoin-Mt. to &aNe it harder for attacNers to target servers or H'9 users specifically> const stdstring CO94T60,4(#"atoshi#)% Client version nu&ber define CO94T6P47"9D6"'QQ9R
#-beta#
a!ter that you switch to header and i! you wish you can edit define define define define
$$CD96P47"9D6,0SD7 $$CD96P47"9D6,9D7 $$CD96P47"9D674P9"9D $$CD96P47"9D6B'9O2
/ / / 1
4o below and comment out only reMuest blocNs fro& nodes outside this range of versions static const int DBO3"6P47"9D6"T07T = E///% static const int DBO3"6P47"9D642 = EF//%
6hose constants are !ound in main.cpp: KF2J comment out 0sN the first connected node for blocN updates static int n0sNedQorBlocNs = /% if (pfro&-KfClient UU (pfro&-KnPersion V DBO3"6P47"9D6"T07T II pfro&-KnPersion K= DBO3"6P47"9D642) UU (n0sNedQorBlocNs V 1 II vodes>siLe() V= 1)) { n0sNedQorBlocNs++% pfro&-K$ushHetBlocNs(pindeGBest. uint<(/))%
Back in $ersion.h do this replace nTi&e field added to C0ddress. starting with this version% if possible. avoid reMuesting addresses nodes older than this static const int C02276T9,46P47"9D = E1F/% static const int C02276T9,46P47"9D = 1%
6hat=s all !or $ersioning
No$ let%s ta"e care of chec"points Cet=s generate a keypair !or our !uture checkpoint ser$er *pen a new terminal tab and make sure you=re in the same directory as ppcoind then $ ./ppcoin! makeke*pair +
,Priatee*, : , *our priate ke* 0,1 ,Publice*, : ,(&!2a3)4!'454%34f36&6'%cf!!&)''(fffae)3f2&6!%(!535b%4&6b5(be!)bba!f%c)44&ee('!66'5f &5)&e32e56b'6()c!%)%2&%6'26aa(c!5b)!%%3%(ae(2&c, 7 -top the node $ ./ppcoin! stop Back to qcreator replace in checkpoints cpp sync-checNpoint &aster Ney const stdstring C"yncChecNpointstr,aster$ub3ey = #/Fc/c:/:cEEfdc;f:;ddEad/dff;adf;1F1cd1Ffb;bc/:c:F E/efeFEfb:a<
static ,apChecNpoints &apChecNpoints = boostassign&ap6list6of ( /. hashHenesisBlocNDfficial ) %
Chan'in' Po(
ow let=s look at some parameters in main.h static const int
static const int "T0346T07H4T6"$0C9H = 1/ ? % 1/-&inute blocN spacing static const int "T0346,960H4 = ? ? F ? E/% &ini&u& age for coin age static const int "T0346,0R60H4 = ? ? F ? ;/% staNe age of full weight
Nou might add here a static const int O0"T6$DW6BODC3 = VblocN nu&berK% " then in main cpp if (9s$roofDfWorN() UU nXeight K O0"T6$DW6BODC3)
return 2o"(1//. error(#0cceptBlocN() reJect proofof-worN at height Yd#. nXeight))% ChecN proof-of-worN or proof-of-staNe if (nBits = HeteGtTarget7eMuired(pindeG$rev. 9s$roofDf"taNe())) return 2o"(1//. error(#0cceptBlocN() incorrect proof-ofworNproof-of-staNe#))%
Ne$ 'enesis bloc" )testnet* #n main.cpp here%s the code 9nit with genesis blocN if (&apBlocN9ndeG>e&pty()) { if (f0llowew) return false% Henesis BlocN CBlocN(hash=//////////1;d<. ver=1. hash$revBlocN=//////////////. hash,erNle7oot=Fae1e. nTi&e=1E1//</. nBits=1d//ffff. nonce=/EE<;E. vtG=1) CTransaction(hash=Fae1e. ver=1. vin>siLe=1. vout>siLe=1. nOocNTi&e=/) CTG9n(CDut$oint(//////. -1). coinbase /Fffff//1d/1/FFF<</F<;////////. script$ub3ey=/GQ12Q1nTi&e = 1EF/E1/% tGew>vin>resiLe(1)% tGew>vout>resiLe(1)% tGew>vin@/A>script"ig = C"cript() VV F<vout@/A>"et4&pty()% CBlocN blocN% blocN>vtG>push6bacN(tGew)% blocN>hash$revBlocN = /% blocN>hash,erNle7oot = blocN>Build,erNleTree()% blocN>nPersion = 1% blocN>nTi&e = 1EF/F:% blocN>nBits = bn$roofDfWorNOi&it>HetCo&pact()% blocN>nonce = 1:;E//;u% if (fTestet) { blocN>nTi&e blocN>nonce debug print
= 1EF/;////% = 1;F;E%
printf(#YsZn#. blocN>HetXash()>To"tring()>c6str())% printf(#YsZn#. hashHenesisBlocN>To"tring()>c6str())% printf(#YsZn#. blocN>hash,erNle7oot>To"tring()>c6str())% assert(blocN>hash,erNle7oot == uint<(#/GEcdffabFd1:aacccprint()% assert(blocN>HetXash() == hashHenesisBlocN)% assert(blocN>ChecNBlocN())%
Cet%s modi!y this. Cet%s make the debug print nicer debug print printf(#,y beautiful blocN hash YsZn#. blocN>HetXash()>To"tring()>c6str())% printf(#hashHenesisBlocN (hardcoded) YsZn#. hashHenesisBlocN>To"tring()>c6str())% printf(#blocN &erNle root YsZn#. blocN>hash,erNle7oot>To"tring()>c6str())%
6hen the magic ingredient the genesis"mining"code paste this abo$e debug print if (true
UU (blocN>HetXash() = hashHenesisBlocN)) { printf(#,ining genesisZn#)% uint< hashTarget = CBigu&()>"etCo&pact(blocN>nBits)>getuint<()% while (blocN>HetXash() K hashTarget) { ++blocN>nonce% if (blocN>nonce == /) { printf(#DC4 W70$$42. incre&enting ti&e#)% ++blocN>nTi&e% if (blocN>nonce Y 1//// == /) { printf(#nonce Y/u hash = Ys Zn#. blocN>nonce. blocN>HetXash()>To"tring()>c6str())%
-ee the de!inition !or block.n6ime 5 4et current timestamp $ !ate #8s 2&53''%255
ow plug that in and reset the nonce if (fTestet)
{ blocN>nTi&e blocN>nonce
= 1F;E<1;;% = /%
7nd let%s redo the human"readable timestamp Henesis blocNN const char? psLTi&esta&p = #Chancellor on brinN of [whatever the daily paper says#%
Build the headless client in the src directory e%re still on testnet as it is speci!ied on the con! !ile 4o to the .ppcoin !older and delete e$erything inside testnet dir
Gun .ppcoind "printtoconsole $$Coin version v/>>Fppc-E-g<<abF-dirty-stanislaw (/1:-/F-< 1FE1F1 +/E//) 2efault data directory ho&eJarNNo>ppcoin ppcoin server starting Ooading addresses>>>
7nd then ,y beautiful blocN hash 1FccppE bool OoadBlocN9ndeG(bool) 0ssertion \blocN>hash,erNle7oot == uint<(#/GEcdffabFd1:aaccc
we need only the merkle root. Put it into the assertion code. assert(blocN>hash,erNle7oot == uint<(#/G1:bffbF<1d:
Cet%s change the Po limit to something easy that we don%t ha$e to wait all day !or it to mine bool OoadBlocN9ndeG(bool f0llowew) { if (fTestet) { hashHenesisBlocN = hashHenesisBlocNTestet% bn$roofDfWorNOi&it = CBigu&(]uint<(/) KK 1<)% n"taNe,in0ge = ? ? F% test net &in age is 1 day nCoinbase,aturity = % bn9nitialXashTarget = CBigu&(]uint<(/) KK /)% n,odifier9nterval = ? /% test net &odifier interval is / &inutes
again build the client and run. ow the mining !or genesis starts. 6his is what # got
9ining genesis nonce (((2((((: hash a65)e')5654)&e5a3b'4'5()%4'a6b!'a)!35b5252c&c'&64&4!e6(!6!bf332( nonce ((('((((: hash a&4b6!b2!'&e(%434e6445e6bfa)'34e(&(ba6%ca4%!2b&4f'2!e)ba36('6a4& nonce (((3((((: hash 3)!(c6%4e('f&%f&6!2%2f)3)&&fe(f5ca''6'!3!eee33)4!%%%(ac&aa!(3c'! nonce (((&((((: hash 3&fea((4633&)&'!%2&a!c(('e%!5ae!&5)%3%6bb(e2)3'(')f%)a66c5434f6' nonce ((()((((: hash 5(a4)eb2'332b'562f6%!6!fcbf&''55&c2()5b36!f3(24b(!f%!cb%6f))2&54 nonce (((%((((: hash '65(&52ca6e(4b5!c2%5e2%2354&''2644(5a24b5f4'%c2%244b&f)5'45(b3)4 9* beautiful block hash ((((e53%5(%&f)24c36c&(6(6c5!)4(eaa&b5!2((fb4&4ca33ea)'%&ca5cc)2( hashenesis;lock ;lockoinbase@xCn<>DutPoint<((((((((((1 -2=1 coinbase (&ffff((2!('(f'6'&3236'!3(3&'!3'3%)&%56'6'%56)63'(%!%5%e%f6'%563'(%26%%f636)%f%5%)% e63%563= >@xDut
6hen update the nonce if (fTestet) { blocN>nTi&e blocN>nonce
= 1F;E<1;;% = <F%
-et the !lag to !alse in your genesis"mining"code if (false UU (blocN>HetXash() = hashHenesisBlocN)) #n main.cpp disable the timestamp check i! on testnet ChecN coinbase ti&esta&p
disabling this for testnet see Xoshi&aru8s re&arNs at httpsbitcointalN>orgindeG>php*topic=1/;;>1/ if (fTestet UU HetBlocNTi&e() K (intnTi&e + n,aGClocN2rift) return 2o"(/. error(#ChecNBlocN() coinbase ti&esta&p is too early#))%
Gebuild and run. Nou ha$e now an unique coin with an identity network and genesis o! it%s own.
Pri&ate test net$or" (et up +irtualbo, sudo apt"get install $irtualbox 6hen get #-* !rom https:help.ubuntu.comcommunityCubuntuDocumentationMinimal#nstall Cet=s get a small OK"bit *Ubuntu 14.04 LTS "Trusty Tahr" 31MB (MD5: a2502844750ecb477!8b4#b$aa8% S&'1: !17c34ce71133$040cc!c02!32482e!b01a1
md>sum miniOK.iso aK>2KFJJQ>2ecb/JQQdF!bJ!!/b0aa!F miniOK.iso -tart $irtualbox 9what is below !ollows http:www.cs.'hu.eduR'oanne$irtualBox.html) Make new SM gi$e it a name and select ubuntu as the *Cea$e the >IKMB memory de!ault you can change it later Cet it create a hard dri$e lea$e the de!ault type SD# dynamically allocated etc ow that it stands there go to settings"?storage
-et up the $irtual cd dri$e +hoose your $irtual disk it should show up under +ontroller #DE
6o copy"paste 4o to general"?ad$anced"? set shared clipboard to birectional *1 boot it !rom -tart #nstallation !ollows ought to be straight!orward. 7!ter it has installed close the SM. 4o to settings and remo$e the iso !ile under controller #DE and restart. Cog in with the details you entered during the installation.
4et these utils sudo apt-get install virtualbox-guest-utils virtualbox-guest-x11 virtualbox-guest-dkms Geboot.
Net$or" $ith the 'uest &irtual machine So we can mine some blocks! Lollow this https:Kbuntu.comarticlesI>IOaccessing"your"$irtualbox"guest"!rom"your"host"os
*pen your linux SM in $irtualbox 4o to LileTPre!erences in tht Sirtualbox Manager window select etworkT3ost"only etworks and add new. -ee that the D3+P ser$er details match
6hen in the settings o! the SM add a new adapter and attach it to your host"only adapter
-tart your SM #ssue i!con!ig #! you are not seeing a new inter!ace then issue i!con!ig "a 6ake note o! the new inter!ace%s name and add it to etcnetworkinter!aces !ile : auto eth1 iface eth1 inet dhcp
-a$e !ile reboot SM #ssue i!con!ig take note o! the #P ping #P o! your SM !rom your host machine ow edit your con! !ile and put this there rpccuser=#enter anything as a userna&e# rpcpassword=#enter anything for a password# rpcport= server=1 listen=1 dae&on=1 testnet=1 addnode=VP, 9$K
*n the SM edit the con! accordingly adding your host #P
*pen your two nodes one on your host one on your SM +heck that they connect. -tart mining with either client or both ./ppcoin! setgenerate true
G-.P!IC( etc
ow let=s do a paint 'ob o$er the ;6 wallet #n srcqtbitcoingui.cpp: BitcoinH'9BitcoinH'9(!Widget ?parent) !,ainWindow(parent). client,odel(/). wallet,odel(/). encryptWallet0ction(/). change$assphrase0ction(/). unlocNWallet0ction(/). locNWallet0ction(/). about!t0ction(/). tray9con(/). notificator(/). rpcConsole(/) { resiLe(/. /)% setWindowTitle(tr(#Qencoin#))%
6he bitmaps go into here srcqtresicons " 6his is the !older that contains all the icons !or your wallet srcqtresimages " 6his is the splash 9loading) screen !or your new coin
Set up server
4et one !rom online.net or somewhere !or example here 9no a!!iliate) https:www.online.netendedicated"cloudUstarter"cloud i! you did that 'ust !ollow https:community.online.netthow"to"create"your"own"peercoin"!ull"acti$e"node"running"on" debian"with"online"labs"cloud/F2