Crypto OS
Non-Technical Crypto OSStage 5 · Crypto Business

Chapter 27 · Why Crypto Products Differ from Web2 Products

Why can crypto products not simply copy Web2 workflows?

Capabilities practiced
BuilderSystem ThinkingAI Literacy
Hands on
Capture each step of a dApp's first-use flow and mark exactly what every signature authorizes.
AI Lab
Have AI draft a feature PRD. Manually add the failure paths it missed: failed transactions, stalls, and front-running.

A Real-World Problem

Someone with eight years of Web2 product experience joins an on-chain team.

Their first assignment is simple: a one-click buy button that swaps stablecoins for another asset. They follow a familiar workflow—loading states, progress bars, success screens, retries, analytics, and A/B testing controls.

Two weeks after launch, support tickets and data reveal six problems:

  1. Some users click and nothing happens. Their wallet lacks the native token needed for gas: they can afford the purchase but cannot submit the transaction.
  2. Someone clicks three times. After forty seconds without a visible response, they assume it is stuck and click twice more. All three transactions execute on-chain.
  3. After seeing the success page, someone asks: “When can I cancel?”
  4. Someone sends to the wrong address and requests a refund from support.
  5. A wallet popup displays hexadecimal text. The user confirms it. Three weeks later, their money disappears: the confirmation granted an unlimited allowance.
  6. Someone complains: “The displayed price was 1.02, but I received 0.97.” The interface never explained what could happen in between.

Web2 has standard answers: balance checks, button debouncing, cancellation endpoints, support refunds, readable permission dialogs, and locked prices. None of those answers works here as assumed.

The problem is not a lack of skill. The familiar workflow rests on three assumptions, none of which holds on-chain.

This chapter asks: what are those assumptions, and what must change in product design when they disappear?

Thought Experiment

Do not consider all of crypto at once. Remove one assumption at a time and see what happens to the product.

Step one: remove undo from your product.

Do not hide the button. Make undo physically impossible. Once users confirm, it happens, and nobody can reverse it—including you, your database, or a court.

Several designs collapse:

  • Confirmation changes from a formality into the main interface. In a reversible world it is courtesy; in an irreversible one it is the last defense.
  • Support changes from solving problems to explaining them. Half your support scripts describe remedies. That half no longer applies.
  • You cannot experiment on live traffic. Gradual rollout is a favorite Web2 tool: roll back if something breaks. Here, rollback cannot restore the affected users' lost money.
  • Onboarding must happen beforehand. Users cannot try first and fix it later.

Step two: require users to produce a key and sign every action in person.

You do not hold this key and cannot act in their place or keep it for them. Every signature opens a wallet window containing text they probably do not understand, leaving them to decide whether to approve.

More assumptions collapse:

  • Step count becomes a cost you must reduce. An extra Web2 step is a usability issue. An extra signature is a drop-off point plus a risk point.
  • Your copy may not be what users see. The wallet renders the popup. You can influence it, but cannot control it.
  • Remember my choice becomes extremely dangerous. On-chain, it can mean one approval, forever, with unlimited allowance.

Step three: let anyone connect another product to yours without telling you.

No application, contract, or permission is needed. They read your contract interface and write code to call it.

This step brings the greatest benefits and the greatest difficulties:

  • Distribution can happen without you doing anything. Someone integrates you, and their users become yours.
  • Your usage assumptions break. You expect a person, but receive a contract; you expect individual calls, but receive a hundred within one transaction.
  • You cannot change interfaces unilaterally. Integrations break together, and you may not know who integrated you.

After these three steps, you are no longer holding Web2 with a blockchain added, but a product with entirely different constraints.

Your Decision

Design a specific feature: one-click reinvestment. Users have earned yield and want to put it back in. On-chain this requires three operations: claim, approve, and deposit.

What Happens

The four choices lead to one conclusion:

The difficulty of on-chain products lies in redrawn boundaries of state and trust, rather than the feature itself.

Many default Web2 designs rest on three implicit assumptions. Compare them with on-chain reality:

Implicit Web2 assumptionOn-chain realityWhat the product must add
Mistakes can be correctedOnce confirmed, nobody can change itComplete pre-confirmation information, simulation, and repeated amount/address checks
My server acts for the userEvery step requires the user's signatureFewer signatures, readable explanations, and bounded permissions
I control my interfaces and usersAnyone can integrate; calls may come from contractsInterface stability commitments, unusual-call handling, and composition checks
Request success means completionTransactions have intermediate states and can be reorganizedA complete state machine and waiting-state copy
Users act for freeEvery write costs moneyFee checks, explanations of failed-transaction fees, and sponsorship trade-offs

