├── test ├── preinstall │ └── alpine:edge ├── test.sh └── test_with_docker.sh ├── distributions ├── CentOSLinux.sh ├── DebianGNULinux.sh ├── base-debianoid.sh ├── base-systemd.sh ├── Fedora.sh ├── base-compile-rocksdb.sh ├── base-conda.sh ├── Ubuntu.sh ├── base-rhel.sh ├── README.md ├── AlpineLinux.sh └── base.sh ├── .travis.yml ├── bootstrap.sh ├── README.md ├── install.sh └── LICENSE /test/preinstall/alpine:edge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | apk update 3 | apk add bash git 4 | -------------------------------------------------------------------------------- /distributions/CentOSLinux.sh: -------------------------------------------------------------------------------- 1 | if [ "$VERSION_ID" != "7" ]; then 2 | warning "Only the latest version (CentOS 7) is officially supported (but this might work)" 3 | fi 4 | 5 | . distributions/base-rhel.sh 6 | -------------------------------------------------------------------------------- /test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd /tmp/electrumx-installer/electrumx-installer 4 | 5 | if [ -e "./test/preinstall/$IMAGE" ]; then 6 | "./test/preinstall/$IMAGE" 7 | fi 8 | 9 | ./install.sh 10 | electrumx_server 11 | 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | language: bash 4 | 5 | services: 6 | - docker 7 | 8 | before_install: 9 | - docker -v 10 | 11 | script: 12 | - test/test_with_docker.sh 13 | 14 | env: 15 | - IMAGE="ubuntu:16.04" 16 | - IMAGE="fedora:28" 17 | - IMAGE="debian:8" 18 | - IMAGE="centos:7" 19 | - IMAGE="debian:9" 20 | - IMAGE="ubuntu:18.04" 21 | -------------------------------------------------------------------------------- /test/test_with_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "docker run -v $(pwd)/..:/tmp/electrumx-installer $IMAGE /tmp/electrumx-installer/electrumx-installer/test/test.sh" 3 | docker run -e IMAGE=$IMAGE -v $(pwd)/..:/tmp/electrumx-installer $IMAGE /tmp/electrumx-installer/electrumx-installer/test/test.sh 2>&1 | tee /tmp/$$.log 4 | if grep -q "required envvar" /tmp/$$.log; then 5 | echo "Success" 6 | exit 0 7 | fi 8 | exit 1 9 | -------------------------------------------------------------------------------- /distributions/DebianGNULinux.sh: -------------------------------------------------------------------------------- 1 | if [ "$VERSION_ID" != "8" && "$VERSION_ID" != "9" ]; then 2 | _warning "Only Debian Stretch and Jessie are officially supported (but this might work)" 3 | fi 4 | 5 | . distributions/base.sh 6 | . distributions/base-systemd.sh 7 | . distributions/base-debianoid.sh 8 | . distributions/base-compile-rocksdb.sh 9 | . distributions/base-conda.sh 10 | 11 | APT="apt-get" 12 | 13 | function install_leveldb { 14 | $APT install -y libleveldb-dev build-essential || _error "Could not install packages" 1 15 | } 16 | -------------------------------------------------------------------------------- /distributions/base-debianoid.sh: -------------------------------------------------------------------------------- 1 | APT="apt-get" 2 | 3 | function install_git { 4 | $APT install -y git || _error "Could not install packages" 5 | } 6 | 7 | function install_script_dependencies { 8 | $APT update 9 | $APT install -y openssl wget || _error "Could not install packages" 10 | } 11 | 12 | function install_rocksdb_dependencies { 13 | $APT install -y libsnappy-dev zlib1g-dev libbz2-dev libgflags-dev || _error "Could not install packages" 14 | } 15 | 16 | function install_compiler { 17 | $APT update 18 | $APT install -y bzip2 build-essential gcc || _error "Could not install packages" 19 | } -------------------------------------------------------------------------------- /distributions/base-systemd.sh: -------------------------------------------------------------------------------- 1 | function install_init { 2 | if [ ! -d /etc/systemd/system ]; then 3 | _error "/etc/systemd/system does not exist. Is systemd installed?" 8 4 | fi 5 | cp /tmp/electrumx/contrib/systemd/electrumx.service /etc/systemd/system/electrumx.service 6 | cp /tmp/electrumx/contrib/systemd/electrumx.conf /etc/ 7 | if [ $USE_ROCKSDB == 1 ]; then 8 | echo -e "\nDB_ENGINE=rocksdb" >> /etc/electrumx.conf 9 | fi 10 | systemctl daemon-reload 11 | systemctl enable electrumx 12 | systemctl status electrumx 13 | _info "Use service electrumx start to start electrumx once it's configured" 14 | } 15 | -------------------------------------------------------------------------------- /distributions/Fedora.sh: -------------------------------------------------------------------------------- 1 | . distributions/base-rhel.sh 2 | 3 | export PYTHONUSERBASE=/usr/local/lib/python3.6/site-packages 4 | 5 | if [ "$VERSION_ID" != "28" ]; then 6 | warning "Only the latest version (Fedora 28) is officially supported (but this might work)" 7 | fi 8 | 9 | has_rocksdb_binary=1 10 | newer_rocksdb=1 11 | 12 | function binary_install_rocksdb { 13 | dnf -y install redhat-rpm-config python3-devel snappy-devel zlib-devel rocksdb-devel lz4-devel bzip2-devel gflags-devel gcc-c++ gcc || _error "Unable to install rocksdb" 1 14 | } 15 | 16 | function binary_uninstall_rocksdb { 17 | $APT remove -y rocksdb rocksdb-devel || _error "Could not remove rocksdb" 1 18 | } 19 | 20 | -------------------------------------------------------------------------------- /distributions/base-compile-rocksdb.sh: -------------------------------------------------------------------------------- 1 | function install_rocksdb { 2 | if ! declare -f install_rocksdb_dependencies > /dev/null; then 3 | _error "install_rocksdb_dependencies needs to be declared in order to use compile-rocksdb/install_rocksdb" 3 4 | fi 5 | install_rocksdb_dependencies 6 | _DIR=$(pwd) 7 | # First, install rocksdb 8 | _info "Loading RocksDB source" 9 | git clone https://github.com/facebook/rocksdb.git /tmp/rocksdb 10 | cd /tmp/rocksdb 11 | # Of course pyrocksdb wouldn't be pyrocksdb if it supported the latest version 12 | git checkout v4.5.1 13 | _info "Compiling RocksDB... This will take a while." 14 | make shared_lib -j 2 || _error "Could not compile rocksdb" 1 15 | make install-shared INSTALL_PATH=/usr || _error "Could not install rocksdb" 1 16 | cd "$_DIR" 17 | } -------------------------------------------------------------------------------- /distributions/base-conda.sh: -------------------------------------------------------------------------------- 1 | # This should be sourced after base.sh! 2 | 3 | eval "base_$(declare -f install_electrumx)" 4 | function install_electrumx { 5 | base_install_electrumx 6 | # We installed to /opt/python, so link it to $PATH 7 | ln -s /opt/python/bin/electrumx* /usr/local/bin/ 8 | } 9 | 10 | function install_python37 { 11 | if ! declare -f install_compiler > /dev/null; then 12 | _error "install_compiler needs to be declared in order to use conda/install_python37" 3 13 | fi 14 | install_compiler 15 | wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /tmp/conda.sh || _error "while getting conda" 1 16 | bash /tmp/conda.sh -b -p /opt/python 17 | /opt/python/bin/conda install python=3.7 18 | ln -s /opt/python/bin/python3 /usr/local/bin/python3.7 19 | } -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -d ~/.electrumx-installer ]; then 3 | echo "~/.electrumx-installer already exists." 4 | echo "Either delete the directory or run ~/.electrumx-installer/install.sh directly." 5 | exit 1 6 | fi 7 | if which git > /dev/null 2>&1; then 8 | git clone https://github.com/EasyX-Community/electrumx-installer ~/.electrumx-installer 9 | cd ~/.electrumx-installer/ 10 | else 11 | which wget > /dev/null 2>&1 && which unzip > /dev/null 2>&1 || { echo "Please install git or wget and unzip" && exit 1 ; } 12 | wget https://github.com/EasyX-Community/electrumx-installer/archive/master.zip -O /tmp/electrumx-master.zip 13 | unzip /tmp/electrumx-master.zip -d ~/.electrumx-installer 14 | rm /tmp/electrumx-master.zip 15 | cd ~/.electrumx-installer/electrumx-installer-master/ 16 | fi 17 | if [[ $EUID -ne 0 ]]; then 18 | which sudo > /dev/null 2>&1 || { echo "You need to run this script as root" && exit 1 ; } 19 | sudo -H ./install.sh "$@" 20 | else 21 | ./install.sh "$@" 22 | fi 23 | -------------------------------------------------------------------------------- /distributions/Ubuntu.sh: -------------------------------------------------------------------------------- 1 | if [ "$VERSION_ID" != "16.04" ] && [ "$VERSION_ID" != "18.04" ]; then 2 | _warning "Only the last two LTS versions (16.04 and 18.04) are officially supported (but this will probably work)" 3 | fi 4 | 5 | . distributions/base.sh 6 | . distributions/base-systemd.sh 7 | . distributions/base-debianoid.sh 8 | . distributions/base-compile-rocksdb.sh 9 | 10 | if [ $(ver "$VERSION_ID") -ge $(ver "18.04") ]; then 11 | newer_rocksdb=1 12 | fi 13 | 14 | has_rocksdb_binary=1 15 | 16 | function install_python37 { 17 | $APT install -y software-properties-common || _error "Could not install package" 5 18 | add-apt-repository -y ppa:deadsnakes/ppa 19 | $APT update 20 | packages="python3.7 python3.7-dev python3.7-distutils" 21 | $APT install -y $packages || _error "Could not install package python3.7" 1 22 | } 23 | 24 | function binary_install_rocksdb { 25 | $APT install -y librocksdb-dev liblz4-dev build-essential libsnappy-dev zlib1g-dev libbz2-dev libgflags-dev || _error "Could not install packages" 1 26 | } 27 | 28 | function binary_uninstall_rocksdb { 29 | $APT remove -y librocksdb-dev || _error "Could not remove rocksdb" 1 30 | } 31 | 32 | function install_leveldb { 33 | $APT install -y libleveldb-dev || _error "Could not install packages" 1 34 | } 35 | -------------------------------------------------------------------------------- /distributions/base-rhel.sh: -------------------------------------------------------------------------------- 1 | function install_compiler { 2 | yum -y update 3 | yum -y install gcc-c++ bzip2 || _error "Could not install packages" 1 4 | } 5 | 6 | function install_script_dependencies { 7 | yum -y install wget openssl 8 | } 9 | 10 | PATH=$PATH:/usr/local/bin 11 | . distributions/base.sh 12 | . distributions/base-systemd.sh 13 | . distributions/base-conda.sh 14 | . distributions/base-compile-rocksdb.sh 15 | 16 | 17 | function install_leveldb { 18 | yum -y install libleveldb-dev build-essential || _error "Could not install packages" 3 19 | } 20 | 21 | function install_git { 22 | yum -y install git || _error "Could not install packages" 2 23 | } 24 | 25 | function install_rocksdb_dependencies { 26 | # /usr/lib is not always included? 27 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib 28 | yum -y install snappy snappy-devel zlib zlib-devel bzip2-libs bzip2-devel libgflags-dev cmake3 make || _error "Could not install packages" 4 29 | ln -s /usr/bin/cmake3 /usr/bin/cmake 30 | _DIR=$(pwd) 31 | git clone https://github.com/gflags/gflags /tmp/gflags 32 | cd /tmp/gflags 33 | mkdir build && cd build 34 | _info "Compiling gflags" 35 | export CXXFLAGS="-fPIC" && cmake .. && make VERBOSE=1 36 | make && make install || _error "Error installing gflags" 1 37 | cd $_DIR 38 | } 39 | -------------------------------------------------------------------------------- /distributions/README.md: -------------------------------------------------------------------------------- 1 | # Adding new distributions 2 | This is the procedure to add a new distribution: 3 | ## Create a file in `distributions/` 4 | The file name must contain the distribution name followed by `.sh`. The installer uses either the `NAME` variable from `/etc/os-release` 5 | if that file exists or the first word from `/etc/issue`. 6 | ## Implement the functions 7 | You need to define the following functions in your distribution file: 8 | - **add_user**: Create a user called `electrumx` 9 | - **install_$python7**: Install Python 3.7. The first `$python` in `$PATH` should resolve to it. 10 | - **install_git**: Install git 11 | - **install_pyrocksdb**: Install pyrocksdb. 12 | - **install_leveldb**: Install libleveldb and its development headers 13 | - **install_init**: Integrate electrumx into the init system and enable it (if necessary). 14 | - **install_script_dependencies**: Install wget and openssl (if available). 15 | 16 | The following functions also need to be defined, but you can source them from `base.sh`: 17 | - create_db_dir(db): Create the database directory and change ownership to the electrumx user 18 | - assert_pyrocksdb: Should exit if rocksdb can't be imported 19 | - install_pip: Install pip to Python 3.6. Only necessary if the installed version doesn't already contain pip. 20 | - install_electrumx: Install electrumx to `/usr/local/bin`. 21 | 22 | You can also source some functions from the `base_*.sh` files. For example, Ubuntu sources `install_init` from `base_systemd.sh` 23 | and `install_git` from `base_debianoid.sh`. 24 | ## Add the distribution to the travis build matrix. 25 | `.travis.yml` contains the CI build matrix (a list called `env`). Look for your distribution on [Docker Hub](https://hub.docker.com/) 26 | and add the image to the build matrix. 27 | -------------------------------------------------------------------------------- /distributions/AlpineLinux.sh: -------------------------------------------------------------------------------- 1 | ERROR_EDGE="electrumX can currently be installed only on the edge Version of Alpine Linux" 2 | grep -q -F "/edge/main" /etc/apk/repositories > /dev/null || _error "${ERROR_EDGE}" 3 | grep -q -F "/edge/community" /etc/apk/repositories > /dev/null || _error "${ERROR_EDGE}" 4 | 5 | . distributions/base.sh 6 | 7 | APK="apk --no-cache" 8 | 9 | function install_script_dependencies { 10 | REPO="http://dl-cdn.alpinelinux.org/alpine/edge/testing" 11 | grep -q -F "${REPO}" /etc/apk/repositories || echo "${REPO}" >> /etc/apk/repositories 12 | apk update 13 | $APK add --virtual electrumX-dep openssl wget gcc g++ 14 | } 15 | 16 | function add_user { 17 | adduser -D electrumx 18 | id -u electrumx || _error "Could not add user account" 1 19 | } 20 | 21 | function install_python37 { 22 | _error "Please install Python 3.7 manually" 23 | } 24 | 25 | function install_git { 26 | $APK add --virtual electrumX-git git 27 | } 28 | 29 | function install_compiler { 30 | $APK add gcc 31 | } 32 | 33 | function install_rocksdb { 34 | $APK add rocksdb 35 | $APK add --virtual electrumX-db rocksdb-dev 36 | } 37 | 38 | function install_leveldb { 39 | $APK add leveldb 40 | } 41 | 42 | function install_init { 43 | # init is not required. Alpine is used for containers running the program directly 44 | : 45 | } 46 | 47 | function generate_cert { 48 | if ! which openssl > /dev/null 2>&1; then 49 | _info "OpenSSL not found. Skipping certificates.." 50 | return 51 | fi 52 | _DIR=$(pwd) 53 | mkdir -p /etc/electrumx/ 54 | cd /etc/electrumx 55 | # openssl default configuration is incomplet under alpine. 56 | # Hence adding this configruation from archlinux to allow certificat creation 57 | # https://www.archlinux.org/packages/core/x86_64/openssl/ 58 | echo "[ req ] 59 | distinguished_name = req_distinguished_name 60 | 61 | [ req_distinguished_name ] 62 | countryName_default = AU 63 | stateOrProvinceName_default = Some-State 64 | 0.organizationName_default = Internet Widgits Pty Ltd" > openssl.cnf 65 | openssl genrsa -des3 -passout pass:xxxx -out server.pass.key 2048 66 | openssl rsa -passin pass:xxxx -in server.pass.key -out server.key 67 | rm server.pass.key 68 | openssl req -new -key server.key -batch -out server.csr 69 | openssl x509 -req -days 1825 -in server.csr -signkey server.key -out server.crt 70 | rm server.csr 71 | chown electrumx:electrumx /etc/electrumx -R 72 | chmod 600 /etc/electrumx/server* 73 | cd $_DIR 74 | echo -e "\nSSL_CERTFILE=/etc/electrumx/server.crt" >> /etc/electrumx.conf 75 | echo "SSL_KEYFILE=/etc/electrumx/server.key" >> /etc/electrumx.conf 76 | echo "TCP_PORT=50001" >> /etc/electrumx.conf 77 | echo "SSL_PORT=50002" >> /etc/electrumx.conf 78 | echo -e "# Listen on all interfaces:\nHOST=" >> /etc/electrumx.conf 79 | } 80 | 81 | function package_cleanup { 82 | $APK del electrumX-dep electrumX-python electrumX-git electrumX-db 83 | } 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electrumx-installer 2 | A script to automate the installation of electrumx 🤖 3 | 4 | Installing electrumx isn't really straight-forward (yet). You have to install the latest version of Python and various dependencies for 5 | one of the database engines. Then you have to integrate electrumx into your init system. 6 | 7 | `electrumx-installer` simplifies this process to running a single command. All that's left to do for you 8 | is to customise the configuration and to start electrumx. 9 | 10 | ## Usage 11 | This installs electrumx using the default options: 12 | 13 | wget https://raw.githubusercontent.com/EasyX-Community/electrumx-installer/master/bootstrap.sh -O - | bash 14 | 15 | You can also set some options if you want more control: 16 | 17 | | -d --dbdir | Set database directory (default: /db/) | 18 | |------------|----------------------------------------| 19 | | --update | Update previously installed version | 20 | | --leveldb | Use LevelDB instead of RocksDB | 21 | 22 | For example: 23 | 24 | wget https://raw.githubusercontent.com/EasyX-Community/electrumx-installer/master/bootstrap.sh -O - | bash -s - -d /media/ssd/electrum-db 25 | 26 | 27 | ## Operating System Compatibility 28 | 29 | The following operating systems are officially supported and automatically being tested against: 30 | 31 | | OS | Status | 32 | |----------|---:| 33 | | Ubuntu 18.04 | [![ubuntu](https://badges.herokuapp.com/travis/EasyX-Community/electrumx-installer?env=IMAGE=%22ubuntu:18.04%22&label=ubuntu:18.04)](https://travis-ci.org/bauerj/electrumx-installer/) | 34 | | Debian Jessie | [![debian](https://badges.herokuapp.com/travis/EasyX-Community/electrumx-installer?env=IMAGE=%22debian:8%22&label=debian:8)](https://travis-ci.org/bauerj/electrumx-installer/) | 35 | | Fedora 29 | [![centos](https://badges.herokuapp.com/travis/EasyX-Community/electrumx-installer?env=IMAGE=%22fedora:28%22&label=fedora:28)](https://travis-ci.org/bauerj/electrumx-installer/) | 36 | | Ubuntu 16.04 | [![ubuntu](https://badges.herokuapp.com/travis/EasyX-Community/electrumx-installer?env=IMAGE=%22ubuntu:16.04%22&label=ubuntu:16.04)](https://travis-ci.org/bauerj/electrumx-installer/) | 37 | | CentOS 7 | [![centos](https://badges.herokuapp.com/travis/EasyX-Community/electrumx-installer?env=IMAGE=%22centos:7%22&label=centos:7)](https://travis-ci.org/bauerj/electrumx-installer/) | 38 | | Debian Stretch | [![debian](https://badges.herokuapp.com/travis/EasyX-Community/electrumx-installer?env=IMAGE=%22debian:9%22&label=debian:9)](https://travis-ci.org/bauerj/electrumx-installer/) | 39 | 40 | 41 | If you prefer a different operating system that's not listed here, see 42 | [`distributions/README.md`](https://github.com/EasyX-Community/electrumx-installer/blob/master/distributions/README.md) to find out how to add it. 43 | Or open an [issue](https://github.com/EasyX-Community/electrumx-installer/issues/new) if you'd rather not do that yourself. 44 | -------------------------------------------------------------------------------- /distributions/base.sh: -------------------------------------------------------------------------------- 1 | # Contains functions that should work on all POSIX-compliant systems 2 | function create_db_dir { 3 | mkdir -p $1 4 | chown electrumx:electrumx $1 5 | } 6 | 7 | function check_pyrocksdb { 8 | python3.9 -B -c "import rocksdb" 9 | } 10 | 11 | function check_x16r-hash { 12 | python3.9 -B -c "import x16r-hash" 13 | } 14 | 15 | function install_electrumx { 16 | _DIR=$(pwd) 17 | rm -rf "/tmp/electrumx/" 18 | git clone $ELECTRUMX_GIT_URL /tmp/electrumx 19 | cd /tmp/electrumx 20 | if [ -n "$ELECTRUMX_GIT_BRANCH" ]; then 21 | git checkout $ELECTRUMX_GIT_BRANCH 22 | else 23 | git checkout $(git describe --tags) 24 | fi 25 | if [ $USE_ROCKSDB == 1 ]; then 26 | # We don't necessarily want to install plyvel 27 | sed -i "s/'plyvel',//" setup.py 28 | fi 29 | if [ "$python" != "python3" ]; then 30 | sed -i "s:usr/bin/env python3:usr/bin/env python3.7:" electrumx_rpc 31 | sed -i "s:usr/bin/env python3:usr/bin/env python3.7:" electrumx_server 32 | fi 33 | 34 | python3.9 -m pip install x16r-hash 35 | python3.9 -m pip install x16rv2-hash 36 | python3.9 -m pip install x16r_hash 37 | python3.9 -m pip install x16rv2_hash 38 | 39 | python3.9 -m pip install . --upgrade > /dev/null 2>&1 40 | if ! python3.7 -m pip install . --upgrade; then 41 | _error "Unable to install electrumx" 7 42 | fi 43 | 44 | cd $_DIR 45 | } 46 | 47 | function install_pip { 48 | wget https://bootstrap.pypa.io/get-pip.py -O /tmp/get-pip.py 49 | python3.9 /tmp/get-pip.py 50 | rm /tmp/get-pip.py 51 | if python3.9 -m pip > /dev/null 2>&1; then 52 | _info "Installed pip to $python" 53 | else 54 | _error "Unable to install pip" 55 | fi 56 | } 57 | 58 | function install_pyrocksdb { 59 | python3.9 -m pip install "Cython>=0.20" 60 | python3.9 -m pip install git+git://github.com/stephan-hof/pyrocksdb.git || _error "Could not install pyrocksdb" 1 61 | } 62 | 63 | function install_python_rocksdb { 64 | python3.9 -m pip install "Cython>=0.20" 65 | python3.9 -m pip install python-rocksdb || _error "Could not install python_rocksdb" 1 66 | } 67 | 68 | function add_user { 69 | useradd electrumx 70 | id -u electrumx || _error "Could not add user account" 1 71 | } 72 | 73 | function generate_cert { 74 | if ! which openssl > /dev/null 2>&1; then 75 | _info "OpenSSL not found. Skipping certificates.." 76 | return 77 | fi 78 | _DIR=$(pwd) 79 | mkdir -p /etc/electrumx/ 80 | cd /etc/electrumx 81 | openssl genrsa -des3 -passout pass:xxxx -out server.pass.key 2048 82 | openssl rsa -passin pass:xxxx -in server.pass.key -out server.key 83 | rm server.pass.key 84 | openssl req -new -key server.key -batch -out server.csr 85 | openssl x509 -req -days 1825 -in server.csr -signkey server.key -out server.crt 86 | rm server.csr 87 | chown electrumx:electrumx /etc/electrumx -R 88 | chmod 600 /etc/electrumx/server* 89 | cd $_DIR 90 | echo -e "\nSSL_CERTFILE=/etc/electrumx/server.crt" >> /etc/electrumx.conf 91 | echo "SSL_KEYFILE=/etc/electrumx/server.key" >> /etc/electrumx.conf 92 | #echo "TCP_PORT=50001" >> /etc/electrumx.conf 93 | #echo "SSL_PORT=50002" >> /etc/electrumx.conf 94 | echo -e "# Listen on all interfaces:\nHOST=" >> /etc/electrumx.conf 95 | } 96 | 97 | function ver { printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' ' '); } 98 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RED='\033[0;31m' 4 | YELLOW='\033[1;33m' 5 | BLUE='\033[0,34m' 6 | NC='\033[0m' # No Color 7 | 8 | DB_DIR="/db" 9 | UPDATE_ONLY=0 10 | UPDATE_PYTHON=0 11 | VERBOSE=0 12 | USE_ROCKSDB=1 13 | ELECTRUMX_GIT_URL="https://github.com/EasyX-Community/electrumx.git" 14 | ELECTRUMX_GIT_BRANCH="master" 15 | 16 | installer=$(realpath $0) 17 | 18 | cd "$(dirname "$0")" 19 | 20 | # Self-update 21 | if which git > /dev/null 2>&1; then 22 | _version_now=$(git rev-parse HEAD) 23 | git pull > /dev/null 2>&1 24 | if [ $_version_now != $(git rev-parse HEAD) ]; then 25 | echo "Updated installer." 26 | exec $installer "$@" 27 | fi 28 | fi 29 | 30 | while [[ $# -gt 0 ]]; do 31 | key="$1" 32 | case $key in 33 | -h|--help) 34 | cat >&2 <&2 76 | exit 12 77 | ;; 78 | esac 79 | shift # past argument or value 80 | done 81 | 82 | # redirect child output 83 | echo "" > /tmp/electrumx-installer-$$.log 84 | exec 3>&1 4>&2 2>/tmp/electrumx-installer-$$.log >&2 85 | 86 | if [ $VERBOSE == 1 ]; then 87 | tail -f /tmp/electrumx-installer-$$.log >&4 & 88 | fi 89 | 90 | 91 | function _error { 92 | if [ -s /tmp/electrumx-installer-$$.log ]; then 93 | echo -en "\n---- LOG OUTPUT BELOW ----\n" >&4 94 | tail -n 50 /tmp/electrumx-installer-$$.log >&4 95 | echo -en "\n---- LOG OUTPUT ABOVE ----\n" >&4 96 | fi 97 | printf "\r${RED}ERROR:${NC} ${1}\n" >&4 98 | if (( ${2:--1} > -1 )); then 99 | exit $2 100 | fi 101 | } 102 | 103 | function _warning { 104 | printf "\r${YELLOW}WARNING:${NC} ${1}\n" >&3 105 | } 106 | 107 | function _info { 108 | printf "\r${BLUE}INFO:${NC} ${1}\n" >&3 109 | } 110 | 111 | function _status { 112 | echo -en "\r$1" >&3 113 | printf "%-75s" " " >&3 114 | echo -en "\n" >&3 115 | _progress 116 | } 117 | 118 | _progress_count=0 119 | _progress_total=8 120 | function _progress { 121 | _progress_count=$(( $_progress_count + 1 )) 122 | _pstr="[=======================================================================]" 123 | _pd=$(( $_progress_count * 73 / $_progress_total )) 124 | printf "\r%3d.%1d%% %.${_pd}s" $(( $_progress_count * 100 / $_progress_total )) $(( ($_progress_count * 1000 / $_progress_total) % 10 )) $_pstr >&3 125 | } 126 | 127 | rocksdb_compile=1 128 | 129 | if [[ $EUID -ne 0 ]]; then 130 | _error "This script must be run as root (e.g. sudo -H $0)" 1 131 | fi 132 | 133 | if [ -f /etc/os-release ]; then 134 | # Load release information 135 | . /etc/os-release 136 | elif [ -f /etc/issue ]; then 137 | NAME=$(cat /etc/issue | head -n +1 | awk '{print $1}') 138 | else 139 | _error "Unable to identify Operating System" 2 140 | fi 141 | 142 | NAME=$(echo $NAME | tr -cd '[[:alnum:]]._-') 143 | 144 | if [ -f "./distributions/$NAME.sh" ]; then 145 | . ./distributions/$NAME.sh 146 | else 147 | _error "'$NAME' is not yet supported" 3 148 | fi 149 | 150 | python="" 151 | 152 | for _python in python3 python3.7 python3.9; do 153 | if which $_python; then 154 | python=$_python 155 | fi 156 | done 157 | 158 | if [ $UPDATE_ONLY == 0 ] || [ $UPDATE_PYTHON == 1 ]; then 159 | if which electrumx_server > /dev/null 2>&1 && [ $UPDATE_PYTHON == 0 ]; then 160 | _error "electrumx is already installed. Use $0 --update to... update." 9 161 | fi 162 | _status "Installing installer dependencies" 163 | install_script_dependencies 164 | _status "Adding new user for electrumx" 165 | add_user 166 | _status "Creating database directory in $DB_DIR" 167 | create_db_dir $DB_DIR 168 | 169 | if [[ $($python -V 2>&1) == *"Python 3.6"* ]] > /dev/null 2>&1 && [ $UPDATE_PYTHON == 0 ]; then 170 | _info "Python 3.6 is already installed." 171 | elif [[ $($python -V 2>&1) == *"Python 3.7"* ]] > /dev/null 2>&1; then 172 | _info "Python 3.7 is already installed." 173 | elif [[ $($python -V 2>&1) == *"Python 3.9"* ]] > /dev/null 2>&1; then 174 | _info "Python 3.9 is already installed." 175 | else 176 | _status "Installing Python 3.7" 177 | python=python3.7 178 | install_python37 179 | if [[ $($python -V 2>&1) == *"Python 3.7"* ]] > /dev/null 2>&1; then 180 | _info "Python 3.7 successfully installed" 181 | else 182 | _error "Unable to install Python 3.7" 4 183 | fi 184 | fi 185 | 186 | 187 | _status "Installing git" 188 | install_git 189 | 190 | if ! $python -m pip > /dev/null 2>&1; then 191 | _progress_total=$(( $_progress_total + 1 )) 192 | _status "Installing pip" 193 | install_pip 194 | fi 195 | 196 | if [ $USE_ROCKSDB == 1 ]; then 197 | _progress_total=$(( $_progress_total + 3 )) 198 | _status "Installing RocksDB" 199 | if [ ! -z $has_rocksdb_binary ]; then 200 | binary_install_rocksdb 201 | else 202 | install_rocksdb 203 | fi 204 | if [ -z $newer_rocksdb ]; then 205 | _status "Installing pyrocksdb" 206 | install_pyrocksdb 207 | else 208 | _status "Installing python_rocksdb" 209 | install_python_rocksdb 210 | fi 211 | _status "Checking pyrocksdb installation" 212 | if [ ! check_pyrocksdb ]; then 213 | if [ ! -z $has_rocksdb_binary ]; then 214 | _status "binary rocksdb doesn't work - compiling instead" 215 | binary_uninstall_rocksdb 216 | install_rocksdb 217 | if [ ! check_pyrocksdb ]; then 218 | _error "pyrocksdb installation still doesn't work" 7 219 | fi 220 | else 221 | _error "pyrocksdb installation doesn't work" 6 222 | fi 223 | fi 224 | else 225 | _status "Installing leveldb" 226 | install_leveldb 227 | fi 228 | 229 | _status "Installing electrumx" 230 | install_electrumx 231 | 232 | if [ $UPDATE_PYTHON == 0 ]; then 233 | 234 | _status "Installing init scripts" 235 | install_init 236 | 237 | _status "Generating TLS certificates" 238 | generate_cert 239 | 240 | fi 241 | 242 | if declare -f package_cleanup > /dev/null; then 243 | _status "Cleaning up" 244 | package_cleanup 245 | fi 246 | _info "electrumx has been installed successfully. Edit /etc/electrumx.conf to configure it." 247 | else 248 | _info "Updating electrumx" 249 | i=0 250 | while $python -m pip show electrumx; do 251 | $python -m pip uninstall -y electrumx || true 252 | ((i++)) 253 | if "$i" -gt 5; then 254 | break 255 | fi 256 | done 257 | if grep '/usr/local/bin/electrumx_server.py' /etc/systemd/system/electrumx.service; then 258 | _info "Updating pre-1.5 systemd configuration to new binary names" 259 | sed -i -- 's/_server.py/_server/g' /etc/systemd/system/electrumx.service 260 | systemctl daemon-reload 261 | fi 262 | install_electrumx 263 | _info "Installed $($python -m pip freeze | grep -i electrumx)" 264 | fi 265 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------