Giter Club home page Giter Club logo

python_blockchain_app's Introduction

python_blockchain_app

A simple tutorial for developing a blockchain application from scratch in Python.

What is blockchain? How it is implemented? And how it works?

Please read the step-by-step implementation tutorial to get your answers :)

Instructions to run

Clone the project,

$ git clone https://github.com/satwikkansal/python_blockchain_app.git

Install the dependencies,

$ cd python_blockchain_app
$ pip install -r requirements.txt

Start a blockchain node server,

$ export FLASK_APP=node_server.py
$ flask run --port 8000

For windows users

set LANG=C.UTF-8
set FLASK_APP=node_server.py
flask run --port 8000

One instance of our blockchain node is now up and running at port 8000.

Run the application on a different terminal session,

$ python run_app.py

For windows users

set LANG=C.UTF-8
set FLASK_APP=run_app.py
flask run --port 8000

The application should be up and running at http://localhost:5000.

Here are a few screenshots

  1. Posting some content

image.png

  1. Requesting the node to mine

image.png

  1. Resyncing with the chain for updated data

image.png

To play around by spinning off multiple custom nodes, use the register_with/ endpoint to register a new node.

Here's a sample scenario that you might wanna try,

# Make sure you set the FLASK_APP environment variable to node_server.py before running these nodes
# already running
$ flask run --port 8000 &
# spinning up new nodes
$ flask run --port 8001 &
$ flask run --port 8002 &

You can use the following cURL requests to register the nodes at port 8001 and 8002 with the already running 8000.

curl -X POST \
  http://127.0.0.1:8001/register_with \
  -H 'Content-Type: application/json' \
  -d '{"node_address": "http://127.0.0.1:8000"}'
curl -X POST \
  http://127.0.0.1:8002/register_with \
  -H 'Content-Type: application/json' \
  -d '{"node_address": "http://127.0.0.1:8000"}'

This will make the node at port 8000 aware of the nodes at port 8001 and 8002, and make the newer nodes sync the chain with the node 8000, so that they are able to actively participate in the mining process post registration.

To update the node with which the frontend application syncs (default is localhost port 8000), change CONNECTED_NODE_ADDRESS field in the views.py file.

Once you do all this, you can run the application, create transactions (post messages via the web inteface), and once you mine the transactions, all the nodes in the network will update the chain. The chain of the nodes can also be inspected by inovking /chain endpoint using cURL.

$ curl -X GET http://localhost:8001/chain
$ curl -X GET http://localhost:8002/chain

python_blockchain_app's People

Contributors

developer79433 avatar inopiae avatar satwikkansal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python_blockchain_app's Issues

Making a POST request to register a new node crashes the node

When I use curl or any other way to make a POST request to http://192.168.8.120:8000/register_with {"node_address": "http://192.168.8.119:8000"}, both front end and backend stop and I'm no longer able to visit the webpage or make any requests.

I have 3 VM's currently setup networked together with static IP addresses:
192.168.8.119 - Node 1
192.168.8.120 - Node 2
192.168.8.121 - Node 3

image

Sending the Post Request

image

What the server shows and continues to show until it times out. At this point everything on this node (192.168.8.120) stops working until the request times out.

image

...

image

Node 1 after the post request is sent

image

Response of the POST request after the request times out

No matter which Node I use or which Node I'm registering, it happens each time.

Quick question about deploying this to share with my class

Hello! I am very new to blockchain, and have been taking a class about it for the past 10 weeks. At the end of the term, the teacher suggested my group follow your tutorial on how to make an actual blockchain with python. After following your guide, I was curious, would there be any way to deploy this so the class can play with it while I am talking about it? If you have any tips on how I can do this that would be great.
Thank you for taking the time,
Trent Farley

How can we generate desired hash code ?

You have mentioned in proof_of_work function that we have to generate hash code until it satisfies our difficulty criteria. But how can we generate different hash codes when hash code for a string remains same no matter how many times we run the algorithm ?

why execute one mine action, confirm all the transactions?

From my understanding, one mine confirms one transaction and records it on one block. So is this something that simulate any real wolrd processing, like bitcoin network? Or, it is just want to keep the things simple to understand?

Can't pop multiple nodes and achieve consensus properly

