Giter VIP home page Giter VIP logo

smartescrow's Introduction

Overview

unaninimity (version 1.2) API and Platform utilizes blockchain and off-blockchain data storage. The blockchain side enables users to ensure the authenticity of information related to real estate and aviation title, in particular its current ownership and all the historical transactions. In addition, non-encrypted metadata regarding transactions, among others contents of all the formulas, are stored in a local database on your server(s).

The structure of the database intentionally doesn't make use of relations to enable easy switch to decentalized storage (such as BitTorrent network, StorJ, FileCoin etc.), in case it will be recommended in the future.

Blockchain contract storage

Fingerprints of all the fields from particular formulars are stored in Ethereum blockchain using smart contract written in Solidity language. They are generated using SHA-224 cryptographic hash function, thus even a small change in the message will result in a mostly different hash, due to the avalanche effect. Example static content of contract stored in blockchain is presented below.

{
   "transferee_name":"1123c599095afde714bd13b6457c482f77fa64a4fe988e2b3eb57750",
   "transferee_address":"78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f",
   "transferee_nationality":"076d364250f10e230a3a28b2a4175d7431b24bc290a8fe4f76f7c054",
   "transferor_name":"bd1a1bdf6eae5ee14c3fee371cca975a5e052009bc67ce8f11cb7271",
   "transferor_address":"78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f",
   "transferor_nationality":"78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f",
   "manufacturer_and_model":"78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f",
   "manufactured":"86665612b0b232cb14f8605473d3a7e0d2f303ff7003c6f8916fdc4f",
   "last_maintenance":"0298f0bd0619d34fbe508628cef38adc827fcf4d93c700588f607adc",
   "serial_number":"83dd3a4315c03a802c7ab4bf6b61b2bd847976c1295e8e7284ec59b7",
   "registration_number":"4cfc3a1811fe40afa401b25ef7fa0379f1f7c1930a04f8755d678474",
   "transfered":"86665612b0b232cb14f8605473d3a7e0d2f303ff7003c6f8916fdc4f"
}

Data is stored in a custom contract, in its only static field, as serialized JSON string (in order to make contract elastic, in sense no ingerention in solidity is required to store additional data). All the required changes can be done by performing quite standard changes in model and serializer).

It is possible to switch to ERC721 tokens with ease, but they seem to be a way too complex as it comes to the current needs.

Prerequirements and technology

API was developed in Python programming language, utilizing Django REST framework, as well as web3.py interface for interacting with the Ethereum blockchain and ecosystem. Apart from these and other python-related requirements (cf. requirements.txt file) two additional applications have to be installed in target system, namely:

  • the solc Solidity compiler (used to compile smart contracts before they are signed and sent),
  • geth or equivalent interface for running a Full Ethereum Node (since contract has to be signed using a private key, for security purposes external services such as Infura do not provide this functionality).

After installing geth type geth account new in order to create an account that will be used for sending contract-related transactions to the network. Account's keyfile and password should be provided in configuration file for proper system functioning (type geth account list to find out where is the relevant keystore file located).

Running, testing, API documentation

In order to install python requirements type pip install -r requirements.txt.

Make sure geth is running and all the required settings are provided in the configuration file. System can be tested eg. using Rinkeby Ethereum Testnet. In this case geth has to be run with an --rinkeby option.

Then type simply run server using python manage.py runserver command in the main project directory. It will be available at 127.0.0.1:8000 by default, where the detailed API documentation should appear.

![(View of API documentation)] https://raw.githubusercontent.com/ubitquity/unanimity/8bc6583e6f4bbd7868ce7c10ed1927ac912cf753/api.png

Setup from scratch

Assuming you have Ubuntu 18.04 (or higher), run commands:

sudo apt update
sudo apt install python3-pip
sudo apt install build-essential libssl-dev
sudo apt install autoconf
sudo apt install libtool
sudo apt install libffi-dev
sudo apt install libgmp-dev
sudo apt install libsecp256k1-dev
sudo apt install pkg-config
sudo pip3 install -r requirements.txt

The last step - make sure that you are in the directory with code, and the requirements.txt is the right path.

After that run:

python manage.py migrate
python manage.py runserver 0:8080

This will run a development instance of your application.

Geth setup

Do a geth installation:

sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
sudo apt-get install solc

Create a new geth account:

geth account new

Remember the password - it is the PASSWORD setting in settings.py You should also see something like this: 2ee833f885a517d557c204b78a2654f1e5020239

This is ACCOUNT setting in settings.py, but prepend '0x' to it, so:

ACCOUNT = '0x2ee833f885a517d557c204b78a2654f1e5020239'

Run:

geth account list

and pick a key file path from there:

keystore:///home/vagrant/.ethereum/keystore/UTC--2018-08-31T11-38-42.406701178Z--2ee833f885a517d557c204b78a2654f1e5020239

Then the KEYFILE setting in settings.py is:

/home/vagrant/.ethereum/keystore/UTC--2018-08-31T11-38-42.406701178Z--2ee833f885a517d557c204b78a2654f1e5020239

