Topic Web and software engineering

Python Blockchain Libraries, and a Simple Chain in Python

The short answer

There's no single Python blockchain library. Python builds the parts around a chain: hashlib for hashing a prototype chain, web3.py for reading and writing to Ethereum-style networks, Ape for testing contracts, and pycoingecko for market data. Production smart contracts are written in the chain's own language, such as Solidity or Vyper.

Written by

Siddharth Kajaria, Founder and CEO

Published

Updated

Reading time

11 min read

At a jeweller's bench, pliers close one new red link into a chain, with a loupe, a small scale and spare links nearby.
In this post11 min read
  1. Which Python blockchain library should you use?
  2. Can you build a blockchain in Python?
  3. How do you connect Python to a real blockchain?
  4. Is Python good for smart contracts?
  5. Where Python fits in a blockchain product
  6. How we’d build it for a fintech product

Key takeaways

Python is rarely the language a blockchain runs on, and almost always a language people use around one. Developers reach for it to prototype a chain and learn how one works, to test and deploy smart contracts, to read on-chain data into a database, and to build the APIs, reports and back-office tools a blockchain product needs.

This guide covers the Python blockchain libraries people search for and what each one actually does. It then builds a small working chain in plain Python, connects to a real test network with web3.py, and ends with how we’d decide where Python belongs in a fintech product.

Which Python blockchain library should you use?

The right Python blockchain library depends on the job: hashlib for building a chain yourself, web3.py for working with Ethereum-style networks, Ape for testing and deploying contracts, and pycoingecko for market data. Expect to combine two or three of them in one project.

Library or tool What it does Use it when
hashlib (standard library) SHA-256 and other hash functions You are building or teaching a simple chain
web3.py Connects to Ethereum and EVM-compatible nodes: reads blocks, balances and contract state, signs and sends transactions Your product reads from or writes to a public or private EVM chain
eth-account Creates keys and signs messages and transactions (web3.py uses it underneath) You manage keys or sign offline
Ape A Python framework to compile, test and deploy smart contracts You write contracts and want Python tests around them
Vyper A contract language with Python-like syntax that compiles for the Ethereum Virtual Machine Your team prefers Python-style syntax for contracts
Algorand Python Write Algorand smart contracts in a subset of Python You build on Algorand
python-bitcoinlib Bitcoin data structures, scripts and transactions You work with Bitcoin transactions directly
solana-py and solders Python clients for the Solana network You build on Solana
pycoingecko A wrapper for the CoinGecko API: prices and market data You need prices for a dashboard or a report, not chain access

A few names come up in searches more often than they come up in real projects. pyblockchain and pychain are the names of small, mostly educational projects rather than one maintained library. Before you depend on any of them, check the repository: when it was last released, whether issues get answers, and whether its licence suits your product. Brownie, the Python contract framework many older tutorials use, now says in its own README that it is no longer actively maintained, and its maintainers point users to Ape.

Hyperledger Fabric, a framework for permissioned business chains, is often listed as a Python option. Its smart contracts (chaincode) are written in Go, Java or JavaScript, so Python’s role there is the application around the network, not the contracts.

Can you build a blockchain in Python?

Yes: with the standard library alone you can build a working chain of hashed, linked blocks with proof of work and a validity check. The version below is about 60 lines. It is not a network (there are no peers and no consensus between nodes), but it shows exactly what a chain is.

import hashlib
import json
import time


def sha256(data: dict) -> str:
    # Sort the keys so the same block always hashes to the same value
    encoded = json.dumps(data, sort_keys=True).encode()
    return hashlib.sha256(encoded).hexdigest()


class Blockchain:
    def __init__(self, difficulty: int = 4):
        self.difficulty = difficulty
        self.pending = []
        self.chain = []
        self.add_block(previous_hash="0" * 64)  # the genesis block

    def add_transaction(self, sender: str, recipient: str, amount: int) -> None:
        self.pending.append({"sender": sender, "recipient": recipient, "amount": amount})

    def proof_of_work(self, block: dict) -> dict:
        # Try nonces until the block's hash starts with `difficulty` zeros
        block["nonce"] = 0
        while not sha256(block).startswith("0" * self.difficulty):
            block["nonce"] += 1
        return block

    def add_block(self, previous_hash: str = "") -> dict:
        block = {
            "index": len(self.chain),
            "timestamp": time.time(),
            "transactions": self.pending,
            "previous_hash": previous_hash or sha256(self.chain[-1]),
        }
        self.chain.append(self.proof_of_work(block))
        self.pending = []
        return block

    def is_valid(self) -> bool:
        for prev, block in zip(self.chain, self.chain[1:]):
            if block["previous_hash"] != sha256(prev):
                return False  # a link in the chain is broken
            if not sha256(block).startswith("0" * self.difficulty):
                return False  # the block skipped its proof of work
        return True


