├── .gitignore
├── README.md
├── app
├── contract.py
├── files
│ ├── Python1.txt
│ ├── Python2.txt
│ └── Solidity.txt
├── server.py
├── storage.sol
└── templates
│ ├── check.html
│ ├── info.html
│ ├── upload.html
│ └── uploaded.html
├── blockchain
├── CustomGenesis.json
├── init.sh
└── start.sh
└── example
└── deploy_contract_and_test.py
/.gitignore:
--------------------------------------------------------------------------------
1 | .python-version
2 | chain-data/
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # File on blockchain
2 |
3 | |Index |Upload result|File info|
4 | |:-------:|:-----------:|:-------:|
5 | |![upload]|![result] |![info] |
6 |
7 |
8 | |Check |Exist |None |
9 | |:------:|:-----:|:------:|
10 | |![check]|![true]|![false]|
11 |
12 |
13 |
14 | ## Initialize blockchain environment
15 | 1. `git clone https://github.com/JungWinter/file-on-blockchain`
16 | 2. `cd file-on-blockchain/blockchain`
17 | 3. `./init.sh`
18 | 4. `./start.sh`
19 |
20 | ## Create account for deploying
21 | 1. Open another terminal and move to `file-on-blockchain/blockchain`
22 | 2. `geth attach ./chain-data/geth.ipc`
23 | 3. In console, `personal.newAccount()` and enter password
24 | 4. `miner.start()` and `miner.stop()`
25 |
26 | ## Deploy simple contract
27 | 1. `cd file-on-blockchain/example`
28 | 2. `python deploy_contract_and_test.py`
29 | 3. :tada:
30 |
31 | ## Run server
32 | 1. `cd file-on-blockchain/app`
33 | 2. `python server.py`
34 | 3. :star:
35 |
36 |
37 | [upload]: https://raw.githubusercontent.com/JungWinter/JungWinter.github.io/master/images/20171203/02_upload_file.png
38 | [result]: https://raw.githubusercontent.com/JungWinter/JungWinter.github.io/master/images/20171203/03_upload_result.png
39 | [info]: https://raw.githubusercontent.com/JungWinter/JungWinter.github.io/master/images/20171203/04_info.png
40 | [check]:https://raw.githubusercontent.com/JungWinter/JungWinter.github.io/master/images/20171203/05_check.png
41 | [true]:https://raw.githubusercontent.com/JungWinter/JungWinter.github.io/master/images/20171203/06_true.png
42 | [false]: https://raw.githubusercontent.com/JungWinter/JungWinter.github.io/master/images/20171203/08_false.png
43 |
--------------------------------------------------------------------------------
/app/contract.py:
--------------------------------------------------------------------------------
1 | import time
2 | from logzero import logger
3 | from web3 import Web3, HTTPProvider
4 | from solc import compile_files
5 |
6 | # Web3 setting
7 | rpc_url = "http://localhost:8545"
8 | w3 = Web3(HTTPProvider(rpc_url))
9 | # w3 = Web3(IPCProvider("./chain-data/geth.ipc"))
10 | w3.personal.unlockAccount(w3.eth.accounts[0], "test", 0)
11 |
12 |
13 | def deploy(contract_file_name, contract_name):
14 |
15 | compiled_sol = compile_files([contract_file_name])
16 | interface = compiled_sol['{}:{}'.format(contract_file_name,
17 | contract_name)]
18 |
19 | contract = w3.eth.contract(abi=interface['abi'],
20 | bytecode=interface['bin'],
21 | bytecode_runtime=interface['bin-runtime'])
22 |
23 | # Deploy
24 | tx_hash = contract.deploy(transaction={'from': w3.eth.accounts[0]})
25 |
26 | logger.info("tx_hash: {}".format(tx_hash))
27 |
28 | # Mining
29 | w3.miner.start(2)
30 | time.sleep(5)
31 | w3.miner.stop()
32 |
33 | # Contract address
34 | tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
35 | contract_address = tx_receipt['contractAddress']
36 | logger.info("contract_address: {}".format(contract_address))
37 | # Use contract
38 | contract_instance = contract(contract_address)
39 | return contract_instance
40 |
41 |
42 | def upload(ins, filehash, filename, filesize, owner):
43 | logger.info("Call upload")
44 | logger.info("{}, {}, {}, {}".format(owner, filehash, filename, filesize))
45 | transaction = ins.transact({"from": w3.eth.accounts[0]})
46 | tx_hash = transaction.upload(owner,
47 | filehash,
48 | filename,
49 | filesize)
50 |
51 | logger.info("Wait Uploading: {}".format(tx_hash))
52 |
53 | w3.miner.start(2)
54 | time.sleep(5)
55 | w3.miner.stop()
56 |
57 | logger.info("Finish Uploading")
58 |
59 |
60 | def get_file_info(ins, filehash):
61 | logger.info("Call get_file_info")
62 | logger.debug(filehash)
63 | file_info = ins.call().getFileInfo(filehash)
64 | logger.debug(file_info)
65 | return file_info
66 |
67 |
68 | def check_file_exist(ins, filehash):
69 | logger.info("Call check_file_exist")
70 | logger.debug(filehash)
71 | is_exist = ins.call().checkExist(filehash)
72 | logger.debug(is_exist)
73 | return is_exist
74 |
--------------------------------------------------------------------------------
/app/files/Python1.txt:
--------------------------------------------------------------------------------
1 | Python
2 |
--------------------------------------------------------------------------------
/app/files/Python2.txt:
--------------------------------------------------------------------------------
1 | Python
2 |
--------------------------------------------------------------------------------
/app/files/Solidity.txt:
--------------------------------------------------------------------------------
1 | Solidity
2 |
--------------------------------------------------------------------------------
/app/server.py:
--------------------------------------------------------------------------------
1 | import os
2 | import hashlib
3 | import contract
4 | from flask import (Flask, request, redirect, url_for, send_from_directory,
5 | render_template)
6 | from werkzeug import secure_filename
7 | from datetime import datetime
8 |
9 | UPLOAD_FOLDER = './files/'
10 | ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
11 | INS = None
12 |
13 | app = Flask(__name__)
14 | app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
15 | app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
16 |
17 |
18 | def allowed_file(filename):
19 | return '.' in filename and \
20 | filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
21 |
22 |
23 | @app.route('/', methods=['GET', 'POST'])
24 | def upload_file():
25 | if request.method == 'POST':
26 | file = request.files['file']
27 | if file and allowed_file(file.filename):
28 | filename = secure_filename(file.filename)
29 | path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
30 | file.save(path)
31 |
32 | owner = request.form["owner"]
33 | filehash = sha256_checksum(path)
34 | filesize = os.path.getsize(path)
35 | upload_on_blockchain(filehash=filehash,
36 | filename=filename,
37 | filesize=filesize,
38 | owner=owner)
39 |
40 | return redirect(url_for('uploaded_file',
41 | filename=filename,
42 | filehash=filehash))
43 | return render_template("upload.html")
44 |
45 |
46 | @app.route('/uploader')
47 | def uploaded_file():
48 | filename = request.args['filename']
49 | filehash = request.args['filehash']
50 | return render_template("uploaded.html",
51 | filename=filename,
52 | filehash=filehash)
53 |
54 |
55 | @app.route('/uploads/
7 | {% if is_exist %}
8 | Result
6 | {{ filename }} exist in blockchain!.
9 | Show file info
10 | Get file
11 | {% else %}
12 | {{ filename }} doesn't exist in blockchain!.
13 | {% endif %}
14 |
7 | {{ filehash }} is {{ info.file_name }}.
8 | GET FILE
9 |
Upload Date: {{ info.upload_date }}
11 |File Size: {{ info.file_size }} bytes
12 | 13 | -------------------------------------------------------------------------------- /app/templates/upload.html: -------------------------------------------------------------------------------- 1 | 2 |6 |
19 |
7 | {{ filename }} is uploaded successfully.
8 | GET FILE
9 |