CHAINWRIGHTPROGRAM STUDIO

EVM COST LAB / A WORKING GAME EXAMPLE

Save game stats.
Cut the gas.

A game saves a player’s experience, health and six other stats. We changed how those values are stored. The same save now uses 75% less gas in this example, with the same allowed values and permission checks.

Gas measures the blockchain work a transaction uses. Using less gas can lower its network fee at the same gas price.

Try the compact version ↗Try the reference version ↗See the numbers ↓

SAME DATA. SAME RULES. SMALLER RECORD.

Eight stats.
One storage slot.

The reference version gives each stat a full-width storage slot. The compact version fits all eight into one slot. Both accept values from zero to 4,294,967,295, allow only the app owner to edit them, and return the same data.

REFERENCE / 8 SLOTS
XPHealthManaStaminaStrengthAgilityIntellectLevel
COMPACT / 1 SLOT
XPHPMPSTSTRAGIINTLV
SAVE ONE NEW PLAYER PROFILE

The same save, using less gas.

74.97% less
Reference205,624
Compact51,472

Gas used for the same transaction, including its base cost, input data, storage work and event.

First-time contract setup
433,039 → 505,723 gas
16.78% more
Setup + first save
638,663 → 557,195 gas
12.76% less
What stayed the same?
Allowed values, permissions,
results and emitted events
Tested
3 fresh runs per version
for each player count

TRADE-OFF / More setup gas and a larger contract. Lower storage costs pay back the difference for this workload.

These savings apply to this bounded data example. They do not mean every contract will use 75–83% less gas. This is a straightforward reference versus compact storage, not a comparison against the best hand-optimized Solidity.

THE FULL COMPARISON

New saves.
Updates. Setup costs.

PLAYERSNEW SAVE / REFERENCE GASNEW SAVE / COMPACT GASNEW SAVE REDUCTIONUPDATE REDUCTIONSETUP + FIRST SAVE REDUCTION
1 player205,62451,47274.97%50.06%12.76%
4 players755,050138,44281.66%66.3%45.78%
8 players1,487,634254,41882.9%70.09%60.42%

The reference and compact versions use the same batch size and exact input bytes in every comparison. The setup column includes deploying the contract and saving those profiles once. The update column measures changing already saved, nonzero stats.

Reading one profile through a transaction falls from 39,611 to 25,012 gas (36.86% less). Normal off-chain reads do not pay a transaction fee. Failed writes were checked too, including a bad value late in a batch: the entire batch rolls back, preserving all earlier values.

USE IT AS A STARTING POINT

Change a stat.
Run the rule.

  1. Open either version. Each has its own saved draft, so the two versions stay separate from your regular counter project.
  2. Choose Build & run EVM. The included plan saves a profile, checks its values, updates it and tries forbidden writes. No wallet is needed.
  3. Change the values or code. Edit the test plan to try your own inputs. A changed source or plan clears the old live result.
  4. Keep your work. Export the project, source and results. Reopen the project to continue.

DETAILS FOR BUILDERS

Check the work
behind the claim.

Exactly what changed?

The storage fields change from uint256 to uint32. Both versions already reject values above the uint32 maximum before conversion or storage. Both keep the same external uint256 interface, owner check, eight-player batch limit and StatsChanged event. Solidity packs the eight smaller fields into one 256-bit slot. This is a known Solidity technique, not a new compiler algorithm.

The new layout is for new deployments. It is not a storage-compatible upgrade for an existing proxy. Do not shrink balances, identifiers or other values unless their allowed range is already bounded appropriately.

How was this measured?

Solidity 0.8.30, optimizer 200, Paris bytecode; Anvil 1.8.6 configured for Cancun on fresh isolated chains. One, four and eight players each ran three times per version, plus a boundary suite per version: 20 runs and 322 passing checks. Paired calls had identical inputs, returned bytes, revert bytes, decoded results and emitted event data. Every reported call-gas value repeated exactly. The tests cover these inputs, not a proof for every possible program or a security audit.

Values and accounts are synthetic. The numbers are measured transaction gas in this exact runner, not a mainnet fee quote. The contract grows from 1,761 to 2,098 runtime bytes and costs more to deploy. Build time was not used as a performance metric.

Which failure cases were checked?

Another caller cannot write. Zero player addresses, empty batches, mismatched arrays and batches above eight are rejected. Every individual field rejects a value of 4,294,967,296; zero and 4,294,967,295 are accepted. A bad last field in a batch rolls back all earlier writes. Unknown players read as zero. The same outcomes and events were checked for both layouts.

What about Solana and the earlier results?

The studio still builds TypeScript into native Solana programs and runs their checks. The earlier measurements include a 111-CU counter increment and byte-for-byte direct-compiler build comparisons. The counter and fee-hook gas results also remain available; this new storage example does not replace or rewrite them.

Open the earlier measurements ↗