Advertisement
Guest User

Coin Gen

a guest
Mar 15th, 2018
1,077
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 15.15 KB | None | 0 0
  1. #!/bin/bash -e
  2. # This script is an experiment to clone litecoin into a
  3. # brand new coin + blockchain.
  4. # Projeto original de tiagosh, modifidaco por Filipe Ospina.
  5. # The script will perform the following steps:
  6. # 1) create first a docker image with ubuntu ready to build and run the new coin daemon
  7. # 2) clone GenesisH0 and mine the genesis blocks of main, test and regtest networks in the container (this may take a lot of time)
  8. # 3) clone litecoin
  9. # 4) replace variables (keys, merkle tree hashes, timestamps..)
  10. # 5) build new coin
  11. # 6) run 4 docker nodes and connect to each other
  12. #
  13. # By default the script uses the regtest network, which can mine blocks
  14. # instantly. If you wish to switch to the main network, simply change the
  15. # CHAIN variable below
  16.  
  17. # change the following variables to match your new coin
  18. COIN_NAME="MyCoin"
  19. COIN_UNIT="MYC"
  20. # 42 million coins at total (litecoin total supply is 84000000)
  21. TOTAL_SUPPLY=42000000
  22. MAINNET_PORT="54321"
  23. TESTNET_PORT="54322"
  24. PHRASE="Some newspaper headline that describes something that happened today"
  25. # First letter of the wallet address. Check https://en.bitcoin.it/wiki/Base58Check_encoding
  26. PUBKEY_CHAR="20"
  27. # number of blocks to wait to be able to spend coinbase UTXO's
  28. COINBASE_MATURITY=100
  29. # leave CHAIN empty for main network, -regtest for regression network and -testnet for test network
  30. CHAIN="-regtest"
  31. # this is the amount of coins to get as a reward of mining the block of height 1. if not set this will default to 50
  32. #PREMINED_AMOUNT=10000
  33.  
  34. # warning: change this to your own pubkey to get the genesis block mining reward
  35. GENESIS_REWARD_PUBKEY=044e0d4bc823e20e14d66396a64960c993585400c53f1e6decb273f249bfeba0e71f140ffa7316f2cdaaae574e7d72620538c3e7791ae9861dfe84dd2955fc85e8
  36.  
  37. # dont change the following variables unless you know what you are doing
  38. LITECOIN_BRANCH=0.14
  39. GENESISHZERO_REPOS=https://github.com/lhartikk/GenesisH0
  40. LITECOIN_REPOS=https://github.com/litecoin-project/litecoin.git
  41. LITECOIN_PUB_KEY=040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9
  42. LITECOIN_MERKLE_HASH=97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9
  43. LITECOIN_MAIN_GENESIS_HASH=12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2
  44. LITECOIN_TEST_GENESIS_HASH=4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0
  45. LITECOIN_REGTEST_GENESIS_HASH=530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9
  46. MINIMUM_CHAIN_WORK_MAIN=0x000000000000000000000000000000000000000000000006805c7318ce2736c0
  47. MINIMUM_CHAIN_WORK_TEST=0x000000000000000000000000000000000000000000000000000000054cb9e7a0
  48. COIN_NAME_LOWER=$(echo $COIN_NAME | tr '[:upper:]' '[:lower:]')
  49. COIN_NAME_UPPER=$(echo $COIN_NAME | tr '[:lower:]' '[:upper:]')
  50. DIRNAME=$(dirname $0)
  51. DOCKER_NETWORK="172.18.0"
  52. DOCKER_IMAGE_LABEL="newcoin-env"
  53. OSVERSION="$(uname -s)"
  54.  
  55. docker_build_image()
  56. {
  57.     IMAGE=$(docker images -q $DOCKER_IMAGE_LABEL)
  58.     if [ -z $IMAGE ]; then
  59.         echo Building docker image
  60.         if [ ! -f $DOCKER_IMAGE_LABEL/Dockerfile ]; then
  61.             mkdir -p $DOCKER_IMAGE_LABEL
  62.             cat <<EOF > $DOCKER_IMAGE_LABEL/Dockerfile
  63. FROM ubuntu:16.04
  64. RUN echo deb http://ppa.launchpad.net/bitcoin/bitcoin/ubuntu xenial main >> /etc/apt/sources.list
  65. RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv D46F45428842CE5E
  66. RUN apt-get update
  67. RUN apt-get -y install ccache git libboost-system1.58.0 libboost-filesystem1.58.0 libboost-program-options1.58.0 libboost-thread1.58.0 libboost-chrono1.58.0 libssl1.0.0 libevent-pthreads-2.0-5 libevent-2.0-5 build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb4.8-dev libdb4.8++-dev libminiupnpc-dev libzmq3-dev libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev python-pip
  68. RUN pip install construct==2.5.2 scrypt
  69. EOF
  70.         fi
  71.         docker build --label $DOCKER_IMAGE_LABEL --tag $DOCKER_IMAGE_LABEL $DIRNAME/$DOCKER_IMAGE_LABEL/
  72.     else
  73.         echo Docker image already built
  74.     fi
  75. }
  76.  
  77. docker_run_genesis()
  78. {
  79.     mkdir -p $DIRNAME/.ccache
  80.     docker run -v $DIRNAME/GenesisH0:/GenesisH0 $DOCKER_IMAGE_LABEL /bin/bash -c "$1"
  81. }
  82.  
  83. docker_run()
  84. {
  85.     mkdir -p $DIRNAME/.ccache
  86.     docker run -v $DIRNAME/GenesisH0:/GenesisH0 -v $DIRNAME/.ccache:/root/.ccache -v $DIRNAME/$COIN_NAME_LOWER:/$COIN_NAME_LOWER $DOCKER_IMAGE_LABEL /bin/bash -c "$1"
  87. }
  88.  
  89. docker_stop_nodes()
  90. {
  91.     echo "Stopping all docker nodes"
  92.     for id in $(docker ps -q -a  -f ancestor=$DOCKER_IMAGE_LABEL); do
  93.         docker stop $id
  94.     done
  95. }
  96.  
  97. docker_remove_nodes()
  98. {
  99.     echo "Removing all docker nodes"
  100.     for id in $(docker ps -q -a  -f ancestor=$DOCKER_IMAGE_LABEL); do
  101.         docker rm $id
  102.     done
  103. }
  104.  
  105. docker_create_network()
  106. {
  107.     echo "Creating docker network"
  108.     if ! docker network inspect newcoin &>/dev/null; then
  109.         docker network create --subnet=$DOCKER_NETWORK.0/16 newcoin
  110.     fi
  111. }
  112.  
  113. docker_remove_network()
  114. {
  115.     echo "Removing docker network"
  116.     docker network rm newcoin
  117. }
  118.  
  119. docker_run_node()
  120. {
  121.     local NODE_NUMBER=$1
  122.     local NODE_COMMAND=$2
  123.     mkdir -p $DIRNAME/miner${NODE_NUMBER}
  124.     if [ ! -f $DIRNAME/miner${NODE_NUMBER}/$COIN_NAME_LOWER.conf ]; then
  125.         cat <<EOF > $DIRNAME/miner${NODE_NUMBER}/$COIN_NAME_LOWER.conf
  126. rpcuser=${COIN_NAME_LOWER}rpc
  127. rpcpassword=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 32; echo)
  128. EOF
  129.     fi
  130.  
  131.     docker run --net newcoin --ip $DOCKER_NETWORK.${NODE_NUMBER} -v $DIRNAME/miner${NODE_NUMBER}:/root/.$COIN_NAME_LOWER -v $DIRNAME/$COIN_NAME_LOWER:/$COIN_NAME_LOWER $DOCKER_IMAGE_LABEL /bin/bash -c "$NODE_COMMAND"
  132. }
  133.  
  134. generate_genesis_block()
  135. {
  136.     if [ ! -d GenesisH0 ]; then
  137.         git clone $GENESISHZERO_REPOS
  138.         pushd GenesisH0
  139.     else
  140.         pushd GenesisH0
  141.         git pull
  142.     fi
  143.  
  144.     if [ ! -f ${COIN_NAME}-main.txt ]; then
  145.         echo "Mining genesis block... this procedure can take many hours of cpu work.."
  146.         docker_run_genesis "python /GenesisH0/genesis.py -a scrypt -z \"$PHRASE\" -p $GENESIS_REWARD_PUBKEY 2>&1 | tee /GenesisH0/${COIN_NAME}-main.txt"
  147.     else
  148.         echo "Genesis block already mined.."
  149.         cat ${COIN_NAME}-main.txt
  150.     fi
  151.  
  152.     if [ ! -f ${COIN_NAME}-test.txt ]; then
  153.         echo "Mining genesis block of test network... this procedure can take many hours of cpu work.."
  154.         docker_run_genesis "python /GenesisH0/genesis.py  -t 1486949366 -a scrypt -z \"$PHRASE\" -p $GENESIS_REWARD_PUBKEY 2>&1 | tee /GenesisH0/${COIN_NAME}-test.txt"
  155.     else
  156.         echo "Genesis block already mined.."
  157.         cat ${COIN_NAME}-test.txt
  158.     fi
  159.  
  160.     if [ ! -f ${COIN_NAME}-regtest.txt ]; then
  161.         echo "Mining genesis block of regtest network... this procedure can take many hours of cpu work.."
  162.         docker_run_genesis "python /GenesisH0/genesis.py -t 1296688602 -b 0x207fffff -n 0 -a scrypt -z \"$PHRASE\" -p $GENESIS_REWARD_PUBKEY 2>&1 | tee /GenesisH0/${COIN_NAME}-regtest.txt"
  163.     else
  164.         echo "Genesis block already mined.."
  165.         cat ${COIN_NAME}-regtest.txt
  166.     fi
  167.  
  168.     MAIN_PUB_KEY=$(cat ${COIN_NAME}-main.txt | grep "^pubkey:" | $SED 's/^pubkey: //')
  169.     MERKLE_HASH=$(cat ${COIN_NAME}-main.txt | grep "^merkle hash:" | $SED 's/^merkle hash: //')
  170.     TIMESTAMP=$(cat ${COIN_NAME}-main.txt | grep "^time:" | $SED 's/^time: //')
  171.     BITS=$(cat ${COIN_NAME}-main.txt | grep "^bits:" | $SED 's/^bits: //')
  172.  
  173.     MAIN_NONCE=$(cat ${COIN_NAME}-main.txt | grep "^nonce:" | $SED 's/^nonce: //')
  174.     TEST_NONCE=$(cat ${COIN_NAME}-test.txt | grep "^nonce:" | $SED 's/^nonce: //')
  175.     REGTEST_NONCE=$(cat ${COIN_NAME}-regtest.txt | grep "^nonce:" | $SED 's/^nonce: //')
  176.  
  177.     MAIN_GENESIS_HASH=$(cat ${COIN_NAME}-main.txt | grep "^genesis hash:" | $SED 's/^genesis hash: //')
  178.     TEST_GENESIS_HASH=$(cat ${COIN_NAME}-test.txt | grep "^genesis hash:" | $SED 's/^genesis hash: //')
  179.     REGTEST_GENESIS_HASH=$(cat ${COIN_NAME}-regtest.txt | grep "^genesis hash:" | $SED 's/^genesis hash: //')
  180.  
  181.     popd
  182. }
  183.  
  184. newcoin_replace_vars()
  185. {
  186.     if [ -d $COIN_NAME_LOWER ]; then
  187.         echo "Warning: $COIN_NAME_LOWER already existing. Not replacing any values"
  188.         return 0
  189.     fi
  190.     if [ ! -d "litecoin-master" ]; then
  191.         # clone litecoin and keep local cache
  192.         git clone -b $LITECOIN_BRANCH $LITECOIN_REPOS litecoin-master
  193.     else
  194.         echo "Updating master branch"
  195.         pushd litecoin-master
  196.         git pull
  197.         popd
  198.     fi
  199.  
  200.     git clone -b $LITECOIN_BRANCH litecoin-master $COIN_NAME_LOWER
  201.  
  202.     pushd $COIN_NAME_LOWER
  203.  
  204.     # first rename all directories
  205.     for i in $(find . -type d | grep -v "^./.git" | grep litecoin); do
  206.         git mv $i $(echo $i| $SED "s/litecoin/$COIN_NAME_LOWER/")
  207.     done
  208.  
  209.     # then rename all files
  210.     for i in $(find . -type f | grep -v "^./.git" | grep litecoin); do
  211.         git mv $i $(echo $i| $SED "s/litecoin/$COIN_NAME_LOWER/")
  212.     done
  213.  
  214.     # now replace all litecoin references to the new coin name
  215.     for i in $(find . -type f | grep -v "^./.git"); do
  216.         $SED -i "s/Litecoin/$COIN_NAME/g" $i
  217.         $SED -i "s/litecoin/$COIN_NAME_LOWER/g" $i
  218.         $SED -i "s/LITECOIN/$COIN_NAME_UPPER/g" $i
  219.         $SED -i "s/LTC/$COIN_UNIT/g" $i
  220.     done
  221.  
  222.     $SED -i "s/84000000/$TOTAL_SUPPLY/" src/amount.h
  223.     $SED -i "s/1,48/1,$PUBKEY_CHAR/" src/chainparams.cpp
  224.  
  225.     $SED -i "s/1317972665/$TIMESTAMP/" src/chainparams.cpp
  226.  
  227.     $SED -i "s;NY Times 05/Oct/2011 Steve Jobs, Apple’s Visionary, Dies at 56;$PHRASE;" src/chainparams.cpp
  228.  
  229.     $SED -i "s/= 9333;/= $MAINNET_PORT;/" src/chainparams.cpp
  230.     $SED -i "s/= 19335;/= $TESTNET_PORT;/" src/chainparams.cpp
  231.  
  232.     $SED -i "s/$LITECOIN_PUB_KEY/$MAIN_PUB_KEY/" src/chainparams.cpp
  233.     $SED -i "s/$LITECOIN_MERKLE_HASH/$MERKLE_HASH/" src/chainparams.cpp
  234.     $SED -i "s/$LITECOIN_MERKLE_HASH/$MERKLE_HASH/" src/qt/test/rpcnestedtests.cpp
  235.  
  236.     $SED -i "0,/$LITECOIN_MAIN_GENESIS_HASH/s//$MAIN_GENESIS_HASH/" src/chainparams.cpp
  237.     $SED -i "0,/$LITECOIN_TEST_GENESIS_HASH/s//$TEST_GENESIS_HASH/" src/chainparams.cpp
  238.     $SED -i "0,/$LITECOIN_REGTEST_GENESIS_HASH/s//$REGTEST_GENESIS_HASH/" src/chainparams.cpp
  239.  
  240.     $SED -i "0,/2084524493/s//$MAIN_NONCE/" src/chainparams.cpp
  241.     $SED -i "0,/293345/s//$TEST_NONCE/" src/chainparams.cpp
  242.     $SED -i "0,/1296688602, 0/s//1296688602, $REGTEST_NONCE/" src/chainparams.cpp
  243.     $SED -i "0,/0x1e0ffff0/s//$BITS/" src/chainparams.cpp
  244.  
  245.     $SED -i "s,vSeeds.push_back,//vSeeds.push_back,g" src/chainparams.cpp
  246.  
  247.     if [ -n "$PREMINED_AMOUNT" ]; then
  248.         $SED -i "s/CAmount nSubsidy = 50 \* COIN;/if \(nHeight == 1\) return COIN \* $PREMINED_AMOUNT;\n    CAmount nSubsidy = 50 \* COIN;/" src/validation.cpp
  249.     fi
  250.  
  251.     $SED -i "s/COINBASE_MATURITY = 100/COINBASE_MATURITY = $COINBASE_MATURITY/" src/consensus/consensus.h
  252.  
  253.     # reset minimum chain work to 0
  254.     $SED -i "s/$MINIMUM_CHAIN_WORK_MAIN/0x00/" src/chainparams.cpp
  255.     $SED -i "s/$MINIMUM_CHAIN_WORK_TEST/0x00/" src/chainparams.cpp
  256.  
  257.     # change bip activation heights
  258.     # bip 34
  259.     $SED -i "s/710000/0/" src/chainparams.cpp
  260.     # bip 65
  261.     $SED -i "s/918684/0/" src/chainparams.cpp
  262.     # bip 66
  263.     $SED -i "s/811879/0/" src/chainparams.cpp
  264.  
  265.     # TODO: fix checkpoints
  266.     popd
  267. }
  268.  
  269. build_new_coin()
  270. {
  271.     # only run autogen.sh/configure if not done previously
  272.     if [ ! -e $COIN_NAME_LOWER/Makefile ]; then
  273.         docker_run "cd /$COIN_NAME_LOWER ; bash  /$COIN_NAME_LOWER/autogen.sh"
  274.         docker_run "cd /$COIN_NAME_LOWER ; bash  /$COIN_NAME_LOWER/configure"
  275.     fi
  276.     # always build as the user could have manually changed some files
  277.     docker_run "cd /$COIN_NAME_LOWER ; make -j2"
  278. }
  279.  
  280.  
  281. if [ $DIRNAME =  "." ]; then
  282.     DIRNAME=$PWD
  283. fi
  284.  
  285. cd $DIRNAME
  286.  
  287. # sanity check
  288.  
  289. case $OSVERSION in
  290.     Linux*)
  291.         SED=sed
  292.     ;;
  293.     Darwin*)
  294.         SED=$(which gsed 2>/dev/null)
  295.         if [ $? -ne 0 ]; then
  296.             echo "please install gnu-sed with 'brew install gnu-sed'"
  297.             exit 1
  298.         fi
  299.         SED=gsed
  300.     ;;
  301.     *)
  302.         echo "This script only works on Linux and MacOS"
  303.         exit 1
  304.     ;;
  305. esac
  306.  
  307.  
  308. if ! which docker &>/dev/null; then
  309.     echo Please install docker first
  310.     exit 1
  311. fi
  312.  
  313. if ! which git &>/dev/null; then
  314.     echo Please install git first
  315.     exit 1
  316. fi
  317.  
  318. case $1 in
  319.     stop)
  320.         docker_stop_nodes
  321.     ;;
  322.     remove_nodes)
  323.         docker_stop_nodes
  324.         docker_remove_nodes
  325.     ;;
  326.     clean_up)
  327.         docker_stop_nodes
  328.         for i in $(seq 2 5); do
  329.            docker_run_node $i "rm -rf /$COIN_NAME_LOWER /root/.$COIN_NAME_LOWER" &>/dev/null
  330.         done
  331.         docker_remove_nodes
  332.         docker_remove_network
  333.         rm -rf $COIN_NAME_LOWER
  334.         if [ "$2" != "keep_genesis_block" ]; then
  335.             rm -f GenesisH0/${COIN_NAME}-*.txt
  336.         fi
  337.         for i in $(seq 2 5); do
  338.            rm -rf miner$i
  339.         done
  340.     ;;
  341.     start)
  342.         if [ -n "$(docker ps -q -f ancestor=$DOCKER_IMAGE_LABEL)" ]; then
  343.             echo "There are nodes running. Please stop them first with: $0 stop"
  344.             exit 1
  345.         fi
  346.         docker_build_image
  347.         generate_genesis_block
  348.         newcoin_replace_vars
  349.         build_new_coin
  350.         docker_create_network
  351.  
  352.         docker_run_node 2 "cd /$COIN_NAME_LOWER ; ./src/${COIN_NAME_LOWER}d $CHAIN -listen -noconnect -bind=$DOCKER_NETWORK.2 -addnode=$DOCKER_NETWORK.1 -addnode=$DOCKER_NETWORK.3 -addnode=$DOCKER_NETWORK.4 -addnode=$DOCKER_NETWORK.5" &
  353.         docker_run_node 3 "cd /$COIN_NAME_LOWER ; ./src/${COIN_NAME_LOWER}d $CHAIN -listen -noconnect -bind=$DOCKER_NETWORK.3 -addnode=$DOCKER_NETWORK.1 -addnode=$DOCKER_NETWORK.2 -addnode=$DOCKER_NETWORK.4 -addnode=$DOCKER_NETWORK.5" &
  354.         docker_run_node 4 "cd /$COIN_NAME_LOWER ; ./src/${COIN_NAME_LOWER}d $CHAIN -listen -noconnect -bind=$DOCKER_NETWORK.4 -addnode=$DOCKER_NETWORK.1 -addnode=$DOCKER_NETWORK.2 -addnode=$DOCKER_NETWORK.3 -addnode=$DOCKER_NETWORK.5" &
  355.         docker_run_node 5 "cd /$COIN_NAME_LOWER ; ./src/${COIN_NAME_LOWER}d $CHAIN -listen -noconnect -bind=$DOCKER_NETWORK.5 -addnode=$DOCKER_NETWORK.1 -addnode=$DOCKER_NETWORK.2 -addnode=$DOCKER_NETWORK.3 -addnode=$DOCKER_NETWORK.4" &
  356.  
  357.         echo "Docker containers should be up and running now. You may run the following command to check the network status:
  358. for i in \$(docker ps -q); do docker exec \$i /$COIN_NAME_LOWER/src/${COIN_NAME_LOWER}-cli $CHAIN getinfo; done"
  359.         echo "To ask the nodes to mine some blocks simply run:
  360. for i in \$(docker ps -q); do docker exec \$i /$COIN_NAME_LOWER/src/${COIN_NAME_LOWER}-cli $CHAIN generate 2  & done"
  361.         exit 1
  362.     ;;
  363.     *)
  364.         cat <<EOF
  365. Usage: $0 (start|stop|remove_nodes|clean_up)
  366.  - start: bootstrap environment, build and run your new coin
  367.  - stop: simply stop the containers without removing them
  368.  - remove_nodes: remove the old docker container images. This will stop them first if necessary.
  369.  - clean_up: WARNING: this will stop and remove docker containers and network, source code, genesis block information and nodes data directory. (to start from scratch)
  370. EOF
  371.     ;;
  372. esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement