Skip to content

HOW TO DEPLOY BLINKTRADE ON GOOGLE COMPUTE ENGINE

Ty Everett edited this page Mar 16, 2018 · 22 revisions

This guide intent to be a reference point on how to deploy a running instance of your own bitcoin exchange platform.

This documentation is outdated. DO NOT try to run an exchange without knowing EXACTLY what you are doing. You will run into problems and be liable for other people's funds. Proceed with caution.

INSTALL GOOGLE COMPUTE ENGINE SDK

You will need to install the following dependencies before you start.

Install Google Compute Engine SDK (https://developers.google.com/cloud/sdk/)

$ curl https://sdk.cloud.google.com | bash

Authenticate SDK using gcloud

$ gcloud auth login
$ gcloud config set project ${PROJECT}
$ gcloud compute ssh ${INSTANCE_NAME} --zone us-central1-a

INSTALL SERVER DEPENDENCIES

Add repositories to sources.list:

# echo "deb http://nginx.org/packages/debian/ wheezy nginx" >> /etc/apt/sources.list
# echo "deb-src http://nginx.org/packages/debian/ wheezy nginx" >> /etc/apt/sources.list
# wget http://nginx.org/keys/nginx_signing.key
# apt-key add nginx_signing.key 
# apt-get update
# apt-get install nginx 
# apt-get install git
# apt-get install python-setuptools python-pip 
# apt-get install python-dev libzmq-dev libzmq-dev 
# pip install honcho
# apt-get install openjdk-7-jre

INSTALL BLINKTRADE FROM SOURCE CODE

Python Dependencies

For pip users:

# cd /opt/${PROJECT}
# pip install -r requirements.txt

or

# easy_install pyzmq
# easy_install crypto
# easy_install tornado
# easy_install sqlalchemy
# easy_install requests

Then ru the following commands:

# cd /opt
# git clone https://github.com/blinktrade/bitex.git ${PROJECT}

INSTALL THE FRONTEND PROJECT

git clone https://github.com/blinktrade/frontend.git
cd ./jsdev
./build_release.sh  # Or ./build_release.bat [Windows]

GENERATING OPENSSL CERTIFICATE

For production environment use ssls.com that accept Bitcoin as payment.

Instructions to generate CSR from ssls.com

For development purpose you can use a self signed certificate as follow:

# cd /etc/ssl/certs
# openssl genrsa -des3 -out server.key 1024
# openssl req -new -key server.key -out server.csr
# cp server.key server.key.org
# openssl rsa -in server.key.org -out server.key
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

You can check your ssl certificate with those commands:

openssl x509 -noout -modulus -in server.com.crt | openssl md5
openssl rsa -noout -modulus -in myserver.key | openssl md5

SETUP NGINX

Edit /etc/nginx/conf.d/${PROJECT}.conf and adjust your env variables using the following template:

upstream ws_${PROJECT}_gateway {
  server   localhost:8445;
}

map $http_upgrade $connection_upgrade {
  default  upgrade;
  ''       close;
}

server {
    listen         80;
    server_name    ${PROJECT_DOMAIN};
    return         301 https://$host$request_uri;
}

server {
    listen       443;
    server_name  ${PROJECT_DOMAIN};

    ssl                  on;
    ssl_certificate     /opt/${PROJECT}/ssl/server.crt;
    ssl_certificate_key /opt/${PROJECT}/ssl/server.key;

    ssl_session_timeout  5m;
    ssl_session_cache shared:SSL:50m;

    ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
    ssl_prefer_server_ciphers   on;

    location / {
        root  /opt/${PROJECT}/static;
        index  ${PROJECT}.html;

        location ~ /(broker_application|my_broker|set_new_password|market|signin|signup|forgot_password|tos|start|trading|offerbook|deposit|withdraw|account_activity|customers|verification|enable_two_factor|ledger|withdraw_requests|deposit_requests|profile|account_overview|ranking)$ {
            rewrite /(.*)  /${PROJECT}.html break;
        }

            location /api/ {
                proxy_pass http://ws_${PROJECT}_gateway;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                rewrite /api(.*)  /api$1 break;
                proxy_redirect off;
            }


        #location  /account_overview/ {
        #    rewrite /(.*)  /${PROJECT}.html break;
        #}

        location /print_boleto/ {
            proxy_pass http://ws_${PROJECT}_gateway;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            rewrite /print_boleto(.*)  /print_boleto$1 break;
            proxy_redirect off;
        }

        location /(account_verification)/ {
            proxy_pass http://ws_${PROJECT}_gateway;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect off;
        }

        location /trade/ {
            rewrite /trade/(.*) /$1 break;

            proxy_pass http://ws_${PROJECT}_gateway;
            proxy_http_version 1.1;
            proxy_redirect off;

            proxy_set_header Host             $host;
            proxy_set_header X-Real-IP        $remote_addr;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header Upgrade          $http_upgrade;
            proxy_set_header Connection       $connection_upgrade;
            proxy_read_timeout                3600s;
        }

        location /get_deposit/ {
            proxy_pass http://ws_${PROJECT}_gateway;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            rewrite /get_deposit(.*)  /get_deposit$1 break;
            proxy_redirect off;
        }

        location /process_deposit/ {
            proxy_pass http://ws_${PROJECT}_gateway;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            rewrite /process_deposit(.*)  /process_deposit$1 break;
            proxy_redirect off;
        }

        location /_webhook/ {
                proxy_pass http://ws_${PROJECT}_gateway;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_redirect off;
        }

        error_page  404             /404.html;
        location = /40x.html {
          root /opt/bitex/static;
        }


        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

Start nginx

# /etc/init.d/nginx start

CONFIGURING API_RECEIVE

Edit the file from /opt/${PROJECT}/config/api_receive.conf

db_engine = "sqlite:////opt/${PROJECT}/db/api_receive.sqlite"
log = "/opt/${PROJECT}/logs/api_receive.log"
port = 9943
rpc_url = "http://localhost:18332"
rpc_username = "your username here"
rpc_password = "your password here"

SETUP TRADE

Edit the file /opt/${PROJECT}/trade.conf

db_echo = False
db_engine = "sqlite:////opt/${PROJECT}/db/bitex.sqlite"
trade_in = "tcp://127.0.0.1:5757"
trade_pub = "tcp://127.0.0.1:5758"
trade_log = "/opt/${PROJECT}/logs/trade.log"
session_timeout_limit = 0
test_mode = False
dev_mode = False
satoshi_mode = False

CONFIGURING WS_GATEWAY

Edit the file /opt/${PROJECT}/ws_gateway.conf

callback_url = "http://${PROJECT_DOMAIN}/process_deposit?s="
url_payment_processor = "${API_RECEIVE_URL}"
trade_in = "tcp://127.0.0.1:5757"
trade_pub = "tcp://127.0.0.1:5758"
gateway_log = "/opt/${PROJECT}/logs/ws_gateway.log"
db_echo = False
db_engine = "sqlite:////${PROJECT}/db/ws_gateway.sqlite"
port=8443

SETUP HONCHO

Edit the file /opt/cryptos/Procfile

engine: python2.7 apps/trade/main.py --config=/opt/bitex/config/trade.conf
gateway: python2.7 apps/ws_gateway/main.py --config=/opt/bitex/config/ws_gateway.conf
api_receive: python2.7 apps/api_receive/main.py --config=/opt/bitex/config/ws_gateway.conf

SETUP MAILER.CONF

trade_pub = "tcp://127.0.0.1:5758"
template_dir = "/opt/bitex/apps/mailer/templates"
mailer_log = "/opt/bitex/logs/mailer.log"
mailchimp_apikey = ""
mailchimp_newsletter_list_id = "0e52f2b3b8"
mandrill_apikey = ""

START BLINKTRADE PLATFORM

After configuring and doing the fine tune we are now able to run the platform, for this use the following command:

# cd /opt/${PROJECT}/
# honcho start

TEST BLINKTRADE PLATFORM

Open you browser at:

http://${PROJECT_DOMAIN}/

SETUP BROKER

At this particular moment the only way to create broker is manually editing the file located on apps/trade/models.py and inserting on db_boostrap method the following code:

if not Broker.get_broker(session, 3):
          e = Broker(id=3,
                     short_name=u'',
                     business_name=u'',
                     address=u'',
                     signup_label='',
                     city='New York',
                     state='NY',
                     zip_code='',
                     country_code='US',
                     lang='en-US',
                     country='United States',
                     phone_number_1=None, phone_number_2=None, skype=None, email='admin@.com',
                     verification_jotform= user_verification_jotform + '?user_id={{UserID}}&username={{Username}}&broker_id={{BrokerID}}&broker_username={{BrokerUsername}}&email={{Email}}&phoneNumber[country]=1',
                     upload_jotform= upload_jotform + '?user_id={{UserID}}&username={{Username}}&broker_id={{BrokerID}}&broker_username={{BrokerUsername}}&deposit_method={{DepositMethod}}&control_number={{ControlNumber}}&deposit_id={{DepositID}}',
                     currencies='USD',
                     withdraw_structure=json.dumps( {
                         'BTC': [
                             {
                                 'method':'bitcoin',
                                 'description':'Bitcoin withdrawal',
                                 'disclaimer': '',
                                 'percent_fee':0.,
                                 'fixed_fee':0,
                                 'fields': [
                                     {'side':'client', 'name': 'Wallet'        , 'validator':'validateAddress',  'type':'text'  , 'value':""       , 'label':'Wallet',        'placeholder':'' },
                                     {'side':'broker', 'name': 'TransactionID' , 'validator':'validateAlphaNum', 'type':'text'  , 'value':""       , 'label':'TransactionID', 'placeholder':'' },
                                     {'side':'broker', 'name': 'Link'          , 'validator':'validateAlphaNum', 'type':'text'  , 'value':""       , 'label':'Link',          'placeholder':'' },
                                     ]
                             }
                         ],
                         'USD': [ {
                                      'method':'cash',
                                      'description':'Cash',
                                      'disclaimer':'Armored car will deliver the cash in hands',
                                      'percent_fee': 1.,
                                      'fixed_fee': 0,
                                      'fields': [
                                      ]
                                  }, {
                                   'method':'ach',
                                   'description':'ACH',
                                   'disclaimer':'1 business day',
                                   'percent_fee': 1.,
                                   'fixed_fee': int(.3 * 1e8), # $0.30
                                   'fields': [
                                       {'side':'client', 'name': 'BankName'     , 'validator':'validateAlphaNum', 'type':'text'  , 'value':""  , 'label':'Banco name', 'placeholder': 'ex. JPMORGAN CHASE BANK, N.A' },
                                       {'side':'client', 'name': 'RoutingNumber', 'validator':'validateAlphaNum', 'type':'text'  , 'value':""  , 'label':'Routing Number', 'placeholder':'ex. 021000021' },
                                       {'side':'client', 'name': 'AccountNumber', 'validator':'validateAlphaNum', 'type':'text'  , 'value':""  , 'label':'Account Number', 'placeholder':'ex. 888888' },
                                       {'side':'broker', 'name': 'TransactionID', 'validator':'validateAlphaNum', 'type':'text'  , 'value':""  , 'label':'TransactionID', 'placeholder':'' },
                                   ]
                                 }
                         ]
                     }),
                     crypto_currencies=json.dumps([
                         {
                             "CurrencyCode": "BTC",
                             "CurrencyDescription":"Bitcoin",
                             "Confirmations":[ [0, 1e8, 0], [ 1e8, 200e8, 3 ], [200e8, 21000000e8, 6 ] ],
                             "Wallets": [
                                 { "type":"cold", "address":"154J1nWscUNY959VxM8SaNpK8sfXUH7z2u", "multisig":False,"signatures":[], "managed_by":"BlinkTrade" },
                                 { "type":"hot", "address":"1Nk7JzvkmuTfMaUKKtRaK8K9PM2UfNcJP3", "multisig":False,"signatures":[], "managed_by":"BlinkTrade" },
                                 ]
                         }
                     ]),
                     accept_customers_from=json.dumps([
                         [ 'US_NY'],  # Only US_NY
                         [ "US",  # except US and all other states
                           "US_AL","US_AK","US_AZ","US_AR","US_CA","US_CO","US_CT","US_DE","US_DC","US_FL",
                           "US_GA","US_HI","US_ID","US_IL","US_IN","US_IA","US_KS","US_KY","US_LA","US_ME",
                           "US_MD","US_MA","US_MI","US_MN","US_MS","US_MO","US_MT","US_NE","US_NV","US_NH",
                           "US_NJ","US_NM","US_NC","US_ND","US_OH","US_OK","US_OR","US_PA","US_RI","US_SC",
                           "US_SD","US_TN","US_TX","US_UT","US_VE","US_VA","US_WA","US_WV","US_WI","US_WY"]
                     ]) ,
                     is_broker_hub=False,
                     support_url='https://www.facebook.com/groups/',
                     tos_url='https://dl.dropboxusercontent.com/u/29731093/cryptsy_tos.html',
                     fee_structure=json.dumps([
                         { "Operation" : "USPS Money Order deposit",       "Fee":"$5"               , "Terms":"30 minutes." },
                         { "Operation" : "Check deposit",                  "Fee":"1%"               , "Terms":"3 business days" },
                         { "Operation" : "Wire transfer deposit",          "Fee":"0.3%"             , "Terms":"Next business day" },
                         { "Operation" : "Wire transfer withdraw",         "Fee":"0.3%"             , "Terms":"Next business day" },
                         { "Operation" : "PayPal withdrawal",              "Fee":"0%"               , "Terms":"Instant" },
                         ]),
                     transaction_fee_buy=20,   # 0.2%
                     transaction_fee_sell=20,  # 0.2%
                     status='1',
                     ranking=5)
          session.add(e)
          session.commit()

SETUP CURRENCIES

Uncoment the follow options on apps/trade/models.py db_boostrap method:

instruments = [
    ['BTCUSD', 'USD', "BTC / USD" ],
    # ['BTCEUR', 'EUR', "BTC / EUR" ],
    # ['BTCCNY', 'CNY', "BTC / CNY" ],
    # ['BTCARS', 'ARS', "BTC / ARS" ],
    # ['BTCGBP', 'GBP', "BTC / GBP" ],
    ['BTCBRL', 'BRL', "BTC / BRL" ],
    # ['BTCJPY', 'JPY', "BTC / JPY" ],
    # ['BTCRUB', 'RUB', "BTC / RUB" ],
    # ['BTCRUB', 'INR', "BTC / INR" ],
    # ['BTCAOA', 'AOA', "BTC / AOA" ],
    # ['BTCAUD', 'AUD', "BTC / AUD" ],
    # ['BTCBSD', 'BSD', "BTC / BSD" ],
    # ['BTCIDR', 'IDR', "BTC / IDR" ],
    # ['BTCILS', 'ILS', "BTC / ILS" ],
    # ['BTCMXN', 'MXN', "BTC / MXN" ],
    ['BTCVEF', 'VEF', "BTC / VEF" ],
    # ['BTCXOF', 'XOF', "BTC / CFA Franc" ],
  ]