There is one architectural rule I refuse to violate when building Shaka. It sounds almost obvious once you hear it, but I watch builders break it constantly — and then spend days chasing phantom bugs they created themselves.

The rule: the smart contract is the single source of truth. The app reads and obeys. It never recomputes money.

Not sometimes. Not mostly. Never.

Why the Rule Exists

The moment you write a fee calculation in JavaScript, you have two codebases computing the same number. They will agree — until they don’t. A decimal precision mismatch. A rounding mode difference. A state update that propagates to the contract before the frontend re-fetches. Any of these creates a divergence between what your UI shows the user and what the contract actually expects.

And divergence, onchain, has a specific and brutal consequence: the transaction reverts.

Smart contracts are programs stored on blockchains to execute transactions. When input constraints or security properties are violated at runtime, the transaction being executed by a smart contract needs to be reverted to avoid undesirable consequences.

Here is what that looks like from a user’s perspective. They see a payment amount in the UI. They approve it. They hit send. The transaction fails. They get an error message they don’t understand, gas is wasted, and their trust in the product collapses. You look at your logs and discover that the UI computed 1020000 and the contract expected 1020001. One wei. Enough to revert.

The EVM undoes all state changes made during the transaction. The transaction fails atomically, as if it never happened.

You built the client-side math to be helpful. You ended up with a landmine.

The Failure Mode Is Subtle Because Replication Feels Right

This is the seductive trap. Replicating contract logic client-side feels correct. It’s the obvious move for a frontend developer coming from traditional software: you know the fee is 2%, so you compute amount * 0.02 in the browser and show the total. Clean, fast, no extra RPC call.

But now you’ve coupled your UI to an assumption about what the contract does. The moment the contract’s internal logic diverges from your assumption — even by one rounding step — you have a bug. And the contract will always win. It is deterministic and authoritative. Your JavaScript is not.

The code of all smart contracts, and all calls to contract methods, are irreversibly appended to a blockchain. Every node participating in the blockchain protocol reads code and calls from the blockchain, instantiates the same code, and executes the same calls, getting the same results and maintaining the same state.

That’s your source of truth. That’s the only computation that matters when the transaction executes. Everything else is a guess.

How Shaka Implements It: Read the Contract, Display What It Returns

In Shaka, payment amounts — including the fee, the split per recipient, the total due — are never computed in the application layer. They are read from the contract.

When a buyer lands on a deal link, the app calls the contract. Functions like quote() return exactly what the contract will charge. Functions like getDeal() return exactly how that deal is structured — amounts, recipients, splits — as the contract knows them. The Shaka protocol charges a 2% fee on each transaction, collected automatically by the smart contract at the moment of payment. This fee is hardcoded and immutable — it cannot be changed by anyone. I don’t mirror that 2% in the frontend. I ask the contract what it’s going to collect and I display that number.

The UI displays what the contract returns. When the user submits the transaction, the values passed in are the exact values that came from the contract read. No transformation. No rounding. No reconstruction.

The smart contract routes every share simultaneously, to every wallet, in a single transaction. For that to work without reversions, the amounts passed to the contract on payment must match what the contract itself computed. The only way to guarantee that is to never compute them independently.

This also means the UI is stateless with respect to financial logic. It’s a display layer. It renders what the chain says. If the chain says the deal costs X, the UI shows X and passes X. The chain never receives a surprise.

This Is a Security Principle, Not Just a Reliability One

Here’s where I think the framing matters. Most people treat “don’t recompute client-side” as a reliability rule — a way to avoid bugs. That’s true, but it undersells the principle. This is fundamentally a security principle.

The client is untrusted. Always. In any sufficiently adversarial environment, you must assume the client can be modified, intercepted, or replaced. A manipulated frontend that computes its own amounts could mislead users into approving transactions for different values than displayed. Since off-chain data is inherently untrusted, strong cryptographic validation is the only way to make it admissible in a deterministic system like Ethereum.

The smart contract has no such weakness. The Shaka smart contracts are immutable. Once deployed, they cannot be modified, upgraded, or overridden by anyone — including Shaka LLC. No human intervention is possible in the execution of smart contract logic.

That’s the definition of an authoritative layer. The contract is not running on your server. It’s not under your control. It’s not subject to your bugs or your configuration drift. Blockchains are uniquely specialized in performing specific categories of computation and generate strong consensus regarding transactions. While they excel at verifying ownership, executing immutable smart contracts, and providing a single source of truth, they lack the feature-richness offered by offchain systems.

Precisely. The chain is authoritative and deterministic. The client is flexible and untrusted. Build accordingly.

When your app computes money client-side, you are importing financial logic into an untrusted environment and treating it as if it were authoritative. You’re not — you’re creating a shadow computation that has to stay synchronized forever with the real one. That’s not a coding problem. That’s a threat model failure.

The Broader Lesson for Onchain Engineering

This principle extends well beyond fee calculations. It’s the core posture for building anything onchain:

Treat the deterministic layer as the source of truth. Treat the client as a view.

The contract knows the state. The app asks the contract. The app renders what it’s told. When the user acts, the app passes exactly what the contract said back to the contract. No reinvention, no reconstruction, no “I think it’s approximately this.”

This creates an architectural wall between the two concerns. Business logic lives in the contract — verified, immutable, transparent. Commissions are distributed automatically by the smart contract on-chain; they are not held, calculated, or paid by Shaka LLC, which does not intervene in their routing. That’s intentional. The contract is the law. The app is the messenger.

Information related to smart contracts is always available. In addition to the code of a smart contract, all users of a blockchain are able to view the values that contract variables hold, historical data, as well as, all transactions related to that contract. If anyone wants to verify what the contract says, they can. The app doesn’t need to be trusted because it’s not the authority — it’s the window.

Where This Comes From

I’m not a classic enterprise developer. My background shapes how I think about trust boundaries. When you spend time thinking about systems where the client cannot be trusted — where the assumption is that any party in the chain might be compromised — you develop a reflex: push authority to the most tamper-resistant layer and keep everything else dumb.

I build onchain. The next web is being built — I’m one of the people building it. That means taking the properties of the chain seriously: immutability, determinism, transparency. Those aren’t buzzwords. They’re what separates onchain logic from traditional server logic. You don’t compromise on them by duplicating critical computation in a JavaScript bundle that runs in a browser you don’t control.

The security-aware builder treats the client as hostile by default. Not because users are adversaries, but because the environment is adversarial — and the chain is the one place in the system where the math is guaranteed.

In Practice: The Questions to Ask

When you’re building an onchain app, ask these before any piece of financial logic touches the frontend:

  • Is this number being computed somewhere in a contract? If yes, read it from the contract. Do not recompute it.
  • Does this value need to be sent back to the contract? If yes, it must come from the contract, not from your arithmetic.
  • What happens if the client-side version of this number is wrong by 1 wei? If the answer is “the transaction reverts,” the computation does not belong client-side.

The contract calculates. The app obeys.

That’s the whole principle. Everything else follows from it.