dApp blockchain: Solidity smart contracts, on-chain/off-chain architecture and React frontend
Full design and development of a decentralized application on public blockchain: Solidity smart contracts, Web3 abstraction layer and React frontend with explicit transaction lifecycle management.
dApp blockchain: smart contracts, on-chain/off-chain architecture and React frontend
Summary
A client with a clear idea for a decentralized application needed to go from concept to a real implementation. The complete solution was designed and built: Solidity smart contracts, on-chain/off-chain architecture, a React frontend and an abstraction layer that isolates the application from Web3 provider details. Before development began, three scope options were proposed; the selected one multiplied the functional value by approximately three compared to the original idea without disproportionately increasing effort.
Context
The client was operating in the Web3 space with a smart contract-based proposal on a public blockchain. The idea was defined from the business side but had no technical architecture yet: it was unclear what logic should run on-chain, what data should stay off-chain, or how the contract model should be structured to remain maintainable and avoid unnecessary gas costs.
The project was starting from scratch, which made it possible to make those decisions upfront rather than inheriting them as debt.
Technical problem
- Without a clear on-chain/off-chain separation, the application would accumulate unnecessary gas costs and contracts that are hard to change.
- Poorly structured contracts in blockchain cannot be patched after deployment: design mistakes have permanent consequences.
- The frontend needed to correctly handle the transaction lifecycle (sent, pending, confirmed, reverted) without coupling that logic to every component.
- Direct integration with a specific Web3 provider would have locked the application into that dependency with no practical way out.
What was built
Solidity smart contracts
Contracts were designed with bounded responsibilities and separation between business logic and state storage. Key design decisions:
- Minimal on-chain surface: only what requires immutability or decentralization guarantees goes on-chain. Everything operational, dynamic or easy to change stays off-chain.
- Standard patterns: role-based access control, events for traceability, explicit validations in each function. No reinventing what the community has already proven.
- Event-driven traceability: events emitted by the contracts allow reconstructing the full history without relying on external storage, which simplifies auditing and reduces failure surface.
Contract testing
Happy paths, expected error scenarios and edge cases were covered: boundary values, calls from unauthorized accounts, potential reentrancy attempts. In an environment where failures cost real money and contracts cannot be patched, tests are not optional.
React frontend
- Abstraction layer over Web3 that isolates the rest of the application from the specific provider. Changing provider or network does not require rewriting the components.
- Explicit management of intermediate transaction states: sent, pending confirmation, confirmed, failed. Latency and reverts are a normal part of blockchain flow; the UI reflects them clearly rather than ignoring them.
- Separation between contract state (on-chain, read via events and read calls) and interface state (local, ephemeral).
Decisions and trade-offs
Moving complex logic on-chain just because it was technically possible was ruled out. Deployed contracts are hard to modify; every on-chain function has a permanent operational cost. The question at each decision point was: does this actually need the chain’s guarantees, or is it cheaper and more flexible to manage it off-chain?
Community-audited and tested patterns were prioritized over custom implementations. In blockchain, originality in contracts is a risk, not a merit.
Some extra initial complexity was accepted in the frontend by adding the abstraction layer, in exchange for real long-term flexibility.
Result
- Deployed, functional application with maintainable contracts and real operation traceability.
- Clear on-chain/off-chain architecture, justified decision by decision, with no unnecessary state on the chain.
- Frontend with correct transaction lifecycle management, ready to handle blockchain’s specific behaviors without surprises for the user.
- Foundation ready to evolve the product: adding features does not require redesigning what was built.
- The client ended the project with their own technical judgment to make future decisions independently.
Tech stack
- Solidity
- Smart contracts
- JavaScript
- React
- Web3 (frontend ↔ contracts abstraction layer)
What this case demonstrates
The ability to design and build a blockchain application end to end: from on-chain/off-chain architecture decisions to Solidity contracts, testing and the frontend. Not just executing what arrives already defined, but proposing the right technical structure before writing the first line of code — knowing that in blockchain, the initial decisions are the ones that matter most.
Building a blockchain application or need to review your contract design before deploying? I can help you define the architecture and take the development forward.