To illustrate how apps can be decentralized with the Zellular Sequencer, let’s look at a basic order book created using Python with Flask for handling user orders and SQLite for data storage. This example is streamlined, focusing solely on demonstrating the practical integration with the Zellular Sequencer, and does not include the extensive features of a full-scale implementation.
Python Code for a Simple Order-Book
The complete code for the sample order book is available at . Below is a brief overview of the code structure:
Setting up the Environment
This section sets up the basic Flask application and the database:
match_order and update_balances implement the core logic of matching orders and updating users balances:
def match_order(new_order):
# Logic to find and process matching orders
...
def update_balances(new_order, matched_order, trade_quantity):
# Logic to update balances after matching orders
...
To decentralize an app like the order-book using the Zellular Sequencer, start by switching to a signature-based authentication system. Here’s how to do it:
Since username and password are no longer needed for authentication, the User table can be eliminated. Additionally, update the user_id field in the Order and Balance table to reference the user’s public_key, which serves as the user identifier in the new version.
class Balance(db.Model):
public_key = db.Column(db.String(500), primary_key=True)
...
class Order(db.Model):
...
public_key = db.Column(db.String(500), nullable=False)
...
Remove the login function, as session-based authentication is no longer used, and users sign every request. Add a signature parameter to the place_order function, using this signature to verify access authorization instead of relying on user sessions.
from ecdsa import VerifyingKey, SECP256k1, BadSignatureError
...
def verify_order(order):
# Serialize the data from the form fields
keys = ['order_type', 'base_token', 'quote_token', 'quantity', 'price']
message = ','.join([order[key] for key in keys]).encode('utf-8')
# Verify the signature
try:
public_key = base64.b64decode(order['public_key'])
signature = base64.b64decode(order['signature'])
vk = VerifyingKey.from_string(public_key, curve=SECP256k1)
vk.verify(signature, message)
except (BadSignatureError, ValueError):
return False
return True
@app.route('/order', methods=['POST'])
def place_order():
if not verify_order(request.form):
return jsonify({"message": "Invalid signature"}), 403
...
The next step in decentralizing the app is to send user-signed orders to the Zellular Sequencer before applying them to the database and update the database after receiving them back from the sequencer. This helps all the nodes running the app apply the requests in a consistent order. Here’s how it should be done:
After signature verification, the place_order function uses the POST /node/{app}/batches endpoint of the Zellular Sequencer service to send the orders to the sequencer before applying them into the database.
zsequencer_url = 'http://5.161.230.186:6001/node/orderbook/batches'
...
@app.route('/order', methods=['POST'])
def place_order():
if not verify_order(request.form):
return jsonify({"message": "Invalid signature"}), 403
keys = ['order_type', 'base_token', 'quote_token', 'quantity', 'price', 'signature']
txs = [{key: request.form[key] for key in keys}]
requests.put(zsequencer_url, json=txs)
return { 'success': True }
import zellular
def process_loop():
verifier = zellular.Verifier("orderbook", "http://5.161.230.186:6001")
for batch, index in verifier.batches():
txs = json.loads(batch)
for i, tx in enumerate(txs):
place_order(tx)
def __place_order(order):
if not verify_order(order):
print("Invalid signature:", order)
return
...
if __name__ == '__main__':
Thread(target=process_loop).start()
app.run(debug=True)
User Authentication
Order Submission
Order Matching
Applying Signature-based Authentication
Identifying Users by their Public Keys
Authorising Users by their Signatures
Sequencing orders before applying them
Sending orders to the Sequencer
Receiving sequenced orders from the sequencer
Add a thread to continuously retrieve finalized, sequenced orders and apply the same routine used in the place_order function to process these orders. can be used to pull the finalized sequence of transaction batches from the Zellular network.
The complete code for the decentralized version of the sample order book can be accessed . Additionally, you can view the GitHub comparison between the centralized and decentralized versions . As demonstrated, integrating the Zellular Sequencer into your apps is straightforward and accessible for any Python developer, without requiring deep expertise in blockchain or smart contracts.