diff --git a/.envSample b/.envSample new file mode 100644 index 0000000..ce8846c --- /dev/null +++ b/.envSample @@ -0,0 +1,6 @@ +APIKEY= +USERDB= +PASSDB= +DBNAME= +INFURAKEY= +CONTRACTADDRS= \ No newline at end of file diff --git a/.gitignore b/.gitignore index f5404bb..3fb973e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ /node_modules /orbitdb -package-lock.json .env diff --git a/ABI.js b/ABI.js index 7c198ae..4899cc5 100644 --- a/ABI.js +++ b/ABI.js @@ -1,437 +1,542 @@ -const abi = [{ - "constant": false, - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "spender", - "type": "address" - }, - { - "name": "tokens", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [{ - "name": "success", - "type": "bool" - }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "spender", - "type": "address" - }, - { - "name": "tokens", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "approveAndCall", - "outputs": [{ - "name": "success", - "type": "bool" - }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "spender", - "type": "address" - }, - { - "name": "tokens", - "type": "uint256" - } - ], - "name": "decreaseApproval", - "outputs": [{ - "name": "success", - "type": "bool" - }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "getETH", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "spender", - "type": "address" - }, - { - "name": "tokens", - "type": "uint256" - } - ], - "name": "increaseApproval", - "outputs": [{ - "name": "success", - "type": "bool" - }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "to", - "type": "address" - }, - { - "name": "tokens", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [{ - "name": "success", - "type": "bool" - }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "tokenAddress", - "type": "address" - }, - { - "name": "tokens", - "type": "uint256" - } - ], - "name": "transferAnyERC20Token", - "outputs": [{ - "name": "success", - "type": "bool" - }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "tokens", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [{ - "name": "success", - "type": "bool" - }], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "_newOwner", - "type": "address" - }], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [{ - "name": "CCDBAddress", - "type": "string" - }], - "name": "updateCCDBAddress", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [{ - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ - "indexed": true, - "name": "from", - "type": "address" - }, - { - "indexed": true, - "name": "to", - "type": "address" - }, - { - "indexed": false, - "name": "tokens", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [{ - "indexed": true, - "name": "tokenOwner", - "type": "address" - }, - { - "indexed": true, - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "name": "tokens", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "constant": true, - "inputs": [], - "name": "_CCDBAddress", - "outputs": [{ - "name": "", - "type": "string" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "_totalSupply", - "outputs": [{ - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [{ - "name": "tokenOwner", - "type": "address" - }, - { - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [{ - "name": "remaining", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [{ - "name": "tokenOwner", - "type": "address" - }], - "name": "balanceOf", - "outputs": [{ - "name": "balance", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "bonus1Ends", - "outputs": [{ - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "bonus2Ends", - "outputs": [{ - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [{ - "name": "", - "type": "uint8" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "endDate", - "outputs": [{ - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [{ - "name": "", - "type": "string" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "newOwner", - "outputs": [{ - "name": "", - "type": "address" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [{ - "name": "", - "type": "address" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "preICOEnds", - "outputs": [{ - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [{ - "name": "", - "type": "string" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [{ - "name": "", - "type": "uint256" - }], - "payable": false, - "stateMutability": "view", - "type": "function" - } -] - - - -module.exports = abi \ No newline at end of file +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": true, + "inputs": [], + "name": "_CCDBAddress", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "addDays", + "type": "uint256" + } + ], + "name": "appendDays", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "bonus1Ends", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "bonus2Ends", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "endDate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "getETH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getPause", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "preICOEnds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "bool", + "name": "p", + "type": "bool" + } + ], + "name": "setPause", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address payable", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokens", + "type": "uint256" + } + ], + "name": "transferAnyERC20Token", + "outputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address payable", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "string", + "name": "newCCDBAddress", + "type": "string" + } + ], + "name": "updateCCDBAddress", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/README.md b/README.md index 5a57dbe..d005706 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,243 @@ # DecaGraphics -Deca Graphics \ No newline at end of file +DECA Charts Code and settings to calculate price, quantity and percentage of reserve in carbon credits. + +**IMPORTANT: Please verify that the database address matches the smart contract address.** + +Official Carbon credits database address ([orbitdb](https://github.com/orbitdb/orbit-db)) +**/orbitdb/zdpuAykPJ4qtBg2toS2vxr5eaPfGEBJmvGerM7V7x8qn5c8hW/decaCCDB** + +## Table of Contents + +[[_TOC_]] + +## General Folder Structure + +```sh +├── ABI.js +├── getEth.js +├── index.js +├── package.json +├── README.md +├── scriptChildNode.js +├── scriptMainNode.js +└── services + ├── decaGraphicsChild.service + └── decaGraphicsMain.service +``` + +## Prerequisites + +Before you begin, ensure you have met the following requirements: + +* Node.js >= 10 + +## Installation + +**Download and install Node.js v10.x and npm.** + +> Using Ubuntu + +```sh + $ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - + $ sudo apt-get install -y nodejs +``` + +> Using Debian, as root + +```sh + $ curl -sL https://deb.nodesource.com/setup_10.x | bash - + $ apt-get install -y nodejs +``` + +**Clone the repo, switch to decagraphics and run npm install** + +```sh + $ git clone https://gitlab.com/deca-currency/decagraphics.git + $ cd decagraphics + $ npm install +``` + +> It's recommended to fix security vulnerabilities in dependencies using the command. + +```sh + $ npm audit fix +``` + +It is necessary to have installed mongodb locally in case of making a connection to another server modify the connection url of mongodb. + +> Once the installation is done, it is necessary to create a database with three collections with the following names: +```sh + $ mongo + use DecaGraphics + db.createCollection("decaPrice") + db.createCollection("decaGeth") + db.createCollection("decaCCTS") +``` + +> After that it is necessary to set the environment variables in an .env file as in the example .envSample file. + +```sh + APIKEY= + USERDB= + PASSDB= + DBNAME= + INFURAKEY= + CONTRACTADDRS= +``` + +In both scripts it is necessary to set the variable 'dates' to the following date in unixtime from there the script will start to run the calculations automatically. + +**Once everything is configured it is necessary to have ipfs running as a service the configuration can be found in [carboncreditsbacklog](https://gitlab.com/deca-currency/carboncreditsbacklog) as well connecting to the nodes mentioned there in order to replicate the orbitdb carbon credits database bd.** + +> The scripts can be tested using node as well the service rest which will take the data from mongodb and expose it in a json format in order to do the calculations on the web page + +```sh + $ node scriptMainNode.js + $ node index.js +``` + +To verify the data can be done from a browser taking into account the use of cors or from a bash. + +```sh + $ curl localhost:5000/decaPrice + $ curl localhost:5000/decaGeth + $ curl localhost:5000/decaCCTS +``` + +## Development + +* The dependencies are already in the package.json +* Ethereum Node +* Bitcoinaverage Api + +The rest service was made in express.js and cors was applied to accept only requests coming from deca.eco as well as helmet.js was used to give a better security to the application and the good practices of [express](https://expressjs.com/es/advanced/best-practice-security.html). + +The main script is scriptMainNode.js performs the calculations found in the document [DECAAnalyticsETHPrice](./pdf/DECAAnalyticsETHPrice.pdf) the other script is backup and is used on another node in case the main one fails. + + +## Deploy + +### Prerequisites + +* Nginx >= 1.14.0 +* Certbot >= 1.6 + +Install Nginx + +```sh + $ sudo apt update + $ sudo apt install nginx +``` + +Install Certbot + +```sh + $ sudo add-apt-repository ppa:certbot/certbot +``` + +> The script is configured as a service to be able to perform the calculations automatically. The configuration file is located in the service folder. + +```sh + $ sudo vim /etc/systemd/system/decaGraphics.service + [Unit] + Description=Deca Graphics Updater + + [Service] + WorkingDirectory=/home/nodemaster/decagraphics/ + ExecStart=/usr/local/bin/node /home/nodemaster/decagraphics/scriptMainNode.js + User=nodemaster + Restart=always + LimitNOFILE=10240 + + [Install] + WantedBy=multi-user.target +``` + +**NOTE: in this example user that runs ipfs, node and orbitdb instance is nodemaster, also the node location is at /usr/local/bin/node** + +**NOTE1: set WorkingDirectory where is the repository, for this example /home/nodemaster/decagraphics/** + +**NOTE2: set where is index.js mostly in the repository as follow path to node path, for this example /home/nodemaster/decagraphics/scriptMainNode.js** + +> Enable the service + +```sh + $ sudo systemctl daemon-reload + $ sudo systemctl enable decaGraphics.service + $ sudo systemctl start decaGraphics.service + $ sudo systemctl status decaGraphics.service +``` +**NOTE: service must be set as active (running), if not please verify the preview steps** + +> It is possible to check in the service logs if any error occurred in the service. + +```sh +● graphicsDeca.service - Graphing Calculator + Loaded: loaded (/lib/systemd/system/graphicsDeca.service; enabled; vendor preset: enabled) + Active: active (running) since Thu 2020-07-23 17:18:50 UTC; 4h 23min ago + Main PID: 629182 (node) + Tasks: 12 (limit: 464185) + CGroup: /system.slice/graphicsDeca.service + └─629182 /usr/bin/node /home/nodemaster/decagraphics/scriptMainNode.js + +Jul 23 21:40:02 icowebsrv node[629182]: zdpuAzCgWw1vAt8yKXFUR49uyhuD4W2jN4fKVmzwXwc9QvKzm +Jul 23 21:40:02 icowebsrv node[629182]: Insert decaPrice +Jul 23 21:40:02 icowebsrv node[629182]: zdpuB1YDWAcW9Ljq6WFo4HKXoaHRYKXfL1B9H4dMDRttcGzXF +Jul 23 21:40:02 icowebsrv node[629182]: Insert decaGeth +Jul 23 21:40:02 icowebsrv node[629182]: zdpuAwMn2mjAMAq9w2siJzi6wqc1W7rDi1fw61iuJdaUTnji8 +Jul 23 21:40:02 icowebsrv node[629182]: Insert decaCCTS +``` + +Once the service is working properly it is necessary to configure the service subtract to be able to access the data from [deca.eco](https://deca.eco/). + +In the nginx config add the proxy pass + + + +```sh +$ vim /etc/nginx/conf.d/example.com.conf +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name example.com www.example.com; + root /var/www/example.com; + index index.html; + try_files $uri /index.html; + location / { + proxy_pass http://localhost:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } +} +``` + +**Remember to open the port in the firewall** + +**Remember to leave the rest service running in a tmux session and check the port.** + +**Now restart up Nginx!** + + +### Add SSL Certificate + +```sh + $ sudo certbot --nginx -d api.deca.eco +``` + +**It is recommended to redirect all http traffic to https** + +Finally renew the certificate with the following command and restart nginx + +```sh +$ sudo certbot renew --dry-run +$ sudo service nginx restart +``` + +# Information and contacts. + +***Developers*** +- Jose [jose@deca.eco](mailto:jose@deca.eco) \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..4825682 --- /dev/null +++ b/index.js @@ -0,0 +1,58 @@ +require('dotenv').config() +var helmet = require('helmet'); +const MongoClient = require('mongodb').MongoClient; +const url = "mongodb://" + process.env.USERDB + ":" + encodeURIComponent(process.env.PASSDB) + "@localhost:27017/" + process.env.DBNAME +const express = require("express"); +const app = express(); +const cors = require('cors') + +app.use(express.json()); +app.use(cors({ + origin: 'https://deca.eco', + methods: ['GET'] +})); +app.use(helmet()) + +app.listen(5000, () => { + + app.get('/decaPrice', async function (req, res) { + const dbm = await MongoClient.connect(url, { + useUnifiedTopology: true + }).catch(err => { + console.log(err); + }); + var db = dbm.db("DECAGraphics"); + db.collection("decaPrice").find({}).toArray(function (err, response) { + if (err) throw err; + res.json(response); + }); + }); + + app.get('/decaGeth', async function (req, res) { + const dbm = await MongoClient.connect(url, { + useUnifiedTopology: true + }).catch(err => { + console.log(err); + }); + var db = dbm.db("DECAGraphics"); + db.collection("decaGeth").find({}).toArray(function (err, response) { + if (err) throw err; + res.json(response); + }); + }); + + app.get('/decaCCTS', async function (req, res) { + const dbm = await MongoClient.connect(url, { + useUnifiedTopology: true + }).catch(err => { + console.log(err); + }); + var db = dbm.db("DECAGraphics"); + db.collection("decaCCTS").find({}).toArray(function (err, response) { + if (err) throw err; + res.json(response); + }); + }); + + console.log("El servidor está inicializado en el puerto 5000"); +}); \ No newline at end of file diff --git a/package.json b/package.json index 86aab13..fb65a74 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "scriptgraficas", + "name": "decagraphics", "version": "1.0.0", - "description": "", + "description": "Script to generate and send data to show graphs in deca.eco", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -15,6 +15,19 @@ "orbit-db": "^0.24.1", "orbit-db-docstore": "^1.9.0", "orbit-db-store": "^3.3.0", - "dotenv": "^8.2.0" - } + "body-parser": "^1.19.0", + "cors": "^2.8.5", + "dotenv": "^8.2.0", + "express": "^4.17.1", + "helmet": "^3.23.3", + "mongodb": "^3.5.9" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@gitlab.com:deca-currency/decagraphics.git" + }, + "bugs": { + "url": "https://gitlab.com/deca-currency/decagraphics/issues" + }, + "homepage": "https://gitlab.com/deca-currency/decagraphics" } diff --git a/pdf/DECAAnalyticsETHPrice.pdf b/pdf/DECAAnalyticsETHPrice.pdf new file mode 100644 index 0000000..0b78ae7 Binary files /dev/null and b/pdf/DECAAnalyticsETHPrice.pdf differ diff --git a/scriptUpdateNode2.js b/scriptChildNode.js similarity index 51% rename from scriptUpdateNode2.js rename to scriptChildNode.js index 9c53af0..79bdaa0 100644 --- a/scriptUpdateNode2.js +++ b/scriptChildNode.js @@ -1,11 +1,12 @@ //Load Environment Variables require('dotenv').config() - //IPFS const IpfsClient = require('ipfs-http-client'); const OrbitDB = require('orbit-db'); //Instance of IPFS locally in IPFS daemon const node = IpfsClient('http://localhost:5001'); +const MongoClient = require('mongodb').MongoClient; +const url = "mongodb://" + process.env.USERDB + ":" + encodeURIComponent(process.env.PASSDB) + "@localhost:27017/" + process.env.DBNAME; //Module for get prices var getEth = require('./getEth'); @@ -18,68 +19,12 @@ const Web3 = require('web3'); const web3 = new Web3(new Web3.providers.WebsocketProvider(process.env.INFURAKEY)); //DECA Contract instance -const decaContract = new web3.eth.Contract(abi, '0xD60DC0805f44d10cAc6594f1a501c67929448957'); - -async function index() { - //Open and load orbitdb databases - const orbitdb = await OrbitDB.createInstance(node) - const db = await orbitdb.docs('/orbitdb/zdpuAykPJ4qtBg2toS2vxr5eaPfGEBJmvGerM7V7x8qn5c8hW/decaCCDB', { - indexBy: 'CCID' - }); - await db.load(); - const db2 = await orbitdb.docs('decaPrices', { - indexBy: 'dates' - }); - await db2.load(); - const db3 = await orbitdb.docs('decaGeth', { - indexBy: 'dates' - }); - await db3.load(); - const db4 = await orbitdb.docs('decaCCT', { - indexBy: 'dates' - }); - await db4.load(); - //Flag to save the following data - let dates = 1591980300; - while (true) { - //Get Carbon Credits Data - const data = db.get(''); - //Compare flag and unixtime to add data - if (Math.round(new Date().getTime() / 1000) == dates) { - dates += 300; - //Get data from functions - let elemsGeth = await getGethElems(dates); - let elemsDECAPrice = await getEth(dates); - let ccTotalEth = await getEthSum(data, dates); - //checks every 2 minutes to see if the data has already been inserted into the DBs if not - setTimeout(function () { - const query1 = db2.query((doc) => doc.dates == dates); - const query2 = db3.query((doc) => doc.dates == dates); - const query3 = db4.query((doc) => doc.dates == dates); - if(query1.length > 0){ - const hash1 = await db2.put(elemsDECAPrice); - console.log(hash1); - } - if(query2.length > 0){ - const hash2 = await db3.put(elemsGeth); - console.log(hash2); - } - if(query3.length > 0){ - const hash3 = await db4.put(ccTotalEth); - console.log(hash3); - } - - }, 20000); - } - } -} - -index(); +const decaContract = new web3.eth.Contract(abi, process.env.CONTRACTADDRS); //Function to save data from web3 and contract (ret TotalSupply, Ethereum, Date) const getGethElems = async (dates) => { let ret = {}; - var balanceEthereum = await web3.eth.getBalance('0xD60DC0805f44d10cAc6594f1a501c67929448957'); + var balanceEthereum = await web3.eth.getBalance(process.env.CONTRACTADDRS); var totalSupply = await decaContract.methods.totalSupply().call(); totalSupply = web3.utils.fromWei(totalSupply, 'ether'); balanceEthereum = web3.utils.fromWei(balanceEthereum, 'ether'); @@ -96,12 +41,81 @@ const getEthSum = async (elemsCC, dates) => { let sumCC = 0; for (let key in elemsCC) { sum += elemsCC[key]['conversionPrice']['ETH']; - } - for (let key in elemsCC) { sumCC += 1; } ret.ccTotal = sumCC; ret.ccTS = sum; ret.dates = dates; return ret; -} \ No newline at end of file +} + +async function index() { + //Open and load orbitdb databases + const orbitdb = await OrbitDB.createInstance(node) + const db = await orbitdb.docs('/orbitdb/zdpuAykPJ4qtBg2toS2vxr5eaPfGEBJmvGerM7V7x8qn5c8hW/decaCCDB', { + indexBy: 'CCID' + }); + await db.load(); + const db2 = await orbitdb.docs('/orbitdb/zdpuB1E3gfmmo17cFD2LEgxsjLzU9pxyW1q1Wde5TNL5QjiJG/decaPrice', { + indexBy: 'dates' + }); + await db2.load(); + const db3 = await orbitdb.docs('/orbitdb/zdpuB3ND1iK3NvYQx939ErZ2WXCaDoz4Lw3hazFUkdVupstBv/decaGeth', { + indexBy: 'dates' + }); + await db3.load(); + const db4 = await orbitdb.docs('/orbitdb/zdpuB2ZiX2QX8Qwwc1EXxo1y944tG6JcBk5UTLHm9b9Nv3Gna/decaCCTS', { + indexBy: 'dates' + }); + await db4.load(); + const dbm = await MongoClient.connect(url, { + useUnifiedTopology: true + }).catch(err => { + console.log(err); + }); + //Flag to save the following data + let dates = 1594230300; + while (true) { + //Compare flag and unixtime to add data + if (Math.round(new Date().getTime() / 1000) == dates) { + var dbo = dbm.db(process.env.DBNAME); + //Get data from functions + const data = db.get(''); + let elemsGeth = await getGethElems(dates); + let elemsDECAPrice = await getEth(dates); + let ccTotalEth = await getEthSum(data, dates); + //checks every 2 minutes to see if the data has already been inserted into the DBs if not + const query1 = db2.query((doc) => doc.dates == dates); + const query2 = db3.query((doc) => doc.dates == dates); + const query3 = db4.query((doc) => doc.dates == dates); + dbo.collection("decaPrice").insertOne(elemsDECAPrice, function (err, res) { + if (err) throw err; + console.log("Insert decaPrice") + }); + dbo.collection("decaGeth").insertOne(elemsGeth, function (err, res) { + if (err) throw err; + console.log("Insert decaGeth") + }); + dbo.collection("decaCCTS").insertOne(ccTotalEth, function (err, res) { + if (err) throw err; + console.log("Insert decaCCTS") + }); + await new Promise(r => setTimeout(r, 180000)); + if (query1.length > 0) { + const hash1 = await db2.put(elemsDECAPrice); + console.log(hash1); + } + if (query2.length > 0) { + const hash2 = await db3.put(elemsGeth); + console.log(hash2); + } + if (query3.length > 0) { + const hash3 = await db4.put(ccTotalEth); + console.log(hash3); + } + dates += 300; + } + } +} + +index(); \ No newline at end of file diff --git a/scriptUpdateNode1.js b/scriptMainNode.js similarity index 58% rename from scriptUpdateNode1.js rename to scriptMainNode.js index c53eb52..b6dd66a 100644 --- a/scriptUpdateNode1.js +++ b/scriptMainNode.js @@ -1,11 +1,12 @@ //Load Environment Variables require('dotenv').config() - //IPFS const IpfsClient = require('ipfs-http-client'); const OrbitDB = require('orbit-db'); //Instance of IPFS locally in IPFS daemon const node = IpfsClient('http://localhost:5001'); +const MongoClient = require('mongodb').MongoClient; +const url = "mongodb://" + process.env.USERDB + ":" + encodeURIComponent(process.env.PASSDB) + "@localhost:27017/" + process.env.DBNAME; //Module for get prices var getEth = require('./getEth'); @@ -17,72 +18,13 @@ const abi = require("./ABI.js"); const Web3 = require('web3'); const web3 = new Web3(new Web3.providers.WebsocketProvider(process.env.INFURAKEY)); -//DECA Contract instance -const decaContract = new web3.eth.Contract(abi, '0xD60DC0805f44d10cAc6594f1a501c67929448957'); - - -async function index() { - //Open and load orbitdb databases - const orbitdb = await OrbitDB.createInstance(node) - const db = await orbitdb.docs('/orbitdb/zdpuAykPJ4qtBg2toS2vxr5eaPfGEBJmvGerM7V7x8qn5c8hW/decaCCDB', { - indexBy: 'CCID' - }); - await db.load(); - const db2 = await orbitdb.docs('decaPrices', { - indexBy: 'dates' - }); - await db2.load(); - const db3 = await orbitdb.docs('decaGeth', { - indexBy: 'dates' - }); - await db3.load(); - const db4 = await orbitdb.docs('decaCCT', { - indexBy: 'dates' - }); - await db4.load(); - //Flag to save the following data - let dates = 1592331780; - while (true) { - //Get Carbon Credits Data - const data = db.get(''); - //Compare flag and unixtime to add data - if (Math.round(new Date().getTime() / 1000) == dates) { - dates += 120; - //Get data from functions - try{ - let elemsDECAPrice = await getEth(dates); - console.log(elemsDECAPrice); - const hash1 = await db2.put(elemsDECAPrice); - console.log(hash1); - }catch{ - console.error("Error in DECA Prices"); - } - try{ - let elemsGeth = await getGethElems(dates); - console.log(elemsGeth); - const hash2 = await db3.put(elemsGeth); - console.log(hash2); - }catch{ - console.error("Error in GETH"); - } - try{ - let ccTotalEth = await getEthSum(data, dates); - console.log(ccTotalEth); - const hash3 = await db4.put(ccTotalEth); - console.log(hash3); - }catch{ - console.error("Error in CCDB") - } - } - } -} - -index(); +//DECA Contract instance +const decaContract = new web3.eth.Contract(abi, process.env.CONTRACTADDRS); //Function to save data from web3 and contract (ret TotalSupply, Ethereum, Date) const getGethElems = async (dates) => { let ret = {}; - var balanceEthereum = await web3.eth.getBalance('0xD60DC0805f44d10cAc6594f1a501c67929448957'); + var balanceEthereum = await web3.eth.getBalance(process.env.CONTRACTADDRS); var totalSupply = await decaContract.methods.totalSupply().call(); totalSupply = web3.utils.fromWei(totalSupply, 'ether'); balanceEthereum = web3.utils.fromWei(balanceEthereum, 'ether'); @@ -99,10 +41,87 @@ const getEthSum = async (elemsCC, dates) => { let sumCC = 0; for (let key in elemsCC) { sum += elemsCC[key]['conversionPrice']['ETH']; - sumCC +=1; + sumCC += 1; } ret.ccTotal = sumCC; ret.ccTS = sum; ret.dates = dates; return ret; } + +async function index() { + //Open and load orbitdb databases + const orbitdb = await OrbitDB.createInstance(node) + const db = await orbitdb.docs('/orbitdb/zdpuAykPJ4qtBg2toS2vxr5eaPfGEBJmvGerM7V7x8qn5c8hW/decaCCDB', { + indexBy: 'CCID' + }); + await db.load(); + const db2 = await orbitdb.docs('/orbitdb/zdpuB1E3gfmmo17cFD2LEgxsjLzU9pxyW1q1Wde5TNL5QjiJG/decaPrice', { + indexBy: 'dates' + }); + await db2.load(); + const db3 = await orbitdb.docs('/orbitdb/zdpuB3ND1iK3NvYQx939ErZ2WXCaDoz4Lw3hazFUkdVupstBv/decaGeth', { + indexBy: 'dates' + }); + await db3.load(); + const db4 = await orbitdb.docs('/orbitdb/zdpuB2ZiX2QX8Qwwc1EXxo1y944tG6JcBk5UTLHm9b9Nv3Gna/decaCCTS', { + indexBy: 'dates' + }); + await db4.load(); + const dbm = await MongoClient.connect(url, { + useUnifiedTopology: true + }) + .catch(err => { + console.log(err); + }); + //Flag to save the following data + let dates = 1595524800; + while (true) { + //Compare flag and unixtime to add data + if (Math.round(new Date().getTime() / 1000) == dates) { + dates += 300; + //Get data from functions + var dbo = dbm.db(process.env.DBNAME); + try { + let elemsDECAPrice = await getEth(dates); + const hash1 = await db2.put(elemsDECAPrice); + dbo.collection("decaPrice").insertOne(elemsDECAPrice, function (err, res) { + if (err) throw err; + console.log("Insert decaPrice") + }); + console.log(hash1); + } catch (error) { + console.log(error); + console.error("Error in DECA Prices"); + } + try { + let elemsGeth = await getGethElems(dates); + console.log(elemsGeth) + const hash2 = await db3.put(elemsGeth); + dbo.collection("decaGeth").insertOne(elemsGeth, function (err, res) { + if (err) throw err; + console.log("Insert decaGeth") + }); + console.log(hash2); + } catch (error) { + console.log(error); + console.error("Error in GETH"); + } + try { + const data = await db.get(''); + let ccTotalEth = await getEthSum(data, dates); + const hash3 = await db4.put(ccTotalEth); + dbo.collection("decaCCTS").insertOne(ccTotalEth, function (err, res) { + if (err) throw err; + console.log("Insert decaCCTS") + }); + console.log(hash3); + } catch (error) { + console.log(error); + console.error("Error in CCDB") + } + } + } +} + +index(); \ No newline at end of file diff --git a/services/decaGraphicsChild.service b/services/decaGraphicsChild.service new file mode 100644 index 0000000..8c7bb60 --- /dev/null +++ b/services/decaGraphicsChild.service @@ -0,0 +1,12 @@ +[Unit] +Description=Deca Graphics Updater + +[Service] +WorkingDirectory=/home/nodemaster/decagraphics/ +ExecStart=/usr/local/bin/node /home/nodemaster/decagraphics/scriptChildNode.js +User=nodemaster +Restart=always +LimitNOFILE=10240 + +[Install] +WantedBy=multi-user.target diff --git a/services/decaGraphicsMain.service b/services/decaGraphicsMain.service new file mode 100644 index 0000000..d4b59e0 --- /dev/null +++ b/services/decaGraphicsMain.service @@ -0,0 +1,12 @@ +[Unit] +Description=Deca Graphics Updater + +[Service] +WorkingDirectory=/home/nodemaster/decagraphics/ +ExecStart=/usr/local/bin/node /home/nodemaster/decagraphics/scriptMainNode.js +User=nodemaster +Restart=always +LimitNOFILE=10240 + +[Install] +WantedBy=multi-user.target