JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

dApps, Wallets, and Signing

A decentralized app is just a website wired to on-chain code. Here is how your wallet signs requests, why reading is free but writing costs gas, and what a token approval really hands over.

Two halves of one app

Think of an ordinary banking website. You see a polished screen in your browser — buttons, balances, a Send button — but the real money lives on the bank's servers, locked behind the company's database. The screen is just a friendly window onto a vault you can't see and don't control.

A decentralized app keeps the friendly window but swaps out the vault. The front-end is a normal website that can live on any server (even your laptop); the *logic and the money* sit in a smart contract on a public chain like Ethereum. So a dApp is really two halves: a front-end you look at, and on-chain code you can't fake or shut down. The front-end can vanish tomorrow and the contract — and your funds — carry on exactly as before.

The wallet as your signing pen

Your wallet isn't a place where coins are stored — those numbers live on the chain. The wallet's real job is to guard one secret: your private key. Think of that key as a signing pen that only you hold, with a signature no one else on Earth can forge. When a dApp wants you to do something, your wallet uses the pen to sign the request, proving the order genuinely came from you.

The cryptography behind that pen is a digital signature. The magic is one-way: your private key creates a signature that anyone can check against your public address, yet no amount of checking ever reveals the key itself. So the whole network can confirm *"yes, the owner of this account really authorized this"* without ever seeing your secret. Sign first, then the signed request can travel safely across the open internet.

Reading is free, writing costs gas

Every interaction with a contract falls into one of two buckets, and the difference decides whether you ever open your wallet. Reading asks the chain a question — *what's my balance? who owns this item?* — and changes nothing. Any node can answer from data it already holds, so reads are instant and free; no signature, no fee. That's why a dApp can show your balances the moment the page loads, before you've approved anything.

Writing is the other bucket: it *changes the shared state* — sending tokens, casting a vote, minting an item. A write has to be re-run and agreed on by every node on the network, then stored forever, so it can't be free. It must be a signed transaction and it carries a gas fee that pays for that worldwide computation. Reading is a librarian glancing at a shelf; writing is everyone in the library rewriting their copy of the book at once.

READ  (a question)            WRITE (a change)
  cost: free                    cost: gas fee
  signature: none               signature: required
  speed: instant                speed: wait for a block
  example: getBalance()         example: transfer(to, 10)

Flow of a write:
  front-end drafts tx  ->  wallet shows it  ->  YOU sign
        ->  broadcast  ->  a validator includes it in a block
        ->  every node re-runs it  ->  state updated forever
Reads ask a question for free; writes change the world and cost gas.

Token approvals: handing over a spending limit

Here is one move that trips up newcomers. Most contracts can't reach into your wallet and pull out your tokens — and that's by design. So when a dApp needs to move tokens *on your behalf* (say, a trading app swapping one coin for another), you first sign a separate transaction called an approval. It tells the token contract: *"this other contract is allowed to spend up to N of my tokens."*

// Solidity: the approval lives in the TOKEN contract
function approve(address spender, uint amount) public {
    allowance[msg.sender][spender] = amount;  // set a limit
}

// Later the dApp's contract may pull tokens, but only
// up to the limit you set:
//   transferFrom(you, someoneElse, amount <= allowance)

// approve(dApp, 50)            -> safe, capped at 50
// approve(dApp, UNLIMITED)     -> convenient, but risky
An approval sets a spending limit; the dApp can later pull up to that amount.

Approvals are genuinely useful — they let an app act smoothly without nagging you to sign on every step. But the catch is the amount. To save you future popups, many dApps ask for an unlimited allowance, and people click through without reading. If that spending contract later turns out to be buggy or malicious, that standing permission is exactly what lets it drain the approved tokens. The fix is simple: prefer approving only the amount you're actually spending, and revoke old allowances you no longer use.

Putting it together

  1. Open the dApp. Its front-end loads and *reads* the chain for free to show your balances — no wallet popup yet.
  2. Click an action. The front-end *drafts* a transaction (for example, a swap) and hands it to your wallet — it cannot send it itself.
  3. Read and sign. Your wallet shows the request and the gas estimate; your signature turns it into a valid, authorized transaction.
  4. The network settles it. The signed write is broadcast, included in a block, re-run by every node, and recorded on-chain forever.

That's the whole pattern. A dApp is a front-end plus on-chain code; your wallet is the pen that signs; reads are free questions while writes are paid changes; and an approval is a spending limit worth setting carefully. Next we'll look at the tokens themselves — the standards that let one contract issue a coin or a collectible that every wallet and app instantly knows how to handle.