As mentioned earlier in the README - it is good to use test network for testing, this can be achieved by using --rinkeby attribute in the get run.

Also - in infura change api to rinkeby, eg.: rinkeby.infura.io/v3/909xxxxxxxxxxxxxxxxx

In the end your settings should look like this:

PRODUCTION

INFURA_URL = 'https://mainnet.infura.io/v3/909xxxxxxxxxxxxxxxxx' KEYFILE = '/home/vagrant/.ethereum/keystore/UTC--2018-08-31T11-38-42.406701178Z--2ee833f885a517d557c204b78a2654f1e5020239' PASSWORD = 'XXXXXXXXX' CHAIN_ID = 1 ACCOUNT = '0x2eexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

TEST

INFURA_URL = 'https://rinkeby.infura.io/v3/909xxxxxxxxxxxxxxxxx' KEYFILE = '/home/vagrant/.ethereum/keystore/UTC--2018-08-31T11-38-42.406701178Z--2ee833f885a517d557c204b78a2654f1e5020239' PASSWORD = 'XXXXXXXXX' CHAIN_ID = 4 ACCOUNT = '0x2eexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

with

geth --rinkeby

running.

As for CHAIN_ID:

0: Olympic, Ethereum public pre-release testnet
1: Frontier, Homestead, Metropolis, the Ethereum public main network
1: Classic, the (un)forked public Ethereum Classic main network, chain ID 61
1: Expanse, an alternative Ethereum implementation, chain ID 2
2: Morden, the public Ethereum testnet, now Ethereum Classic testnet
3: Ropsten, the public cross-client Ethereum testnet
4: Rinkeby, the public Geth PoA testnet
8: Ubiq, the public Gubiq main network with flux difficulty chain ID 8
42: Kovan, the public Parity PoA testnet
77: Sokol, the public POA Network testnet
99: Core, the public POA Network main network
7762959: Musicoin, the music blockchain
61717561: Aquachain, ASIC resistant chain
[Other]: Could indicate that your connected to a local development test network.

So in case of testing - you should have 4 set up, in case of production 1.

File Upload
  1. Make sure you run the migrations:

    python3 manage.py migrate

  2. Install paramiko (SSH connection handling):

    sudo -H pip3 install paramiko

File Upload is done in two steps:

  • first you need to upload file under POST /files/
  • in the response you will get the needed file_hash
  • at this stage there will be an ssh connection triggered and the file metadata will reach your servers
  • you can use file_hash now in your contracts
  1. Setup SSH credentials, as we do not want to store SSH credentials in the repository, do:
  • create a file in the project root dir: ssh-credentials (touch ssh-credentials)

  • place there a json with credentials (you can use nano editor -> nano ssh-credentials):

    {
        "username": "{username}",
        "password": "{password}"
    }
    
  • ask System Administrator for the login credentials (username and password)

  1. After all of it is done - run:

    python manage.py runserver 0:8080

Environment setup

Install docker-compose:

sudo -H pip3 install docker-compose

Careful! Read the note about keyfile first.

Run:

docker-compose build 

The above command will build your container.

Create the file in the project root dir:

docker-compose-prod.yaml

Add following content to it

version: '2'
services:
  app-api:
    environment:
      - INFURA_URL=
      - KEYFILE=
      - PASSWORD=
      - CHAIN_ID=
      - ACCOUNT=
      - SSH_USERNAME=
      - SSH_PASSWORD=
      - UBITQUITY_HOST=45.32.1.3
      - UBITQUITY_FILE_PATH=/var/www/html/unanimity/folder
  • Change UBITQUITY_HOST to your server's IP address
  • Change the UBITQUITY_FILE_PATH to your server's path

Fill the empty settings with proper values (this is extremely important). The UBITQUITY_ prefixed environment variables can be as they are.

Note: keyfile

Keyfile is private at should be known only to the owner. This is not included in the repository. When you create your geth account (on rinkeby on any other network) - after listing the accounts you can see the key file path. Copy this key to the root folder of the application and run docker-compose build, later on add env variable with PATH as follows: KEYFILE=/app/UTC--2018-09-06T16-44-51....

!IMPORTANT, be very careful with the key and working with version control system (git), never push your key to the repository.

After settings all of the variables, run:

> docker-compose -f docker-compose.yaml -f docker-compose-prod.yaml up -d

You are ready to go. Go to the browser and type: <host_ip>:8080/

Entering Docker Container

To enter the docker container run:

docker-compose exec app-api bash

To switch between Testnet in Docker to Production ("mainnet")

in the root dir you have:

docker-composer-prod.yaml```

Names are confusing sorry for that - just rush

docker-composer-prod.yaml -> testnet settings
docker-compose-prod-settings.yaml -> prod settings

now you need to run two commands:
```sudo docker-compose -f docker-compose.yaml -f docker-compose-prod.yaml stop```

This will stop the current service, and:

```sudo docker-compose -f docker-compose.yaml -f docker-compose-prod-settings.yaml up -d```

... and vice-versa. You can simply switch testnet with mainnet

smartescrow's People

Contributors

ranabilalzafar avatar ubitquity avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.