diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9d6b38c --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +private_key=your private key +address=your BFY address \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d42f752 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__/ +build/ +dist/ +.env + +/main.spec \ No newline at end of file diff --git a/README.md b/README.md index 54f011d..f3226ec 100644 --- a/README.md +++ b/README.md @@ -1 +1,140 @@ -# BFY-Data-Uploader \ No newline at end of file +# BFY File Uploader + +BFY File Uploader is a program that allows you to upload files to the BlockyFile network. It provides a command-line interface and supports various options to customize the upload process. + +## Requirements + +Python version 3.6> <=3.9 + +## Usage with pre-compiled + +BFY File Uploader provides pre-compiled binaries for both Windows and Linux platforms, allowing you to run the program without the need for additional installations. + + +### Windows + +1. Download the Windows executable file from the [Releases](https://github.com/BlockyFile/BFY-Data-Uploader/releases) page. +2. Unzip all file and put into a folder +3. Double-click on the downloaded file to run the main.exe executable. + +### Linux + +1. Download the Linux executable file from the [Releases](https://github.com/BlockyFile/BFY-Data-Uploader/releases) page. +2. Unzip all file and put into a folder +3. Open the terminal and navigate to the directory where the downloaded file is located. +4. Run the following command to make the file executable: + +```bash +chmod +x main +``` + +4. Execute the program by running: + +```bash +./main +``` + +Please note that the pre-compiled binaries are available in the "Releases" section of the GitHub repository. + +For more detailed information and usage examples, refer to the [documentation](https://docs.blockyfile.org/). + +## Usage + +Before running the program, make sure to configure the `.env` file. Follow the steps below: + +1. Rename the `.env.example` file to `.env`. +2. Open the `.env` file and enter your BlockyFile address and private key. To retrieve the private key from MetaMask, follow these steps: + - Open MetaMask and click on the account icon in the top right corner. + - Select "Account Details". + - Click on the "Export Private Key" button. + - Copy the private key and paste it into the `.env` file. + + +To run the program, you need to install the required dependencies using the following command: + +```bash +pip3 install -r requirements.txt +``` +After installing the dependencies, you can execute the program using the following command: + +```bash +python main.py +``` + +Please note that Python 3 is required, but versions higher than 3.10 are currently not supported. + +## Program Options + +The program can be executed with the following flags: + +- `-t`, `--time_out`: Timeout time with RPC (default: 1200) +- `-e`, `--encoding_type`: Encoding Type of the file. Valid options: base64, base64withpassword (default: base64) +- `-g`, `--gui`: Enable/Disable GUI. Valid options: True, False (default: True) +- `-i`, `--input`: Path of the file to upload (works only with `--gui False`) +- `-rpc`: RPC URL of BlockyFile (default: https://node1.blockyfile.org/) +- `-p`, `--password`: Password for base64withpassword encoding (default: Password) +- `-gasprice`: GasPrice for transaction + +## Documentation + +For more information and detailed usage instructions, please refer to the [official documentation](https://docs.blockyfile.org/). The documentation provides additional details on the program's features, configuration, and usage. + +Please note that the issue with Python 3.10 compatibility will be resolved shortly. + +## For Windows + +For Windows, you may need to install the following package: [vc_redist.x64.exe](https://aka.ms/vs/17/release/vc_redist.x64.exe). + + +## Usage of api.py + +The `api.py` file located in the `tool` directory can be used to run the API server for BlockyFile. Follow the instructions below to execute the script and set the memory limit for contract size: + +1. Make sure you have Python installed on your system. + +2. Open a terminal or command prompt. + +3. Navigate to the `tool` directory of the BlockyFile project. + +4. Run the following command to execute the `api.py` script: + + ```bash + python api.py + ``` + + or + + ```bash + python3 api.py + ``` + + Note: Use `python` or `python3` depending on your Python installation. + +5. If you want to set the memory limit for contract size, use the `-m` flag followed by the desired memory limit. For example: + + ```bash + python api.py -m 256 + ``` + + This command sets the memory limit to 256 MB for contract size. + +6. Once the script is running, the API server will be accessible at `http://localhost:8080`. + +You can now make API requests to the BlockyFile server and retrieve file details or perform other operations. + +Please note that the `api.py` script should be executed in a secure environment and appropriate security measures should be taken to protect the server and its resources. + + + +## Planned Features + +The following features are planned for future releases: + +- Addition of base85 encoding for reduced cost. +- Integration with third-party web platforms for easier usage in DApps. +- Code optimization for improved performance. +- Fix bugs with python v3.10 and highter. +- Addition of NFTv2 creation functionality directly in the data uploader. +- Addition stats to api. + +Please note that these features are not yet available in the current version of the program but they will all be added before the MainNet is released. \ No newline at end of file diff --git a/contracts/aggregator.sol b/contracts/aggregator.sol new file mode 100644 index 0000000..4284d1a --- /dev/null +++ b/contracts/aggregator.sol @@ -0,0 +1,1695 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.8.18; + + +abstract contract A { + string data; + function delateAll() virtual public; + function SetOwner(address) virtual public; + function getValue() virtual public view returns(string memory); + function GetData() virtual public view returns(string memory); // No implementation, just the function signature. This is just so Solidity can work out how to call it. + function RemoveAll() virtual public; + +} +contract main { + string encode = "base64"; + string type_format = "application/pdf"; + uint size = 0; + address owner = msg.sender; + + function GetEncode() public view returns (string memory) { + return encode; + } + + function GetFormat() public view returns (string memory) { + return type_format; + } + + function Get_Size() public view returns (uint) { + return size; + } + + function GetOwner() public view returns (address) { + return owner; + } + + + + + + + + + + + + + function GetData() public view returns(string memory) { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + return string.concat(my_0.getValue()); + } + + + + function RemoveAll() public{ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + + + + + + + function SetOwner(address newowner) public { + if(tx.origin == owner){ + owner = newowner; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + else{ + revert("Not the owner"); + } + } + + +} \ No newline at end of file diff --git a/contracts/contract.sol b/contracts/contract.sol new file mode 100644 index 0000000..9e1f351 --- /dev/null +++ b/contracts/contract.sol @@ -0,0 +1,26 @@ +pragma solidity ^0.5.0; + +contract SolidityTest { +string data = "data:application/pdf;base64,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IDAgNTk1LjMwMzkzNzAwNzg3NCA4NDEuODg5NzYzNzc5NTI4XS9Hcm91cDw8L1MvVHJhbnNwYXJlbmN5L0NTL0RldmljZVJHQi9JIHRydWU+Pi9Db250ZW50cyA1IDAgUj4+CmVuZG9iagoKNyAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDM0IDAgUi9SZXNvdXJjZXMgNDYgMCBSL01lZGlhQm94WzAgMCA1OTUuMzAzOTM3MDA3ODc0IDg0MS44ODk3NjM3Nzk1MjhdL0dyb3VwPDwvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1ZT4+L0NvbnRlbnRzIDggMCBSPj4KZW5kb2JqCgoxMCAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDM0IDAgUi9SZXNvdXJjZXMgNDYgMCBSL01lZGlhQm94WzAgMCA1OTUuMzAzOTM3MDA3ODc0IDg0MS44ODk3NjM3Nzk1MjhdL0dyb3VwPDwvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1ZT4+L0NvbnRlbnRzIDExIDAgUj4+CmVuZG9iagoKMTMgMCBvYmoKPDwvVHlwZS9QYWdlL1BhcmVudCAzNCAwIFIvUmVzb3VyY2VzIDQ2IDAgUi9NZWRpYUJveFswIDAgNTk1LjMwMzkzNzAwNzg3NCA4NDEuODg5NzYzNzc5NTI4XS9Hcm91cDw8L1MvVHJhbnNwYXJlbmN5L0NTL0RldmljZVJHQi9JIHRydWU+Pi9Db250ZW50cyAxNCAwIFI+PgplbmRvYmoKCjE2IDAgb2JqCjw8L1R5cGUvUGFnZS9QYXJlbnQgMzQgMCBSL1Jlc291cmNlcyA0NiAwIFIvTWVkaWFCb3hbMCAwIDU5NS4zMDM5MzcwMDc4NzQgODQxLjg4OTc2Mzc3OTUyOF0vR3JvdXA8PC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0IvSSB0cnVlPj4vQ29udGVudHMgMTcgMCBSPj4KZW5kb2JqCgoxOSAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDM0IDAgUi9SZXNvdXJjZXMgNDYgMCBSL01lZGlhQm94WzAgMCA1OTUuMzAzOTM3MDA3ODc0IDg0MS44ODk3NjM3Nzk1MjhdL0dyb3VwPDwvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1ZT4+L0NvbnRlbnRzIDIwIDAgUj4+CmVuZG9iagoKMjIgMCBvYmoKPDwvVHlwZS9QYWdlL1BhcmVudCAzNCAwIFIvUmVzb3VyY2VzIDQ2IDAgUi9NZWRpYUJveFswIDAgNTk1LjMwMzkzNzAwNzg3NCA4NDEuODg5NzYzNzc5NTI4XS9Hcm91cDw8L1MvVHJhbnNwYXJlbmN5L0NTL0RldmljZVJHQi9JIHRydWU+Pi9Db250ZW50cyAyMyAwIFI+PgplbmRvYmoKCjI1IDAgb2JqCjw8L1R5cGUvUGFnZS9QYXJlbnQgMzQgMCBSL1Jlc291cmNlcyA0NiAwIFIvTWVkaWFCb3hbMCAwIDU5NS4zMDM5MzcwMDc4NzQgODQxLjg4OTc2Mzc3OTUyOF0vR3JvdXA8PC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0IvSSB0cnVlPj4vQ29udGVudHMgMjYgMCBSPj4KZW5kb2JqCgoyOCAwIG9iago8PC9UeXBlL1BhZ2UvUGFyZW50IDM0IDAgUi9SZXNvdXJjZXMgNDYgMCBSL01lZGlhQm94WzAgMCA1OTUuMzAzOTM3MDA3ODc0IDg0MS44ODk3NjM3Nzk1MjhdL0dyb3VwPDwvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCL0kgdHJ1ZT4+L0NvbnRlbnRzIDI5IDAgUj4+CmVuZG9iagoKMzEgMCBvYmoKPDwvVHlwZS9QYWdlL1BhcmVudCAzNCAwIFIvUmVzb3VyY2VzIDQ2IDAgUi9NZWRpYUJveFswIDAgNTk1LjMwMzkzNzAwNzg3NCA4NDEuODg5NzYzNzc5NTI4XS9Hcm91cDw8L1MvVHJhbnNwYXJlbmN5L0NTL0RldmljZVJHQi9JIHRydWU+Pi9Db250ZW50cyAzMiAwIFI+PgplbmRvYmoKCjM0IDAgb2JqCjw8L1R5cGUvUGFnZXMKL1Jlc291cmNlcyA0NiAwIFIKL01lZGlhQm94WyAwIDAgNTk1LjMwMzkzNzAwNzg3NCA4NDEuODg5NzYzNzc5NTI4IF0KL0tpZHNbIDEgMCBSIDQgMCBSIDcgMCBSIDEwIDAgUiAxMyAwIFIgMTYgMCBSIDE5IDAgUiAyMiAwIFIgMjUgMCBSIDI4IDAgUiAzMSAwIFIgXQovQ291bnQgMTE+PgplbmRvYmoKCjQ3IDAgb2JqCjw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAzNCAwIFIKL09wZW5BY3Rpb25bMSAwIFIgL1hZWiBudWxsIG51bGwgMF0KL0xhbmcoaXQtSVQpCj4+CmVuZG9iagoKNDggMCBvYmoKPDwvQ3JlYXRvcjxGRUZGMDA1NzAwNzIwMDY5MDA3NDAwNjUwMDcyPgovUHJvZHVjZXI8RkVGRjAwNEMwMDY5MDA2MjAwNzIwMDY1MDA0RjAwNjYwMDY2MDA2OTAwNjMwMDY1MDAyMDAwMzcwMDJFMDAzMz4KL0NyZWF0aW9uRGF0ZShEOjIwMjMwNTI4MTAwNTQwKzAyJzAwJyk+PgplbmRvYmoKCnhyZWYKMCA0OQowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwNTEwNjggMDAwMDAgbiAKMDAwMDAwMDAxOSAwMDAwMCBuIAowMDAwMDAyMTEyIDAwMDAwIG4gCjAwMDAwNTEyMzggMDAwMDAgbiAKMDAwMDAwMjEzMyAwMDAwMCBuIAowMDAwMDA0NTE5IDAwMDAwIG4gCjAwMDAwNTE0MDggMDAwMDAgbiAKMDAwMDAwNDU0MCAwMDAwMCBuIAowMDAwMDA3MjYzIDAwMDAwIG4gCjAwMDAwNTE1NzggMDAwMDAgbiAKMDAwMDAwNzI4NCAwMDAwMCBuIAowMDAwMDEwMDU2IDAwMDAwIG4gCjAwMDAwNTE3NTAgMDAwMDAgbiAKMDAwMDAxMDA3OCAwMDAwMCBuIAowMDAwMDEyNTExIDAwMDAwIG4gCjAwMDAwNTE5MjIgMDAwMDAgbiAKMDAwMDAxMjUzMyAwMDAwMCBuIAowMDAwMDE0MzMyIDAwMDAwIG4gCjAwMDAwNTIwOTQgMDAwMDAgbiAKMDAwMDAxNDM1NCAwMDAwMCBuIAowMDAwMDE1OTQwIDAwMDAwIG4gCjAwMDAwNTIyNjYgMDAwMDAgbiAKMDAwMDAxNTk2MiAwMDAwMCBuIAowMDAwMDE3Njk3IDAwMDAwIG4gCjAwMDAwNTI0MzggMDAwMDAgbiAKMDAwMDAxNzcxOSAwMDAwMCBuIAowMDAwMDE5NjU0IDAwMDAwIG4gCjAwMDAwNTI2MTAgMDAwMDAgbiAKMDAwMDAxOTY3NiAwMDAwMCBuIAowMDAwMDIxNDc2IDAwMDAwIG4gCjAwMDAwNTI3ODIgMDAwMDAgbiAKMDAwMDAyMTQ5OCAwMDAwMCBuIAowMDAwMDIzNzE4IDAwMDAwIG4gCjAwMDAwNTI5NTQgMDAwMDAgbiAKMDAwMDAyMzc0MCAwMDAwMCBuIAowMDAwMDM1MDc0IDAwMDAwIG4gCjAwMDAwMzUwOTcgMDAwMDAgbiAKMDAwMDAzNTI4NyAwMDAwMCBuIAowMDAwMDM1ODA5IDAwMDAwIG4gCjAwMDAwMzYxNjcgMDAwMDAgbiAKMDAwMDA0OTc3NSAwMDAwMCBuIAowMDAwMDQ5Nzk4IDAwMDAwIG4gCjAwMDAwNDk5OTAgMDAwMDAgbiAKMDAwMDA1MDU1NSAwMDAwMCBuIAowMDAwMDUwOTcwIDAwMDAwIG4gCjAwMDAwNTEwMTMgMDAwMDAgbiAKMDAwMDA1MzE0OSAwMDAwMCBuIAowMDAwMDUzMjQ3IDAwMDAwIG4gCnRyYWlsZXIKPDwvU2l6ZSA0OS9Sb290IDQ3IDAgUgovSW5mbyA0OCAwIFIKL0lEIFsgPDQ1RkVEQjBBRjA2NUQwMEU0MTBBNzM5QkFCODY5ODI5Pgo8NDVGRURCMEFGMDY1RDAwRTQxMEE3MzlCQUI4Njk4Mjk+IF0KL0RvY0NoZWNrc3VtIC82OTU1MEE4QTc0MUJDQTczNEU3OTMzQ0UwQjVCREM1MQo+PgpzdGFydHhyZWYKNTM0MjIKJSVFT0YK"; +address owner = msg.sender; + + function getValue() public view returns(string memory) { + return data; + } + function delateAll() public { + require(tx.origin == owner, "Not the owner"); + + data = ""; + } + function SetOwner(address newowner) public { + if(tx.origin == owner){ + owner = newowner; + } + else{ + revert("Not the owner"); + } + } + function GetOwner() public view returns (address) { + return owner; + } +} \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..8599f3d Binary files /dev/null and b/logo.png differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..40f70f3 --- /dev/null +++ b/main.py @@ -0,0 +1,866 @@ +from tkinter import * +from tkinter.ttk import * +from tkinter.filedialog import askopenfilename +import tkinter as tk +import os +import sys +import base64 +import platform +import solcxir +from textwrap import wrap +from web3 import Web3 +import threading +from itertools import islice +from Crypto.Cipher import AES +from Crypto.Hash import SHA256 +from Crypto import Random +import sv_ttk +from tkinter import ttk +from decouple import config +import argparse + +parser = argparse.ArgumentParser(description='BFY Data uploader') +parser.add_argument("-t", "--time_out", help="Timeout time with RPC", type=int, default=1200) #20 minuts of time out? Yes maybe no one mine on the pool +parser.add_argument("-e", "--encoding_type", help="Encoding Type of the file valid options: base64, base64withpassword", type=str, default="base64") +parser.add_argument("-g", "--gui", help="Enable/Disable gui", type=str, default="True") +parser.add_argument("-i", "--input", help="Patch of the file to upload (work only with --gui False)", type=str) +parser.add_argument("-rpc", help="RPC url of blockyfile", type=str, default= "https://node1.blockyfile.org/") +parser.add_argument("-p", "--password", help="Password of base64withpassword encoding", type=str, default= "Password") +parser.add_argument("-gasprice", help="GasPrice for transaction", type=int) + + +args = parser.parse_args() +encodingtype = args.encoding_type +timeoutblockchain = args.time_out +gui = args.gui +filepath = args.input +rpc = args.rpc +passwordbase64 = args.password + + + +web3 = Web3(Web3.HTTPProvider(rpc, request_kwargs={'timeout': timeoutblockchain})) +if platform.system() == "Linux": + screensize = "475x300" +if platform.system() == "Windows": + screensize = "435x300" + +if args.gasprice == None: + gasprice = web3.eth.gas_price + print("gas:" + str(web3.fromWei(web3.eth.gas_price, 'gwei'))) +else: + gasprice = web3.toWei(args.gasprice, 'gwei') + print("gas:" + str(args.gasprice)) + +constfrocontract = 0.0000000000715 * float(gasprice) #is the 0.0000000000715 1 trasaction of 100kb (the max one for 1 block) + +def encrypt(key, source, encode=True): + key = SHA256.new(key).digest() # use SHA-256 over our key to get a proper-sized AES key + IV = Random.new().read(AES.block_size) # generate IV + encryptor = AES.new(key, AES.MODE_CBC, IV) + padding = AES.block_size - len(source) % AES.block_size # calculate needed padding + source += bytes([padding]) * padding # Python 2.x: source += chr(padding) * padding + data = IV + encryptor.encrypt(source) # store the IV at the beginning and encrypt + return base64.b64encode(data).decode("latin-1") if encode else data + +def clearFile(): + indice = 52 + conta = 0 + for i in range(101): + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + #print("Your name: " + data[3]) + + + data[indice] = " \n" + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +1 + + indice = 1050 + for i in range(101): + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " \n" + data[indice+1] = " \n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +2 + conta = conta +1 + + + indice = 1350 + for i in range(101): + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " \n" + data[indice+1] = " \n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +2 + conta = conta +1 +#region Archivatore Dati + +def UploadToBlockchain(): + from solcxir import compile_standard + solcxir.install_solc('0.5.0') + if gui == "True": + ws.update_idletasks() + compiledcontract = compile_standard({ + "language": "Solidity", + "sources" : { "contract.sol": { + "content": contratto + }}, + "settings": { + "outputSelection": { + "*": { "*": + ["abi", "metadata", "evm.bytecode", "evm.sourceMap"]} + } + } + }, solc_version = "0.5.0") + + + # 4. Export contract data + abi = compiledcontract['contracts']['contract.sol']['SolidityTest']['abi'] + bytecode = compiledcontract['contracts']['contract.sol']['SolidityTest']['evm']['bytecode']['object'] + + + # Create address variable + account_from = { + 'private_key': config('private_key'), + 'address': config('address'), + } + + print(f'Attempting to deploy from account: { account_from["address"] }') + + # 4. Create contract instance + Incrementer = web3.eth.contract(abi=abi, bytecode=bytecode) + + # 5. Build constructor tx + construct_txn = Incrementer.constructor().buildTransaction( + { + 'from': account_from['address'], + 'gasPrice': gasprice, + 'chainId': 171, + 'nonce': web3.eth.get_transaction_count(account_from['address']) + } + ) + + # 6. Sign tx with PK + tx_create = web3.eth.account.sign_transaction(construct_txn, account_from['private_key']) + + # 7. Send tx and wait for receipt + tx_hash = web3.eth.send_raw_transaction(tx_create.rawTransaction) + tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=timeoutblockchain) + + print(f'Contract deployed at address: { tx_receipt.contractAddress }') + return tx_receipt.contractAddress +#endregion + +#region UploadAggregator +def UploadAggregator(): + import solcxir + from solcxir import compile_files + solcxir.install_solc('0.8.18') #don't use 0.8.20 or > + + compiledcontract = compile_files( + ["contracts/aggregator.sol"], + output_values=["abi", "metadata", "bin"], + solc_version="0.8.18", + optimize = True, + via_ir = True + ) + + + + contract_id, contract_interface = compiledcontract.popitem() + + # 4. Export contract data + abi = contract_interface['abi'] + bytecode = contract_interface['bin'] + + # Create address variable + account_from = { + 'private_key': config('private_key'), + 'address': config('address'), + } + + print(f'Attempting to deploy from account: { account_from["address"] }') + + # 4. Create contract instance + Incrementer = web3.eth.contract(abi=abi, bytecode=bytecode) + + # 5. Build constructor tx + construct_txn = Incrementer.constructor().buildTransaction( + { + 'from': account_from['address'], + + 'gasPrice': gasprice, + 'chainId': 171, + 'nonce': web3.eth.get_transaction_count(account_from['address']) + } + ) + + # 6. Sign tx with PK + tx_create = web3.eth.account.sign_transaction(construct_txn, account_from['private_key']) + + # 7. Send tx and wait for receipt + tx_hash = web3.eth.send_raw_transaction(tx_create.rawTransaction) + tx_receipt = web3.eth.wait_for_transaction_receipt(tx_hash, timeout=timeoutblockchain) + + print(f'Contract deployed at address: { tx_receipt.contractAddress }') + return tx_receipt.contractAddress +#endregion +solcxir.install_solc('0.8.18') + + +ws = Tk() +ws.title('BlockyFile data upload') +ws.geometry(screensize) + + +#region Convert File to string +def open_file(): + if gui == "True": + ws.option_add('*foreground', 'black') # set all tk widgets' foreground to black + filepath = askopenfilename(title="Select file", filetypes=(("text files", ".txt .pdf .docx"), ("image files", ".png .jpeg .jpg .gif .webp"), ("video files", ".mp4 .webm .mkv .avi .m4v"), ("audio files", ".mp3 .m4a .ogg .wav"), ("website files", ".html .js .css"), ("all files (not supported)", "*.*"))) + if filepath is not None: + pass + print(filepath) + else: + filepath = args.input + + global base64_utf8_str, dataurl, size, ContractToBeCreated, contrctlist, cut, type_format, sizemb + binary_fc = open(filepath, 'rb').read() # fc aka file_content + base64_utf8_str = base64.b64encode(binary_fc).decode('utf-8') + + ext = filepath.split('.')[-1] + #tryed with mimetypes but don't work all time + if ext == 'png': + type_format = "image/png" + dataurl = f'data:image/png;base64,{base64_utf8_str}' + if ext == 'jpeg': + type_format = "image/jpeg" + dataurl = f'data:image/jpeg;base64,{base64_utf8_str}' + if ext == 'gif': + type_format = "image/gif" + dataurl = f'data:image/gif;base64,{base64_utf8_str}' + if ext == 'webp': + type_format = "image/webp" + dataurl = f'data:image/webp;base64,{base64_utf8_str}' + if ext == 'jpg': + type_format = "image/jpg" + dataurl = f'data:image/jpg;base64,{base64_utf8_str}' + if ext == 'webm': + type_format = "image/webm" + dataurl = f'data:video/webm;base64,{base64_utf8_str}' + if ext == 'mkv': + type_format = "video/x-matroska" + dataurl = f'data:video/x-matroska;base64,{base64_utf8_str}' + if ext == 'avi': + type_format = "video/x-msvideo" + dataurl = f'data:video/x-msvideo;base64,{base64_utf8_str}' + if ext == 'm4a': + type_format = "audio/x-m4a" + dataurl = f'data:audio/x-m4a;base64,{base64_utf8_str}' + if ext == 'ogg': + type_format = "audio/ogg" + dataurl = f'data:audio/ogg;base64,{base64_utf8_str}' + if ext == 'wav': + type_format = "audio/wav" + dataurl = f'data:audio/wav;base64,{base64_utf8_str}' + if ext == 'mp3': + type_format = "audio/mpeg" + dataurl = f'data:audio/mpeg;base64,{base64_utf8_str}' + if ext == 'mp4': + type_format = "video/mp4" + dataurl = f'data:video/mp4;base64,{base64_utf8_str}' + if ext == 'm4v': + type_format = "video/mp4" + dataurl = f'data:video/mp4;base64,{base64_utf8_str}' + if ext == 'html': + type_format = "text/html" + dataurl = f'data:text/html;base64,{base64_utf8_str}' + if ext == 'css': + type_format = "text/css" + dataurl = f'data:text/css;base64,{base64_utf8_str}' + if ext == 'js': + type_format = "text/javascript" + dataurl = f'data:text/javascript;base64,{base64_utf8_str}' + if ext == 'pdf': + type_format = "application/pdf" + dataurl = f'data:application/pdf;base64,{base64_utf8_str}' + if ext == 'docx': + type_format = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + dataurl = f'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,{base64_utf8_str}' + #print(dataurl) + if encodingtype == "base64withpassword": + if gui == "True": + dataurl = encrypt(bytes(textbox.get(), encoding='utf-8'), bytes(dataurl, encoding='utf-8')) + else: + dataurl = encrypt(bytes(passwordbase64, encoding='utf-8'), bytes(dataurl, encoding='utf-8')) + + #about this part: https://ibb.co/BTWvk1V don't ask, it just work + size = len(dataurl)/1024 + sizemb = int(len(dataurl)/1048576) #for write in contract + ContractToBeCreated = int(len(dataurl)/100000) # 100kb = 1 divisione, 500k = 5 divisioni + print("size: " + str(size) + " bytes") + contrctlist = [] + # check if the number of kb does not exceed 110 for each contract if making one more. error found 260 kb divided into 2 parts would be 130 or greater than 126 + if ContractToBeCreated > 0: + if int(size)/ContractToBeCreated > 110: + ContractToBeCreated = ContractToBeCreated + 1 + print("Contracts to do: " + str(ContractToBeCreated)) + + cut = int(len(dataurl)/ContractToBeCreated) #it just work : ) + print("bytes per block: " + str(cut)) + cost = str(round((ContractToBeCreated * constfrocontract), 2)) + if cost == "0.0": cost = "<" + str(round((1 * constfrocontract), 2)) + + #endregion + + + adhar3 = Label( + ws, + text="contracts to create " + str(ContractToBeCreated+1) + ) + + adhar3.grid(row=2, column=0, padx=10) + + adhar4 = Label( + ws, + text="Cost: " + cost + ) + adhar4.grid(row=2, column=1, padx=10) + + +def uploadFiles(): + global pb1 + pb1 = ttk.Progressbar( + ws, + orient=HORIZONTAL, + length=300, + mode='determinate' + ) + + pb1.grid(row=5, columnspan=3, pady=30) + if gui == "True": + ws.update_idletasks() + threading.Thread(target=start).start() + + +def start(): + +#region Archivatore Dati + if size > 100: + b = wrap(dataurl, cut+10) + i=0 + contrctlist = [] + while i < int(ContractToBeCreated): + if gui == "True": + ws.update_idletasks() + with open('contracts/contract.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + #print("Your name: " + data[3]) + global contratto + + data[3] = 'string data = "' + b[i] + '";\n' + + # and write everything back + with open('contracts/contract.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + + with open('contracts/contract.sol', 'r') as file: + # read a list of lines into data + contratto = file.read() + + print("uploading " + str(i+1) + " contract:") + + contrctlist.append(UploadToBlockchain()) + i = i +1 + if gui == "True": + pb1['value'] += (100/ContractToBeCreated) + ws.update_idletasks() + + + + + else: + contrctlist = [] + with open('contracts/contract.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + #print("Your name: " + data[3]) + + + data[3] = 'string data = "' + dataurl + '";\n' + + # and write everything back + with open('contracts/contract.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + + with open('contracts/contract.sol', 'r') as file: + # read a list of lines into data + contratto = file.read() + contrctlist.append(UploadToBlockchain()) + + + + for i in contrctlist: + print(i) + # aggregator start + global Aggregator + + + if (len(contrctlist)) > 71: + contrctlist = [contrctlist[x:x+70] for x in range(0, len(contrctlist), 70)] + AggregatorList = [] + for contract in contrctlist: + indice = 52 + conta = 0 + for i in contract: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +1 + conta = conta +1 + #Delate All funcion + indice = 1050 + conta = 0 + deleteallreturn = "" + for i in contract: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + data[indice+1] = " "+ "my_" + str(conta) + ".delateAll();\n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +2 + conta = conta +1 + + indice = 1350 + conta = 0 + for i in contract: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + data[indice+1] = " "+ "my_" + str(conta) + ".SetOwner(newowner);\n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + indice = indice +2 + conta = conta +1 + + + + + conta = 0 + concatenamente = "" + for i in contract: + concatenamente = concatenamente + "my_" + str(conta) + ".getValue()," + conta = conta + 1 + #write return + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + data[15] = " string encode = \"" + encodingtype + "\"" + ";\n" + data[16] = " string type_format = \"" + type_format + "\"" + ";\n" + data[17] = " uint size = " + str(sizemb) + ";\n" + data[1036] = " " + "return string.concat(" + concatenamente[:-1] + ");\n" + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + contratto = file.read() + AggregatorList.append(UploadAggregator()) + #clear the file + clearFile() + + + indice = 52 + conta = 0 + for i in AggregatorList: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +1 + conta = conta +1 + #Delate All funcion + indice = 1050 + conta = 0 + deleteallreturn = "" + for i in AggregatorList: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + data[indice+1] = " "+ "my_" + str(conta) + ".delateAll();\n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +2 + conta = conta +1 + + indice = 1350 + conta = 0 + for i in AggregatorList: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + data[indice+1] = " "+ "my_" + str(conta) + ".SetOwner(newowner);\n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +2 + conta = conta +1 + #upload aggregator with aggregator generated + indice = 52 + conta = 0 + for i in AggregatorList: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + #print("Your name: " + data[3]) + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +1 + conta = conta +1 + #fineciclo + conta = 0 + concatenamente = "" + for i in AggregatorList: + concatenamente = concatenamente + "my_" + str(conta) + ".GetData()," + conta = conta + 1 + #scrivi return + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + data[15] = " string encode = \"" + encodingtype + "\"" + ";\n" + data[16] = " string type_format = \"" + type_format + "\"" + ";\n" + data[17] = " uint size = " + str(sizemb) + ";\n" + data[1036] = " " + "return string.concat(" + concatenamente[:-1] + ");\n" + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + contratto = file.read() + + Aggregator = UploadAggregator() + + + #clear the file + + clearFile() + + + + + else: + + indice = 52 + conta = 0 + for i in contrctlist: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +1 + conta = conta +1 + #Delate All funcion + indice = 1050 + conta = 0 + deleteallreturn = "" + for i in contrctlist: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + data[indice+1] = " "+ "my_" + str(conta) + ".delateAll();\n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + #corretto fino a qui + indice = indice +2 + conta = conta +1 + + indice = 1350 + conta = 0 + for i in contrctlist: + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + + + + + data[indice] = " "+ "A my_" + str(conta) + "= A(" + i + ");\n" + data[indice+1] = " "+ "my_" + str(conta) + ".SetOwner(newowner);\n" + + + + + # and write everything back + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + + indice = indice +2 + conta = conta +1 + + + + #fineciclo + conta = 0 + concatenamente = "" + for i in contrctlist: + concatenamente = concatenamente + "my_" + str(conta) + ".getValue()," + conta = conta + 1 + #scrivi return + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + data = file.readlines() + data[15] = " string encode = \"" + encodingtype + "\"" + ";\n" + data[16] = " string type_format = \"" + type_format + "\"" + ";\n" + data[17] = " uint size = " + str(sizemb) + ";\n" + data[1036] = " " + "return string.concat(" + concatenamente[:-1] + ");\n" + with open('contracts/aggregator.sol', 'w') as file: + file.writelines( data ) + with open('contracts/aggregator.sol', 'r') as file: + # read a list of lines into data + contratto = file.read() + Aggregator = UploadAggregator() + #clear the file + + clearFile() + +#endregion + if gui == "True": + + pb1.destroy() + Label(ws, text='File Uploaded Successfully!', foreground='green').grid(row=4, columnspan=2, pady=10) + + + textbox = Entry(ws, width=45) + textbox.insert(0, "This is Temporary Text...") + textbox.grid(row=8, column=0, pady=10) + + textbox.delete(0, END) + textbox.insert(0, Aggregator) + + + + +adhar = Label( + ws, + text='Upload file: ' + ) +adhar.grid(row=0, column=0, padx=0) + +adharbtn = Button( + ws, + text ='Choose File', + command = lambda:open_file() + ) +adharbtn.grid(row=0, column=1, sticky="e") + + +upld = Button( + ws, + text='Upload Files', + command=uploadFiles + ) +upld.grid(row=3, columnspan=2, pady=10) +upld.grid(sticky=tk.W + tk.E) + + +def restart(): + python = sys.executable + os.execl(python, python, * sys.argv) + + +upld = Button( + ws, + text='Restart', + command=restart + ) +upld.grid(row=9, columnspan=2, pady=10) +upld.grid(sticky=tk.W + tk.E) + + +adhar2 = Label( + ws, + text=' Upload Status:' + ) +adhar2.grid(row=4, column=0, padx=10) + +adhar4 = Label( + ws, + text=' (Before chose file)' + ) +adhar4.grid(row=10, column=0, padx=7) + +adhar3 = Label( + ws, + text=' Encryption type:' + ) +adhar3.grid(row=11, column=0, padx=10) + +def handle_checkbutton_selection(): + if checkbutton1_var.get() == 1: + checkbutton2_var.set(0) + textbox.grid_forget() + global encodingtype + encodingtype = "base64" + + +def handle_checkbutton_selection2(): + if checkbutton2_var.get() == 1: + checkbutton1_var.set(0) + global textbox + textbox = Entry(ws, width=25) + textbox.insert(0, "Password") + textbox.grid(row=14, column=0, pady=10) + global encodingtype + encodingtype = "base64withpassword" + + +checkbutton1_var = tk.IntVar() +checkbutton2_var = tk.IntVar() +checkbutton1 = ttk.Checkbutton(ws, text="base64", variable=checkbutton1_var, command=handle_checkbutton_selection) +checkbutton2 = ttk.Checkbutton(ws, text="base64 + password", variable=checkbutton2_var, command=handle_checkbutton_selection2) +checkbutton1.grid(row=13, column=0, sticky="w", padx=0, ipadx = 0) +checkbutton2.grid(row=13, column=1, sticky="w", padx=0, ipadx = 0) +sv_ttk.set_theme("dark") + +#base64 is default +checkbutton1_var.set(1) +if gui == "True": + ws.iconphoto(False, PhotoImage(file = "logo.png")) + ws.mainloop() +else: + open_file() + start() + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0a4c219 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +web3==5.31.4 +sv-ttk +python-decouple +pycryptodome +Flask +py-solc-x-ir \ No newline at end of file diff --git a/tools/api.py b/tools/api.py new file mode 100644 index 0000000..da526c7 --- /dev/null +++ b/tools/api.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python +# encoding: utf-8 +import json +from flask import Flask, request, jsonify, send_file +from web3 import Web3 +import urllib +from Crypto.Cipher import AES +from Crypto.Hash import SHA256 +from Crypto import Random +import base64 +import argparse + +parser = argparse.ArgumentParser(description='Api for get file from blockyfile') +parser.add_argument("-m", "--memory_limit", help="Max Megabyte for file request", type=int, default=100) +args = parser.parse_args() + +w3 = Web3(Web3.HTTPProvider('https://node1.blockyfile.org/', request_kwargs={'timeout':60})) #https://gorgo.epicmario71.com + +app = Flask(__name__) + +memorylimit = args.memory_limit + +def decrypt(key, source, decode=True): + if decode: + source = base64.b64decode(source.encode("latin-1")) + key = SHA256.new(key).digest() # use SHA-256 over our key to get a proper-sized AES key + IV = source[:AES.block_size] # extract the IV from the beginning + decryptor = AES.new(key, AES.MODE_CBC, IV) + data = decryptor.decrypt(source[AES.block_size:]) # decrypt + padding = data[-1] # pick the padding value from the end; Python 2.x: ord(data[-1]) + if data[-padding:] != bytes([padding]) * padding: # Python 2.x: chr(padding) * padding + raise ValueError("Invalid padding...") + return data[:-padding] # remove the padding + +contract_abi = [ + { + "inputs": [], + "name": "Get_Size", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GetEncode", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GetFormat", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GetData", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] + +# Create a contract object + + +@app.route('/json/', methods=['GET']) +def query_records(): + contract_address = request.args.get('contract_address') + if contract_address == None: + response = "No andress input" + else: + if contract_address.islower(): + indirizzosexy = Web3.toChecksumAddress(contract_address) + contract = w3.eth.contract(address=indirizzosexy, abi=contract_abi) + else: + contract = w3.eth.contract(address=contract_address, abi=contract_abi) + if contract.functions.Get_Size().call() < memorylimit: + result = contract.functions.GetData().call() + encode = contract.functions.GetEncode().call() + size = contract.functions.Get_Size().call() + response = jsonify({'data': result, 'encode': encode, 'size': size}) + response.headers.add('Access-Control-Allow-Origin', '*') + else: + response = "Password needed use /password/" + return response + +@app.route('/v1/', methods=['GET']) +def query_records_image(): + contract_address = request.args.get('contract_address') + if contract_address.islower(): + indirizzosexy = Web3.toChecksumAddress(contract_address) + contract = w3.eth.contract(address=indirizzosexy, abi=contract_abi) + else: + contract = w3.eth.contract(address=contract_address, abi=contract_abi) + + if contract.functions.GetEncode().call() == "base64": + + if contract.functions.Get_Size().call() < memorylimit: + result = contract.functions.GetData().call() + data_file = urllib.request.urlopen(result) + response = send_file(data_file, mimetype=contract.functions.GetFormat().call()) + response.headers.add('Access-Control-Allow-Origin', '*') + else: + response = "Memory limit reached" + else: + response = "Password needed use /password/" + + return response + + + +@app.route('/password/', methods=['GET']) +def query_records_password(): + + contract_address = request.args.get('contract_address') + password = request.args.get('password') + + if contract_address.islower(): + indirizzosexy = Web3.toChecksumAddress(contract_address) + contract = w3.eth.contract(address=indirizzosexy, abi=contract_abi) + else: + contract = w3.eth.contract(address=contract_address, abi=contract_abi) + if contract.functions.Get_Size().call() < memorylimit: + result = contract.functions.GetData().call() + if password == None: + return "No Password" + password = bytes(password, encoding='utf-8') + decrypted = decrypt(password, result) + data_file = urllib.request.urlopen(decrypted.decode("utf-8")) + response = send_file(data_file, mimetype=contract.functions.GetFormat().call()) + response.headers.add('Access-Control-Allow-Origin', '*') + + return response + else: + return "Memory limit reached" + +app.run(debug=True, host='0.0.0.0', port=8080, threaded=True)