I have four terminals open at the same time.
In the first terminal I execute:
$ export FLASK_APP=node_server.py && flask run --port 8000

In the second one:
$ flask run --port 8001

In the third one:
$ curl -X POST http://127.0.0.1:8001/register_with -H 'Content-Type: application/json' -d '{"node_address": "http://127.0.0.1:8000"}'
Which outputs "Registration Successful". All good so far.

In the fourth one I type:
$ python run_app.py

Here is the problem. When I visit localhost:5000, a loop is crashing the second node (:8001)
Looking at the second terminal I get this.
Imgur
From my understanding this is caused by the get_chain() method which
calls consensus().
Imgur
But consensus calls get_chain() back!
Imgur

Am I missing something?
Really cool project btw. (As long as you run one node 馃榿)

Request mining button not working

I finish all code like you write.
And also follow your "How to run" instructions.
But when i click any buttons on the webpages, there is a Not Found error.
14
13

URL not Found

Hi Satvik,

I'm facing issue similar to issue 25 and 32. I'm running the server on port 8000 and the application on port 5000, when I enter some text on the app and click mine, it navigates to the URL--http://127.0.0.1:8000/mine which says URL not found. Can you please suggest how do I fix it?

I've attached screenshots for your reference.

![Uploading image.png鈥
Server

application

mine

app not working on chrome

there are several issues after following the instructions given.

  1. first page opens, but the transactions are not recorded anywhere, nor does mining works
  2. all the post methods urls don't work either.(405 method not allowed error)

Not found

The requested URL was not found on the server.

curl -XPOST to \register_with throwing code error

I am new to all of this, including Python, Flask, json, and venv. I have found my way through all issues, but am faced with one I can't resolve.

When I apply all the curl commands to execute the \register_with endpoint, I get an error showing that the the json object in the POST is not subscriptable - a 'NoneType' object is returned. What is up?

Screenshot shows my two nodes running node_server.py, the additional cmd shell with the curl statement, and the node 8001 error message on line 219 of node_server.py. I can't figure this out. Any assistance is appreciated.

image

I hope this image comes through and is useful, I am also new to GitHub.

While this is not a critical issue to my current project (I am expanding some features and functionality for a Python class final project) I would like to understand my failing and further understand this application and how it functions.

Thanks, Peter Thompson

Cannot click buttons on webpage

I finish all code like you write.
And also follow your "How to run" instructions.
But when i click any buttons on the webpages, there is a Not Found error.

404 returned when registering with another node

First of all thanks satwikkansal for an awesome blockchain python tutorial!

When I tried to register a new node with an existing node by using these commands

$ flask run --port 8001

(in  a new terminal tab)$  curl -X POST \
  http://127.0.0.1:8001/register_with \
  -H 'Content-Type: application/json' \
  -d '{"node_address": "http://127.0.0.1:8000"}'

I got this returned back -

<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>

I checked the tab with port 8001, and I found port 8001 does receive this request, but also it shows a 404 error:
127.0.0.1 - - [31/Mar/2020 23:14:21] "POST /register_with HTTP/1.1" 404 -

Could anyone help me overcome this issue? Thanks!

Can麓t execute the Blockchain

Hi there,

actually my problem is similar to this case: [https://github.com//issues/32].
I adapted all recommendations on this solution, but still facing some challenges...

If I want to execute the Blockchain, Pot http://127.0.0.1:8000/ opens:

image

If I want do enter some data, and klick on request to mine, I get Not found:
image

This is how it looks on my terminal:

image

Honestly, I don麓t find my mistake and I guess it might be a really tiny mistake - since am still very new in to programming...

Would be great, if someone could help me/give me a hint!

Thank you so much in advance for your help.

Node Register - Own node_adress never returned

When a new register is done (one node to another), the "parent" node, or the node who receives the request never returns its own node_adress. For that reason, on children Node will be always necessary to register first a node, and then syncing.

I'll open a new branch, but not sure if I'm missing something.

Ty!

Backend storage

In using litecore, I notice the ledger population pickups at the same place where left off if a node is shutdown. This indicates a flat storage of the ledger. Have you considered moving from runtime storage to more of a flat storage. I have been using UnQLite.

Blockchain data goes to node 8000/chain

Hi,

I am trying to retrieve the chain data and post it under the data content on the web page, but all chain data content are being sent node 8000, instead of 5000.

Tutorial no longer accessible

Please Satwik Kansal,
You had a nice text explaning line per line your project at this link:
"Please read the step-by-step implementation tutorial to get your answers :)" [https://www.ibm.com/developerworks/cloud/library/cl-develop-blockchain-app-in-python/index.html]
I was reading and studying using it but IBM remove.
Please, Is this text posted in another place?
Thank you and nice project!

Not able to execute the blockchain

I have followed these steps to run project but I am not able to execute it:

Step 1: I have cloned the complete project from github.

Step 2: I am using windows 10 so I have opened command prompt and set:
SET FLASK_APP=node_server.py
flask run

After executing step 2: I see following message on the screen:

  • Environment: production
    WARNING: This is a development server. Do not use it in a production deployment.
    Use a production WSGI server instead.
  • Debug mode: off
  • Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Step 3:
When i am typing http://127.0.0.1:5000/ in browser it says:

Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

When i checked the trace in command prompt, it says:

HTTPConnectionPool(host='127.0.0.1', port=8000): Max retries exceeded with url: /chain (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x03C0A4A8>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it'))
127.0.0.1 - - [25/Mar/2020 13:44:49] "锟絒35m锟絒1mGET / HTTP/1.1锟絒0m" 500 -

Kind help in this regard is highly appreciated.

How to add another node on local machine?

I trying to add another node by running the app again on port 5001 as I am running one on 5000. I am able to use the free ngrok version to run it that way. If i go to the node server and go to /add_nodes it gives a 405 error. What am I doing wrong?

flask for windows

The link to the windows flask instruction was not fully clear. I wanted to share the resolution for this.

in CMD:

set FLASK_APP=node_server.py
flask run --port 8000

Unable to mine from new node (localhost:8001)

Hi Satwik,

Thanks for putting this all together!
Is it possible to mine from other nodes?

For example, in the web interface (localhost:5000), I post from node1, is it possible to mine the transaction from node2 using the api? When interacting with the API http://localhost:8001/mine, the ledger does not update. The only way that I could mine is through http://localhost:8000/mine.

However, the ledger is being distributed, so it is visible and in sync at both http://localhost:8000/chain AND http://localhost:8001/chain.

At the moment, this project doest seem to support mining from any other nodes accept for port 8000, however, I could be missing something.

Error

Press butto POST generates:
Traceback (most recent call last):
File "c:\pf_c\python38\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "c:\pf_c\python38\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "c:\pf_c\python38\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "c:\pf_c\python38\lib\site-packages\flask_compat.py", line 39, in reraise
raise value
File "c:\pf_c\python38\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "c:\pf_c\python38\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functionsrule.endpoint
File "F:\Alexandria\Devel\GITRepoWork\python_blockchain_app\app\views.py", line 64, in submit_textarea
requests.post(new_tx_address,
File "c:\pf_c\python38\lib\site-packages\requests\api.py", line 119, in post
return request('post', url, data=data, json=json, **kwargs)
File "c:\pf_c\python38\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "c:\pf_c\python38\lib\site-packages\requests\sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "c:\pf_c\python38\lib\site-packages\requests\sessions.py", line 685, in send
r.content
File "c:\pf_c\python38\lib\site-packages\requests\models.py", line 829, in content
self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b''
File "c:\pf_c\python38\lib\site-packages\requests\models.py", line 754, in generate
raise ChunkedEncodingError(e)
requests.exceptions.ChunkedEncodingError: ("Connection broken: ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None)", ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None))
127.0.0.1 - - [29/Nov/2020 19:09:24] "鈫怺35m鈫怺1mPOST /submit HTTP/1.1鈫怺0m" 500 -
Thanks for Your info [email protected]

Request to mine not working

I tried running the code but it says "URL NOT FOUND".You mentioned that the port is running on 8000 instead of 5000. Can you elaborate on the changes to be made?
output
output2
output3

Pin markupsafe version in requirements.txt

When i was trying to run the application as explained in the readme there is an error on the following command

> flask run --port 8000
[.....]
ImportError: cannot import name 'soft_unicode' from 'markupsafe'

After searching online i found that there is a breaking change in the library that has been made recently that causes this issue.
Pinning the version in the requirements fixes the issue.
markupsafe==2.0.1

Internal Server Error (Ubuntu)

Following the instructions in the latest version of ubuntu with the full python stack, we're encountering an internal server error. We put the run_app in debug=false and assigned a static IP to the node and receive a command line error of "Failed to establish a new connection: (Errno 111) connection refused. We have disabled all firewalls and port forwarding.

App not working

i followed your instruction step by steps but when run the app on windows google chrome the error look like.

12

how to run project in a single Port

all is done and work properly but the problem is that in this project we have 2 ports and run separately in two terminals .
terminal 1:
i) node_server.py 127.0.0.1:8000
terminal 2:
ii) run_app.py 127.0.0.1:5000.

i want to run this project in a single port and only one terminal in use.
what are the changes of the code to run this project in a single port instead of two different ports.

Submit transaction to all miners

Shouldn't all miners get notified when a transaction is submitted? If not, it's as if "my miners" validate "my transactions" and so do everyone else's. Instead of having a separation between dealers and miners where the latter compete to validate the transaction of the former. Just wanted to know if this was intentional

Transaction size

I was wondering what is the transaction block size limit since blockchains usually have a 1MB limit on their blocks.

How to add another pc into the network?

I would like to add another pc to the network but not sure on how should I do that.I believed I have to edit this line "CONNECTED_NODE_ADDRESS field in the views.py file" but how should i initialize another node?

Request to mine button not working

I finish all code like you write.
And also follow your "How to run" instructions.
But when i click any buttons on the webpages,
there is a Not Found error.

5
6
7

Implementation is not 100% decentralized

I am new to git! many thanks. 鉂も潳

[instances]

  1. I run a new instance(server) on port=8000.
    2.I run another instance(client) on port=5000.

[running]

  1. I access localhost:5000 and i see UI that I can interact and run commands.
  2. I access localhost:8000 and nothing displayed however command line displays output and executed commands by the client at localhost:5000 (assumption).

[later]

  1. I run yet another (duplicate) instance of port=8000. This port rejects clients or rather the first instance says; "No, I was here first". I still can't use the desired app features.
  2. I run another instance on port=9000 and access localhost:9000. I can use the app without worry.

[conclusions]
If port=8000 goes down then the entire system crashes. All data lost 馃槩

[exceptions handled]
1.
requests.exceptions.ConnectionError
requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=8000): Max retries exceeded with url: /chain (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000232FF828048>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it',))

Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

requests.exceptions.ConnectionError

I have this error: requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=8000): Max retries exceeded with url: /chain (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000021A10EC5C10>: Failed to establish a new connection: [WinError 10061] No se puede establecer una conexi贸n ya que el equipo de destino deneg贸 expresamente dicha conexi贸n'))

what would i do to solve it and run the code? cheers

i suggest to work with threads in the mining process

When a mining started, it can take too long depending on how the difficulty have been configured, so when that operation start the api is waiting the process end before return a response, it's same when trying to access the api with any other endpoint /chain,... etc, so i suggest to use threads as i do:

from threading import Thread

def mine():
    .... mine() content....

...... some code here...
@app.route.....
def request_for_mine():
    .... some code here....
    # Launch the thread for the mine process, so that the API will be still available 
    Thread(target = mine).start() 

    return response

Received a typeerror message JSON as string not as bytes

Hi there,

I love this project... I received a typeerror message on the :5000 instance. This was resolved by replacing

chain = json.loads(response.content)

with

chain = json.loads(response.content.decode('utf-8'))

in the '/app/view.py' file

Changes to be made views.py

"To update the node with which the frontend application syncs (default is localhost port 8000), change CONNECTED_NODE_ADDRESS field in the views.py file"

CONNECTED_NODE_ADDRESS = "http://127.0.0.1:8000"

What change has to be made to views.py ?

mining reward

where do you save reward transaction for mining a block ?
Thanks

check_chain_validity() being redundant

During consensus, we are checking the validity of chain.
chain = response.json()['chain'] is used to get the chain.
But during the registration process, we use create_chain_from_dump() function.
Inside the function, we create new block without hash attribute and add that block to a dummy blockchain using add_block method, which itself performs all hash related checks.
so if we use create_chain_from_dump to get the chain during the consensus step, check_chain_validity is redundant.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    馃枛 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 馃搳馃搱馃帀

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google 鉂わ笍 Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.