Rows four and five are additional gaps that are easily missed.

Row four: Web2 requests succeed or fail, with loading as the intermediate state. An on-chain transaction may be signed but unbroadcast, waiting in the mempool, included but not finalized, or removed by a reorganization. Each means something different to users.

Row five: on-chain operations are not free. Trying something has a price, and pricing changes behavior: users hesitate, batch actions, or stay away when fees are high.

Build a Model

Three Non-Negotiable Constraints

  1. Irreversible
  2. Requires signatures
  3. Composable
These are environmental constraints, not features. Every product decision happens within them.
ConstraintWhat it removesDesigns it demands
IrreversibleUndo, refunds, rollback, and live rollout experimentsEarlier confirmation, simulation, limits, and allowlists
Requires signaturesServer actions on users' behalf and silent renewalsFewer steps, readable explanations, bounded amounts and expiry
ComposableControl over callers and freedom to change interfacesStable interfaces, defensive assumptions, batch and contract-call handling

The third is easily mistaken for a purely technical issue, but it is a positioning question. Composability means your product can be someone's entry point or someone's component. Entry points need usability; components need stable interfaces, clear documentation, and predictable behavior. Most teams do not choose clearly and end up doing neither well enough.

Six Transaction States

Product teams must internalize this state machine. Every box needs an interface and copy. Missing one leaves users to imagine what happened, usually the worst possibility.

  1. Constructing
  2. Awaiting signature
  3. Broadcast
  4. Awaiting confirmation
  5. Confirmed
  6. Final
Web2 often has only loading and complete. Here there are six states, and state five can return to state three.
StateWhat users experienceCommon product mistake
ConstructingThe interface calculates amounts, routes, and feesNo explanation of why quoted and executed prices may differ
Awaiting signatureA wallet popup opensNo explanation of what this signature does
BroadcastThe transaction entered the network but is not includedNo transaction receipt for users to inspect
Awaiting confirmationIncluded, but not enough confirmationsDisplaying success—the most expensive mistake
ConfirmedThe confirmation threshold is reachedNot explaining the threshold
FinalPractically no longer changeableTreating it as identical to the previous state

State four deserves attention. Displaying success with insufficient confirmations promises something you cannot guarantee. Chapter 1 distinguished displayed receipt from completed settlement; on-chain, the product must express the gap.

Failure-Path Checklist

This is the table most worth taking away. Check every row when writing a PRD for a transaction feature:

FailureWhat users seeWhat the product should do
No native token for gasClicking does nothingCheck beforehand, explain what is missing and where to obtain it
Insufficient asset balanceA cryptic wallet errorCheck beforehand and offer the available maximum in the input
Insufficient allowanceFailure, with fees still chargedCheck allowances and explain approval versus execution
Slippage exceeds toleranceTransaction revertsExplain why and offer adjustment; do not increase it by default
Front-runningExecution worse than the quoteExplain price protection and quote expiry
Stuck in the mempoolEndless spinnerGive a transaction receipt, lookup link, and available actions
Contract execution fails midwayFailure without fee refundSimulate beforehand, blocking certain failures before signing
User rejects in the walletReturn to the original interfaceDistinguish cancellation from failure instead of treating both as errors
Congestion and fee spikesLong wait for inclusionShow current fees and allow users to wait
Chain reorganizationA transaction shown as successful disappearsExactly why state four must not say success

Seven of these ten can be blocked before signing. One extra pre-signature check offers the highest return in on-chain product work: less drop-off, fewer losses, and fewer support requests.

Four Signature Types

A wallet confirmation can mean four entirely different things. Your interface must distinguish them because the wallet may not.

TypeWhat it doesReversible?What the product must explain
Transfer signatureSends assets awayNoRecipient, amount, and that the action ends here
Approval signatureLets a contract use a particular assetYes, but requires active revocationAmount, expiry, and whether the target contract is upgradeable
Message signatureProves address control without an on-chain transaction or feeNot applicableIt does not move funds—say so explicitly, or users may be afraid
Offline-order signatureSigns authorization someone else can execute on-chainDepends on designExpiry, permitted executors, and invalidation method

The second is the entry to the “you signed it yourself” risk path in Chapter 24. Three concrete actions minimize it: approve only what is needed, set expiry, and provide a place to view and revoke past approvals.

The fourth is often misunderstood because it is free and off-chain, resembling a message signature. But it is executable authorization, and users do not choose when execution occurs. Any such feature must explain expiry and invalidation in its own interface.

What It Is Called

