measure-on-chain-svg-gas-cost
Use when a generative NFT renders SVG or JSON inside the contract and tokenURI gas must stay under a viewer's call limit. Measures the real cost and the dominant contributor before optimizing.
- License 许可
- MIT
- 最近更新
- 2026-11-14
- Stars
- ★ 81
- Forks
- 17
01 前言 Front Matter
- name
- measure-on-chain-svg-gas-cost
- description
- Use when a generative NFT renders SVG or JSON inside the contract and tokenURI gas must stay under a viewer's call limit. Measures the real cost and the dominant contributor before optimizing.
02 资源文件 3
- 许可证LICENSE1.0 KB
- 参考文档SOURCE.md355 B
- 参考文档TRUST.auto.yaml2.2 KB
03 SKILL.md 正文
Measure on-chain SVG gas cost
Rendering an SVG inside the contract pushes bytes into tokenURI; naive concatenation can cost hundreds of thousands of gas per call and blow the eth_call gas limit some wallets use.
Procedure
-
Baseline the byte size of a metadata read:
cast call $NFT "tokenURI(uint256)(string)" 1 --rpc-url $RPC | wc -c cast call $NFT "tokenURI(uint256)(string)" 1 --rpc-url $RPC --gas-limit 50000000 >/dev/null && echo "renders" -
Measure the actual gas with forge:
forge test --match-test testTokenURIGas --gas-reportor in a script:
forge script script/UriGas.s.sol --gas-limit 50000000. -
Decompose the cost. Static bytes read from storage are cheap; repeated
string.concatin a loop grows O(n²) because each concat copies the whole running string. Prefer oneabi.encodePackedpass. -
Compare storage strategies per byte: a
bytesslot costs 20000 gas SSTORE per 32-byte word, while SSTORE2 bytecode costs ~200 gas to deploy per byte and ~200 to read — cheaper for large static blobs read rarely. -
Benchmark the base64 encoder separately. Pure-Solidity base64 of a fixed string is fine; encoding a long dynamic string in the same call nearly doubles the work.
-
Verify the rendered output parses before optimizing further:
cast call $NFT "tokenURI(uint256)(string)" 1 --rpc-url $RPC \ | jq -r '.image' | sed 's#data:image/svg+xml;base64,##' | base64 -d | xmllint --noout - -
Set a budget: if
tokenURIexceeds ~30M gas, some RPCs and wallets drop the call and the collection renders blank. Cut bytes, not promises.
Pitfalls
- Optimizing storage misses the true cost: string concatenation and base64 dominate.
- SVG path data stored as
string[]becomes one SLOAD per element per trait; pack the whole drawing into a single blob. tokenURIthat reverts on a gas limit makes every token render blank across marketplaces at once.- Off-by-one in base64 padding silently corrupts the image while still returning text.
- Gas measured by
eth_estimateGasexcludes part of the read path; measure witheth_callat an explicit high gas.
Verification
forge test --match-test testTokenURIGas --gas-report | grep -i tokenURI
Pass: the reported tokenURI gas is under your budget and xmllint --noout - exits 0 on the decoded SVG. Report the measured gas, the biggest cost contributor, and the storage strategy chosen.
04 同仓库更多 Skills
recipe-performance
Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold/warm/background-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout/paint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.
mexc-spot-websocket
MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.
mexc-spot-rest
MEXC Spot REST workflows for public data, signed account requests, orders, wallet/admin actions, and secure signing without exposing API keys.
mexc-futures-websocket
MEXC Futures WebSocket workflows for public streams, private account/order/position streams, ping/pong, subscriptions, and depth maintenance.
0xklen-version-and-refresh-sanctions-lists
暂无简介
verify-tests-cover-changed-lines
Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.