Manual:Installation manual

From Skalex wiki
Revision as of 11:44, 1 June 2016 by Admin (talk | contribs) (Created page with " = 1. Server setup = Please perform all steps given in this document in the given order. They are built upon each other. == 1.1. System requirements == The server-side syste...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

1. Server setup

Please perform all steps given in this document in the given order. They are built upon each other.

1.1. System requirements

The server-side system components of draglet run on Java, PHP, Apache httpd and MySQL. Some smaller support scripts are given in bash syntax. All of these components can run on a wide range of operating systems. We have tested the full functionality on Debian 8. The package lists and configuration instructions work for a Debian 8 system with all package using the Debian 8 standard release and folder layout. To run draglet on a different operating system some instructions will need adjustment. draglet components run independent of each other. By installing the components on separate servers many different system deployments are possible. We are giving three examples that cover the most frequent usages.

1.2. Deployment suggestions

1.2.1. Single server setup

All components are deployed to the same system. This type of setup is recommended for test installations with little need for wallet security and system performance. A single Debian 8 server with 2 GB of RAM and a 50 GB hard disk will work for this setup. If you want to run bitcoind in production mode additional 50 GB for the Bitcoin blockchain will be needed. InstallationManual1.jpg

1.2.2. Cluster setup

Setup with 3 clustered servers. This type of setup is recommended for production setups of exchanges with low traffic and high security requirements. Component distribution: Server 1 runs the components cxServer (see 2.4) and cxClient (see 2.7). Server 2 runs the components cxAdmin (see 2.3) and cxEngine (see 2.6). Server 3 runs the component cxWallet (see Fehler: Referenz nicht gefunden).

Server hardware: Debian 8 server with 2 GB of RAM and a 30 GB hard disk for each of the three servers. Additional 40 GB (at the time of writing) for the Bitcoin blockchain will be needed on Server 3. Database: Replace package percona-server-server with package percona-xtradb-cluster-56 for all three servers and setup a database cluster as described in https://www.percona.com/software/mysql-database/percona-xtradb-cluster. InstallationManual2.jpg


1.2.3. High throughput cluster setup

Setup with 5 clustered servers. This type of setup is recommended for production setups of exchanges with high traffic and high security requirements. Component distribution: Server 1 runs the components cxServer (see 2.4) and cxClient (see 2.7). Server 2 runs the components cxServer (see 2.4) and cxClient (see 2.7). Server 3 runs the components cxAdmin (see 2.3) and the module “engine” of component cxEngine (see 2.6). Server 4 runs the modules “remote”, “mapu”, “balser”, “shaba” and “meba” of component cxEngine (see 2.6). Server 5 runs the component cxWallet (see Fehler: Referenz nicht gefunden). A load balancer distributes client traffic between servers 1 and 2. Additional servers running cxServer and cxClient can be added to handle higher customer load.

Server hardware: Debian 8 server with 4 GB of RAM and a 100 GB hard disk for each of the three servers. Additional 40 GB (at the time of writing) for the Bitcoin blockchain will be needed on Server 5. 8 or 16 core CPUs on servers 1, 2 and 3 can be used to achieve top performance for high throughput.

1.3. Server Installation

1.3.1. Required additional package sources

Some of the packages required are not available in the standard Debian repositories. We require some additional package sources.

Percona Create /etc/apt/sources.list.d/percona.list: deb http://repo.percona.com/apt jessie main deb-src http://repo.percona.com/apt jessie main Run apt-key adv --keyserver keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A

Java 8 Create /etc/apt/sources.list.d/java8.list: deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main

Run apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886

1.3.2. Perform initial update

apt-get update apt-get upgrade

1.3.3. Package list

The following Debian 8 packages are recommended to run draglet: apt-get install exim4 ntp pwgen curl php5-dev php-pear pkg-config nmap libzmq3 apt-get install libzmq3-dev libapache2-mod-php5 apt-get install apache2 percona-server-server-5.6 php5-cli php5-mysql php5-curl apt-get install php5-intl daemontools-run apt-get install oracle-java8-installer ant ruby-compass libtool-bin Notes on installation of MySQL/Percona Server package: Installation of mysql-server/percona-server will ask to supply a root password. On test installations re-use the server's root user's password. On production installations choose an appropriate password.

On installation of Java 8, you will get prompted to accept the Oracle binary license agreement. To complete the installation, please read and agree to the terms.

1.3.4. Install ZMQ bindings for PHP

Run these commands. When asked for prefix of libzmq installation, press <ENTER>: pecl install zmq-beta echo extension=zmq.so > /etc/php5/mods-available/zmq.ini cd /etc/php5/cli/conf.d/ ln -s ../../mods-available/zmq.ini 20-zmq.ini

On all server setups except pure cxWallet servers, additionaly run: cd /etc/php5/apache2/conf.d/ ln -s ../../mods-available/zmq.ini 20-zmq.ini

1.3.5. Install ZMQ bindings for Java

Run these commands: cd /root wget https://github.com/zeromq/jzmq/archive/v3.1.0.tar.gz -O jzmq-3.1.0.tar.gz tar zxf jzmq-3.1.0.tar.gz cd jzmq-3.1.0 ./autogen.sh ./configure --prefix=/opt/jzmq-3.1.0 nice make make install

1.3.6. Configure timezone for PHP

Local timezone needs to be configured for both PHP Apache module and PHP CLI. In these two files: /etc/php5/apache2/php.ini (Note: This file does not exist and is not required on cxWallet server setups in cluster setup mode) /etc/php5/cli/php.ini Find the line:

date.timezone =

and change it to date.timezone = <your timezone from http://www.timezoneconverter.com/cgi-bin/timezones.tzc>


Activate Apache modules Note: This step is NOT required for coiner servers on cluster setup mode. cd /etc/apache2/mods-enabled/ ln -s ../mods-available/rewrite.load . ln -s ../mods-available/headers.load . ln -s ../mods-available/expires.load . ln -s ../mods-available/ssl.load . ln -s ../mods-available/ssl.conf . ln -s ../mods-available/php5* . ln -s ../mods-available/socache_shmcb.load . /etc/init.d/apache2 restart

1.3.7. Install Source Guardian for PHP

Run these commands: cd /root wget http://www.sourceguardian.com/loaders/download/loaders.linux-x86_64.tar.gz tar xzf loaders.linux-x86_64.tar.gz cp ixed.5.6.lin /usr/lib/php5/20131226/ echo "extension=ixed.5.6.lin" > /etc/php5/mods-available/sg.ini ln -s /etc/php5/mods-available/sg.ini /etc/php5/cli/conf.d/sg.ini ln -s /etc/php5/mods-available/sg.ini /etc/php5/apache2/conf.d/sg.ini

1.3.8. Configure MTA

Exim4 is installed by default on Debian installations, but not configured. Run: dpkg-reconfigure exim4-config You can choose all default values when asked. Only when asked for Root and postmaster mail recipient enter your operator's e-mail address. If not asked for mail recipients they are already configured in /etc/aliases. In this case edit /etc/aliases and root and postmaster alias with your operator's e-mail address.

1.3.9. Security setup

The setup processes for configuration of the following processes are not given in this manual: database cluster setup database cluster security system backup VPN setup encryption of wallet partitions They go beyond the scope of this document and should be done by an experienced Linux system administrator. Your exchange will work without these steps but will lack some security features.


2. Components setup

2.1. Prepare database

Run the following commands from the linux shell to initially setup and configure the mysql database. When prompted for the password, insert the password you gave to the mysql administrative user in Chapter 1.3.5. Create the database “draglet” with specific character set: mysql -u root -p -e 'CREATE DATABASE draglet DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;'

Setup the database users and save the passwords to your secured store: mysql -u root -p -e 'CREATE user "api_frontend"@"localhost" identified by "<api_frontend password>";' mysql -u root -p -e 'CREATE user "api_backend"@"localhost" identified by "<api_backend password>";' mysql -u root -p -e 'CREATE user "api_btcd"@"localhost" identified by "<api_btcd password>";'


2.2. Prepare components

Create the cx-components folder, then download https://www.draglet.com/draglet-3.5.0.tar and copy it to /home/cx-components. Run: mkdir /home/cx-components cd /home/cx-components wget https://www.draglet.com/download/draglet-3.5.0.tar tar xf draglet-3.5.0.tar

Create the folder /home/license. mkdir /home/license

Order a draglet license from certificates@draglet.com and copy it to /home/license.

2.3. Install cxAdmin

2.3.1. Unpack cxAdmin

cd /home/cx-components tar jxf cx-admin-3.5.0.tar.bz2 ln -s /home/cx-components/cx-admin-3.5.0 /home/cx-components/cx-admin

2.3.2. Set component parameters

Execute: cp /home/cx-components/cx-admin/app/config/parameters.yml.dist \ /home/cx-components/cx-admin/app/config/parameters.yml and then edit /home/cx-components/cx-admin/app/config/parameters.yml to match your environment and set the correct path to the license file.

2.3.3. Bootstrap database

Change user to root to allow migrations to run. In /home/cx-components/cx-admin/app/config/parameters.yml set acces to the root user and password you have configured in 1.3.3: database_user: root database_password: <root password> Setup database through migrations /home/cx-components/cx-admin/app/console doctrine:migrations:migrate In /home/cx-components/cx-admin/app/config/parameters.yml reset to the credentials you have created in 2.1: database_user: api_backend database_password: <api_backend password> Reset database user privileges: Create a file /home/cx-components/privileges.sql and copy the following content into it: REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.account TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.account_entry TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.account_entry_type TO 'api_frontend'@'localhost'; GRANT SELECT, UPDATE (is_current, account_id) ON draglet.account_number TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.achievement TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.achievement_group TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.chart_category TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.chart_entry TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.currency TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.execution TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.execution_external TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.feedback TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, UPDATE (seen_at) ON draglet.notification TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.order_type TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, UPDATE (state, nominal) ON draglet.orderbook TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.terms TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.two_factor_auth TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, DELETE ON draglet.two_factor_choice TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, DELETE ON draglet.two_factor_instance TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.two_factor_config TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, UPDATE ON draglet.user TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.user_achievement TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.user_action TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, UPDATE (value), DELETE ON draglet.user_annex TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.transfer TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.setting TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.market TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.market_conversion TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, DELETE ON draglet.login_failure TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.support_message TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.admin_user TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.exchange TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.exchange_market TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.language TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.email TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.user_upload TO 'api_frontend'@'localhost'; GRANT INSERT ON draglet.withdraw_request_fiat TO 'api_frontend'@'localhost'; GRANT SELECT ON draglet.market_maker TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT, UPDATE (state, nominal) ON draglet.shadow_order TO 'api_frontend'@'localhost'; GRANT SELECT, INSERT ON draglet.payment_request TO 'api_frontend'@'localhost'; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE (balance) ON draglet.account TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE (credited,admin_id) ON draglet.account_entry TO 'api_backend'@'localhost'; GRANT SELECT ON draglet.account_entry_type TO 'api_backend'@'localhost'; GRANT SELECT, UPDATE(deep_freeze_address_id, is_current, account_id), DELETE ON draglet.account_number TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, DELETE ON draglet.account_reservation TO 'api_backend'@'localhost'; GRANT SELECT,INSERT ON draglet.chart_category TO 'api_backend'@'localhost'; GRANT SELECT,INSERT,UPDATE ON draglet.chart_entry TO 'api_backend'@'localhost'; GRANT SELECT,INSERT,UPDATE,DELETE ON draglet.currency TO 'api_backend'@'localhost'; GRANT SELECT,INSERT ON draglet.execution TO 'api_backend'@'localhost'; GRANT SELECT,INSERT, UPDATE ON draglet.execution_external TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE (message, context, created_at) ON draglet.notification TO 'api_backend'@'localhost'; GRANT SELECT ON draglet.order_type TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE (user_id,nominal,ask_price,state,executable_nominal) ON draglet.orderbook TO 'api_backend'@'localhost'; GRANT SELECT, INSERT ON draglet.terms TO 'api_backend'@'localhost'; GRANT SELECT ON draglet.two_factor_auth TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, DELETE ON draglet.two_factor_config TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE, DELETE ON draglet.user TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE(value), DELETE ON draglet.user_annex TO 'api_backend'@'localhost'; GRANT SELECT, DELETE ON draglet.transfer TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE(value, modified_at, modified_by_id) ON draglet.setting TO 'api_backend'@'localhost'; GRANT SELECT,INSERT,UPDATE,DELETE ON draglet.market TO 'api_backend'@'localhost'; GRANT SELECT, UPDATE(dso_spread, active) ON draglet.market_conversion TO 'api_backend'@'localhost'; GRANT SELECT,INSERT,UPDATE(handled_at) ON draglet.support_message TO 'api_backend'@'localhost'; GRANT SELECT,INSERT,UPDATE ON draglet.admin_user TO 'api_backend'@'localhost'; GRANT SELECT,INSERT,UPDATE(target),DELETE ON draglet.deep_freeze_address TO 'api_backend'@'localhost'; GRANT SELECT, UPDATE(nostro_accounts_holder_id, fee_difference_sponsor_id) ON draglet.exchange TO 'api_backend'@'localhost'; GRANT SELECT ON draglet.exchange_market TO 'api_backend'@'localhost'; GRANT SELECT ON draglet.language TO 'api_backend'@'localhost'; GRANT SELECT, INSERT, UPDATE ON draglet.email TO 'api_backend'@'localhost'; GRANT SELECT ON draglet.wallet_condition TO 'api_backend'@'localhost'; GRANT SELECT, DELETE ON draglet.user_upload TO 'api_backend'@'localhost'; GRANT SELECT, UPDATE (admin_id, handled_at, account_entry_id) ON draglet.withdraw_request_fiat TO 'api_backend'@'localhost'; GRANT SELECT, DELETE, UPDATE, INSERT ON draglet.maker_order TO 'api_backend'@'localhost'; GRANT SELECT, UPDATE ON draglet.market_maker TO 'api_backend'@'localhost'; GRANT SELECT, UPDATE ON draglet.shadow_order TO 'api_backend'@'localhost'; GRANT SELECT, UPDATE ON draglet.payment_request TO 'api_backend'@'localhost'; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'api_btcd'@'localhost'; GRANT SELECT, UPDATE (balance) ON draglet.account TO 'api_btcd'@'localhost'; GRANT SELECT, INSERT, UPDATE (credited) , DELETE ON draglet.account_entry TO 'api_btcd'@'localhost'; GRANT SELECT ON draglet.account_entry_type TO 'api_btcd'@'localhost'; GRANT SELECT, INSERT, UPDATE(registered_on_daemon) ON draglet.account_number TO 'api_btcd'@'localhost'; GRANT SELECT, INSERT ON draglet.chart_category TO 'api_btcd'@'localhost'; GRANT SELECT,INSERT,UPDATE(price) ON draglet.chart_entry TO 'api_btcd'@'localhost'; GRANT SELECT ON draglet.currency TO 'api_btcd'@'localhost'; GRANT INSERT ON draglet.notification TO 'api_btcd'@'localhost'; GRANT SELECT ON draglet.user TO 'api_btcd'@'localhost'; GRANT SELECT, UPDATE (result, processed_at) ON draglet.user_action TO 'api_btcd'@'localhost'; GRANT SELECT, INSERT, UPDATE (confirmations, txid, suspended) ON draglet.transfer TO 'api_btcd'@'localhost'; GRANT SELECT ON draglet.setting TO 'api_btcd'@'localhost'; GRANT SELECT ON draglet.market TO 'api_btcd'@'localhost'; GRANT SELECT, UPDATE(actual, cleared_at), DELETE ON draglet.deep_freeze_address TO 'api_btcd'@'localhost'; GRANT SELECT ON draglet.exchange TO 'api_btcd'@'localhost'; GRANT SELECT,INSERT,DELETE ON draglet.wallet_condition TO 'api_btcd'@'localhost';

save the file and run: mysql -u root -p draglet < /home/cx-components/privileges.sql

2.3.4. Finalize web-setup

Install assets, make cache and logs writable for the Apache process: /home/cx-components/cx-admin/app/console assetic:dump chmod 777 /home/cx-components/cx-admin/app/logs/ \ /home/cx-components/cx-admin/app/cache/

2.3.5. Setup Apache VHost

Create the Apache VHost file for cxAdmin. The following occurrences of <vhost-name> should be replaced with cxClient's vhost with additional "admin”. Example: new-exchange.draglet.com -> admin.new-exchange.draglet.com Create the file /etc/apache2/sites-available/<vhost-name>.conf. <VirtualHost *:80>

 DocumentRoot /home/cx-components/cx-admin/web
 ServerName <vhost-name>
 # for production environment set prod
 # for test environment set test
 # for develop environment set dev
 SetEnv CX_ENV test
 <Directory /home/cx-components/cx-admin/web>
   Options FollowSymLinks
   AllowOverride All
   Require all granted
   # apache 2.2:
  1. Order allow,deny
  2. allow from all
 </Directory>
 ErrorLog ${APACHE_LOG_DIR}/<vhost-name>-error.log
 LogLevel warn
 CustomLog ${APACHE_LOG_DIR}/<vhost-name>-access.log combined

</VirtualHost> Activate the new VHost and restart Apache: cd /etc/apache2/sites-enabled/ ln -s ../sites-available/<vhost-name>.conf . /etc/init.d/apache2 restart

2.3.6. Create initial admin account(s)

Make up account credentials to access cx-Admin [user]/[password]. To create an admin user (put real_name into double quotes if necessary): /home/cx-components/cx-admin/app/console \ draglet:admin:create-user [user] [real_name] [password] Repeat step if necessary. To change the password of an existing admin user: /home/cx-components/cx-admin/app/console \ draglet:admin:change-password [user] [password]

2.3.7. Manual configuration steps

Add fiat currencies in table currency. If you insert currencies, which are not licensed, to the database, markets involving this currencies will not work and orders will not get executed. Please ask you system provider to inform which currencies are valid within your current license. Example for currencies BTC and EUR: mysql -u root -p -e \ "INSERT INTO draglet.currency (id, name, type_id, wanted_confirmations) \ VALUES ('BTC', 'Bitcoin', '2', '6');"

mysql -u root -p -e \ "INSERT INTO draglet.currency (id, name, type_id, deposit_text) \ VALUES ('USD', 'US Dollar', '1', 'Please change the deposit text in the back office application');" Change entries of table setting to reflect the new setup by replacing "my-exchange" with the name of the new exchange. The installIdent will be visible in the chart names. It is important, that the values for “installIdent” as well as “baseUrl” exactly match your license file. So please compare the values which you enter for this fields with the ones from you license file before manipulating the database. If different values will be detected, the system will not work. There are some examples, how to modify the settings table, as follows. UPDATE setting SET value='support@<your-exchange>' WHERE id='mailToSupport'; UPDATE setting SET value='admin@<your-exchange>' WHERE id='mailToTech'; UPDATE setting SET value='admin@<your-exchange>' WHERE id='mailToVaultmaster'; UPDATE setting SET value='noreply@<your-exchange>' WHERE id='mailFromEmail '; UPDATE setting SET value='<your-exchange-indent>' WHERE id='installIdent'; UPDATE setting SET value='<your-exchange-base-url>' WHERE id='baseUrl'; UPDATE setting SET value='<your-name>' WHERE id='mailFromName';

Update e-mail templates in the settings table with new exchange name and remove the bootcamp texts.

2.3.8. Setup charts-generator service

Create a new service in daemontools and halt it. cd /etc/service mkdir charts-generator Stop the new service. The following command should not produce any output. Re-run the command until no output is shown. svc -d charts-generator Create /etc/service/charts-generator/run file with content (replace -e test with -e prod for production systems):

  1. !/bin/sh

exec setuidgid www-data /usr/bin/env php \ /home/cx-components/cx-admin/app/console \ draglet:service:charts-updater --no-debug -e test Make the run file executable and start the service: chmod +x /etc/service/charts-generator/run svc -u charts-generator Validate if the service is running correctly. Therefore execute the following command. ps -ef | grep charts-updater

Make sure a line like this appears. php /home/cx-components/cx-admin/app/console draglet:service:charts-updater

2.3.9. Setup frontend-broker service

Create a new service in daemontools and halt it. cd /etc/service mkdir frontend-broker Stop the new service. The following command should not produce any output. Re-run the command until no output is shown. svc -d frontend-broker Create /etc/service/frontend-broker/run file with content (replace -e test with -e prod for production systems):

  1. !/bin/sh

exec setuidgid www-data /usr/bin/env php \ /home/cx-components/cx-admin/app/console \ draglet:service:broker --no-debug -e test Make the run files executable and start the service: chmod +x /etc/service/frontend-broker/run svc -u frontend-broker Validate if the service is running correctly. Therefore execute the following command. ps -ef | grep broker

Make sure a line like this appears. php /home/cx-components/cx-admin/app/console draglet:service:broker

2.3.10. Setup orderbook service

Create a new service in daemontools and halt it. cd /etc/service mkdir orderbook-service Stop the new service. The following command should not produce any output. Re-run the command until no output is shown. svc -d orderbook-service Create /etc/service/orderbook-service/run file with content (replace -e test with -e prod for production systems):

  1. !/bin/sh

exec setuidgid www-data /usr/bin/env php \ /home/cx-components/cx-admin/app/console \ draglet:service:orderbook --no-debug -e test Make the run files executable and start the service: chmod +x /etc/service/orderbook-service/run svc -u orderbook-service Validate if the service is running correctly. Therefore execute the following command. ps -ef | grep orderbook

Make sure a few lines like this appears. php /home/cx-components/cx-admin/app/console draglet:service:orderbook

2.4. Install cxServer

2.4.1. Unpack cxServer

cd /home/cx-components tar jxf cx-server-3.5.0.tar.bz2 ln -s /home/cx-components/cx-server-3.5.0 /home/cx-components/cx-server

2.4.2. Set component parameters

execute: cp /home/cx-components/cx-server/app/config/parameters.yml.dist /home/cx-components/cx-server/app/config/parameters.yml and then edit /home/cx-components/cx-server/app/config/parameters.yml to match your environment and set the correct path to the license file.

2.4.3. Finalize web-setup

Make cache and logs writable for the Apache process chmod 777 /home/cx-components/cx-server/app/logs/ /home/cx-components/cx-server/app/cache/

2.5. Install crypto daemons

2.5.1. Add a user for running the crypto daemons and give him access to /home/secret/

adduser cryptodaemon mkdir -p /home/secret chgrp cryptodaemon /home/secret The details of the new user can be empty. IMPORTANT: Make sure to use the latest stable version and modify these commands accordingly. For each crypto daemon, setup one service job in daemontools. This example will setup the Bitcoin daemon version 0.11.2 downloaded from https://bitcoin.org/en/download This should apply to all crypto-currencies. More can be downloaded from: https://litecoin.org/ http://dogecoin.com/ (Dogecoin Core 64bit) These additional crypto daemons are optional.

2.5.2. Additional packages required when compiling additional crypto daemons

NOTE: These are required only, when compiling from source. apt-get install build-essential libssl-dev libdb-dev libdb++-dev libboost-all-dev libqrencode-dev

2.5.3. Download, extract and install daemon to local directory

cd /home/cryptodaemon mkdir bin .bitcoin wget https://bitcoin.org/bin/bitcoin-core-0.11.2/bitcoin-0.11.2-linux64.tar.gz tar zxf bitcoin-0.11.2-linux64.tar.gz ln -s /home/cryptodaemon/bitcoin-0.11.2/bin/bitcoind /home/cryptodaemon/bin

2.5.4. Configure crypto daemon

Generate a random RPC password pwgen 40 1 Create /home/cryptodaemon/.bitcoin/bitcoin.conf as follows testnet=1 mempoolexpiry=1 rpcthreads=2 rpcuser=bitcoinrpc rpcpassword=<40-char-random-string-generated-above> Give ownership to config .bitcoin directory to proper user: chown -R cryptodaemon:cryptodaemon /home/cryptodaemon/.bitcoin

2.5.5. Create daemontool service

cd /etc/service mkdir daemon-btcd Stop the new service. The following command should not produce any output. Re-run the command until no output is shown. svc -d daemon-btcd Create /etc/service/daemon-btcd/run:

  1. !/bin/bash

exec setuidgid cryptodaemon /home/cryptodaemon/bin/bitcoind \ -datadir=/home/cryptodaemon/.bitcoin/ Make it executable and start the service: chmod +x /etc/service/daemon-btcd/run svc -u daemon-btcd

2.5.6. Unpack cxWallet

cd /home/cx-components tar jxf cx-wallet-3.5.0.tar.bz2 ln -s /home/cx-components/cx-wallet-3.5.0 /home/cx-components/cx-wallet

2.5.7. Set component parameters

execute: cp /home/cx-components/cx-wallet/app/config/parameters.yml.dist \ /home/cx-components/cx-wallet/app/config/parameters.yml and then edit /home/cx-components/cx-wallet/app/config/parameters.yml to match your environment and set the correct path to the license file. Also edit key "wallets" in /home/cx-components/cx-wallet/app/config/parameters.yml with the connection details created above, as in the following example:

   wallets:
       BTC:
           port: 18332
           username: bitcoinrpc
           password: <rpcpassword from /home/cryptodaemon/.bitcoin/bitcoin.conf>
       LTC:
           port: 19332
           username: litecoinrpc
           password: <rpcpassword from .litecoin.conf>

IMPORTANT: Currency codes ("BTC" and "LTC" in this example) have to match the database column currency.id.

2.5.8. Test daemon connection

Test connection setup by using: /home/cx-components/cx-wallet/app/console draglet:talk-crypto <currency-code> In the interactive shell, use "getblockcount" or "getinfo" and verify the daemon answers. Note: Some daemons will not answer to RPC requests, before the block chain is completely synced. In case of connection problems (CommunicatorException): make sure the daemon process is actually running (i.e. the daemontools service is starting it) make sure connection details are correct (username and password) make sure the port number is correct for the daemon (every currency uses a different rpc port and testnet installations usually use a port different from mainnet)

2.5.9. Create key-pair for encrypted user actions

Create a directory and place public/private key-pair there. mkdir -p /home/secret/certs/users chmod 710 /home/secret/certs chgrp www-data /home/secret/certs cd /home/secret/certs/ openssl genrsa -out btcd.pri 4096 openssl rsa -in btcd.pri -pubout -out ua-pubkey.pem ua-pubkey.pem is the public key. It is required for cxServer. btcd.pri is the private key. It is required for cxWallet. IMPORTANT: Copy ua-pubkey.pem to /home/secret/certs/ua-pubkey.pem to any server running cxServer.

2.5.10. Add cxWallet service

cd /etc/service mkdir wallet-service Stop the new service. The following command should not produce any output. Re-run the command until no output is shown. svc -d wallet-service Create /etc/service/wallet-service/run for TEST (replace -e test with -e prod for production systems):

  1. !/bin/sh

exec /usr/bin/env php /home/cx-components/cx-wallet/app/console \ draglet:service:crypto-communicator --no-debug -e test Make it executable and start the service: chmod +x /etc/service/wallet-service/run svc -u wallet-service Validate if the service is running correctly. Therefore execute the following command. ps -ef | grep crypto-communicator

Make sure a few lines like this appears. php /home/cx-components/cx-wallet/app/console draglet:service:crypto-communicator


2.6. Install cxEngine

2.6.1. Unpack cxEngine

cd /home/cx-components tar jxf cx-engine-3.5.0.tar.bz2 ln -s /home/cx-components/cx-engine-3.5.0 /home/engine

2.6.2. Configure engine

Create /home/engine/draglet.yml with the following content. Then replace and edit the values of the content with your details. user: api_backend passwd: <api_backend_password> connection_url: "jdbc:mysql://127.0.0.1:3306/draglet?serverTimezone=Europe/Berlin" driver_class: "com.mysql.jdbc.Driver" market_poll_interval: "5000" matcher_sleep_time: "100" fetcher_sleep_time: "3000" engine_remex_socket_connection: "tcp://127.0.0.1:5517" engine_publisher_socket_connection: "tcp://127.0.0.1:38905" engine_server_socket_connection_base: "tcp://0.0.0.0:38920" remex_publisher_socket_connection: "tcp://127.0.0.1:38907" orderbook_service_socket_connection: "tcp://127.0.0.1:38909" broker_socket_connection: "tcp://127.0.0.1:38903" remex_inproc_socket_connection: "tcp://127.0.0.1:38910" last_quote_writer_timeout: "60000" engine_inproc_socket_connection: "inproc://engine" fetcher_inproc_socket_connection: "inproc://fetcher" ioc_inproc_socket_connection: "inproc://ioc" dso_client_certs_path: "/home/certs/client-certs/" ignore_http_host: "true" maker_order_synchronizer_sleep_time: "600000" connection_pool_size: "60" merchant_inproc_socket_connection: "inproc://merchant" merchant_publisher_socket_connection: "tcp://127.0.0.1:38911" shaba_inproc_socket_connection: "tcp://127.0.0.1:38919" shaba_publisher_socket_connection: "tcp://127.0.0.1:38913" confidence_check_url: "https://chain.so/api/v2/get_confidence/BTCTEST/"

  1. PROD: confidence_check_url: "https://chain.so/api/v2/get_confidence/BTC/"

balser_valid_period: "300" balser_server_socket_connection: "tcp://0.0.0.0:38908" balser_client_socket_connection: "tcp://127.0.01:38908" executor_client_count: "3" engine_balser_inproc_socket_connection: "inproc://engine_balser" engine_balser_timeout: "3000" license_file_path: "/home/license/license.pem" icinga_base_path: "/tmp/ic-services"

2.6.3. Create daemontools service

Create engine service and stop the new service. The following command should not produce any output. Re-run the command until no output is shown. cd /etc/service mkdir engine svc -d engine Create /etc/service/engine/run with following content (replace <machine name>). Omit engine modules that are not required on the server that you are about to set up. Module name jar file jvm parameter engine draglet-engine-1.0-SNAPSHOT.jar com.draglet.batch.EngineMarketAdmin remote draglet-remote-1.0-SNAPSHOT.jar com.draglet.batch.RemoteExecutorMarketAdmin mapu draglet-mapu-1.0-SNAPSHOT.jar com.draglet.batch.MapuAdmin balser draglet-balser-1.0-SNAPSHOT.jar com.draglet.batch.BalserAdmin shaba draglet-shaba-1.0-SNAPSHOT.jar com.draglet.batch.ShabaAdmin meba draglet-meba-1.0-SNAPSHOT.jar com.draglet.batch.MerchantAdmin

  1. !/bin/bash

export LD_LIBRARY_PATH=/opt/jzmq-3.1.0/lib cd /home/engine && exec java -Xss256k -cp \ /opt/jzmq-3.1.0/share/java/zmq.jar:lib/*:draglet-common-1.0-SNAPSHOT.jar\ draglet-balser-1.0-SNAPSHOT.jar:draglet-engine-1.0-SNAPSHOT.jar:\ draglet-remote-1.0-SNAPSHOT.jar:draglet-mapu-1.0-SNAPSHOT.jar:\ draglet-shaba-1.0-SNAPSHOT.jar:draglet-meba-1.0-SNAPSHOT.jar \ -Dlog4j.configurationFile=log4j2.xml -DisThreadContextMapInheritable=true \ com.draglet.batch.Batch draglet.yml com.draglet.batch.BalserAdmin \ com.draglet.batch.ShabaAdmin com.draglet.batch.MapuAdmin \ com.draglet.batch.EngineMarketAdmin com.draglet.batch.RemoteExecutorMarketAdmin \ com.draglet.batch.MerchantAdmin 50

Make the run file executable and start the services: chmod +x engine/run svc -u engine Validate if the service is running correctly. Therefore execute the following command. ps -ef | grep java

Make sure a line like this appears. java -Xss256k -cp /opt/jzmq-3.1.0/share/java/zmq.jar:lib/*:draglet-balser-1.0-SNAPSHOT.jar:draglet-engine-1.0-SNAPSHOT.jar:draglet-remote-1.0-SNAPSHOT.jar:draglet-mapu-1.0-SNAPSHOT.jar:draglet-shaba-1.0-SNAPSHOT.jar -Dlog4j.configurationFile=log4j2.xml -DisThreadContextMapInheritable=true com.draglet.batch.Batch draglet.yml com.draglet.batch.BalserAdmin com.draglet.batch.ShabaAdmin com.draglet.batch.MapuAdmin com.draglet.batch.EngineMarketAdmin com.draglet.batch.RemoteExecutorMarketAdmin 50


2.7. Install cxClient

2.7.1. Unpack cxClient

cd /home/cx-components tar jxf cx-client-3.5.0.tar.bz2 ln -s /home/cx-components/cx-client-3.5.0 /home/web cd /home/web chgrp -R www-data * .htaccess

2.7.2. Setup Apache Vhost

Create the Apache VHost file for cxCLient. The following occurrences of <vhost-name> should be replaced with cxClient's vhost. Example: new-exchange.draglet.com Create the file /etc/apache2/sites-available/<vhost-name>.conf. <VirtualHost *:80>

       DocumentRoot /home/web
       ServerName <vhost-name>
       SetEnv API_PATH "/home/cx-components/cx-server/"
       # for production environment set prod
 	  # for test environment set test
       # for develop environment set dev
       SetEnv CX_ENV test
       <Directory /home/web>
           Options FollowSymLinks
           AllowOverride All
           Require all granted
       </Directory>
       ErrorLog ${APACHE_LOG_DIR}/<vhost-name>-error.log
       LogLevel warn
       CustomLog ${APACHE_LOG_DIR}/<vhost-name>-access.log combined

</VirtualHost>

2.7.3. Activate VHost and restart Apache

cd /etc/apache2/sites-enabled/ ln -s ../sites-available/<vhost-name>.conf . /etc/init.d/apache2 restart

2.8. Component update

The update process is the same as the installation process. After downloading and unpacking the draglet installation file compare the component versions to the downloaded versions. Only for the components that have changed rerun the installation process.


3. Initial setup

3.1. Setup account holders

Within a market setup, some system users for price differences and fees, the so called “Account holders”, have to be defined. This users get charged price or fee difference which may occur within remote executions at a liquidity provider. Furthermore the specified users get credited the fees which are paid by customers. After a user was created using cxClient, the following sql commands might have to be executed to manual set the user enabled. UPDATE user set enabled = 1 WHERE email ='<the users email address>';

3.2. Setup market makers

To set up a market market, the specific market has to be licensed. A market maker could be edited via cx-Admin by click on the target symbol at the actions area in market overview. To create a market maker, it has to be inserted into the database directly using following query. INSERT INTO market_maker (market_id, maker_active, taker_active, base_price_definer, orders_per_side, min_volume_limit, offset_strategy) VALUES (<your_market_id>,

<1=makers are active,
0=markers are not active>,

<1=takers are active, 0=takers are not active>, <'chart'=the current chart value will be used as base price, 'fixed'=a fixed price will be used as base price >, <number of orders that will be inserted at bid and ask side>, <the minimum volume of an order, multiplied with 1e8>, <'absolute'=the limit difference between two orders will be absolute, 'percentages'=the limit difference between two orders is percentage based >);

To configure the market maker, the field “offset_strategy_config” as well as the field “base_price_definer_config” are used. Therefore, json formated data has to be inserted into the corresponding fields, like in the following examples. UPDATE market_maker SET offset_strategy_config= ' {"offset": <your offset like 0.15 for 0.15 %(percentaged) or 0.15 (absolute)>} ' WHERE market_id = <the corresponding market id>;

UPDATE market_maker SET base_price_definer_config= ' {"price": <your base price like 5 (fixed)>} ' WHERE market_id = <the corresponding market id>; Please note that the field “base_price_definer_config” should only be filled if the base_price_definer “fixed” is chosen. Futhermore, the market maker api path has to be configured. Therefore edit the file /home/cx-admin/app/config/parameters.yml and insert the value for the parameter “market_maker_api”. The parameter represents the protocol and the first part of the draglet api like the following example. market_maker_api: 'http://<your exchange>/gateway'

Within the next step the market maker user has to be configured in the settings table. To achieve this, a new system user has to be created. This user will be chosen if an order will be placed. UPDATE setting SET value='<market maker email>' WHERE id='marketMakerUser'; UPDATE setting SET value='<market maker password>' WHERE id='marketMakerPass';

To activate the market taker, the taker user and password has to configured in the settings table as well. UPDATE setting SET value='<market taker email>' WHERE id='marketTakerUser'; UPDATE setting SET value='<market taker password>' WHERE id='marketTakerPass'; To start the market makers create the file /etc/cron.d/maker with the following content (replace -e test with -e prod for production systems).

  1. market maker
  • /3 * * * * www-data /usr/bin/env php /home/cx-components/cx-admin/app/console draglet:cron:market-maker -e test
  • * * * * www-data /usr/bin/env php /home/cx-components/cx-admin/app/console draglet:cron:market-taker -e test


4. Exchange maintenance

4.1. cxAdmin logs

cxAdmin logs are located in /home/cx-components/cx-admin/app/logs. For test installations (as configured in 2.3.5, 2.3.8, 2.3.9 and 2.3.10) the name of the log is test.log. For prod installations it is prod.log.

4.2. cxServer logs

cxServer logs are located in /home/cx-components/cx-server/app/logs. For test installations (as configured together with cxClient in 2.7.2) the name of the log is test.log. For prod installations it is prod.log.

4.3. cxWallet logs

cxWallet logs are located in /home/cx-components/cx-wallet/app/logs. For test installations (as configured in 2.5.10) the name of the log is test.log. For prod installations it is prod.log.

4.4. cxEngine logs

cxEngine logs are located in /home/engine/logs. Each engine module writes separate logs. engine.log has orderbook information and (remote-)trade executions. balser.log has account locking information. shaba.log and mapu.log have DSO publishing and execution information. fetcher.log provides polling information from non-draglet exchanges. meba.log shows informations concerning merchant backend.

4.5. cxClient logs

The client logs to the Javascript console of the browser.

4.6. Operator mails

In case of system failures the component send e-mails to the address configured in 1.3.8.

4.7. Add currency

After executing one of the SQLs below wait for 10 min. until the chart updater process has created the chart categories. If you insert currencies, which are not licensed, to the database, markets involving this currencies will not work and orders will not get executed. Please ask you system provider to inform which currencies are valid within your current license.

4.7.1. Fiat currency

Replace USD and US Dollar in this script with the currency you are creating: INSERT INTO draglet.currency (id, name, type_id, deposit_text) VALUES ('USD', 'US Dollar', '1', 'Please change the deposit text in the back office application'); INSERT INTO account (user_id, currency_id, balance) SELECT id, 'USD', 0 FROM user;

4.7.2. Crypto currency

Replace BTC and Bitcoin in this script with the currency you are creating: INSERT INTO draglet.currency (id, name, type_id, wanted_confirmations) VALUES ('BTC', 'Bitcoin', '2', '6');

4.8. Add language

If you insert languages, which are not licensed, to the database, services involving this languages will not work. Please ask you system provider to inform which languages are valid within your current license. Replace pl and Polski in this script with the language you want to set up. The individual e-mail texts are edited in the cxAdmin interface: INSERT INTO `language`(`id`, `name`, `active`) VALUES ('pl','Polski',1) INSERT INTO `email` (`ident`, `language`, `mime_type`, `subject`, `content`) VALUES ('account_deleted', 'pl', 'text/plain', 'Account at <exchange>.com deleted', 'we have deleted your user account as requested.\n\nWe hope to see you again in the future.'), ('mail_change', 'pl', 'text/plain', 'New email address at <exchange>.com', 'You requested to change your email address. Please confirm your new email address by clicking the following link:\nTemplate:Link\n\nIf you do not wish to change your current email address, please ignore this mail - the link provided is only valid for 24 hours.'), ('mail_changed', 'pl', 'text/plain', 'Email address changed', 'You have successfully confirmed your new email address.\n\nWe will only use this new email address for contacting you in the future.'), ('password_change', 'pl', 'text/plain', 'Password change at <exchange>.com', 'we received a request to reset your password.\n\nIf you want to reset your password, please click on the following link and set your new password:\n\nTemplate:Link\n\nPlease note that the link only remains valid for one hour.\nIn case you do not want to reset your password, simply ignore this email - no actions will be taken.'), ('payment_canceled', 'pl', 'text/plain', 'payment canceled', 'A payment of Template:AmountBTC Template:CryptoCurrencyCode (Template:AmountFiat Template:FiatCurrencyCode) for the reference Template:ReferenceId received at Template:ReceivedTime was canceled.\nRisk option: Template:RiskOption.\nThe transaction id is Template:TransactionId. It has Template:Confirmations confirmations and requires Template:WantedConfirmations confirmations.'), ('payment_confirmed', 'pl', 'text/plain', 'payment confirmed', 'A payment of Template:AmountBTC Template:CryptoCurrencyCode (Template:AmountFiat Template:FiatCurrencyCode) for the reference Template:ReferenceId received at Template:ReceivedTime was confirmed.\nRisk option: Template:RiskOption.\nThe transaction id is Template:TransactionId. It has Template:Confirmations confirmations and requires Template:WantedConfirmations confirmations.'), ('payment_received', 'pl', 'text/plain', 'payment received', 'A payment of Template:AmountBTC Template:CryptoCurrencyCode (Template:AmountFiat Template:FiatCurrencyCode) for the reference Template:ReferenceId was received at Template:ReceivedTime.\nRisk option: Template:RiskOption.\nThe transaction id is Template:TransactionId. It has Template:Confirmations confirmations and requires Template:WantedConfirmations confirmations.'), ('registration', 'pl', 'text/plain', 'Your registration at <exchange>.com', 'Thank you for your registration for <exchange>.\r\n\r\nIn order to complete your registration, please confirm your e-mail address through the following link:\r\n\r\nTemplate:Link\r\n\r\nAfter activating the link, the registration process should be completed and your account is ready to use.\r\n\r\nIn case you did not try to register with your e-mail address, simply ignore this e-mail. If the registration process is incomplete, we will delete your data after a 24 hours.\r\n\r\n'), ('request_delete', 'pl', 'text/plain', 'Account deletion request at <exchange>.com', 'You have requested to delete your user account. Please click the following link to confirm the deletion:\nTemplate:Link\n\nIf you do not want to delete your account, simply ignore this email. The link provided is only valid for one hour.'), ('two_factor', 'pl', 'text/plain', '2-Factor Code', 'we hereby send your requested 2-Factor authentication code.\n\nYour code is: Template:Code\n\nIf you did not interact with our website in a way, that requires seperate authentication, please contact us immediately.'), ('welcome', 'pl', 'text/plain', 'Welcome to <exchange>.com', 'thank you very much for your registration to <exchange>.\r\n\r\nTemplate:Link\r\n\r\nThe registration process has been completed, you are now enabled to log in to your account.\r\n\r\nWe hope you will enjoy a great and hopefully successful time with <exchange>!'); INSERT INTO `setting` (`id`, `modified_by_id`, `value`, `type`, `description`, `version`, `modified_at`, `editable`, `license_option`) VALUES ('mailLayout_pl_text-plain', 1, 'Dear customer,\r\n\r\n{% block content %}{% endblock %}\r\n\r\nBest regards,\r\nyour <exchange> team.\r\n\r\n--\r\ninfo@<exchange>.com', 'textarea', 'text/plain Layout for emails in polish', 4, '2014-12-03 10:11:09', 0, NULL);

In addition to these scripts you have to copy the files labels-locale_en.js and messages-locale_en.js in the i10n folder. In this example they would be copied to labels-locale_pl.js and messages-locale_pl.js. Edit them labels-locale_pl.js and messages-locale_pl.js to start with: var labelsLocale_pl = { var messagesLocale_pl = {


5. Connect a market to the DSO

5.1. Create subdomain

In order to run the DSO on your exchange you need a new subdomain dso.<yourexchange> that works with SSL because client authentication in the DSO is certificate based. Create a self signed SSL certificate for the dso vhost with openssl. Therefore, firstly create the folder /home/certs/. This folder is dedicated for storing the certificates. mkdir /home/certs

Then navigate to the folder and execute the following commands. Please fill in reasonable details when prompted for country, company, passwords etc by the wizard. Please enter dso.<yourexchange> as common name when prompted.

cd /home/certs openssl genrsa -des3 -out dso.key 2048 openssl req -new -key dso.key -out dso.csr cp dso.key dso.key.org openssl rsa -in dso.key.org -out dso.key openssl x509 -req -days 365 -in dso.csr -signkey dso.key -out dso.crt

5.2. Create vhost for subdomain

The vhost file for the new dso subdomain should look like this: ExpiresActive On ExpiresDefault "now"

<Directory /home/web/components/>

       ExpiresDefault "access plus 1 months"

</Directory> <Directory /home/web/releases/>

       ExpiresDefault "access plus 1 months"

</Directory>

<VirtualHost *:443>

 ServerName dso.<yourexchange>
 SetEnv API_PATH "/home/cx-components/cx-server/"
	    # for production environment set prod
 	  # for test environment set test
       # for develop environment set dev
 SetEnv CX_ENV prod
 SSLEngine on
 SSLCertificateFile /home/certs/dso.crt
 SSLCertificateKeyFile /home/certs/dso.key
   SSLCACertificateFile    /home/certs/client-certs/dragletCA.crt
   SSLVerifyClient         optional
   SSLVerifyDepth          1
   SSLOptions              +StdEnvVars
   SSLProtocol             all -SSLv2 -SSLv3
   SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
   SSLHonorCipherOrder     on
   SetEnvIf User-Agent ".*MSIE [1-5].*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
   SetEnvIf User-Agent ".*MSIE [6-9].*" ssl-unclean-shutdown
   # HSTS (mod_headers is required) (15768000 seconds = 6 months)
   Header always add Strict-Transport-Security "max-age=15768000"
 DocumentRoot /home/web
 <Directory /home/web>
   Options FollowSymLinks
   AllowOverride All
   Require all granted
 </Directory>
 ErrorLog ${APACHE_LOG_DIR}/dso.<yourexchange>-error.log
 LogLevel warn
 CustomLog ${APACHE_LOG_DIR}/dso.<yourexchange>-access.log combined

</VirtualHost>

If SSL isn't enabled in your apache config yet, do it now: cd /etc/apache2/mods-enabled/ ln -s ../mods-available/ssl.load . ln -s ../mods-available/ssl.conf . ln -s ../mods-available/socache_shmcb.load .

Activate the new VHost and restart Apache: cd /etc/apache2/sites-enabled/ ln -s ../sites-available/dso.<yourexchange>.conf . /etc/init.d/apache2 restart

5.3. Create market

Create the new market as explained in https://www.draglet.com/releases/release-3.2/images/dragletBackOfficeManual.pdf. The database id of the new market is referred to as <market_id> in the scripts below. Get a client certificate for the new market as well as dragletCA.crt that is referenced in the vhost file above from certificates@draglet.com. The client certificate's client-name is referred to as <new-client> in the scripts below. You need a certificate for every DSO connection of your new market. If your market receives liquidity from trust deposit and connects to two other local markets you need 3 certificates for this market in order to identify it correctly via the DSO. In this example the two other local markets also need one certificate each as described in 5.5. Create the folder /home/certs/client-certs. This folder is dedicated to store the mentioned client certificates. mkdir /home/certs/client-certs

Register a user to become the nostro account holder of your new market. The user id is referred to as <nostro_account_holder_id> in the scripts below. The nostro account will mirror your account balance on this DSO connection. The created user should be set to enabled like explained in chapter 3.1.

5.4. Connect to Trust Deposit liquidity network

Trust Deposit DSO markets must have minimum nominal set to 0.01. You can connect either to the testnet DSO using testnet Bitcoin or to the production DSO. For a testnet connection register an account with https://tf-test.draglet.com, for production register at https://www.trust-deposit.net and get KYC approval. In the script below replace URL 'https://dso.trust-deposit.net' with 'https://tf-test.draglet.com' and client name 'trust-deposit' with 'tf-test' for a testnet connection. After registering for an Trust Deposit account request a client certificate for each new market from certificates@draglet.com. Please include the information, that you want to connect to the Trust Deposit DSO (test or production). Send your registered Trust Deposit User as well as the dso subdomain dso.<your_exchange> and the the market your are connecting in your request. Check the next free id in table exchange. The exchange id is referred to as <exchange_id> in the scripts below. INSERT INTO `draglet`.`exchange` ( `id` , `nostro_accounts_holder_id` , `fee_difference_sponsor_id` , `name` , `base_path` , `driver` , `client_name` ) VALUES ( '<exchange_id>', '<nostro_account_holder_id>', '<nostro_account_holder_id>', '<new-client>', 'https://dso.trust-deposit.net', 'dso', 'trust-deposit' ); INSERT INTO `draglet`.`exchange_market` ( `id` , `exchange_id` , `market_ident` , `nominal_currency` , `limit_currency` ) VALUES ( '<exchange_id>', '<exchange_id>', 'BTC-EUR', 'BTC', 'EUR' ); INSERT INTO `draglet`.`market_conversion` ( `id` , `exchange_market_id` , `market_id` , `active` , `nominal_converter_category_id` , `limit_converter_category_id` , `nominal_conversion_inverted` , `limit_conversion_inverted` , `dso_spread` ) VALUES ( '<exchange_id>', '<exchange_id>', '<market_id>', '1', NULL , NULL, '0', '0', NULL );

5.5. Connect to another market from your own exchange

You can use this configuration option if you want to share liquidity between 2 or more markets of your exchange. This works best if a EUR or USD market is the liquidity distributor with other markets getting instant fiat conversion through the DSO. The id of the distributing market is referred to as <dist_market_id> in the scripts below. If a market is distributing liquidity to several other markets of the same exchange it identifies with a different client certificate for each connection. To connect your new market to an existing market from your own exchange you need two certificates from certificates@draglet.com: The one expained in 5.3 and another one to connect the existing market to your new market. This second client-name is referred to as <dist-client> in the scripts below. Store the certificate in /home/certs/client-certs. Find the chart category that provides the conversion rate between the previously existing market to the new one. For each fiat currency that is created the charting engine will automatically create the categories FX_EUR_<new> and FX_USD_<new>. Find the key in the database table chart_category (referred to as <chart_category_id>). Register a user to become the nostro account holder of this new connection of your previously existing market. The user id is referred to as <dist_nostro_account_holder_id> in the scripts below. Check the 2 next free ids in table exchange. The exchange ids are referred to as <exchange_id> and <dist_exchange_id> in the scripts below. Now insert two DSO connections. One from the new market to the previously existing market and one from the previously existing market to the new one. The scripts assume that the distributing market is BTC-EUR. Replace EUR with USD if your central market runs on USD : INSERT INTO `draglet`.`exchange` ( `id` , `nostro_accounts_holder_id` , `fee_difference_sponsor_id` , `name` , `base_path` , `driver` , `client_name` ) VALUES ( '<exchange_id>', '<nostro_account_holder_id>', '<nostro_account_holder_id>', '<new-client>', 'https://dso.<your_exchange>', 'dso', '<dist-client>' ); INSERT INTO `draglet`.`exchange_market` ( `id` , `exchange_id` , `market_ident` , `nominal_currency` , `limit_currency` ) VALUES ( '<exchange_id>', '<exchange_id>', 'BTC-EUR', 'BTC', 'EUR' ); INSERT INTO `draglet`.`market_conversion` ( `id` , `exchange_market_id` , `market_id` , `active` , `nominal_converter_category_id` , `limit_converter_category_id` , `nominal_conversion_inverted` , `limit_conversion_inverted` , `dso_spread` ) VALUES ( '<exchange_id>', '<exchange_id>', '<market_id>', '1', NULL, '<chart_category>', '0', '0', NULL ); INSERT INTO `draglet`.`exchange` ( `id` , `nostro_accounts_holder_id` , `fee_difference_sponsor_id` , `name` , `base_path` , `driver` , `client_name` ) VALUES ( '<dist_exchange_id>', '<dist_nostro_account_holder_id>', '<dist_nostro_account_holder_id>', '<dist-client>', 'https://dso.<your_exchange>', 'dso', '<new-client>' ); INSERT INTO `draglet`.`exchange_market` ( `id` , `exchange_id` , `market_ident` , `nominal_currency` , `limit_currency` ) VALUES ( '<dist_exchange_id>', '<dist_exchange_id>', 'BTC-EUR', 'BTC', 'EUR' ); INSERT INTO `draglet`.`market_conversion` ( `id` , `exchange_market_id` , `market_id` , `active` , `nominal_converter_category_id` , `limit_converter_category_id` , `nominal_conversion_inverted` , `limit_conversion_inverted` , `dso_spread` ) VALUES ( '<dist_exchange_id>', '<dist_exchange_id>', '<dist_market>', '1', NULL , NULL, '0', '0', NULL );


6. Colored Coins (Open Assets)

6.1. Python 3.4

Make sure Python 3.4 and Pip is installed. apt-get install python3.4 python3-pip

6.2. Run a bitcoind with txindex

1. Setup an additional bitcoind service as /etc/service/daemon-btcd-cc 2. Configure the run script to use an alternative config directory using -datadir=/home/cryptodaemon/.bitcoin-cc/ 3. Create the alternative datadir and use a bitcoin.conf file like this: testnet=1 rpcthreads=20 rpcuser=bitcoinrpc rpcpassword=<generate-a-new-40-char-passphrase> port=6035 rpcport=6036 txindex=1 server=1 4. Start the bitcoind and let it sync. Install colorcore and dependencies cd /home/cryptodaemon git clone https://github.com/OpenAssets/colorcore.git cd colorcore pip3 install --upgrade -r requirements.txt


6.3. Configure colorcore

Edit /home/cryptodaemon/colorcore/config.ini: [general]

  1. The following blockchain providers are supported:
  2. - bitcoind (default): Connects to Bitcoin Core
  3. - chain.com: Connects to the chain.com API
  4. - chain.com+bitcoind: Connects to the chain.com API, and uses Bitcoin Core for the local wallet
  5. blockchain-provider=bitcoind

[environment]

  1. For MainNet
  2. version-byte=0
  3. p2sh-version-byte=5
  4. asset-version-byte=23
  5. dust-limit=600
  6. default-fees=30000
  1. For TestNet

version-byte=111 p2sh-version-byte=196 asset-version-byte=115 dust-limit=600 default-fees=30000

[cache]

  1. Path of the cache file (use :memory: to disable)

path=cache.db

[rpc]

  1. The port on which to expose the Colorcore RPC interface

port=6060

[bitcoind]

  1. Replace username, password and port with the username, password and port for Bitcoin Core
  2. The default port is 8332 in MainNet and 18332 in TestNet

rpcurl=http://bitcoinrpc:<rpc-password-from-bitcoin.conf>@localhost:6036

[chain.com]

  1. Enable those settings to use the lightweight mode (chain.com blockchain provider)
  2. base-url=https://api.chain.com/v1/bitcoin/
  3. api-key-id=<get an API key from chain.com>
  4. secret=<get an API serect from chain.com>

6.4. Create service for colorcore daemon

Create the service directory and stop the service. cd /etc/service mkdir daemon-coco svc -d daemon-coco Create the run script /etc/service/daemon-coco/run.

  1. !/bin/bash

cd /home/cryptodaemon/colorcore && exec python3 colorcore.py server Make it executable and start the service: chmod +x daemon-coco/run svc -u daemon-coco

6.5. Enable license option in cxAdmin

Enable the license key "assets" in cxAdmin.

6.6. Configure colorcore in cxWallet

Add to parameters.yml in cxWallet:

   colorcore:
       port: 6036
       username: bitcoinrpc
       password: <rpc-password-from-bitcoin.conf>
       colorport: 6060