Wallet UXWallet UX

Users approve every operation your product initiates through an application you do not control.

This is a distinctive structure: your critical conversion step occurs in someone else's interface. You can explain the content on your side and reduce how often users must switch over.

Wallets differ enormously in display, support for limits and expiry, and interpretation of call data. Ask during design how the same instruction appears in three major wallets. T13 covers implementation differences.

SignatureSignature

Authorization of content with a private key—the only “I agree” in the on-chain world.

Three properties matter: it cannot be forged (only the key holder produces it), it cannot be denied (you cannot later claim you did not sign), and its effect depends on the content, not the setting (the same signature has the same effect elsewhere).

The third creates product risk: a user taught to approve every popup will carry that habit to phishing sites. Teaching users to read signatures is part of the product, not merely security education.

GasGas

The fee users pay for the network to execute an operation.

Three properties reshape design: payment requires the native token (a newcomer holding only stablecoins cannot proceed), fees vary dramatically with congestion, and failed transactions also incur fees.

The third particularly needs product handling. Simulating and blocking a certain failure before signing saves both fees and frustration.

Some designs let others pay these fees, greatly reducing first-use friction. But the cost moves to the product provider and attracts addresses seeking to exploit it—the problem Chapter 28 examines.

FinalityFinality

The point at which a transaction is practically no longer changeable.

It is a curve, not a switch: more confirmations reduce the chance of change. Chains vary significantly (Chapter 8 compared them). Choose a threshold for your chain and tell users what it is.

The green success check should appear after your selected threshold, not merely upon inclusion in a block.

IrreversibilityIrreversibility

After confirmation, nobody can undo the action.

This is the product meaning of “more like cash” in Chapter 1. Cash handed over stays handed over; there is no support desk.

Its design requirement fits one sentence: move the effort Web2 spends after mistakes to before mistakes. Confirmation screens, checks, simulation, limits, and address verification become core functionality rather than optional polish.

ComposabilityComposability

Anyone can call your contracts and integrate your product without your approval.

Distribution can happen by itself: others integrate you, their users become yours, and you spend nothing. Chapter 9 described this distinctive smart-contract property.

The cost is losing three things: control over callers, freedom to change interfaces, and assumptions about usage. The third is dangerous: you expect people but receive contracts, or one call but receive a hundred in one transaction. Before encoding an assumption, ask whether it still holds when the caller is code.

Hands-on

Hands onScreenshot a DApp's first-use workflow and identify exactly what each signature authorizesA testnet wallet + a DApp deployed on a testnet + a block explorerFree, entirely on a testnet. If the product only supports mainnet, stop at the signature popup, inspect it, and cancel without confirming

The goal is to break the workflow into frames, not simply use the product. Go slowly and screenshot every step.

Prepare a new, clean wallet address, not your everyday wallet. Obtain a little native token from a testnet faucet. Choose a DApp you have never used.

Screenshot from the homepage through your first meaningful action.

Capture every screen, including loading states, errors, and wallet popups. Capture the whole wallet popup, including expandable sections.

Count total screens, screens requiring a decision, and signatures. These three numbers describe the product's first-use cost.

Analyze every signature popup using this table.

Signature numberWallet displayWhich of the four types?AllowanceExpiryExplained in product UI?
1
2

Allowance is the key column. For approval signatures, check whether the requested amount matches the operation or is an enormous number. The latter means unlimited approval.

If the popup is unclear, copy its contents and inspect the contract and interface name in a block explorer. Repeating this builds intuition for common signature types.

Deliberately trigger three failures and screenshot each.

TriggerWhat to observe
Spend the native token, then initiate an operationDoes the product check beforehand? Is the message readable or an error code?
Enter more than your balanceDoes validation happen during input or after signing?
Reject the wallet popupDoes the product distinguish user cancellation from transaction failure?

The third reveals product maturity especially well. Reporting intentional cancellation as “Transaction failed, please retry” is common and harmful.

Record every state transition's timing.

Start timing at confirmation. Note the first interface change, the transaction receipt's appearance, and the success message.

Use the receipt to check the block explorer: how many confirmations existed when the product displayed success?

This is the lab's most valuable number. Compare it with the interface wording: success, submitted, or awaiting confirmation?

Audit approvals, then revoke them.

Use an approval inspection tool, or read contracts through a block explorer, to find this address's approvals and amounts.

The operation may already have left a permanent, unlimited approval. Revoke it and record the steps and fees required.

This closes the “you signed it yourself” path from Chapter 24. Afterward, audit your everyday wallet as well.

Write a three-part conclusion.