chain = Blockchain()
chain.add_transaction("asha", "ravi", 25)
chain.add_block()
print(len(chain.chain), chain.is_valid())  # 2 True

chain.chain[1]["transactions"][0]["amount"] = 2500  # tamper with history
print(chain.is_valid())  # False

Run it with python3 chain.py. It prints 2 True, then False once a past transaction is changed. It runs on Python 3.9 and later with nothing to install.

How the code works

Four ideas carry the whole thing:

  • Hashing. sha256() turns a block into a fixed-length fingerprint. Change one character of the block and the fingerprint changes completely. Sorting the JSON keys keeps the fingerprint stable for the same data.
  • Linking. Each block stores the hash of the block before it in previous_hash. Editing an old block changes its hash, which no longer matches the link stored in the next block.
  • Proof of work. proof_of_work() keeps changing the nonce until the block’s hash starts with a set number of zeros. Finding that nonce takes many attempts, and checking it takes one. Raise difficulty from 4 to 5 and mining takes roughly 16 times longer.
  • Validation. is_valid() walks the chain and checks both rules for every block. In the example, the tampered block fails the proof-of-work check, because its new hash almost certainly no longer starts with four zeros. In a longer chain, an attacker who re-mined the tampered block would still be caught, because the link check on the next block would fail.

What a toy chain leaves out

A real network adds the parts that make a chain trustworthy between strangers.

4 parts a real network adds

  1. 01

    Signatures

    Transactions are signed with the sender’s private key, so nobody can spend on someone else’s behalf. In Python, eth-account or the cryptography package handles this.

  2. 02

    Peers and consensus

    Many nodes hold copies of the chain and agree on one history, through proof of work, proof of stake or a voting protocol in permissioned networks.

  3. 03

    Merkle trees

    Blocks commit to their transactions through a single root hash, so a light client can prove one transaction is included without downloading the block.

  4. 04

    Storage and state

    Real nodes persist blocks to disk and keep a state database (balances, contract storage) that is updated block by block.

You don’t need to build these yourself for a product. Node software for the major networks already exists, written in languages such as Go, Rust, C++ and Java. Python’s job is to talk to it.

How do you connect Python to a real blockchain?

You connect Python to a real blockchain through web3.py and an RPC endpoint: a URL for a node you run or rent from a node provider. Start on a test network such as Sepolia, where the currency has no value and you can get test funds from a public faucet.

Install it with pip install web3. The examples below use the web3.py version 7 names; older tutorials use version 6 names such as rawTransaction.

import os
from decimal import Decimal

from web3 import Web3

w3 = Web3(Web3.HTTPProvider(os.environ["SEPOLIA_RPC_URL"]))
print(w3.is_connected(), w3.eth.block_number)

address = Web3.to_checksum_address(os.environ["MY_ADDRESS"])
balance = w3.eth.get_balance(address)
print(w3.from_wei(balance, "ether"), "test ETH")

Read a smart contract

To read a contract you need its address and its ABI, the description of its functions. This reads a token balance from any ERC-20 token contract, using only the two functions it needs:

ERC20_ABI = [
    {"name": "balanceOf", "type": "function", "stateMutability": "view",
     "inputs": [{"name": "owner", "type": "address"}],
     "outputs": [{"name": "", "type": "uint256"}]},
    {"name": "decimals", "type": "function", "stateMutability": "view",
     "inputs": [], "outputs": [{"name": "", "type": "uint8"}]},
]

token = w3.eth.contract(
    address=Web3.to_checksum_address(os.environ["TOKEN_ADDRESS"]), abi=ERC20_ABI
)
raw = token.functions.balanceOf(address).call()
print(Decimal(raw) / 10 ** token.functions.decimals().call())

Send a transaction

Sending changes state, so it needs a signature from your private key and a fee. Keep the key in an environment variable or a secrets manager, never in the code or the repository.

account = w3.eth.account.from_key(os.environ["PRIVATE_KEY"])
base_fee = w3.eth.get_block("latest")["baseFeePerGas"]

