hello stranger 👋
dvf / blockchain Goto Github PK
View Code? Open in Web Editor NEWA simple Blockchain in Python
License: MIT License
A simple Blockchain in Python
License: MIT License
hello stranger 👋
There is a need to add implementation of following CIs in this project.
Yes, I would like to work on this issue
:blockchain-master Vaibhav$ docker run --rm -p 80:5000 blockchain
Tried everything from 127.0.0.1:80 to localhost:5000
But everytime i get same 404 error.
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Line 50-51 in blockchain.py
print(f'{last_block}')
print(f'{block}')
My compiler reads this as invalid syntax. I have never seen python syntax like that, care to explain what it means?
Your docstrings need improvement::
:param last_proof: <int> Previous Proof
:param proof: <int> Current Proof
:return: <bool> True if correct, False if not.
this is a bit weired, if you consider sphinx, which is the default, you would write it like this::
:param last_proof: previous proof
:type last_proof: int
:param proof: current proof
:type proof: int
:rtype: bool
Hey @dvf, have you thought about putting up on Digital Ocean or somewhere? I thought it could be fun to have a few nodes up and running.
Interestingly, you start having to solve issues of bootstrapping and discovery once you do that - just like a real blockchain!
Thank you for the kind article
I enjoyed it and tried to reproduce it and play it
I got this error
I used python==3.6.3, Flask==0.12.2, and requests==2.18.4
File ".\blockchain.py", line 204, in mine
block = blockchain.new_block(proof)
TypeError: new_block() missing 1 required positional argument: 'previous_hash'
I installed pyhton 3.6.4.But when I exec the cmd pip install pipenv
,I got some Exception.
Exception: Traceback (most recent call last): File "/home/linux/.local/lib/python2.7/site-packages/pip/basecommand.py", line 215, in main status = self.run(options, args) File "/home/linux/.local/lib/python2.7/site-packages/pip/commands/install.py", line 342, in run prefix=options.prefix_path, File "/home/linux/.local/lib/python2.7/site-packages/pip/req/req_set.py", line 784, in install **kwargs File "/home/linux/.local/lib/python2.7/site-packages/pip/req/req_install.py", line 851, in install self.move_wheel_files(self.source_dir, root=root, prefix=prefix) File "/home/linux/.local/lib/python2.7/site-packages/pip/req/req_install.py", line 1064, in move_wheel_files isolated=self.isolated, File "/home/linux/.local/lib/python2.7/site-packages/pip/wheel.py", line 345, in move_wheel_files clobber(source, lib_dir, True) File "/home/linux/.local/lib/python2.7/site-packages/pip/wheel.py", line 323, in clobber shutil.copyfile(srcfile, destfile) File "/usr/lib/python2.7/shutil.py", line 83, in copyfile with open(dst, 'wb') as fdst: IOError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/pathlib.pyc'
could you help me?Thanks in advance
My OS is ubuntukylin-16.04-desktop-amd64(Linux version 4.4.0-21-generic)
I have following error:
ERROR in app: Exception on /transactions/new [POST]
File "C:/Users/小草/Downloads/Compressed/blockchain-master/blockchain-master/blockchain.py", line 237, in new_transaction
if not all(k in values for k in required):
File "C:/Users/小草/Downloads/Compressed/blockchain-master/blockchain-master/blockchain.py", line 237, in
if not all(k in values for k in required):
TypeError: argument of type 'NoneType' is not iterable
Hello,
I am a n00b at python and I C&P blockchain.py into a file on my Ubuntu server running on an OrangePi PC. The OS is Armbian with Ubuntu Server 16.04. I followed the tutorial on HackerNoon as well.
The error:
File "blockchain.py", line 7, in
import requests
ModuleNotFoundError: No module named 'requests'
Any ideas would be helpful, I really like how this integrates HTTP requests when other examples I found do not.
as the title.
when i have 2 node
http://127.0.0.1:5000
chain:
{ "chain": [ { "index": 1, "previous_hash": "1", "proof": 100, "timestamp": 1520730726.336663, "transactions": [] }, { "index": 2, "previous_hash": "68017de6ce598dc398c5f0a4798dbcb89131f260347df5faed3e8b7afccdace1", "proof": 161458, "timestamp": 1520730744.8993568, "transactions": [ { "amount": 1, "recipient": "86d8dd6c88b740e4854c777a4a1181b3", "sender": "0" } ] } ], "length": 2 }
http://127.0.0.1:5001
chain:
{ "chain": [ { "index": 1, "previous_hash": "1", "proof": 100, "timestamp": 1520730719.285117, "transactions": [] }, { "index": 2, "previous_hash": "7c644d59e6db9aa7fdfd3017695e9623dd72eaec364b2c6868a8b95861b13641", "proof": 90033, "timestamp": 1520730754.616982, "transactions": [ { "amount": 1, "recipient": "cff17fd013b24dc780c576b741dc3fdb", "sender": "0" } ] }, { "index": 3, "previous_hash": "13cca2f4b1c7481438e96ef531b917764a680e5e73701fe9eb34afec724a0a3d", "proof": 23126, "timestamp": 1520730788.67462, "transactions": [ { "amount": 1, "recipient": "cff17fd013b24dc780c576b741dc3fdb", "sender": "0" } ] } ], "length": 3 }
It can't sync chain data.
I've added some basic tests with Travis, but we still need to test the Proof of Work algorithm.
If anyone would like to help out please feel welcome!
I get a 405 Method Not Allowed error when running this. Did anyone else have this issue? I am running code directly pulled from this repo
I think it would be great to display the current information from the blockchain such as the number of users, transactions, and coins within the process.
File "blockchain.py", line 260, in register_nodes
nodes = values.get('nodes')
AttributeError: 'NoneType' object has no attribute 'get'
Is anyone else having this issue?
I think you have mistake in line 58:
if not self.valid_proof(last_block['proof'], block['proof'], last_block['previous_hash']):
should be:
if not self.valid_proof(last_block['proof'], block['proof'], block['previous_hash']):
resolve_conflicts() does not work because there is an error of 58 line.
https://github.com/dvf/blockchain/blob/master/blockchain.py#L58
...
if not self.valid_proof(last_block['proof'], block['proof'], last_block['previous_hash']):
...
should be
...
if not self.valid_proof(last_block['proof'], block['proof'], block['previous_hash']):
...
the parameter "last_block['previous_hash']" is wrong, should be "block['previous_hash']".
After I debug it, the code does work.
We should write some tests...
I was following the recommended steps to setup the project with pipenv, but pipenv is somehow not being installed into the path.
I tried pip install pipenv
with and without sudo
on MacOS, with no luck. The install appears successful, but I only get "command not found" when I try to run pipenv
Any suggestions?
(As a side note, how do I attach a label to an issue? I saw the suggestion to add a "help wanted" label but I don't see how to add that.)
There seems to be an error in the following line of code: https://github.com/dvf/blockchain/blob/master/blockchain.py#L58
The third parameter should be block['previous_hash']
, not last_block['previous_hash']
.
I read your post https://hackernoon.com/learn-blockchains-by-building-one-117428612f46
and implement with django, django rest framework https://github.com/skyepodium/blockchain_django
your post is very helpful and make easy to learn about blockchain
but i have a question
when i shut down or restart django server, Blockchain class disappeared. because of a lifecycle
summary
How can I safely manage the block chain regardless of the server restart?
Looking at the code, it looks to me that the proofs don't depend on the hash of a block. Couldn't I change the block and rehash everything?
So I could change transaction information, change the 'previous_hash' accordingly, and then leave the proofs the same?
The crux of the matter seems to be that the validity of the proof only depends on the current proof and the last_proof. No where does it depend on the previous_hash
nor on the current hash of the block
In the valid_proof
method
guess = f'{last_proof}{proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
It would be nice to see the same implementation in some popular languages:
JavaScript, TypeScript, C#, Go.
Any takers?
def resolve_conflicts(self) -> bool:
...
# Replace our chain if we discovered a new, valid chain longer than ours
if new_chain:
self.chain = new_chain
+ self.current_transactions = []
return True
Hey,
Just out of pure curiosity, if I were to add a data
field to the block, what would be the adequate minimum size limit that would work without breaking the internet? I say size and not length because I am interested in storing chunks of binary(3-5mb) each. Is this even possible?
Cheers,
blockchain/tests/test_blockchain.py
Line 38 in 250a01c
Hello People,
I was reading your code, what a nice little project !
I've been asking myself about the "Proof-of-Work" (PoW) part. I think PoW might be somehow broken. As far as I understand, "Proof-of-Work" is done before rewarding the miner, i.e. a node finds a solution, then a new block is created including the "proof". Finally, the node pushes a new transaction that rewards itself. But this last transaction is not "linked" to any other in a sense that one would be able to easily modify it and to forge a new transaction that gives one the fresh mined coin (i.e. one could use a proof that he did not generate). It would be very easy to "correct" it so far, moving the proof_of_work right after the new_transaction instruction.
Actually, it seems there is something more painful as none of the "current block transactions" are part of PoW. Since then, one could forge a whole new block without any effort based on the last proof.
Maybe Am I misunderstanding the whole design ?
Thanks for your project,
I think I'll contribute to it very soon :-)
I tried to run the docker container after a successful build and ran into this error:
Traceback (most recent call last):
File "/app/blockchain.py", line 12, in <module>
class Blockchain:
File "/app/blockchain.py", line 135, in Blockchain
def last_block(self) -> Dict[str: Any]:
File "/usr/local/lib/python3.6/typing.py", line 682, in inner
return func(*args, **kwds)
File "/usr/local/lib/python3.6/typing.py", line 1106, in __getitem__
params = tuple(_type_check(p, msg) for p in params)
File "/usr/local/lib/python3.6/typing.py", line 1106, in <genexpr>
params = tuple(_type_check(p, msg) for p in params)
File "/usr/local/lib/python3.6/typing.py", line 374, in _type_check
raise TypeError(msg + " Got %.100r." % (arg,))
TypeError: Parameters to generic types must be types. Got slice(<class 'str'>, typing.Any, None).
Please help. TIA
I get the following error
File "/Users/cgriffin1/Desktop/blockchain-master/blockchain.py", line 7, in
import requests
ModuleNotFoundError: No module named 'requests'
Hey,
All dependencies are installed:
If I run two nodes and I want to register one to the other, I get this error:
AttributeError: 'NoneType' object has no attribute 'get'
I use Postman and do a POST
to http://localhost:5000/nodes/register
With this body:
{
"nodes": ["http://127.0.0.1:5001"]
}
I started the nodes like this:
$ pipenv run python blockchain.py
$ pipenv run python blockchain.py -p 5001
Same with adding new transactions.
POST
to http://localhost:5000/transactions/new
:
{
"sender": "d4ee26eee15148ee92c6cd394edd974e",
"recipient": "ae348f5c97d14ec887b922699628e8c0",
"amount": 1
}
Here the full error:
[2017-11-16 20:50:33,482] ERROR in app: Exception on /transactions/new [POST]
Traceback (most recent call last):
File "~/.local/share/virtualenvs/blockchain-ji30_lee/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "~/.local/share/virtualenvs/blockchain-ji30_lee/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "~/.local/share/virtualenvs/blockchain-ji30_lee/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "~/.local/share/virtualenvs/blockchain-ji30_lee/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "~/.local/share/virtualenvs/blockchain-ji30_lee/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "~/.local/share/virtualenvs/blockchain-ji30_lee/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "blockchain.py", line 221, in new_transaction
if not all(k in values for k in required):
File "blockchain.py", line 221, in <genexpr>
if not all(k in values for k in required):
TypeError: argument of type 'NoneType' is not iterable
127.0.0.1 - - [16/Nov/2017 20:50:33] "POST /transactions/new HTTP/1.1" 500 -
What am I doing wrong?
The /chain request handler could lie about its own chain's length being longer than the actual number of items in the chain because the consensus code doesn't check that the number of items matches the length field value. Theoretically, this could be used to impose one's own chain on all nodes. Effects might include: falsifying transactions and deletion of transactions for profit.
Full disclosure on the bug report because I understand that the spirit of this code was a learning exercise.
Found this code via: https://hackaday.com/2017/11/23/learn-about-blockchains-by-building-one/ "You are not going to launch a cryptocurrency using this code..." (correct!), and https://hackernoon.com/learn-blockchains-by-building-one-117428612f46
In the program Postman when I do GET http://localhost:5001/mine, I receive the Error Message: "Something went wrong. And we are reporting a custom error message."
In the CMD on Win7 the blockchain.py is running correctly.
I'm stuck on this step.
File "blockchain.py", line 50
print(f'{last_block}')
^
SyntaxError: invalid syntax
that single quote mark has some problems ,could you please help me...
When trying to open http://localhost:5000/mine this error jumps up
127.0.0.1 - - [01/May/2018 18:00:58] "GET /mine HTTP/1.1" 500 -
Traceback (most recent call last):
"BlockChain.py", line 125, in mine
amount=1,
TypeError: new_transaction() got an unexpected keyword argument 'sender'
I'm using Python 3
Trying to get concensus working but having a problem. Not sure what I'm doing wrong. Here are the steps I'm taking.
Pre-requisites: Build from dockefile on two hosts, one with IP of 10.0.0.10 and 10.0.0.20.
curl -X POST -H "Content-Type: application/json" -d '{
"nodes": ["http://10.0.0.20"] }' http://10.0.0.10/nodes/register
Verify that the chain is longer on by browsing to both http://10.0.0.10/chain and http://10.0.0.20/chain
Browse to http://10.0.0.10/nodes/resolve
At this point I expect the chain from 10.0.0.20 to be adopted on 10.0.0.10. However, 10.0.0.10 claims "our chain is authoritative" and doesn't grab the longer chain from 10.0.0.20. Any ideas on what I might be doing wrong?
@dvf I really hope you're not working in real life like you do here... 19 open pull requests? You wanted collaboration and got it - seems like you don't know what to do with it!
Really, i understand that this is your project and you don't have to do anything you don't want to but then state that. That's not what you did. You requested ports and you got them. Now it's your turn(?). TIME TO MERGE BROTHER!! You seem to absolutely not give a shit that people care about this project.
Sure, they all can just fork it and play around but your project aggregates people that really like it and want to contribute and bring this idea further. Now what you do is, not give a shit about all of that.
That's surely a valid decision but not the one with the most brains bro. I really hope you're better organized in real life, really...
This is one of those things that absolutely show that you are not capable of getting shit done - which is of course just my personal subjective opinion.
"I then mined some new Blocks on node 2, to ensure the chain was longer. Afterward, I called GET /nodes/resolve on node 1, where the chain was replaced by the Consensus Algorithm:"
i follow the steps, but redo the several times , the code cant run to “ 'message': 'Our chain was replaced',”, it seem like some anything wrong “replaced = blockchain.resolve_conflicts()” ?
dont understand when i run three instances for docker, and miner insert some data, then make three instances list is not same(node_B list data more node_A) ,then add register node node_A to node_B , then POST node_B "nodes/resolve". but wait a little long time,(it seem like node_B replace the list ) but the node_B is not changed, it is so wried ....
thx for help~
Hi there, when I try setup 2 nodes I cannot get them to operate on the same chain.
Does anyone have a solution to this?
Awesome project/blog.
Has anyone ran into the following error? First time Postman user so i have a hunch im not using the ui correctly...
Thanks in advance,
G
TypeError: argument of type 'NoneType' is not iterable
127.0.0.1 - - [23/Nov/2017 13:56:27] "POST /transactions/new HTTP/1.1" 500 -
[2017-11-23 13:57:17,723] ERROR in app: Exception on /transactions/new [POST]
Traceback (most recent call last):
File "/Users/StrattonStudios/.pyenv/versions/qblockchain/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/Users/StrattonStudios/.pyenv/versions/qblockchain/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/StrattonStudios/.pyenv/versions/qblockchain/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/StrattonStudios/.pyenv/versions/qblockchain/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/StrattonStudios/.pyenv/versions/qblockchain/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/StrattonStudios/.pyenv/versions/qblockchain/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functionsrule.endpoint
File "blockchain.py", line 215, in new_transaction
if not all(k in values for k in required):
File "blockchain.py", line 215, in
if not all(k in values for k in required):
TypeError: argument of type 'NoneType' is not iterable
I have blockchain.py running on 2 OrangePi Ubuntu servers. I am eager to see the 2 synchronize but am having trouble doing so.
I can mine and view the chain with no problems. I created a bunch of blocks on 1 server and want to get the other server synced. When I try to access /nodes/register and /transactions/new I get a 405 Method Not Allowed - The method is not allowed for the requested URL.
Am I missing a step?
There is a need to add implementation of unittests, Pytest and Flake8 in this project.
Yes, I would like to work on this issue
Sorry if this is the wrong place to ask this kind of questions, but this is the closest I could find to a place to discuss blockchain technologies related stuff that isn't exactly related to some specific implementation.
With that out of the way...
If mining farms are so expensive and inefficient why are't they disincentivized?
I'm asking because there are some cryptocurrencies that have mining pools that leverage their collective computational power, in a way that's more efficient for each node connected to the pool and also for the network as a whole.
Will you come out with part 2 with Transaction Validation Mechanism?
From this link https://hackernoon.com/learn-blockchains-by-building-one-117428612f46
I'm working on Part 2. So I thought I'd share a bit of the roadmap. I'm aiming on publishing sometime in the next week but still have a few hurdles and could use your expertise.
Hop on to our Slack if you wanna get involved.
get_chain
, post_transactions
, get_nodes
, post_block
, ...aiohttp
over Flaskasyncio
allows us to have an event loop for introspection (and pinging other nodes)private.key
, public.key
which should be generated before runtime.None of the commands work except for printing the chain and mining. All other commands do not work.
see: #50
The underlying exploit to tamper with a blockchain is described there
props to: @TimelessP
The fix should be fairly simple:
affected file: blockchain/blockchain.py
Line 82 in 4010cf3
A noted, currently it reads:
if length > max_length and self.valid_chain(chain):
@TimelessP suggests a change as follows:
if length > max_length and self.valid_chain(chain) and length == len(chain):
(and then of course the same fix needs to be applied to the C# code)
Additionally, be sure to log offending hosts.
@property def last_block(self) -> Dict[str : Any]: return self.chain[-1]
should be:
@property def last_block(self) -> Dict[str , Any]: return self.chain[-1]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.