Three things this product does well:
Three failure paths it omitted:
The first thing I would change:

Use the failure checklist to check the second part. Typically three to five of the ten are unhandled, representing the next quarter's work.

AI Lab

AI LabAsk AI for a feature PRD draft, then add missing failure paths: failed transactions, stuck transactions, and front-runningLevel 2 · AI Copilot

The division of work is clear, making this a useful way to understand AI's boundaries in product work:

What models do well: expand a feature description into a structured document with goals, roles, flows, interface elements, analytics, and acceptance criteria. They write this quickly and consistently, saving considerable labor.

What models systematically do poorly: failure paths. Training materials contain far more Web2 PRDs, where failures are fewer and usually repairable. The omissions are structural, not occasional.

Write a PRD draft for this feature:
<Description, such as swapping asset A for asset B in one operation>

Target chain: <chain>. Target users: <newcomers / experienced users>.

Part one: main flow. For each step specify:
- What the user sees
- Whether a signature is required, and its type: transfer / approval / message / offline order
- For approvals, the allowance and expiry, with reasons

Part two: transaction states. For constructing / awaiting signature / broadcast /
awaiting confirmation / confirmed / final, describe interface copy and available actions.
State exactly when success appears and its criteria.

Part three: failure paths. For each, give triggers, user-visible behavior, and handling:
No native token / insufficient balance / insufficient allowance / excess slippage /
front-running / stuck in mempool / contract execution failure / user cancellation /
network congestion / chain reorganization

Part four: list uncertainties separately.

Rules:
- Do not propose undo, rollback, or refunds unless you explain their on-chain implementation.
- Give concrete interface copy for every failure; do not merely say “show a friendly message.”

Notice that the prompt supplies all ten failure paths. Deliberately: omit them and the model omits them; list them and it writes them well. The missing piece is the checklist, not capability, and a person must supply that checklist.

After receiving the draft, do three things:

  1. Inspect all ten paths in part three. Are they complete? Is each response feasible on-chain?
  2. Compare part two with your lab observations. At which state did the tested product show success? Does the model do the same?
  3. Find invented features. Common examples are one-click undo of the previous transaction and automatic retries with refunded gas. The former does not exist; the latter cannot recover the gas.

Four common errors, ordered by danger:

  1. Importing Web2 reversibility assumptions. Requirements such as cancellation within fifteen minutes have no on-chain implementation.
  2. Showing success at broadcast. Reducing the state machine to two boxes causes many of the six support problems above.
  3. Defaulting to unlimited approvals. “Request approval on first use” without an amount usually becomes unlimited in implementation.
  4. Ignoring front-running. Without a Web2 equivalent, models rarely raise it themselves. T24 covers the mechanism.

Save your additions separately. After three features, the repeated additions become your own on-chain product checklist, more useful than any template.

Verify these points yourself after using AI

  • Does its success path confuse transaction broadcast with completed execution?
  • How many of the ten failure paths are covered? Missing native tokens, insufficient allowance, and excess slippage are commonly omitted
  • Does it handle wallet rejection separately from transaction failure?
  • Does every signature step specify its type, allowance, and expiry?
  • Does approval default to unlimited or required-only allowance?
  • Does it describe the interface and user actions for a transaction stuck in the mempool?
  • Does it omit front-running, or provide a concrete product response?
  • Most importantly, are its retry, undo, and rollback behaviors actually possible on-chain?

Real-World Case

Unlimited approvals became the industry defaultLong-standing

Early products requested enormous allowances on first approval to reduce interactions: approve once, never see another popup. This solved a real usability problem, became convention, and was copied by later products.

Years later, the cost appeared: wallets accumulated forgotten, permanent, unlimited approvals, some targeting upgradeable contracts. Most losses through the fifth outflow path in Chapter 24 happen here.

The lesson is not criticism of the original choice, but the lifespan of product defaults: a decision made to save one click can remain effective in wallets long after the product dies.

It showed success, then disappearedDuring chain reorganizationsNetworks with slower confirmations

A product displays a green check and “Transaction successful” immediately upon block inclusion. Usually this seems fine.

Then a small reorganization replaces the block, and the transaction is not included again. The user has already seen success, closed the page, and acted on the assumption of receipt.

Reorganizations are normal system behavior. The product's mistake is making a promise it had no right to make.

The fix is simple: before the threshold, show “Submitted, awaiting confirmation (2/12).” Only then show success. One more state, one fewer category of incident.

A large swap was front-runCommon in public mempools

A user accepts a displayed quote. The transaction enters a public mempool, visible to everyone before execution.