tx = {
    "to": Web3.to_checksum_address(os.environ["RECIPIENT"]),
    "value": w3.to_wei(Decimal("0.001"), "ether"),
    "nonce": w3.eth.get_transaction_count(account.address),
    "gas": 21000,  # a plain transfer
    "maxPriorityFeePerGas": w3.to_wei(1, "gwei"),
    "maxFeePerGas": base_fee * 2 + w3.to_wei(1, "gwei"),
    "chainId": 11155111,  # Sepolia
}
signed = account.sign_transaction(tx)
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(receipt.status)  # 1 means it succeeded

The same pattern covers contract writes: build the call with token.functions.transfer(to, amount).build_transaction({...}), sign it and send it.

Read market data with pycoingecko

When you need prices rather than chain data, pycoingecko is the short route. It calls CoinGecko’s API, so check their current terms and rate limits before you depend on it in a product.

from pycoingecko import CoinGeckoAPI

cg = CoinGeckoAPI()  # or CoinGeckoAPI(demo_api_key="...") with a free Demo key
print(cg.get_price(ids="bitcoin,ethereum", vs_currencies="inr"))

Is Python good for smart contracts?

Python is not the usual language for the contract itself, but it is very good for everything around it. On Ethereum and other EVM chains, contracts are mostly written in Solidity, or in Vyper, which borrows Python’s syntax and keeps the language small on purpose. Algorand is one exception: its tooling compiles a subset of Python into contract code.

Where Python earns its place is the work around the contract:

  • Testing. Ape runs contract tests written in Python against a local chain, so you can test edge cases (a zero transfer, a missing approval, a paused contract) before anything is deployed.
  • Deployment scripts. The same scripts deploy to a testnet first and a main network later, with the addresses recorded.
  • Monitoring. A Python worker watches the contract’s events and alerts someone when something unusual happens.

Where Python fits in a blockchain product

Most of a blockchain product is ordinary software, and much of it suits Python well. These five jobs are where it fits best.

5 jobs for Python

  1. 01

    Indexing

    A worker reads contract events with web3.py (get_logs, or a contract’s events filters) and writes them to PostgreSQL, so the app can query history from its own database instead of asking the chain each time.

  2. 02

    APIs

    Django, FastAPI or Flask serve the app and the admin panel from that indexed data. See our Python web development services for how we’d structure that layer.

  3. 03

    Reconciliation

    A daily job matches on-chain transfers against the internal ledger, the bank or the payment gateway, and flags every mismatch.

  4. 04

    Reporting and analytics

    pandas and a dashboard turn the indexed data into the numbers finance and operations ask for.

  5. 05

    Testing and tooling

    Contract tests, deployment scripts and load scripts.

Python’s limit is raw speed in the node itself: validating thousands of signatures a second or running a consensus protocol. Those parts live in the node software, and you use them rather than rebuild them. For a broader view of where Python is the right tool, see when to use Python.

Building a fintech product?

How we’d build it for a fintech product

Our first question would be whether the product needs a shared ledger at all. A blockchain earns its cost when several parties who don’t fully trust one operator must share one record that none of them can quietly rewrite. When one company runs the system, a normal database with an append-only history table, signed entries and regular backups usually does the same job faster and cheaper. Our post on whether your business needs a blockchain covers that decision in more depth.

If a chain does fit, here is how we’d approach the build, in six steps.

  1. Choose the network type

  2. Keep personal data off the chain

  3. Put Python where it fits

  4. Design the history trail from day one

  5. Plan key custody

  6. Settle the regulatory questions early

For more on regulated financial products, see our fintech app development page. If you need people to build the Python side, you can hire Python developers.

02 FAQ

Questions, answered

What does proof of work do in a blockchain?
Proof of work makes adding a block slow and checking it fast. A miner keeps changing a number called the nonce until the block's hash meets a target, such as starting with a set number of zeros. Rewriting an old block means redoing that work for it and for every block after it, which makes tampering expensive.
Do I need a blockchain for my fintech product?
Often not. A blockchain earns its cost when several parties who don't fully trust one operator must share a record that none of them can quietly rewrite. When one company runs the system, a normal database with an append-only history table, signed entries and regular backups usually does the same job faster and more cheaply.
Which Python library talks to Ethereum?
web3.py. It connects to an Ethereum or EVM-compatible node through an RPC endpoint, reads balances, blocks and contract state, and signs and sends transactions. Start on a testnet such as Sepolia, and keep private keys in environment variables or a secrets manager, never in code.
Is pycoingecko a blockchain library?
No. pycoingecko is a Python wrapper for the CoinGecko API. It returns prices, market data and coin metadata collected by CoinGecko, but it does not connect to a chain or send transactions. Use it for dashboards and reports, and web3.py when you need on-chain data.