← all builds

From-Scratch Build · Web3

Smart-Contract Dev Tutorial

A beginner-friendly walkthrough for writing a Solidity smart contract, compiling and deploying it to a local Ethereum chain, and then calling it from Python — every step runs on my own machine with no real money involved. Rebuilt from scratch to learn the end-to-end blockchain developer workflow.

SolidityHardhatLocal chain web3.pyABI · events

What it is

A contract, a chain, and a client — all local

A smart contract is a small program that lives on a blockchain: anyone can call its functions, and its stored data is shared and tamper-resistant. This build is a complete, step-by-step tutorial that takes a tiny example contract from source code to a running, callable program — entirely on a private blockchain running on my laptop, so there is no cost and nothing to lose while learning.

The example contract is deliberately minimal: a public counter you can increment, a function that emits a log message, a read-only getter, and one function that always fails on purpose. That last one matters — it lets the tutorial show how a contract rejects an invalid call, not just how the happy path works.

The core idea I wanted to learn: deploying a contract produces two artifacts that matter — an address (where it lives) and an ABI (the description of how to call it). Hand those to any client, in any language, and it can talk to the contract. The blockchain is just the runtime.

The stack

Tools under the hood

The point of this rebuild was the toolchain a blockchain developer actually uses. Here is what each piece does.

contract

Solidity

The language smart contracts are written in. The example holds a counter and a couple of functions, compiled down to bytecode the chain can run.

toolkit

Hardhat

The development environment that compiles the contract, manages network settings and runs a deploy script — the command centre of the project.

local chain

Local Ethereum node

A private blockchain running on the machine, pre-funded with test accounts so deploying and transacting cost nothing real.

interface

ABI

The Application Binary Interface — a JSON description of the contract's functions and events that any client reads to know how to call it.

client

web3.py

A Python library that connects to the chain, reads contract values, signs and sends transactions, and decodes the events that come back.

events

Logs & reverts

Contracts emit events when state changes and revert when a rule is broken. The tutorial reads both, so success and failure are visible.

Architecture

The workflow, step by step

The tutorial is a pipeline: source code in one end, a live contract you can poke from Python out the other. Most of it is local; the public-testnet path I left as a clearly-marked next step.

  1. Write the contract built

    A short Solidity file with a counter, an increment, an event emitter, a getter and a deliberate failure.

  2. Compile built

    The toolkit turns the source into bytecode plus an ABI, the two things every later step depends on.

  3. Run a local chain built

    Start a private Ethereum node with funded test accounts so deployment and transactions are free.

  4. Deploy built

    A script pushes the contract onto the chain and saves its address and ABI to files for the client to read.

  5. Call from Python built

    A web3.py script reads the counter, sends a signed increment transaction, decodes the event, and catches the intentional revert.

  6. Deploy to a public testnet future

    The same flow against a shared test network with real RPC and key handling. Configured but left as future work in this build.

How it runs

From source to a signed transaction

The end-to-end loop is what makes it click — the contract and the client are separate programs that meet over the chain:

In my rebuild I focused on the fully-local loop: compile, spin up the private chain, deploy, then run the Python client end to end so I could see a read, a signed write, a decoded event and a clean revert all in one run.

Reflection

What rebuilding it taught me