[{"data":1,"prerenderedAt":1786},["ShallowReactive",2],{"navigation":3,"/zksync-network/zksync-era/security-best-practices":761,"/zksync-network/zksync-era/security-best-practices-surround":1781},[4,325,440],{"title":5,"_path":6,"children":7},"ZKsync Network","/zksync-network",[8,10,25,37,86,248,262,316],{"title":9,"_path":6},"Introduction",{"title":11,"_path":12,"children":13},"Quickstart","/zksync-network/quick-start",[14,16,19,22],{"title":15,"_path":12},"Setup",{"title":17,"_path":18},"Deploy your first contract","/zksync-network/quick-start/deploy-your-first-contract",{"title":20,"_path":21},"Interact with your contract","/zksync-network/quick-start/interact-with-your-contract",{"title":23,"_path":24},"Build a Frontend","/zksync-network/quick-start/build-a-frontend",{"title":26,"_path":27,"children":28},"Environment","/zksync-network/environment",[29,31,34],{"title":30,"_path":27},"Elastic Network Chains",{"title":32,"_path":33},"L1 contracts","/zksync-network/environment/l1-contracts",{"title":35,"_path":36},"System contracts","/zksync-network/environment/l2-contracts",{"title":38,"_path":39,"children":40},"Unique features","/zksync-network/unique-features",[41,74],{"title":42,"_path":43,"children":44},"ZKsync SSO","/zksync-network/unique-features/zksync-sso",[45,47,50,53,56,59,62,65,68,71],{"title":46,"_path":43},"SSO Intro",{"title":48,"_path":49},"Getting Started","/zksync-network/unique-features/zksync-sso/getting-started",{"title":51,"_path":52},"Architecture","/zksync-network/unique-features/zksync-sso/architecture",{"title":54,"_path":55},"Auth Server","/zksync-network/unique-features/zksync-sso/auth-server",{"title":57,"_path":58},"Sessions","/zksync-network/unique-features/zksync-sso/sessions",{"title":60,"_path":61},"Passkeys","/zksync-network/unique-features/zksync-sso/passkeys",{"title":63,"_path":64},"Accounts","/zksync-network/unique-features/zksync-sso/accounts",{"title":66,"_path":67},"Account Recovery","/zksync-network/unique-features/zksync-sso/account-recovery",{"title":69,"_path":70},"Transaction Flow","/zksync-network/unique-features/zksync-sso/transaction-flow",{"title":72,"_path":73},"FAQs","/zksync-network/unique-features/zksync-sso/faqs",{"title":75,"_path":76,"children":77},"ZKsync Connect","/zksync-network/unique-features/zksync-connect",[78,80,83],{"title":79,"_path":76},"Overview",{"title":81,"_path":82},"Messaging","/zksync-network/unique-features/zksync-connect/messaging",{"title":84,"_path":85},"Interop Messages Guide","/zksync-network/unique-features/zksync-connect/interop-messages",{"title":87,"_path":88,"children":89},"Tooling","/zksync-network/tooling",[90,104,159,184,239,242,245],{"title":91,"_path":92,"children":93},"Local setup","/zksync-network/tooling/local-setup",[94,95,98,101],{"title":48,"_path":92},{"title":96,"_path":97},"anvil-zksync","/zksync-network/tooling/local-setup/anvil-zksync-node",{"title":99,"_path":100},"Docker L1 - L2 Nodes","/zksync-network/tooling/local-setup/dockerized-l1-l2-nodes",{"title":102,"_path":103},"Continuous Integration","/zksync-network/tooling/local-setup/continuous-integration",{"title":105,"_path":106,"children":107},"Hardhat","/zksync-network/tooling/hardhat",[108,109,112,125],{"title":79,"_path":106},{"title":110,"_path":111},"Installation","/zksync-network/tooling/hardhat/installation",{"title":113,"_path":114,"children":115},"Guides","/zksync-network/tooling/hardhat/guides",[116,119,122],{"title":117,"_path":118},"Getting started","/zksync-network/tooling/hardhat/guides/getting-started",{"title":120,"_path":121},"Migrating Hardhat project to ZKsync Era","/zksync-network/tooling/hardhat/guides/migrating-to-zksync",{"title":123,"_path":124},"Compiling non-inlinable libraries","/zksync-network/tooling/hardhat/guides/compiling-libraries",{"title":126,"_path":127,"children":128},"Plugins","/zksync-network/tooling/hardhat/plugins",[129,132,135,138,141,144,147,150,153,156],{"title":130,"_path":131},"hardhat-zksync","/zksync-network/tooling/hardhat/plugins/hardhat-zksync",{"title":133,"_path":134},"hardhat-zksync-solc","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-solc",{"title":136,"_path":137},"hardhat-zksync-vyper","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-vyper",{"title":139,"_path":140},"hardhat-zksync-deploy","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-deploy",{"title":142,"_path":143},"hardhat-zksync-upgradable","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-upgradable",{"title":145,"_path":146},"hardhat-zksync-verify","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-verify",{"title":148,"_path":149},"hardhat-zksync-verify-vyper","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-verify-vyper",{"title":151,"_path":152},"hardhat-zksync-ethers","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-ethers",{"title":154,"_path":155},"hardhat-zksync-node","/zksync-network/tooling/hardhat/plugins/hardhat-zksync-node",{"title":157,"_path":158},"Hardhat Community Plugins","/zksync-network/tooling/hardhat/plugins/other-plugins",{"title":160,"_path":161,"children":162},"Foundry","/zksync-network/tooling/foundry",[163,165,167,169],{"title":79,"_path":164},"/zksync-network/tooling/foundry/overview",{"title":110,"_path":166},"/zksync-network/tooling/foundry/installation",{"title":48,"_path":168},"/zksync-network/tooling/foundry/getting-started",{"title":170,"_path":171,"children":172},"Migration Guide","/zksync-network/tooling/foundry/migration-guide",[173,175,178,181],{"title":79,"_path":174},"/zksync-network/tooling/foundry/migration-guide/overview",{"title":176,"_path":177},"Compilation","/zksync-network/tooling/foundry/migration-guide/compilation",{"title":179,"_path":180},"Deployment","/zksync-network/tooling/foundry/migration-guide/deployment",{"title":182,"_path":183},"Testing","/zksync-network/tooling/foundry/migration-guide/testing",{"title":185,"_path":186,"children":187},"ZKsync CLI","/zksync-network/tooling/zksync-cli",[188,189,192,195,198,201,204,207,210,213],{"title":48,"_path":186},{"title":190,"_path":191},"Reading transaction data","/zksync-network/tooling/zksync-cli/reading-transaction-data",{"title":193,"_path":194},"Wallet actions","/zksync-network/tooling/zksync-cli/wallet-actions",{"title":196,"_path":197},"Bridging","/zksync-network/tooling/zksync-cli/bridging",{"title":199,"_path":200},"Interact with contracts","/zksync-network/tooling/zksync-cli/interact-with-contracts",{"title":202,"_path":203},"Creating projects","/zksync-network/tooling/zksync-cli/creating-projects",{"title":205,"_path":206},"Running a node","/zksync-network/tooling/zksync-cli/running-a-node",{"title":208,"_path":209},"Configuring chains","/zksync-network/tooling/zksync-cli/configuring-chains",{"title":211,"_path":212},"Troubleshooting","/zksync-network/tooling/zksync-cli/troubleshooting",{"title":214,"_path":215,"children":216},"CLI Reference","/zksync-network/tooling/zksync-cli/reference",[217,218,221,224,227,230,233,236],{"title":79,"_path":215},{"title":219,"_path":220},"zksync-cli bridge","/zksync-network/tooling/zksync-cli/reference/zksync-cli-bridge",{"title":222,"_path":223},"zksync-cli config chains","/zksync-network/tooling/zksync-cli/reference/zksync-cli-config-chains",{"title":225,"_path":226},"zksync-cli contract","/zksync-network/tooling/zksync-cli/reference/zksync-cli-contract",{"title":228,"_path":229},"zksync-cli create","/zksync-network/tooling/zksync-cli/reference/zksync-cli-create",{"title":231,"_path":232},"zksync-cli dev","/zksync-network/tooling/zksync-cli/reference/zksync-cli-dev",{"title":234,"_path":235},"zksync-cli transaction","/zksync-network/tooling/zksync-cli/reference/zksync-cli-transaction",{"title":237,"_path":238},"zksync-cli wallet","/zksync-network/tooling/zksync-cli/reference/zksync-cli-wallet",{"title":240,"_path":241},"Block explorers","/zksync-network/tooling/block-explorers",{"title":243,"_path":244},"ZKsync External Node","/zksync-network/tooling/external-node",{"title":246,"_path":247},"ZKsync Easy On-Ramp","/zksync-network/tooling/zksync-easy-onramp",{"title":249,"_path":250,"children":251},"ZKsync OS Developer Preview","/zksync-network/zksync-os",[252,254,257,260],{"title":253,"_path":250},"ZKsync OS Overview",{"title":255,"_path":256},"Network Details","/zksync-network/zksync-os/network-details",{"title":258,"_path":259},"Developer Quickstart","/zksync-network/zksync-os/quickstart",{"title":72,"_path":261},"/zksync-network/zksync-os/faqs",{"title":263,"_path":264,"children":265},"ZKsync Era","/zksync-network/zksync-era",[266,268,271,274,313],{"title":267,"_path":264},"About ZKsync Era",{"title":269,"_path":270},"ZKsync Era RPC","/zksync-network/zksync-era/network-details",{"title":272,"_path":273},"Features","/zksync-network/zksync-era/unique-features",{"title":275,"_path":276,"children":277},"Ecosystem","/zksync-network/zksync-era/ecosystem",[278,280,283,286,289,292,295,298,301,304,307,310],{"title":279,"_path":276},"Explore the ecosystem",{"title":281,"_path":282},"Bridges","/zksync-network/zksync-era/ecosystem/bridges",{"title":284,"_path":285},"Cross chain","/zksync-network/zksync-era/ecosystem/cross-chain",{"title":287,"_path":288},"Data indexers","/zksync-network/zksync-era/ecosystem/data-indexers",{"title":290,"_path":291},"Monitoring","/zksync-network/zksync-era/ecosystem/monitoring",{"title":293,"_path":294},"Network faucets","/zksync-network/zksync-era/ecosystem/network-faucets",{"title":296,"_path":297},"NFT marketplaces","/zksync-network/zksync-era/ecosystem/nft-marketplaces",{"title":299,"_path":300},"Oracles","/zksync-network/zksync-era/ecosystem/oracles",{"title":302,"_path":303},"RPC providers","/zksync-network/zksync-era/ecosystem/node-providers",{"title":305,"_path":306},"Wallets","/zksync-network/zksync-era/ecosystem/wallets",{"title":308,"_path":309},"User Onboarding","/zksync-network/zksync-era/ecosystem/user-onboarding",{"title":311,"_path":312},"Paymasters","/zksync-network/zksync-era/ecosystem/paymasters",{"title":314,"_path":315},"Security and best practices","/zksync-network/zksync-era/security-best-practices",{"title":317,"_path":318,"children":319},"Contributing","/zksync-network/contributing",[320,322],{"title":321,"_path":318},"Contributing to Documentation",{"title":323,"_path":324},"Protocol Contributions","/zksync-network/contributing/protocol-contributions",{"title":326,"_path":327,"children":328},"ZK Stack","/zk-stack",[329,331,334,364,386,402,437],{"title":330,"_path":327},"ZK Stack Overview",{"title":332,"_path":333},"ZKsync Chains","/zk-stack/zk-chains",{"title":335,"_path":336,"children":337},"Components","/zk-stack/components",[338,340,343,346,355,358,361],{"title":339,"_path":336},"ZK Stack Components Overview",{"title":341,"_path":342},"ZKsync OS","/zk-stack/components/zksync-os",{"title":344,"_path":345},"ZKsync OS Server","/zk-stack/components/server",{"title":347,"_path":348,"children":349},"ZKsync Airbender","/zk-stack/components/zksync-airbender",[350,352],{"title":351,"_path":348},"Airbender Overview",{"title":353,"_path":354},"Airbender Deep Dive","/zk-stack/components/zksync-airbender/deepdive",{"title":356,"_path":357},"Block explorer","/zk-stack/components/block-explorer",{"title":359,"_path":360},"Portal","/zk-stack/components/portal",{"title":362,"_path":363},"Fee withdrawer","/zk-stack/components/fee-withdrawer",{"title":365,"_path":366,"children":367},"Run a ZKsync Chain","/zk-stack/running",[368,371,374,377,380,383],{"title":369,"_path":370},"Launch a ZKsync chain","/zk-stack/running/quickstart",{"title":372,"_path":373},"Interact with your chain","/zk-stack/running/using-a-local-zk-chain",{"title":375,"_path":376},"ZKsync Gateway","/zk-stack/running/gateway-settlement-layer",{"title":378,"_path":379},"Prover setup","/zk-stack/running/proving",{"title":381,"_path":382},"Ownership Model","/zk-stack/running/ownership-model",{"title":384,"_path":385},"Rollup as a Service","/zk-stack/running/raas",{"title":387,"_path":388,"children":389},"Customizations","/zk-stack/customizations",[390,393,396,399],{"title":391,"_path":392},"Custom base tokens","/zk-stack/customizations/custom-base-tokens",{"title":394,"_path":395},"Validium in ZK Stack","/zk-stack/customizations/validium",{"title":397,"_path":398},"Configurations","/zk-stack/customizations/configurations",{"title":400,"_path":401},"Transaction filtering","/zk-stack/customizations/transaction-filtering",{"title":403,"_path":404,"children":405},"Prividium™","/zk-stack/prividium",[406,409,411,413,416,419,422,425,428,431,434],{"title":407,"_path":408},"Prividium™ Overview","/zk-stack/prividium/overview",{"title":272,"_path":410},"/zk-stack/prividium/features",{"title":51,"_path":412},"/zk-stack/prividium/architecture",{"title":414,"_path":415},"Deployment Model","/zk-stack/prividium/deployment",{"title":417,"_path":418},"Proxy RPC API","/zk-stack/prividium/proxy",{"title":420,"_path":421},"Administration and User Management","/zk-stack/prividium/administration-user-management",{"title":423,"_path":424},"Permissions and Access Control","/zk-stack/prividium/permissions-overview",{"title":426,"_path":427},"Prividium™ SDK","/zk-stack/prividium/sdk",{"title":429,"_path":430},"Private Block Explorer","/zk-stack/prividium/explorer",{"title":432,"_path":433},"Developer Considerations","/zk-stack/prividium/developer-considerations",{"title":435,"_path":436},"Prividium™ License Model","/zk-stack/prividium/license",{"title":438,"_path":439},"Open Source License","/zk-stack/license",{"title":441,"_path":442,"children":443},"ZKsync Protocol","/zksync-protocol",[444,446,463,488,501,522,541,554,758],{"title":445,"_path":442},"Getting started with ZKsync protocol",{"title":447,"_path":448,"children":449},"ZKsync protocol overview","/zksync-protocol/rollup",[450,451,454,457,460],{"title":447,"_path":448},{"title":452,"_path":453},"Bridging assets","/zksync-protocol/rollup/bridging-assets",{"title":455,"_path":456},"Finality","/zksync-protocol/rollup/finality",{"title":458,"_path":459},"Data availability","/zksync-protocol/rollup/data-availability",{"title":461,"_path":462},"Pubdata compression","/zksync-protocol/rollup/pubdata-compression",{"title":341,"_path":464,"children":465},"/zksync-protocol/zksyncos",[466,467,470,473,476,479,482,485],{"title":253,"_path":464},{"title":468,"_path":469},"Double Resource Accounting","/zksync-protocol/zksyncos/double-accounting",{"title":471,"_path":472},"Bootloader","/zksync-protocol/zksyncos/bootloader",{"title":474,"_path":475},"Execution Environments","/zksync-protocol/zksyncos/execution-environment",{"title":477,"_path":478},"System","/zksync-protocol/zksyncos/system",{"title":480,"_path":481},"Processing of Transactions","/zksync-protocol/zksyncos/tx-processing",{"title":483,"_path":484},"System Hooks","/zksync-protocol/zksyncos/system-hooks",{"title":486,"_path":487},"Runner Flow","/zksync-protocol/zksyncos/runner-flow",{"title":375,"_path":489,"children":490},"/zksync-protocol/gateway",[491,493,495,498],{"title":492,"_path":489},"Gateway Overview",{"title":272,"_path":494},"/zksync-protocol/gateway/features",{"title":496,"_path":497},"Data Availability Considerations","/zksync-protocol/gateway/da-considerations",{"title":499,"_path":500},"Frequently Asked Questions","/zksync-protocol/gateway/gateway-faq",{"title":502,"_path":503,"children":504},"Web3 API","/zksync-protocol/api",[505,507,510,513,516,519],{"title":506,"_path":503},"API Overview",{"title":508,"_path":509},"Conventions","/zksync-protocol/api/conventions",{"title":511,"_path":512},"Ethereum JSON-RPC API","/zksync-protocol/api/ethereum-rpc",{"title":514,"_path":515},"Debug JSON-RPC API","/zksync-protocol/api/debug-rpc",{"title":517,"_path":518},"ZKsync JSON-RPC API","/zksync-protocol/api/zks-rpc",{"title":520,"_path":521},"PubSub JSON-RPC API","/zksync-protocol/api/pub-sub-rpc",{"title":523,"_path":524,"children":525},"Contracts","/zksync-protocol/contracts",[526,528],{"title":527,"_path":524},"ZKsync contracts",{"title":32,"_path":529,"children":530},"/zksync-protocol/contracts/l1-contracts",[531,532,535,538],{"title":32,"_path":529},{"title":533,"_path":534},"L1 ecosystem contracts","/zksync-protocol/contracts/l1-contracts/l1-ecosystem-contracts",{"title":536,"_path":537},"Shared bridges","/zksync-protocol/contracts/l1-contracts/shared-bridges",{"title":539,"_path":540},"ZKsync Chain addresses","/zksync-protocol/contracts/l1-contracts/zk-chain-addresses",{"title":542,"_path":543,"children":544},"Protocol security","/zksync-protocol/security",[545,548,551],{"title":546,"_path":547},"Audits","/zksync-protocol/security/audits",{"title":549,"_path":550},"Bug bounty","/zksync-protocol/security/bug-bounty",{"title":552,"_path":553},"Withdrawal delay","/zksync-protocol/security/withdrawal-delay",{"title":555,"_path":556,"children":557},"EraVM Chains","/zksync-protocol/era-vm",[558,560,587,596,613,678,690,712,739],{"title":559,"_path":556},"EraVM Overview",{"title":561,"_path":562,"children":563},"Transactions","/zksync-protocol/era-vm/transactions",[564,567,570,573],{"title":565,"_path":566},"Transaction lifecycle","/zksync-protocol/era-vm/transactions/transaction-lifecycle",{"title":568,"_path":569},"Blocks and batches","/zksync-protocol/era-vm/transactions/blocks",{"title":571,"_path":572},"L1 \u003C-> L2 communication","/zksync-protocol/era-vm/transactions/l1_l2_communication",{"title":574,"_path":575,"children":576},"Fee model","/zksync-protocol/era-vm/transactions/fee-model",[577,578,581,584],{"title":574,"_path":575},{"title":579,"_path":580},"How L2 gas price works","/zksync-protocol/era-vm/transactions/fee-model/how-l2-gas-price-works",{"title":582,"_path":583},"How ZKsync Chains charges for pubdata","/zksync-protocol/era-vm/transactions/fee-model/how-we-charge-for-pubdata",{"title":585,"_path":586},"ZKsync fee structure","/zksync-protocol/era-vm/transactions/fee-model/fee-structure",{"title":588,"_path":589,"children":590},"EraVM","/zksync-protocol/era-vm/vm",[591,593],{"title":592,"_path":589},"ZKsync Virtual Machine primer",{"title":594,"_path":595},"VM formal specification","/zksync-protocol/era-vm/vm/formal-spec",{"title":523,"_path":597,"children":598},"/zksync-protocol/era-vm/contracts",[599,600,602,604,607,610],{"title":527,"_path":597},{"title":471,"_path":601},"/zksync-protocol/era-vm/contracts/bootloader",{"title":35,"_path":603},"/zksync-protocol/era-vm/contracts/system-contracts",{"title":605,"_path":606},"Handling L1->L2 ops on ZKsync","/zksync-protocol/era-vm/contracts/handling-l1-l2-ops",{"title":608,"_path":609},"Handling pubdata","/zksync-protocol/era-vm/contracts/handling-pubdata",{"title":611,"_path":612},"Pubdata post 4844","/zksync-protocol/era-vm/contracts/pubdata-post-4844",{"title":614,"_path":615,"children":616},"Circuits","/zksync-protocol/era-vm/circuits",[617,618,621,672,675],{"title":79,"_path":615},{"title":619,"_path":620},"ZK terminology","/zksync-protocol/era-vm/circuits/zk-terminology",{"title":622,"_path":623,"children":624},"Concrete circuits","/zksync-protocol/era-vm/circuits/circuits",[625,626,629,632,635,638,641,644,647,650,653,656,659],{"title":79,"_path":623},{"title":627,"_path":628},"Circuit testing","/zksync-protocol/era-vm/circuits/circuits/circuit-testing",{"title":630,"_path":631},"CodeDecommitter","/zksync-protocol/era-vm/circuits/circuits/code-decommitter",{"title":633,"_path":634},"DemuxLogQueue","/zksync-protocol/era-vm/circuits/circuits/demux-log-queue",{"title":636,"_path":637},"ECRecover","/zksync-protocol/era-vm/circuits/circuits/ecrecover",{"title":639,"_path":640},"KeccakRoundFunction","/zksync-protocol/era-vm/circuits/circuits/keccak-round-function",{"title":642,"_path":643},"L1MessagesHasher","/zksync-protocol/era-vm/circuits/circuits/l1-messages-hasher",{"title":645,"_path":646},"LogSorter","/zksync-protocol/era-vm/circuits/circuits/log-sorter",{"title":648,"_path":649},"Main VM","/zksync-protocol/era-vm/circuits/circuits/main-vm",{"title":651,"_path":652},"RAMPermutation","/zksync-protocol/era-vm/circuits/circuits/ram-permutation",{"title":654,"_path":655},"Sha256RoundFunction","/zksync-protocol/era-vm/circuits/circuits/sha256-round-function",{"title":657,"_path":658},"StorageApplication","/zksync-protocol/era-vm/circuits/circuits/storage-application",{"title":660,"_path":661,"children":662},"Sorting and deduplicating","/zksync-protocol/era-vm/circuits/circuits/sorting",[663,664,667,670],{"title":79,"_path":661},{"title":665,"_path":666},"SortDecommitments","/zksync-protocol/era-vm/circuits/circuits/sorting/sort-decommitments",{"title":668,"_path":669},"StorageSorter","/zksync-protocol/era-vm/circuits/circuits/sorting/storage-sorter",{"title":645,"_path":671},"/zksync-protocol/era-vm/circuits/circuits/sorting/log-sorter",{"title":673,"_path":674},"Boojum gadgets","/zksync-protocol/era-vm/circuits/boojum-gadgets",{"title":676,"_path":677},"Boojum function - `check_if_satisfied`","/zksync-protocol/era-vm/circuits/boojum-function-check-if-satisfied",{"title":679,"_path":680,"children":681},"Compilers","/zksync-protocol/era-vm/compiler",[682],{"title":683,"_path":684,"children":685},"Compiler toolchain overview","/zksync-protocol/era-vm/compiler/toolchain",[686,687],{"title":683,"_path":684},{"title":688,"_path":689},"LLVM framework","/zksync-protocol/era-vm/compiler/toolchain/llvm",{"title":691,"_path":692,"children":693},"Differences from L1","/zksync-protocol/era-vm/differences",[694,697,700,703,706,709],{"title":695,"_path":696},"EVM instructions","/zksync-protocol/era-vm/differences/evm-instructions",{"title":698,"_path":699},"Nonces","/zksync-protocol/era-vm/differences/nonces",{"title":701,"_path":702},"Libraries","/zksync-protocol/era-vm/differences/libraries",{"title":704,"_path":705},"Precompiles","/zksync-protocol/era-vm/differences/pre-compiles",{"title":707,"_path":708},"Native AA vs EIP 4337","/zksync-protocol/era-vm/differences/native-vs-eip4337",{"title":710,"_path":711},"Contract deployment","/zksync-protocol/era-vm/differences/contract-deployment",{"title":713,"_path":714,"children":715},"EVM Bytecode Interpreter","/zksync-protocol/era-vm/evm-interpreter",[716,718,721,724,727,730,733,736],{"title":79,"_path":717},"/zksync-protocol/era-vm/evm-interpreter/overview",{"title":719,"_path":720},"EVM bytecode deployment and execution","/zksync-protocol/era-vm/evm-interpreter/deployment-execution",{"title":722,"_path":723},"EraVM ↔ EVM Contract Interactions","/zksync-protocol/era-vm/evm-interpreter/era-evm-interactions",{"title":725,"_path":726},"Differences Between the EVM Bytecode Interpreter and Ethereum","/zksync-protocol/era-vm/evm-interpreter/evm-differences",{"title":728,"_path":729},"Technical Architecture of the EVM Interpreter","/zksync-protocol/era-vm/evm-interpreter/technical-details",{"title":731,"_path":732},"EVM Gas Interpretation","/zksync-protocol/era-vm/evm-interpreter/evm-gas-interpretation",{"title":734,"_path":735},"Pre Deployed Contracts","/zksync-protocol/era-vm/evm-interpreter/pre-deployed-contracts",{"title":737,"_path":738},"EVM Bytecode Interpreter FAQ","/zksync-protocol/era-vm/evm-interpreter/faq",{"title":740,"_path":741,"children":742},"Account Abstraction","/zksync-protocol/era-vm/account-abstraction",[743,744,747,749,752,755],{"title":9,"_path":741},{"title":745,"_path":746},"Design","/zksync-protocol/era-vm/account-abstraction/design",{"title":311,"_path":748},"/zksync-protocol/era-vm/account-abstraction/paymasters",{"title":750,"_path":751},"Building smart accounts","/zksync-protocol/era-vm/account-abstraction/building-smart-accounts",{"title":753,"_path":754},"Signature validation","/zksync-protocol/era-vm/account-abstraction/signature-validation",{"title":756,"_path":757},"Extending EIP-4337","/zksync-protocol/era-vm/account-abstraction/extending-4337",{"title":759,"_path":760},"Upgrades and migrations","/zksync-protocol/upgrades-and-migrations",{"_path":315,"_dir":762,"_draft":763,"_partial":763,"_locale":764,"title":314,"description":765,"body":766,"_type":1774,"_id":1775,"_source":1776,"_file":1777,"_stem":1778,"_extension":1779,"sitemap":1780},"zksync-era",false,"","Guidelines to help you build secure, efficient, and maintainable smart contracts on ZKsync chains powered by EraVM.",{"type":767,"children":768,"toc":1764},"root",[769,777,807,827,838,847,914,922,992,1028,1041,1070,1075,1081,1093,1111,1123,1128,1133,1139,1144,1168,1173,1185,1204,1217,1550,1578,1583,1608,1620,1626,1646,1651,1663,1669,1674,1684,1689,1744,1749,1753,1758],{"type":770,"tag":771,"props":772,"children":773},"element","p",{},[774],{"type":775,"value":776},"text","Before developing on a ZKsync chain running EraVM, review these best practices. Following these recommendations will\nhelp you optimize performance, maintain security, and align your contracts with the design of the EraVM.",{"type":770,"tag":778,"props":779,"children":781},"h2",{"id":780},"use-call-instead-of-send-or-transfer",[782,784,791,793,799,801],{"type":775,"value":783},"Use ",{"type":770,"tag":785,"props":786,"children":788},"code",{"className":787},[],[789],{"type":775,"value":790},"call",{"type":775,"value":792}," instead of ",{"type":770,"tag":785,"props":794,"children":796},{"className":795},[],[797],{"type":775,"value":798},".send",{"type":775,"value":800}," or ",{"type":770,"tag":785,"props":802,"children":804},{"className":803},[],[805],{"type":775,"value":806},".transfer",{"type":770,"tag":771,"props":808,"children":809},{},[810,812,818,819,825],{"type":775,"value":811},"Avoid using ",{"type":770,"tag":785,"props":813,"children":815},{"className":814},[],[816],{"type":775,"value":817},"payable(addr).send(x)",{"type":775,"value":800},{"type":770,"tag":785,"props":820,"children":822},{"className":821},[],[823],{"type":775,"value":824},"payable(addr).transfer(x)",{"type":775,"value":826},".\nThese functions only provide a 2300 gas stipend, which may not be enough if the call triggers state changes or other operations that require more L2 gas.",{"type":770,"tag":771,"props":828,"children":829},{},[830,831,836],{"type":775,"value":783},{"type":770,"tag":785,"props":832,"children":834},{"className":833},[],[835],{"type":775,"value":790},{"type":775,"value":837}," instead.",{"type":770,"tag":771,"props":839,"children":840},{},[841],{"type":770,"tag":842,"props":843,"children":844},"strong",{},[845],{"type":775,"value":846},"Instead of:",{"type":770,"tag":848,"props":849,"children":853},"pre",{"className":850,"code":851,"language":852,"meta":764,"style":764},"language-solidity shiki shiki-themes github-light github-light github-dark","payable(addr).send(x); // or\npayable(addr).transfer(x);\n","solidity",[854],{"type":770,"tag":785,"props":855,"children":856},{"__ignoreMap":764},[857,892],{"type":770,"tag":858,"props":859,"children":862},"span",{"class":860,"line":861},"line",1,[863,869,875,881,886],{"type":770,"tag":858,"props":864,"children":866},{"style":865},"--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583",[867],{"type":775,"value":868},"payable",{"type":770,"tag":858,"props":870,"children":872},{"style":871},"--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8",[873],{"type":775,"value":874},"(addr).",{"type":770,"tag":858,"props":876,"children":878},{"style":877},"--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0",[879],{"type":775,"value":880},"send",{"type":770,"tag":858,"props":882,"children":883},{"style":871},[884],{"type":775,"value":885},"(x); ",{"type":770,"tag":858,"props":887,"children":889},{"style":888},"--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D",[890],{"type":775,"value":891},"// or\n",{"type":770,"tag":858,"props":893,"children":895},{"class":860,"line":894},2,[896,900,904,909],{"type":770,"tag":858,"props":897,"children":898},{"style":865},[899],{"type":775,"value":868},{"type":770,"tag":858,"props":901,"children":902},{"style":871},[903],{"type":775,"value":874},{"type":770,"tag":858,"props":905,"children":906},{"style":877},[907],{"type":775,"value":908},"transfer",{"type":770,"tag":858,"props":910,"children":911},{"style":871},[912],{"type":775,"value":913},"(x);\n",{"type":770,"tag":771,"props":915,"children":916},{},[917],{"type":770,"tag":842,"props":918,"children":919},{},[920],{"type":775,"value":921},"Use:",{"type":770,"tag":848,"props":923,"children":925},{"className":850,"code":924,"language":852,"meta":764,"style":764},"(bool s, ) = addr.call{value: x}(\"\");\nrequire(s);\n",[926],{"type":770,"tag":785,"props":927,"children":928},{"__ignoreMap":764},[929,979],{"type":770,"tag":858,"props":930,"children":931},{"class":860,"line":861},[932,937,943,948,953,958,963,968,974],{"type":770,"tag":858,"props":933,"children":934},{"style":871},[935],{"type":775,"value":936},"(",{"type":770,"tag":858,"props":938,"children":940},{"style":939},"--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF",[941],{"type":775,"value":942},"bool",{"type":770,"tag":858,"props":944,"children":945},{"style":871},[946],{"type":775,"value":947}," s, ) ",{"type":770,"tag":858,"props":949,"children":950},{"style":865},[951],{"type":775,"value":952},"=",{"type":770,"tag":858,"props":954,"children":955},{"style":871},[956],{"type":775,"value":957}," addr.call{value",{"type":770,"tag":858,"props":959,"children":960},{"style":865},[961],{"type":775,"value":962},":",{"type":770,"tag":858,"props":964,"children":965},{"style":871},[966],{"type":775,"value":967}," x}(",{"type":770,"tag":858,"props":969,"children":971},{"style":970},"--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF",[972],{"type":775,"value":973},"\"\"",{"type":770,"tag":858,"props":975,"children":976},{"style":871},[977],{"type":775,"value":978},");\n",{"type":770,"tag":858,"props":980,"children":981},{"class":860,"line":894},[982,987],{"type":770,"tag":858,"props":983,"children":984},{"style":865},[985],{"type":775,"value":986},"require",{"type":770,"tag":858,"props":988,"children":989},{"style":871},[990],{"type":775,"value":991},"(s);\n",{"type":770,"tag":771,"props":993,"children":994},{},[995,997,1002,1003,1008,1010,1026],{"type":775,"value":996},"This approach replicates the behavior of ",{"type":770,"tag":785,"props":998,"children":1000},{"className":999},[],[1001],{"type":775,"value":798},{"type":775,"value":800},{"type":770,"tag":785,"props":1004,"children":1006},{"className":1005},[],[1007],{"type":775,"value":806},{"type":775,"value":1009}," while providing more flexibility and avoiding gas-limit issues.\nSee ",{"type":770,"tag":1011,"props":1012,"children":1016},"a",{"href":1013,"rel":1014},"https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/",[1015],"nofollow",[1017,1019,1024],{"type":775,"value":1018},"Consensys’ explanation of ",{"type":770,"tag":785,"props":1020,"children":1022},{"className":1021},[],[1023],{"type":775,"value":806},{"type":775,"value":1025}," risks",{"type":775,"value":1027}," for additional context.",{"type":770,"tag":771,"props":1029,"children":1030},{},[1031,1033,1039],{"type":775,"value":1032},"While ",{"type":770,"tag":785,"props":1034,"children":1036},{"className":1035},[],[1037],{"type":775,"value":1038},".call",{"type":775,"value":1040}," is safer in terms of gas, it does not provide built-in reentrancy protection. To prevent vulnerabilities:",{"type":770,"tag":1042,"props":1043,"children":1044},"ul",{},[1045,1058],{"type":770,"tag":1046,"props":1047,"children":1048},"li",{},[1049,1051,1056],{"type":775,"value":1050},"Follow the ",{"type":770,"tag":842,"props":1052,"children":1053},{},[1054],{"type":775,"value":1055},"checks-effects-interactions",{"type":775,"value":1057}," pattern.",{"type":770,"tag":1046,"props":1059,"children":1060},{},[1061,1063,1068],{"type":775,"value":1062},"Use a ",{"type":770,"tag":842,"props":1064,"children":1065},{},[1066],{"type":775,"value":1067},"reentrancy guard",{"type":775,"value":1069}," when interacting with external contracts.",{"type":770,"tag":771,"props":1071,"children":1072},{},[1073],{"type":775,"value":1074},"These practices help secure your contracts against reentrancy attacks and unexpected external behavior.",{"type":770,"tag":778,"props":1076,"children":1078},{"id":1077},"use-the-proxy-pattern",[1079],{"type":775,"value":1080},"Use the Proxy Pattern",{"type":770,"tag":771,"props":1082,"children":1083},{},[1084,1086,1091],{"type":775,"value":1085},"ZKsync chains running EraVM support Solidity and Vyper code compilation into ",{"type":770,"tag":842,"props":1087,"children":1088},{},[1089],{"type":775,"value":1090},"EraVM bytecode",{"type":775,"value":1092}," using custom compilers.\nAlthough the compilers undergoes extensive testing to ensure EVM compatibility, minor issues can occasionally appear.",{"type":770,"tag":1094,"props":1095,"children":1097},"callout",{"icon":1096},"i-heroicons-light-bulb",[1098],{"type":770,"tag":771,"props":1099,"children":1100},{},[1101,1103,1109],{"type":775,"value":1102},"ZKsync chains running EraVM also support EVM Bytecode from the ",{"type":770,"tag":785,"props":1104,"children":1106},{"className":1105},[],[1107],{"type":775,"value":1108},"solc",{"type":775,"value":1110}," compiler.",{"type":770,"tag":771,"props":1112,"children":1113},{},[1114,1116,1121],{"type":775,"value":1115},"To handle potential compiler patches or updates, use the ",{"type":770,"tag":842,"props":1117,"children":1118},{},[1119],{"type":775,"value":1120},"Proxy pattern",{"type":775,"value":1122}," when deploying new contracts.\nThis allows you to recompile and upgrade your contract logic without requiring a full redeployment.",{"type":770,"tag":771,"props":1124,"children":1125},{},[1126],{"type":775,"value":1127},"After your contracts have proven stable, you can migrate to an immutable version if desired.",{"type":770,"tag":771,"props":1129,"children":1130},{},[1131],{"type":775,"value":1132},"Using the Proxy pattern during the initial deployment phase reduces maintenance effort and ensures flexibility as the EraVM continues to evolve.",{"type":770,"tag":778,"props":1134,"children":1136},{"id":1135},"do-not-rely-on-ethereum-gas-logic",[1137],{"type":775,"value":1138},"Do Not Rely on Ethereum Gas Logic",{"type":770,"tag":771,"props":1140,"children":1141},{},[1142],{"type":775,"value":1143},"The gas model on ZKsync chains running EraVM differs from Ethereum’s. Two key factors influence gas costs:",{"type":770,"tag":1145,"props":1146,"children":1147},"ol",{},[1148,1158],{"type":770,"tag":1046,"props":1149,"children":1150},{},[1151,1156],{"type":770,"tag":842,"props":1152,"children":1153},{},[1154],{"type":775,"value":1155},"State-diff-based data availability",{"type":775,"value":1157}," – transaction costs depend on L1 gas prices.",{"type":770,"tag":1046,"props":1159,"children":1160},{},[1161,1166],{"type":770,"tag":842,"props":1162,"children":1163},{},[1164],{"type":775,"value":1165},"Distinct computational model",{"type":775,"value":1167}," – the EraVM uses a different opcode pricing model and computational trade-offs compared to the EVM.",{"type":770,"tag":771,"props":1169,"children":1170},{},[1171],{"type":775,"value":1172},"Because of these differences, gas usage on a ZKsync chain cannot be directly compared to Ethereum.\nAvoid hardcoding gas constants in your contracts, as future changes to ZKsync’s fee model could make these assumptions invalid.",{"type":770,"tag":778,"props":1174,"children":1176},{"id":1175},"account-for-gasperpubdatabyte",[1177,1179],{"type":775,"value":1178},"Account for ",{"type":770,"tag":785,"props":1180,"children":1182},{"className":1181},[],[1183],{"type":775,"value":1184},"gasPerPubdataByte",{"type":770,"tag":771,"props":1186,"children":1187},{},[1188,1190,1195,1197,1202],{"type":775,"value":1189},"Each transaction on ZKsync includes a constant called ",{"type":770,"tag":785,"props":1191,"children":1193},{"className":1192},[],[1194],{"type":775,"value":1184},{"type":775,"value":1196},".\nThis value is set by the operator, although users define an upper bound for it in EIP-712 transactions.\nSince ",{"type":770,"tag":785,"props":1198,"children":1200},{"className":1199},[],[1201],{"type":775,"value":1184},{"type":775,"value":1203}," fluctuates with L1 gas prices, relying solely on gas limits can lead to unpredictable behavior.",{"type":770,"tag":771,"props":1205,"children":1206},{},[1207,1209,1215],{"type":775,"value":1208},"For example, in Gnosis Safe’s ",{"type":770,"tag":785,"props":1210,"children":1212},{"className":1211},[],[1213],{"type":775,"value":1214},"execTransaction",{"type":775,"value":1216}," method:",{"type":770,"tag":848,"props":1218,"children":1220},{"className":850,"code":1219,"language":852,"meta":764,"style":764},"// We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n// We also include the 1/64 in the check that is not send along with a call to counteract potential shortcomings because of EIP-150\nrequire(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n// Use scope here to limit variable lifetime and prevent `stack too deep` errors\n{\n    uint256 gasUsed = gasleft();\n    // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n    // We only subtract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n    success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n    gasUsed = gasUsed.sub(gasleft());\n\n    // ...\n}\n",[1221],{"type":770,"tag":785,"props":1222,"children":1223},{"__ignoreMap":764},[1224,1232,1240,1349,1358,1367,1395,1404,1413,1486,1522,1532,1541],{"type":770,"tag":858,"props":1225,"children":1226},{"class":860,"line":861},[1227],{"type":770,"tag":858,"props":1228,"children":1229},{"style":888},[1230],{"type":775,"value":1231},"// We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n",{"type":770,"tag":858,"props":1233,"children":1234},{"class":860,"line":894},[1235],{"type":770,"tag":858,"props":1236,"children":1237},{"style":888},[1238],{"type":775,"value":1239},"// We also include the 1/64 in the check that is not send along with a call to counteract potential shortcomings because of EIP-150\n",{"type":770,"tag":858,"props":1241,"children":1243},{"class":860,"line":1242},3,[1244,1248,1252,1257,1262,1267,1272,1277,1282,1287,1292,1297,1302,1307,1312,1317,1322,1326,1330,1335,1340,1345],{"type":770,"tag":858,"props":1245,"children":1246},{"style":865},[1247],{"type":775,"value":986},{"type":770,"tag":858,"props":1249,"children":1250},{"style":871},[1251],{"type":775,"value":936},{"type":770,"tag":858,"props":1253,"children":1254},{"style":939},[1255],{"type":775,"value":1256},"gasleft",{"type":770,"tag":858,"props":1258,"children":1259},{"style":871},[1260],{"type":775,"value":1261},"() ",{"type":770,"tag":858,"props":1263,"children":1264},{"style":865},[1265],{"type":775,"value":1266},">=",{"type":770,"tag":858,"props":1268,"children":1269},{"style":871},[1270],{"type":775,"value":1271}," ((safeTxGas ",{"type":770,"tag":858,"props":1273,"children":1274},{"style":865},[1275],{"type":775,"value":1276},"*",{"type":770,"tag":858,"props":1278,"children":1279},{"style":939},[1280],{"type":775,"value":1281}," 64",{"type":770,"tag":858,"props":1283,"children":1284},{"style":871},[1285],{"type":775,"value":1286},") ",{"type":770,"tag":858,"props":1288,"children":1289},{"style":865},[1290],{"type":775,"value":1291},"/",{"type":770,"tag":858,"props":1293,"children":1294},{"style":939},[1295],{"type":775,"value":1296}," 63",{"type":770,"tag":858,"props":1298,"children":1299},{"style":871},[1300],{"type":775,"value":1301},").",{"type":770,"tag":858,"props":1303,"children":1304},{"style":877},[1305],{"type":775,"value":1306},"max",{"type":770,"tag":858,"props":1308,"children":1309},{"style":871},[1310],{"type":775,"value":1311},"(safeTxGas ",{"type":770,"tag":858,"props":1313,"children":1314},{"style":865},[1315],{"type":775,"value":1316},"+",{"type":770,"tag":858,"props":1318,"children":1319},{"style":939},[1320],{"type":775,"value":1321}," 2500",{"type":770,"tag":858,"props":1323,"children":1324},{"style":871},[1325],{"type":775,"value":1286},{"type":770,"tag":858,"props":1327,"children":1328},{"style":865},[1329],{"type":775,"value":1316},{"type":770,"tag":858,"props":1331,"children":1332},{"style":939},[1333],{"type":775,"value":1334}," 500",{"type":770,"tag":858,"props":1336,"children":1337},{"style":871},[1338],{"type":775,"value":1339},", ",{"type":770,"tag":858,"props":1341,"children":1342},{"style":970},[1343],{"type":775,"value":1344},"\"GS010\"",{"type":770,"tag":858,"props":1346,"children":1347},{"style":871},[1348],{"type":775,"value":978},{"type":770,"tag":858,"props":1350,"children":1352},{"class":860,"line":1351},4,[1353],{"type":770,"tag":858,"props":1354,"children":1355},{"style":888},[1356],{"type":775,"value":1357},"// Use scope here to limit variable lifetime and prevent `stack too deep` errors\n",{"type":770,"tag":858,"props":1359,"children":1361},{"class":860,"line":1360},5,[1362],{"type":770,"tag":858,"props":1363,"children":1364},{"style":871},[1365],{"type":775,"value":1366},"{\n",{"type":770,"tag":858,"props":1368,"children":1370},{"class":860,"line":1369},6,[1371,1376,1381,1385,1390],{"type":770,"tag":858,"props":1372,"children":1373},{"style":939},[1374],{"type":775,"value":1375},"    uint256",{"type":770,"tag":858,"props":1377,"children":1378},{"style":871},[1379],{"type":775,"value":1380}," gasUsed ",{"type":770,"tag":858,"props":1382,"children":1383},{"style":865},[1384],{"type":775,"value":952},{"type":770,"tag":858,"props":1386,"children":1387},{"style":939},[1388],{"type":775,"value":1389}," gasleft",{"type":770,"tag":858,"props":1391,"children":1392},{"style":871},[1393],{"type":775,"value":1394},"();\n",{"type":770,"tag":858,"props":1396,"children":1398},{"class":860,"line":1397},7,[1399],{"type":770,"tag":858,"props":1400,"children":1401},{"style":888},[1402],{"type":775,"value":1403},"    // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n",{"type":770,"tag":858,"props":1405,"children":1407},{"class":860,"line":1406},8,[1408],{"type":770,"tag":858,"props":1409,"children":1410},{"style":888},[1411],{"type":775,"value":1412},"    // We only subtract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n",{"type":770,"tag":858,"props":1414,"children":1416},{"class":860,"line":1415},9,[1417,1422,1426,1431,1436,1441,1446,1451,1456,1460,1464,1469,1473,1477,1481],{"type":770,"tag":858,"props":1418,"children":1419},{"style":871},[1420],{"type":775,"value":1421},"    success ",{"type":770,"tag":858,"props":1423,"children":1424},{"style":865},[1425],{"type":775,"value":952},{"type":770,"tag":858,"props":1427,"children":1428},{"style":877},[1429],{"type":775,"value":1430}," execute",{"type":770,"tag":858,"props":1432,"children":1433},{"style":871},[1434],{"type":775,"value":1435},"(to, value, data, operation, gasPrice ",{"type":770,"tag":858,"props":1437,"children":1438},{"style":865},[1439],{"type":775,"value":1440},"==",{"type":770,"tag":858,"props":1442,"children":1443},{"style":939},[1444],{"type":775,"value":1445}," 0",{"type":770,"tag":858,"props":1447,"children":1448},{"style":865},[1449],{"type":775,"value":1450}," ?",{"type":770,"tag":858,"props":1452,"children":1453},{"style":871},[1454],{"type":775,"value":1455}," (",{"type":770,"tag":858,"props":1457,"children":1458},{"style":939},[1459],{"type":775,"value":1256},{"type":770,"tag":858,"props":1461,"children":1462},{"style":871},[1463],{"type":775,"value":1261},{"type":770,"tag":858,"props":1465,"children":1466},{"style":865},[1467],{"type":775,"value":1468},"-",{"type":770,"tag":858,"props":1470,"children":1471},{"style":939},[1472],{"type":775,"value":1321},{"type":770,"tag":858,"props":1474,"children":1475},{"style":871},[1476],{"type":775,"value":1286},{"type":770,"tag":858,"props":1478,"children":1479},{"style":865},[1480],{"type":775,"value":962},{"type":770,"tag":858,"props":1482,"children":1483},{"style":871},[1484],{"type":775,"value":1485}," safeTxGas);\n",{"type":770,"tag":858,"props":1487,"children":1489},{"class":860,"line":1488},10,[1490,1495,1499,1504,1509,1513,1517],{"type":770,"tag":858,"props":1491,"children":1492},{"style":871},[1493],{"type":775,"value":1494},"    gasUsed ",{"type":770,"tag":858,"props":1496,"children":1497},{"style":865},[1498],{"type":775,"value":952},{"type":770,"tag":858,"props":1500,"children":1501},{"style":871},[1502],{"type":775,"value":1503}," gasUsed.",{"type":770,"tag":858,"props":1505,"children":1506},{"style":877},[1507],{"type":775,"value":1508},"sub",{"type":770,"tag":858,"props":1510,"children":1511},{"style":871},[1512],{"type":775,"value":936},{"type":770,"tag":858,"props":1514,"children":1515},{"style":939},[1516],{"type":775,"value":1256},{"type":770,"tag":858,"props":1518,"children":1519},{"style":871},[1520],{"type":775,"value":1521},"());\n",{"type":770,"tag":858,"props":1523,"children":1525},{"class":860,"line":1524},11,[1526],{"type":770,"tag":858,"props":1527,"children":1529},{"emptyLinePlaceholder":1528},true,[1530],{"type":775,"value":1531},"\n",{"type":770,"tag":858,"props":1533,"children":1535},{"class":860,"line":1534},12,[1536],{"type":770,"tag":858,"props":1537,"children":1538},{"style":888},[1539],{"type":775,"value":1540},"    // ...\n",{"type":770,"tag":858,"props":1542,"children":1544},{"class":860,"line":1543},13,[1545],{"type":770,"tag":858,"props":1546,"children":1547},{"style":871},[1548],{"type":775,"value":1549},"}\n",{"type":770,"tag":771,"props":1551,"children":1552},{},[1553,1555,1561,1563,1569,1571,1576],{"type":775,"value":1554},"This logic enforces a minimum ",{"type":770,"tag":785,"props":1556,"children":1558},{"className":1557},[],[1559],{"type":775,"value":1560},"gasleft()",{"type":775,"value":1562}," but does not account for ",{"type":770,"tag":785,"props":1564,"children":1566},{"className":1565},[],[1567],{"type":775,"value":1568},"gasPerPubdata",{"type":775,"value":1570},".\nA malicious user could exploit a high ",{"type":770,"tag":785,"props":1572,"children":1574},{"className":1573},[],[1575],{"type":775,"value":1568},{"type":775,"value":1577}," value to increase gas costs or cause transaction failures.",{"type":770,"tag":771,"props":1579,"children":1580},{},[1581],{"type":775,"value":1582},"When porting logic from Ethereum:",{"type":770,"tag":1042,"props":1584,"children":1585},{},[1586,1598,1603],{"type":770,"tag":1046,"props":1587,"children":1588},{},[1589,1591,1596],{"type":775,"value":1590},"Include ",{"type":770,"tag":785,"props":1592,"children":1594},{"className":1593},[],[1595],{"type":775,"value":1568},{"type":775,"value":1597}," in your gas calculations.",{"type":770,"tag":1046,"props":1599,"children":1600},{},[1601],{"type":775,"value":1602},"Add a safety margin to handle price fluctuations.",{"type":770,"tag":1046,"props":1604,"children":1605},{},[1606],{"type":775,"value":1607},"Avoid assumptions based on Ethereum’s static gas model.",{"type":770,"tag":771,"props":1609,"children":1610},{},[1611,1613,1618],{"type":775,"value":1612},"Currently, ZKsync operators use accurate and fair values for ETH L1 pricing and ",{"type":770,"tag":785,"props":1614,"children":1616},{"className":1615},[],[1617],{"type":775,"value":1568},{"type":775,"value":1619},",\nbut preparing your contracts for future decentralization ensures long-term stability and reliability.",{"type":770,"tag":778,"props":1621,"children":1623},{"id":1622},"use-native-account-abstraction-for-validation",[1624],{"type":775,"value":1625},"Use Native Account Abstraction for Validation",{"type":770,"tag":771,"props":1627,"children":1628},{},[1629,1631,1637,1639,1644],{"type":775,"value":1630},"Do not rely on ",{"type":770,"tag":785,"props":1632,"children":1634},{"className":1633},[],[1635],{"type":775,"value":1636},"ecrecover",{"type":775,"value":1638}," for signature verification.\nZKsync chains running EraVM use ",{"type":770,"tag":842,"props":1640,"children":1641},{},[1642],{"type":775,"value":1643},"native account abstraction",{"type":775,"value":1645},", which supports flexible authentication\nmechanisms such as multisignature wallets or custom signature schemes.",{"type":770,"tag":771,"props":1647,"children":1648},{},[1649],{"type":775,"value":1650},"Assuming all accounts use ECDSA private keys may cause compatibility issues.\nInstead, rely on the built-in account abstraction mechanisms for validation to ensure forward compatibility.",{"type":770,"tag":771,"props":1652,"children":1653},{},[1654,1656,1661],{"type":775,"value":1655},"Learn more in the ",{"type":770,"tag":1011,"props":1657,"children":1658},{"href":741},[1659],{"type":775,"value":1660},"Account Abstraction guide",{"type":775,"value":1662},".",{"type":770,"tag":778,"props":1664,"children":1666},{"id":1665},"test-in-a-local-environment",[1667],{"type":775,"value":1668},"Test in a Local Environment",{"type":770,"tag":771,"props":1670,"children":1671},{},[1672],{"type":775,"value":1673},"Always test your contracts locally before deploying to mainnet.\nLocal testing allows you to verify contract behavior in a controlled environment, reduce latency, and avoid transaction costs.",{"type":770,"tag":771,"props":1675,"children":1676},{},[1677,1682],{"type":770,"tag":785,"props":1678,"children":1680},{"className":1679},[],[1681],{"type":775,"value":96},{"type":775,"value":1683}," allows you to simulate mainnet behavior for development purposes.",{"type":770,"tag":771,"props":1685,"children":1686},{},[1687],{"type":775,"value":1688},"To test locally:",{"type":770,"tag":1145,"props":1690,"children":1691},{},[1692,1702,1724,1734],{"type":770,"tag":1046,"props":1693,"children":1694},{},[1695,1700],{"type":770,"tag":842,"props":1696,"children":1697},{},[1698],{"type":775,"value":1699},"Set up the local environment",{"type":775,"value":1701}," using one of the available tools.",{"type":770,"tag":1046,"props":1703,"children":1704},{},[1705,1710,1712,1716,1718,1722],{"type":770,"tag":842,"props":1706,"children":1707},{},[1708],{"type":775,"value":1709},"Run your tests",{"type":775,"value":1711}," with frameworks such as ",{"type":770,"tag":842,"props":1713,"children":1714},{},[1715],{"type":775,"value":160},{"type":775,"value":1717}," and ",{"type":770,"tag":842,"props":1719,"children":1720},{},[1721],{"type":775,"value":105},{"type":775,"value":1723},"  to verify expected behavior.",{"type":770,"tag":1046,"props":1725,"children":1726},{},[1727,1732],{"type":770,"tag":842,"props":1728,"children":1729},{},[1730],{"type":775,"value":1731},"Review results",{"type":775,"value":1733}," and confirm that events, gas usage, and outputs match expectations.",{"type":770,"tag":1046,"props":1735,"children":1736},{},[1737,1742],{"type":770,"tag":842,"props":1738,"children":1739},{},[1740],{"type":775,"value":1741},"Iterate and refine",{"type":775,"value":1743}," before deploying to testnet or mainnet.",{"type":770,"tag":771,"props":1745,"children":1746},{},[1747],{"type":775,"value":1748},"Local testing helps you identify issues early, ensuring a more reliable and predictable deployment on ZKsync chains.",{"type":770,"tag":1750,"props":1751,"children":1752},"hr",{},[],{"type":770,"tag":771,"props":1754,"children":1755},{},[1756],{"type":775,"value":1757},"By following these best practices, you can improve the security, reliability, and maintainability of your smart\ncontracts across all ZKsync chains powered by the EraVM.",{"type":770,"tag":1759,"props":1760,"children":1761},"style",{},[1762],{"type":775,"value":1763},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":764,"searchDepth":894,"depth":894,"links":1765},[1766,1768,1769,1770,1772,1773],{"id":780,"depth":894,"text":1767},"Use call instead of .send or .transfer",{"id":1077,"depth":894,"text":1080},{"id":1135,"depth":894,"text":1138},{"id":1175,"depth":894,"text":1771},"Account for gasPerPubdataByte",{"id":1622,"depth":894,"text":1625},{"id":1665,"depth":894,"text":1668},"markdown","content:00.zksync-network:68.zksync-era:90.security-best-practices.md","content","00.zksync-network/68.zksync-era/90.security-best-practices.md","00.zksync-network/68.zksync-era/90.security-best-practices","md",{"loc":315},[1782,1784],{"_path":312,"title":311,"description":1783},"Paymasters are specialized accounts designed to subsidize transaction fees for users, enhancing usability and flexibility within protocols.\nThey also facilitate the payment of fees using ERC20 tokens, instead of the default ETH.",{"_path":318,"title":321,"description":1785},"Learn how to propose, write, and validate documentation changes for ZKsync Docs.",1775831128721]