A program notices the order can move the price, places a transaction before it and another afterward, and captures the difference. The user receives a worse price than quoted.

Everything on-chain works normally. No contract is compromised. This is a natural consequence of public mempools, not a malfunction.

Products can disclose quote expiry, explain tolerance rather than inviting blind adjustments, flag large-order risks, or use submission routes outside the public mempool. First acknowledge the issue in the interface; the worst option is leaving users to guess afterward. T24 explains the mechanism.

After someone integrates your contractCommon with composable protocols

A protocol launches assuming callers are people, using its own interface, one operation at a time. Rate limits, risk controls, and analytics all rest on this assumption.

Months later another team integrates it. Users act elsewhere and calls arrive here: a contract address sends dozens of calls in one transaction, with no interface-side preliminary checks.

Daily activity immediately becomes distorted (the aggregator issue in Chapter 23), rate limits stop working, and business assumptions may fail outright.

This is composability's cost, not someone's fault. Design must ask whether every assumption still holds if the caller is code rather than a person.

Change One Variable

What ifYour product pays users' gas fees

First-use friction falls substantially. Users no longer need native tokens from elsewhere, eliminating the most common failure path.

Three consequences follow. Costs move to you, fluctuating with congestion beyond your control. You need abuse prevention, because addresses will seek to exhaust sponsored allowances—the economics Chapter 28 examines. Users lose awareness of costs, changing their understanding of why other products charge fees.

More subtly, sponsorship usually requires offline authorization that you execute on-chain. This changes the signature from type one to type four, and changes its risks. Users still sign, but different content—the interface must explain this even when the experience feels smoother.

What ifYour product runs on a very fast, inexpensive chain

The six-state machine seems compressed: little waiting, negligible fees, cheap retries. Many designs can indeed be simpler.

But all three constraints remain. Irreversibility remains: faster confirmation means it arrives sooner. Signatures remain: their cost changes from waiting to interruption, which still causes drop-off. Composability remains.

A reverse effect also matters: cheap experimentation makes wash activity and incentive farming cheaper. What you save in product friction may return as growth-side problems.

Do not assume a faster, cheaper chain permits Web2 product design. It changes parameters, not constraints.

What ifYour users know nothing about wallets and have never signed

This is a product-form decision rather than merely better onboarding, with three paths.

First, educate: teach wallets, signatures, and gas. Conversion will be low, but retained users understand their actions.

Second, hide: remove the visible wallet. Carefully answer who holds the private key. If you do, you are a custodian. If users hold an abstracted key, explain how they recover control if you disappear.

Third, change users: acknowledge the feature is unsuitable for complete beginners and serve wallet users first.

All are legitimate, but choose explicitly. A common failure combines hidden complexity with avoidance of custody responsibility, producing something that looks custodial without custodial protections.

What ifYou build only an integrable protocol, without your own interface

You move from entry point to component, changing the evaluation criteria entirely.

What matters more: interface stability, documentation, predictable behavior, batch and contract-call support, and low integration costs.

What matters less: visuals, onboarding, and conversion funnels. Integrators handle those.

What becomes very difficult: knowing who your users are. Calls come from other contracts and you see addresses. Chapter 26's income statement remains calculable, but Chapter 28's retention analysis becomes difficult.

Distribution can happen by itself, but growth depends on other teams' product decisions. Much of Chapter 29's BD work promotes these integrations.

Takeaway Questions

4
Who is the user?

This chapter adds an on-chain follow-up: is the caller a person or a contract?

An integrated protocol sees code as its caller. This can invalidate product assumptions about user behavior, beyond distorting analytics. Before any feature ask: does this assumption hold if the caller is code?

9
Who bears the risk?

At the product layer: after this signature, what is the worst outcome, and who bears the loss?

An approval can permit all assets within the allowance to be taken. An offline order can execute at an unfavorable time. A feature unable to state these risks should not launch.

16
What permissions does an agent have?

The human version is: what permissions does this signature grant, for how much, and until when?

An approval unable to answer all three opens the risk path in Chapter 24. Product actions are clear: approve as needed, add expiry, provide visibility and revocation. Doing these well protects users more than security education alone.

18
Which decisions must keep a human in the loop?

On-chain products give an unambiguous answer: a person must approve the final step of any irreversible fund movement.

This follows because irreversible errors cannot be corrected by another attempt, rather than automation being inherently unreliable. Design should ask how to give people enough information before confirmation, the entire purpose of the failure checklist.

Chapter Check

Key idea

Irreversibility, signatures, and composability reshape almost every product decision.

Finished this chapter’s lab? Mark it completeView all progress

On this page