diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..e7e9d11d
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,2 @@
+# Default ignored files
+/workspace.xml
diff --git a/.idea/Blockchain.iml b/.idea/Blockchain.iml
new file mode 100644
index 00000000..f67c1c68
--- /dev/null
+++ b/.idea/Blockchain.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..105ce2da
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..c8dce967
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..be782971
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..94a25f7f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Pipfile.lock b/Pipfile.lock
index da56139b..3839443f 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": [
@@ -39,18 +39,18 @@
},
"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:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
+ "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
- "version": "==2.6"
+ "version": "==2.8"
},
"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:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
+ "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
],
"index": "pypi",
- "version": "==2.18.4"
+ "version": "==2.22.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/basic_block_gp/blockchain.py b/basic_block_gp/blockchain.py
index 54ead5c1..4e763263 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.last_block)
}
# Reset the current list of transactions
+ self.current_transactions = []
# Append the chain to the block
+ self.chain.append(block)
# Return the new block
- pass
+ return block
def hash(self, block):
"""
@@ -48,12 +54,18 @@ def hash(self, block):
"""
# Use json.dumps to convert json into a string
+ # (not necessary on pythn3) makes sure all keys in dictionary turned into string in alphebecic order
+ string_block = json.dumps(block, sort_keys=True)
# Use hashlib.sha256 to create a hash
# It requires a `bytes-like` object, which is what
# .encode() does.
+ # change string block to .encode() to change from object to string
+ 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 version comes raw hash
+
# TODO: Create the block_string
@@ -64,9 +76,10 @@ def hash(self, block):
# 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
+ hex_hash = raw_hash.hexdigest()
# TODO: Return the hashed block string in hexadecimal format
- pass
+ return hex_hash
@property
def last_block(self):
@@ -80,14 +93,18 @@ def proof_of_work(self, block):
in an effort to find a number that is a valid proof
: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):
"""
- Validates the Proof: Does hash(block_string, proof) contain 3
+ Validates the Proof: Does hash(block_string, proof) contain 3 -- add 2 strings together
leading zeroes? Return true if the proof is valid
:param block_string: The stringified block to use to
check in combination with `proof`
@@ -97,8 +114,10 @@ def valid_proof(block_string, proof):
:return: True if the resulting hash is a valid proof, False otherwise
"""
# TODO
- pass
- # return True or False
+ guess = f'{block_string}{proof}'.encode()
+ guess_hash = hashlib.sha256(guess).hexdigest()
+ # slice off first 3 and see if it = all 0's
+ return guess_hash[:6] == '000000'
# Instantiate our Node
@@ -114,11 +133,14 @@ 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
@@ -127,7 +149,8 @@ def mine():
@app.route('/chain', methods=['GET'])
def full_chain():
response = {
- # TODO: Return the chain and its current length
+ 'chain': blockchain.chain,
+ 'length': len(blockchain.chain),
}
return jsonify(response), 200