From 8242e56594e8da50b8f6d5d49396c9c642693393 Mon Sep 17 00:00:00 2001 From: LilySu Date: Wed, 11 Mar 2020 12:36:59 -0400 Subject: [PATCH 1/2] updated read.me for pull --- README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/README.md b/README.md index 204d46a7..c22efc6c 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,86 @@ https://imgur.com/xSlgvtl * Basic Wallet (basic_wallet_p) Based on blockchain by dvf. Used under MIT license: https://github.com/dvf/blockchain + +*Instructions: Click on the raw button in the upper right hand corner of this box. Copy and paste the template into the README.md document on your github. Fill in the titles, information and links where prompted! Feel free to stray a bit to suit your project but try to stick to the format as closely as possible for consistency across DSWG projects.* + +# Project Name +This project is a part of the [Data Science Working Group](http://datascience.codeforsanfrancisco.org) at [Code for San Francisco](http://www.codeforsanfrancisco.org). Other DSWG projects can be found at the [main GitHub repo](https://github.com/sfbrigade/data-science-wg). + +#### -- Project Status: [Active, On-Hold, Completed] + +## Project Intro/Objective +The purpose of this project is ________. (Describe the main goals of the project and potential civic impact. Limit to a short paragraph, 3-6 Sentences) + +### Partner +* [Name of Partner organization/Government department etc..] +* Website for partner +* Partner contact: [Name of Contact], [slack handle of contact if any] +* If you do not have a partner leave this section out + +### Methods Used +* Inferential Statistics +* Machine Learning +* Data Visualization +* Predictive Modeling +* etc. + +### Technologies +* R +* Python +* D3 +* PostGres, MySql +* Pandas, jupyter +* HTML +* JavaScript +* etc. + +## Project Description +(Provide more detailed overview of the project. Talk a bit about your data sources and what questions and hypothesis you are exploring. What specific data analysis/visualization and modelling work are you using to solve the problem? What blockers and challenges are you facing? Feel free to number or bullet point things here) + +## Needs of this project + +- frontend developers +- data exploration/descriptive statistics +- data processing/cleaning +- statistical modeling +- writeup/reporting +- etc. (be as specific as possible) + +## Getting Started + +1. Clone this repo (for help see this [tutorial](https://help.github.com/articles/cloning-a-repository/)). +2. Raw Data is being kept [here](Repo folder containing raw data) within this repo. + + *If using offline data mention that and how they may obtain the data from the froup)* + +3. Data processing/transformation scripts are being kept [here](Repo folder containing data processing scripts/notebooks) +4. etc... + +*If your project is well underway and setup is fairly complicated (ie. requires installation of many packages) create another "setup.md" file and link to it here* + +5. Follow setup [instructions](Link to file) + +## Featured Notebooks/Analysis/Deliverables +* [Notebook/Markdown/Slide Deck Title](link) +* [Notebook/Markdown/Slide DeckTitle](link) +* [Blog Post](link) + + +## Contributing DSWG Members + +**Team Leads (Contacts) : [Full Name](https://github.com/[github handle])(@slackHandle)** + +#### Other Members: + +|Name | Slack Handle | +|---------|-----------------| +|[Full Name](https://github.com/[github handle])| @johnDoe | +|[Full Name](https://github.com/[github handle]) | @janeDoe | + +## Contact +* If you haven't joined the SF Brigade Slack, [you can do that here](http://c4sf.me/slack). +* Our slack channel is `#datasci-projectname` +* Feel free to contact team leads with any questions or if you are interested in contributing! + + From 002108fdb7a82cb7af900d80f8f28c516544dcba Mon Sep 17 00:00:00 2001 From: LilySu Date: Wed, 11 Mar 2020 21:44:18 -0400 Subject: [PATCH 2/2] updated with work notes --- Pipfile.lock | 63 ++++---- README.md | 105 +++++++++++++ basic_block_gp/blockchain.py | 42 +++-- client_mining_p/blockchain.py | 281 +++++++++++++++++++++++++++++++++- client_mining_p/my_id.txt | 2 +- 5 files changed, 451 insertions(+), 42 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index da56139b..6a83c293 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "36d1480b2857d3ca47d87e44b63f4bb1c3ba85e9fba71a9389c6f8161f5edd29" + "sha256": "1cfc261928838be069088d094d13b664d7ff98667a8a9b432e94c3241ab5ad6c" }, "pipfile-spec": 6, "requires": { @@ -18,10 +18,10 @@ "default": { "certifi": { "hashes": [ - "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", - "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" + "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", + "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" ], - "version": "==2019.6.16" + "version": "==2019.11.28" }, "chardet": { "hashes": [ @@ -32,25 +32,25 @@ }, "click": { "hashes": [ - "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", - "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + "sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc", + "sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a" ], - "version": "==7.0" + "version": "==7.1.1" }, "flask": { "hashes": [ - "sha256:0749df235e3ff61ac108f69ac178c9770caeaccad2509cb762ce1f65570a8856", - "sha256:49f44461237b69ecd901cc7ce66feea0319b9158743dd27a2899962ab214dac1" + "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", + "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" ], "index": "pypi", - "version": "==0.12.2" + "version": "==1.1.1" }, "idna": { "hashes": [ - "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", - "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4" + "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb", + "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa" ], - "version": "==2.6" + "version": "==2.9" }, "itsdangerous": { "hashes": [ @@ -61,10 +61,10 @@ }, "jinja2": { "hashes": [ - "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", - "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" + "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250", + "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49" ], - "version": "==2.10.1" + "version": "==2.11.1" }, "markupsafe": { "hashes": [ @@ -72,13 +72,16 @@ "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", @@ -95,31 +98,33 @@ "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", - "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" ], "version": "==1.1.1" }, "requests": { "hashes": [ - "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b", - "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e" + "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee", + "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6" ], "index": "pypi", - "version": "==2.18.4" + "version": "==2.23.0" }, "urllib3": { "hashes": [ - "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b", - "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" + "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", + "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" ], - "version": "==1.22" + "version": "==1.25.8" }, "werkzeug": { "hashes": [ - "sha256:865856ebb55c4dcd0630cdd8f3331a1847a819dda7e8c750d3db6f2aa6c0209c", - "sha256:a0b915f0815982fb2a09161cb8f31708052d0951c3ba433ccc5e1aa276507ca6" + "sha256:169ba8a33788476292d04186ab33b01d6add475033dfc07215e6d219cc077096", + "sha256:6dc65cf9091cf750012f56f2cad759fa9e879f511b5ff8685e456b4e3bf90d16" ], - "version": "==0.15.4" + "version": "==1.0.0" } }, "develop": { @@ -132,11 +137,11 @@ }, "flake8": { "hashes": [ - "sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661", - "sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8" + "sha256:45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb", + "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca" ], "index": "pypi", - "version": "==3.7.7" + "version": "==3.7.9" }, "mccabe": { "hashes": [ diff --git a/README.md b/README.md index 204d46a7..8296507f 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,108 @@ https://imgur.com/xSlgvtl * Basic Wallet (basic_wallet_p) Based on blockchain by dvf. Used under MIT license: https://github.com/dvf/blockchain + +*Instructions: Click on the raw button in the upper right hand corner of +this box. Copy and paste the template into the README.md document on +your github. Fill in the titles, information and links where prompted! +Feel free to stray a bit to suit your project but try to stick to the +format as closely as possible for consistency across DSWG projects.* + +# Project Name +This project is a part of the [Data Science Working +Group](http://datascience.codeforsanfrancisco.org) at [Code for San +Francisco](http://www.codeforsanfrancisco.org). Other DSWG projects can +be found at the [main GitHub +repo](https://github.com/sfbrigade/data-science-wg). + +#### -- Project Status: [Active, On-Hold, Completed] + +## Project Intro/Objective +The purpose of this project is ________. (Describe the main goals of the +project and potential civic impact. Limit to a short paragraph, 3-6 +Sentences) + +### Partner +* [Name of Partner organization/Government department etc..] +* Website for partner +* Partner contact: [Name of Contact], [slack handle of contact if any] +* If you do not have a partner leave this section out + +### Methods Used +* Inferential Statistics +* Machine Learning +* Data Visualization +* Predictive Modeling +* etc. + +### Technologies +* R +* Python +* D3 +* PostGres, MySql +* Pandas, jupyter +* HTML +* JavaScript +* etc. + +## Project Description +(Provide more detailed overview of the project. Talk a bit about your +data sources and what questions and hypothesis you are exploring. What +specific data analysis/visualization and modelling work are you using to +solve the problem? What blockers and challenges are you facing? Feel +free to number or bullet point things here) + +## Needs of this project + +- frontend developers +- data exploration/descriptive statistics +- data processing/cleaning +- statistical modeling +- writeup/reporting +- etc. (be as specific as possible) + +## Getting Started + +1. Clone this repo (for help see this +[tutorial](https://help.github.com/articles/cloning-a-repository/)). +2. Raw Data is being kept [here](Repo folder containing raw data) within +this repo. + + *If using offline data mention that and how they may obtain the data +from the froup)* + +3. Data processing/transformation scripts are being kept [here](Repo +folder containing data processing scripts/notebooks) +4. etc... + +*If your project is well underway and setup is fairly complicated (ie. +requires installation of many packages) create another "setup.md" file +and link to it here* + +5. Follow setup [instructions](Link to file) + +## Featured Notebooks/Analysis/Deliverables +* [Notebook/Markdown/Slide Deck Title](link) +* [Notebook/Markdown/Slide DeckTitle](link) +* [Blog Post](link) + + +## Contributing DSWG Members + +**Team Leads (Contacts) : [Full Name](https://github.com/[github +handle])(@slackHandle)** + +#### Other Members: + +|Name | Slack Handle | +|---------|-----------------| +|[Full Name](https://github.com/[github handle])| @johnDoe | +|[Full Name](https://github.com/[github handle]) | @janeDoe | + +## Contact +* If you haven't joined the SF Brigade Slack, [you can do that +here](http://c4sf.me/slack). +* Our slack channel is `#datasci-projectname` +* Feel free to contact team leads with any questions or if you are +interested in contributing! + diff --git a/basic_block_gp/blockchain.py b/basic_block_gp/blockchain.py index 54ead5c1..65832359 100644 --- a/basic_block_gp/blockchain.py +++ b/basic_block_gp/blockchain.py @@ -31,13 +31,19 @@ def new_block(self, proof, previous_hash=None): """ block = { - # TODO + "index": len(self.chain) + 1, + "timestamp":time(), + "transactions":self.current_transactions, + "proof":proof, + "previous_hash": previous_hash or self.hash(self.chain[-1]) #or self.lastblock } # Reset the current list of transactions - # Append the chain to the block + current_transactions = [] + # Append the block to the chain + self.chain.append(block) # Return the new block - pass + return block def hash(self, block): """ @@ -48,14 +54,18 @@ def hash(self, block): """ # Use json.dumps to convert json into a string + string_block = json.dumps(block, sort_keys=True)#if orders change, the hash would be different # Use hashlib.sha256 to create a hash # It requires a `bytes-like` object, which is what # .encode() does. + raw_hash = hashlib.sha256(string_block.encode()) # It converts the Python string into a byte string. # We must make sure that the Dictionary is Ordered, # or we'll have inconsistent hashes + hex_hash = raw_hash.hexdigest() # TODO: Create the block_string + return hex_hash # TODO: Hash this string using sha256 @@ -81,8 +91,12 @@ def proof_of_work(self, block): :return: A valid proof for the provided block """ # TODO - pass - # return proof + block_string = json.dumps(block, sort_keys=True) + proof = 0 + while self.valid_proof(block_string, proof) is False: + proof += 1 + + return proof @staticmethod def valid_proof(block_string, proof): @@ -97,7 +111,11 @@ def valid_proof(block_string, proof): :return: True if the resulting hash is a valid proof, False otherwise """ # TODO - pass + + guess = f'{block_string}{proof}'.encode() + guess_hash = hashlib.sha256(guess).hexdigest() + + return guess_hash[:3] == '000'#slice off last 6, see if it equals all zeros # return True or False @@ -114,21 +132,25 @@ def valid_proof(block_string, proof): @app.route('/mine', methods=['GET']) def mine(): # Run the proof of work algorithm to get the next proof - + proof = blockchain.proof_of_work(blockchain.last_block) # Forge the new Block by adding it to the chain with the proof + previous_hash = blockchain.hash(blockchain.last_block) + block = blockchain.new_block(proof, previous_hash) response = { - # TODO: Send a JSON response with the new block + 'new_block': block } - return jsonify(response), 200 @app.route('/chain', methods=['GET']) def full_chain(): response = { - # TODO: Return the chain and its current length + # TODO: Send a JSON response with the new block + 'chain': blockchain.chain, + 'length': len(blockchain.chain) } + return jsonify(response), 200 diff --git a/client_mining_p/blockchain.py b/client_mining_p/blockchain.py index a0a26551..919743ce 100644 --- a/client_mining_p/blockchain.py +++ b/client_mining_p/blockchain.py @@ -1,2 +1,279 @@ -# Paste your version of blockchain.py from the basic_block_gp -# folder here +import hashlib +import json +from time import time +from uuid import uuid4 +from flask import Flask, jsonify, request + +import random +import string + + +class Blockchain(object): + def __init__(self): + self.chain = [] + self.current_transactions = [] + + # Create the genesis block + self.new_block(previous_hash=1, proof=100) + + def new_block(self, proof, previous_hash=None): + """ + Create a new Block in the Blockchain + + A block should have: + * Index + * Timestamp + * List of current transactions + * The proof used to mine this block + * The hash of the previous block + + :param proof: The proof given by the Proof of Work algorithm + :param previous_hash: (Optional) Hash of previous Block + :return: New Block + """ + + block = { + "index": len(self.chain) + 1, + "timestamp":time(), + "transactions":self.current_transactions, + "proof":proof, + "previous_hash": previous_hash or self.hash(self.chain[-1]) #or self.lastblock + } + + # Reset the current list of transactions + current_transactions = [] + # Append the block to the chain + self.chain.append(block) + # Return the new block + return block + + def hash(self, block): + """ + Creates a SHA-256 hash of a Block + + :param block": Block + "return": + """ + + # Use json.dumps to convert json into a string + string_block = json.dumps(block, sort_keys=True)#if orders change, the hash would be different + # Use hashlib.sha256 to create a hash + # It requires a `bytes-like` object, which is what + # .encode() does. + raw_hash = hashlib.sha256(string_block.encode()) + # It converts the Python string into a byte string. + # We must make sure that the Dictionary is Ordered, + # or we'll have inconsistent hashes + hex_hash = raw_hash.hexdigest() + + # TODO: Create the block_string + return hex_hash + + # TODO: Hash this string using sha256 + + # By itself, the sha256 function returns the hash in a raw string + # that will likely include escaped characters. + # This can be hard to read, but .hexdigest() converts the + # hash to a string of hexadecimal characters, which is + # easier to work with and understand + + # TODO: Return the hashed block string in hexadecimal format + pass + + @property #property decorator, don't need to use + #parenthesis when you use this, acts like a property not a method, + # gives you the last block + def last_block(self): + return self.chain[-1] + + def proof_of_work(self, block): + """ + Simple Proof of Work Algorithm + Stringify the block and look for a proof. + Loop through possibilities, checking each one against `valid_proof` + in an effort to find a number that is a valid proof + :return: A valid proof for the provided block + """ + # TODO + block_string = json.dumps(block, sort_keys=True) + proof = 0 + while self.valid_proof(block_string, proof) is False: + proof += 1 + + return proof + + @staticmethod + def valid_proof(block_string, proof): + """ + Validates the Proof: Does hash(block_string, proof) contain 3 + leading zeroes? Return true if the proof is valid + :param block_string: The stringified block to use to + check in combination with `proof` + :param proof: The value that when combined with the + stringified previous block results in a hash that has the + correct number of leading zeroes. + :return: True if the resulting hash is a valid proof, False otherwise + """ + # TODO + + guess = f'{block_string}{proof}'.encode() + guess_hash = hashlib.sha256(guess).hexdigest() # turn into a hexadecimal string + + return guess_hash[:3] == '000'#slice off last 6, see if it equals all zeros + # we compare hexidecimal strings + + +# Instantiate our Node +app = Flask(__name__) + +# Generate a globally unique address for this node +node_identifier = str(uuid4()).replace('-', '') + +# Instantiate the Blockchain +blockchain = Blockchain() + + +@app.route('/mine', methods=['GET']) +def mine(): + # Run the proof of work algorithm to get the next proof + proof = blockchain.proof_of_work(blockchain.last_block) + # Forge the new Block by adding it to the chain with the proof + previous_hash = blockchain.hash(blockchain.last_block) + block = blockchain.new_block(proof, previous_hash) + + response = { + 'new_block': block + } + return jsonify(response), 200 + +@app.route('/check', methods=['POST']) + # if the incoming proof sent by the client is valid, and if so add the block +def check(): + + +# Modify the mine endpoint to instead receive and validate or reject a new proof sent by a client. +# It should accept a POST +# Use data = request.get_json() to pull the data out of the POST + data = request.get_json() +# Note that request and requests both exist in this project +# Check that 'proof', and 'id' are present + if data and ("proof" in data) and ("id" in data): + id = data["id"] + proof = data["proof"] + + # get back in json the last block in the last_block route + # convert to string + # tack on extra info + # hash + # check if the hash has "000000" at the start, and then send proof (the thing you added to string before hashing) to /mine + # if it matches proof + # print something + + response = { + # return a 400 error using jsonify(response) with a 'message' + 'match': 'It is a match', + } + return jsonify(response) + else: + response = { + # return a 400 error using jsonify(response) with a 'message' + 'ERROR 400': '400 Error, proof and id are not present', + } + return jsonify(response) +# Return a message indicating success or failure. Remember, a valid proof should fail for all senders except the first. + + + + +# # Get the last block from the server +# # Run the proof_of_work function until a valid proof is found, validating or rejecting each attempt. Use a copy of valid_proof to assist. +# proof = blockchain.proof_of_work(blockchain.last_block) +# # Print messages indicating that this has started and finished. +# # Modify it to generate proofs with 6 leading zeroes. +# # Print a message indicating the success or failure response from the server +# # Add any coins granted to a simple integer total, and print the amount of coins the client has earned +# # Continue mining until the app is interrupted. + + + +# # Run the proof of work algorithm to get the next proof +# proof = blockchain.proof_of_work(blockchain.last_block) +# # Forge the new Block by adding it to the chain with the proof +# previous_hash = blockchain.hash(blockchain.last_block) +# block = blockchain.new_block(proof, previous_hash) + +# response = { +# 'new_block': block +# } +# # return a 400 error using jsonify(response) with a 'message' +# data = request.get_json() + +# return jsonify(response), 200 + + +@app.route('/chain', methods=['GET']) +def full_chain(): + response = { + # TODO: Send a JSON response with the new block + 'chain': blockchain.chain, + 'length': len(blockchain.chain) + } + + return jsonify(response), 200 + + +@app.route('/last_block', methods=['GET']) +def get_last_block(): + # get back in json the last block in the last_block route + # convert to string + # tack on extra info + # hash + # check if the hash has "000000" at the start, and then send proof (the thing you added to string before hashing) to /mine + # get back in json the last block in the last_block route + last_block = blockchain.last_block + if last_block and ("previous_hash" in last_block): + last_block = last_block["previous_hash"] + # convert to string + convert_to_string = str(last_block) + string.ascii_letters + # tack on extra info + newly_generated_alphanumeric_char = random.choice(string.ascii_letters) + newly_generated_alphanumeric_char = newly_generated_alphanumeric_char.lower() + hash_with_added_str = convert_to_string + newly_generated_alphanumeric_char + newly_generated_alphanumeric_char + + hashed_last_block = blockchain.hash(hash_with_added_str) + + response = { + "last_block":hashed_last_block + } + + return jsonify(response), 200 + + +# Run the program on port 5000 +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) + + +#take hash function, take the item at the end of it + +#take information in latest block +# take from last block +#run through hash function, see if it checks out +#see if you hav eenough leading zeros to match + +#a hash of the previous block for guesses + + +#condition to make new block +#someone makes a proof that works + +#take hash of previous block tack characters to end +#find hash to get condition = 3 zeros in front +#if you find, submit the proof +#server check it, yes it is true when i hash with this block, this is what satisfies requirements +#if block gets added you get a lambda coin + + +#check if proof and id are present, use jsonfiy response if not 400 +#id is when you get paid \ No newline at end of file diff --git a/client_mining_p/my_id.txt b/client_mining_p/my_id.txt index 757227a3..fb3493a9 100644 --- a/client_mining_p/my_id.txt +++ b/client_mining_p/my_id.txt @@ -1 +1 @@ -your-name-here +lily