diff --git a/.prettierignore b/.prettierignore index 3f5a5547..d9130750 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,3 +3,4 @@ node_modules .idea public **/*.md +*.md diff --git a/assets/custom-icons.ts b/assets/custom-icons.ts new file mode 100644 index 00000000..c83cebe2 --- /dev/null +++ b/assets/custom-icons.ts @@ -0,0 +1,68 @@ +export const customIcons = { + custom: { + icons: { + 'metamask-logo': { + body: ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `, + }, + }, + }, +}; diff --git a/components/content/NetworkAdder.vue b/components/content/NetworkAdder.vue new file mode 100644 index 00000000..22d435d2 --- /dev/null +++ b/components/content/NetworkAdder.vue @@ -0,0 +1,48 @@ + + + diff --git a/content/00.build/00.zksync-101/1.zksync-overview.md b/content/00.build/00.zksync-101/1.zksync-overview.md new file mode 100644 index 00000000..6ab0626e --- /dev/null +++ b/content/00.build/00.zksync-101/1.zksync-overview.md @@ -0,0 +1,73 @@ +--- +title: zkSync overview +description: A quick overview of what is zkSync +--- + +## What is zkSync? + +**zkSync Era** is a Layer 2 **[ZK +rollup](https://docs.zksync.io/build/developer-reference/rollups.html#what-are-zk-rollups)**, a trustless protocol that +uses cryptographic validity proofs to provide scalable and low-cost transactions on Ethereum. In zkSync Era, computation +is performed off-chain and most data is stored off-chain as well. Transactions are bundled into batches before +generating a validity proof. As all validity proofs are proven on the Ethereum mainchain, users enjoy the same security +level as in Ethereum. + +zkSync Era is made to look and feel like Ethereum, but with a higher throughput and lower fees. Just like on Ethereum, +smart contracts are written in Solidity/Vyper and can be called using the same clients as the other EVM-compatible +chains. + +You don't need to register a separate private key before using it; zkSync supports existing Ethereum wallets out of the +box. + +## Main features +:check-icon Mainnet-like security with zero reliance on 3rd parties. + +:check-icon Permissionless EVM-compatible smart contracts. + +:check-icon Preserving key EVM features, such as smart contract composability. + +:check-icon Standard Web3 API. + +:check-icon State updates via transaction outputs (also known as state diffs) which provides significant cost savings +over transaction inputs. + +:check-icon Native account abstraction with improvements over EIP4337 (implemented in Ethereum and other rollups). + +You can find [more information about zkSync Era in l2beat](https://l2beat.com/scaling/projects/zksync-era#stage). + +## Developer experience + +zkSync Era was built to provide a similar developer experience as Ethereum. + +:check-icon Smart contracts can be written in Solidity or Vyper. + +:check-icon Most contracts work out of the box so migrating projects is seamless. + +:check-icon Smart contracts are compiled with custom compilers: **[zksolc and +zkvyper](https://docs.zksync.io/zk-stack/components/compiler/toolchain/overview.html)**. + +:check-icon Use existing frameworks +like **[Hardhat](https://docs.zksync.io/build/tooling/hardhat/getting-started.html),** libraries like Ethers, Viem, or +web3.js, and tools like theGraph, Thirdweb, or Chainlink. + +:check-icon Web3 API compatibility enables support of most developer tools. + +:check-icon Different **[tools for testing and debugging +locally](https://docs.zksync.io/build/test-and-debug/getting-started.html)**. + +## User experience + +Interacting with applications built on zkSync Era is seamless, cheap and fast. + +- Transactions have instant confirmations and fast finality on L1. +- Transaction fees are extremely low (see [average transaction costs + here](https://www.growthepie.xyz/fundamentals/transaction-costs)). +- Transaction fees can be conveniently paid with ERC20 tokens (e.g. USDC) thanks to **[native account abstraction and + paymasters](https://docs.zksync.io/build/developer-reference/account-abstraction.html)**. +- Support for existing Ethereum-based wallets like Metamask, TrustWallet, Zerion or Rabby. + +## Get started + +- Follow [this guide to add the zkSync network to your wallet](connect-zksync). +- Get [testnet funds from one of the faucets](faucet) +- Deploy your first smart contract to zkSync Era in the **[quickstart](quickstart)**. diff --git a/content/00.build/00.zksync-101/2.connect-zksync.md b/content/00.build/00.zksync-101/2.connect-zksync.md new file mode 100644 index 00000000..687faef2 --- /dev/null +++ b/content/00.build/00.zksync-101/2.connect-zksync.md @@ -0,0 +1,43 @@ +--- +title: Connect to zkSync +description: Step-by-step guide to connect your wallet to zkSync. +--- + +## Add zkSync Era to your wallet + +You can add zkSync Era to your wallet using the buttons below: + +:network-adder{ network="mainnet" } +:network-adder{ network="testnet" } + +### Manual settings + +To manually add zkSync Era as a custom network in your wallet, follow these steps: + +1. Find the “Add Network” option in your wallet (in Metamask, you can find this in the networks dropdown). +2. Click “Add Network" +3. Fill in the following details for the zkSync Era network you want to add: + +#### Mainnet network details + +- Network Name: `zkSync Era Mainnet` +- RPC URL: `https://mainnet.era.zksync.io` +- Chain ID: `324` +- Currency Symbol: `ETH` +- Block Explorer URL: `https://explorer.zksync.io/` +- WebSocket URL: `wss://mainnet.era.zksync.io/ws` + +#### Sepolia testnet network details + +- Network Name: `zkSync Era Sepolia Testnet` +- RPC URL: `https://sepolia.era.zksync.dev` +- Chain ID: `300` +- Currency Symbol: `ETH` +- Block Explorer URL: `https://sepolia.explorer.zksync.io/` +- WebSocket URL: `wss://sepolia.era.zksync.dev/ws` + +Click on "Save" to add the zkSync Era network to your wallet. + +## How to get started? + +Begin by [getting testnet funds from one of the available faucets](faucet). diff --git a/content/00.build/00.zksync-101/3.faucet.md b/content/00.build/00.zksync-101/3.faucet.md new file mode 100644 index 00000000..5ed09a50 --- /dev/null +++ b/content/00.build/00.zksync-101/3.faucet.md @@ -0,0 +1,45 @@ +--- +title: Network Faucets +description: Get testnet funds to build and deploy to %%zk_testnet_name%%. +--- +## %%zk_testnet_name%% faucets + +Use any of the following faucets to get funds directly on %%zk_testnet_name%%: + +### Chainstack + +[Chainstack Faucet](https://faucet.chainstack.com/zksync-testnet-faucet) is an easy to use Multi-Chain Faucet. You can +use Chainstack Faucet to claim %%zk_testnet_name%% ETH. + +### LearnWeb3 + +You can use [LearnWeb3's zkSync Sepolia Faucet](https://learnweb3.io/faucets/zksync_sepolia/) to claim zkSync Sepolia +Testnet ETH. + +## Sepolia faucets + +::callout{icon="i-heroicons-light-bulb"} +Use any of the following faucets to claim SepoliaETH, which you can bridge to %%zk_testnet_name%% using the [zkSync +bridge](https://portal.zksync.io/bridge/?network=sepolia). +:: + +- [LearnWeb3 Sepolia faucet](https://learnweb3.io/faucets/sepolia) +- [QuickNode Sepolia faucet](https://faucet.quicknode.com/ethereum/sepolia) +- [Alchemy Sepolia faucet](https://sepoliafaucet.com/) +- [Proof of Work Sepolia faucet](https://sepolia-faucet.pk910.de/) +- [Infura Sepolia faucet](https://www.infura.io/faucet/sepolia/) +- [Ethereum Ecosystem Sepolia faucet](https://www.ethereum-ecosystem.com/faucets/ethereum-sepolia) + +### Circle USDC faucet + +[Circle's Testnet Faucet](https://faucet.circle.com/) provides USDC on zkSync Sepolia or Ethereum +Sepolia Testnet. + +### Aave ERC20 token faucet + +[Aave's Sepolia faucet](https://staging.aave.com/faucet/) provides popular ERC20 tokens like +WBTC, USDT, LINK, AAVE or DAI. + +## Next steps + +Deploy your first smart contract to zkSync following the [quickstart tutorial](quickstart). diff --git a/content/00.build/00.zksync-101/4.quickstart.md b/content/00.build/00.zksync-101/4.quickstart.md new file mode 100644 index 00000000..d0cd30ab --- /dev/null +++ b/content/00.build/00.zksync-101/4.quickstart.md @@ -0,0 +1,121 @@ +--- +title: Deploy your first contract +description: Deploy a smart contract to zkSync from your browser in under 5 minutes +--- + +This tutorial shows you how to deploy and interact with a smart contract on zkSync Era in less than 5 minutes. +It will help you get familiar with the zkSync smart contract development and deployment process using different tools. + +This is what we're going to do: + +:check-icon Build a smart contract to exchange secret messages with Zeek. + +:check-icon Deploy the smart contract to the %%zk_testnet_name%%. + +:check-icon Interact with the contract from your browser using Remix or Atlas. + +## Prerequisites + +1. Before you start, make sure that +[you’ve configured the zkSync Sepolia tesnet in your browser wallet by following the instructions here](connect-zksync). +2. In addition, fund your wallet with %%zk_testnet_name%% ETH using [one of the available faucets](faucet). + +## Review the smart contract code + +The smart contract will store messages from users in a hashed format and emit events with replies from Zeek. +The entire code is as follows: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract ZeekSecretMessages { + bytes32[] private messages; + + // Event to acknowledge a new message + event MessageReceived(string); + + constructor() { + // Zeek initializes the contract with a welcome message + emit MessageReceived("Zeek welcomes you to zkSync!"); + } + + // Function to send a "secret" message to Zeek + function sendMessage(string memory _message) public { + bytes32 hashedMessage = keccak256(abi.encodePacked(_message)); + messages.push(hashedMessage); + + // Acknowledge the message receipt with Zeek's reply + emit MessageReceived("ZK is the endgame - Message received!"); + } + + // Function to count the total messages sent to Zeek + function getTotalMessages() public view returns (uint) { + return messages.length; + } +} +``` + +The Solidity smart contract contains two functions: + +- `sendMessage` stores the messages sent by users in the `messages` state variable. +- `getTotalMessages` returns the number of messages stored in the smart contract. + +::callout{icon="i-heroicons-light-bulb"} +zkSync Era is [EVM compatible](/build/resources/glossary#evm-compatible). +You can write smart contracts with Solidity or Vyper and use existing popular libraries like OpenZeppelin. +:: + +## Deploy the contract + +To deploy the contract we can use either Atlas or Remix: + +::content-switcher +--- +items: [{ + label: 'Atlas', + partial: '_quickstart/_atlas_deploy_contract' +}, { + label: 'Remix', + partial: '_quickstart/_remix_deploy_contract' +}] +--- +:: + +## Check the contract in explorer + +Copy the smart contract address from Atlas/Remix and search it via the [%%zk_testnet_name%% +explorer](%%zk_testnet_block_explorer_url%%). You’ll see the contract has a transaction from the message we just sent. + +![Contract in zkSync explorer](/images/101-quickstart/101-contract-deployed.png) + +Click on the transaction hash link to check all its details, like timestamp, the account that send it, transaction fee +etc. The status will be “Processed” on zkSync and “Sending” on Ethereum. [Learn more about the transaction lifecycle on +zkSync](/zk-stack/concepts/transaction-lifecycle). + +In the “Contract” tab you’ll see the contract source code as Atlas and Remix automatically verified the contract for us. +When a smart contract is verified in a block explorer, it means that the source code of the contract has been published +and matched to the compiled version on the blockchain enhancing transparency, as users can review the contract’s source +code to understand its functions and intentions. + +Finally in the “Events” tab, you’ll see the replies from Zeek as these are emitted as events in our smart contract. + +![Contract events in zkSync explorer](/images/101-quickstart/101-contract-events.png) + +ZK is the endgame ✌️ + +## Takeaways + +- **EVM-compatibility**: zkSync Era is EVM-compatible and you can write smart contracts in Solidity or Vyper as in + Ethereum. +- **Custom compilers**: smart contracts deployed to zkSync Era must be compiled with the customs compilers: `zksolc` for + Solidity and `zkvyper` for Vyper. +- **Browser-based IDEs**: Existing tools like Atlas and Remix use zkSync custom compilers under the hood. + +## Next steps + +- Join the [zkSync developer community in Discord](https://join.zksync.dev/) where you can ask any questions about this tutorial in the #dev-101 + channel +- Continue learning by [deploying an ERC20 token to zkSync](erc20-token). +- Join our :external-link{text="GitHub Discussions Community" href="%%zk_git_repo_zksync-developers%%/discussions/"} to + help other devs building on zkSync or share your project. diff --git a/content/00.build/00.zksync-101/5.erc20-token.md b/content/00.build/00.zksync-101/5.erc20-token.md new file mode 100644 index 00000000..582212d5 --- /dev/null +++ b/content/00.build/00.zksync-101/5.erc20-token.md @@ -0,0 +1,45 @@ +--- +title: Create an ERC20 token +description: In this tutorial you'll build and deploy an ERC20 token to %%zk_testnet_name%% +--- + +This tutorial shows you how to deploy and interact with an ERC20 token on %%zk_testnet_name%%. + +This is what we’re going to do: + +:check-icon Build an ERC20 token smart contract with additional custom logic + +:check-icon Deploy the smart contract to the %%zk_testnet_name%% using Remix or Atlas. + +## Prerequisites + +Before you start, make sure that you’ve configured the zkSync Sepolia tesnet in your browser wallet by following the +instructions here. + +In addition, fund your wallet with testnet ETH on %%zk_testnet_name%%. + +To complete this tutorial we’ll use either Atlas or Remix. Select your preferred tool: + +::content-switcher +--- +items: [{ + label: 'Atlas', + partial: '_erc20_tutorial/_atlas_erc20_tutorial' +}, { + label: 'Remix', + partial: '_erc20_tutorial/_remix_erc20_tutorial' +}] +--- +:: + +## Takeaways + +- **zkSync is EVM compatible** and supports existing smart contract libraries like OpenZeppelin +- **Use popular libraries like** `ethers` , `viem`, or `web3.js` to interact with smart contracts deployed on zkSync. + +## Next steps + +- Join the zkSync developer community in Discord where you can ask any questions about this tutorial in the #dev-101 + channel +- Continue learning by deploying an ERC20 token to zkSync Era. +- Join our GitHub Discussions community to help other devs building on zkSync or share your project. diff --git a/content/00.build/00.zksync-101/6.paymasters-introduction.md b/content/00.build/00.zksync-101/6.paymasters-introduction.md new file mode 100644 index 00000000..ecec77f7 --- /dev/null +++ b/content/00.build/00.zksync-101/6.paymasters-introduction.md @@ -0,0 +1,183 @@ +--- +title: Paymasters introduction +description: Learn about paymasters and use one to pay transaction fees with your own token +--- + +This tutorial makes use of smart contracts deployed in the previous two tutorials, [Deploy your first +contract](quickstart) and [Create an ERC20 token](erc20-token). This section introduces one of the custom features +of zkSync: native account abstraction and paymasters. + +In this tutorial we will: + +:check-icon Learn about paymasters. + +:check-icon Review the testnet paymaster smart contract code. + +:check-icon Use the testnet paymaster to pay transaction fees with our own ERC20 token. + +Before you start, make sure that you’ve configured the zkSync Sepolia tesnet in your browser wallet by [following the2.connect-zksync.md +instructions here](2.connect-zksync.md). + +## What is a paymaster? + +Paymasters are smart contracts with a very specific function: pay the transaction fees on behalf of the user. In order +to do so, paymasters have ETH balance which they use to pay the transaction fees to the protocol. + +Being smart contracts, paymasters can have logic and validations to pay, or not the transaction fees. + +Every paymaster has these two functions: + +- `validateAndPayForPaymasterTransaction` : it receives the transaction parameters (fields like `from`, `amount` , `to` + ), use these to do the required validations, and pay the transaction fee. +- `postTransaction`: this function runs after the transaction is executed and it’s optional. + +![zksync paymaster](/images/101-paymasters/zksync-paymaster.png) + +## Paymaster smart contract code + +Although application developers are encouraged to create their own paymaster smart contract, zkSync provides a testnet +paymaster for convenience and testing purposes. + +::callout{icon="i-heroicons-light-bulb"} +The testnet paymaster address is +[0x3cb2b87d10ac01736a65688f3e0fb1b070b3eea3](https://sepolia.explorer.zksync.io/address/0x3cb2b87d10ac01736a65688f3e0fb1b070b3eea3) +:: + +Here is the code: + +::drop-panel + ::panel{label="TestnetPaymaster.sol"} + ```solidity + // SPDX-License-Identifier: MIT + + pragma solidity 0.8.20; + + import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + + import "./interfaces/IPaymaster.sol"; + import "./interfaces/IPaymasterFlow.sol"; + import "./L2ContractHelper.sol"; + + // This is a dummy paymaster. It expects the paymasterInput to contain its "signature" as well as the needed exchange rate. + // It supports only approval-based paymaster flow. + contract TestnetPaymaster is IPaymaster { + function validateAndPayForPaymasterTransaction( + bytes32, + bytes32, + Transaction calldata _transaction + ) external payable returns (bytes4 magic, bytes memory context) { + // By default we consider the transaction as accepted. + magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; + + require(msg.sender == BOOTLOADER_ADDRESS, "Only bootloader can call this contract"); + require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long"); + + bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]); + if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { + // While the actual data consists of address, uint256 and bytes data, + // the data is not needed for the testnet paymaster + (address token, uint256 amount, ) = abi.decode(_transaction.paymasterInput[4:], (address, uint256, bytes)); + + // Firstly, we verify that the user has provided enough allowance + address userAddress = address(uint160(_transaction.from)); + address thisAddress = address(this); + + uint256 providedAllowance = IERC20(token).allowance(userAddress, thisAddress); + require(providedAllowance >= amount, "The user did not provide enough allowance"); + + // The testnet paymaster exchanges X wei of the token to the X wei of ETH. + uint256 requiredETH = _transaction.gasLimit * _transaction.maxFeePerGas; + if (amount < requiredETH) { + // Important note: while this clause definitely means that the user + // has underpaid the paymaster and the transaction should not accepted, + // we do not want the transaction to revert, because for fee estimation + // we allow users to provide smaller amount of funds then necessary to preserve + // the property that if using X gas the transaction success, then it will succeed with X+1 gas. + magic = bytes4(0); + } + + // Pulling all the tokens from the user + try IERC20(token).transferFrom(userAddress, thisAddress, amount) {} catch (bytes memory revertReason) { + // If the revert reason is empty or represented by just a function selector, + // we replace the error with a more user-friendly message + if (revertReason.length <= 4) { + revert("Failed to transferFrom from users' account"); + } else { + assembly { + revert(add(0x20, revertReason), mload(revertReason)) + } + } + } + + // The bootloader never returns any data, so it can safely be ignored here. + (bool success, ) = payable(BOOTLOADER_ADDRESS).call{value: requiredETH}(""); + require(success, "Failed to transfer funds to the bootloader"); + } else { + revert("Unsupported paymaster flow"); + } + } + + function postTransaction( + bytes calldata _context, + Transaction calldata _transaction, + bytes32, + bytes32, + ExecutionResult _txResult, + uint256 _maxRefundedGas + ) external payable override { + // Nothing to do + } + + receive() external payable {} + } + ``` + :: +:: + +In the `validateAndPayForPaymasterTransaction` it is: + +1. checking that the paymasterInput is `approvalBased`. +2. checks that the allowance of a given ERC20 is enough. +3. Transfers the transaction fee (`requiredETH`) in ERC20 from the user’s balance to the paymaster. +4. Transfer the transaction fee in ETH from the paymaster contract to the bootloader. + +## How to send a transaction through a paymaster? + +In order to send a transaction through a paymaster, the transaction must include the following additional parameters: + +- `paymasterAddress`: the smart contract address of the paymaster +- `type`: should be `General` or `ApprovalBased` (to pay fees with ERC20 tokens) +- `minimalAllowance`: the amount of ERC20 tokens to be approved for spending (for `approvalBased` type paymasters only). +- `innerInput`: any payload we want to send to the paymaster (optional). + +We’ll see an example next. + +## Interacting with the testnet paymaster + +We’re going to interact with the `ZeekSecretMessages.sol` contract that we created in the first tutorial and use the +ERC20 token that we deployed in the second tutorial to pay the transaction fees. + +::content-switcher +--- +items: [{ + label: 'Atlas', + partial: '_paymaster_intro/_atlas_paymaster_intro' +}, { + label: 'Remix', + partial: '_paymaster_intro/_remix_paymaster_intro' +}] +--- +:: + +## Takeaways + +- Paymasters on zkSync allow any account to pay fees with ERC20 tokens or enable gasless transactions. +- Paymasters are smart contracts that can have any validations and rules. +- To send a transaction through a paymaster, we only need to include additional parameters in the transaction. + +## Next steps + +- Learn more about paymasters and native account abstraction in this section of the docs. +- Browse different paymaster examples in [this open source + repository](https://github.com/matter-labs/paymaster-examples). +- Continue learning by building a GoFundMe clone on zkSync. diff --git a/content/00.build/00.zksync-101/_dir.yml b/content/00.build/00.zksync-101/_dir.yml new file mode 100644 index 00000000..a409bec0 --- /dev/null +++ b/content/00.build/00.zksync-101/_dir.yml @@ -0,0 +1 @@ +title: zkSync 101 diff --git a/content/00.build/00.zksync-101/_erc20_tutorial/_atlas_erc20_tutorial.md b/content/00.build/00.zksync-101/_erc20_tutorial/_atlas_erc20_tutorial.md new file mode 100644 index 00000000..29731e26 --- /dev/null +++ b/content/00.build/00.zksync-101/_erc20_tutorial/_atlas_erc20_tutorial.md @@ -0,0 +1,130 @@ +--- +title: ERC20 token with Atlas +--- +## Custom ERC20 token code + +ERC20 tokens are a standard for fungible tokens, which can be traded and represent a fixed value. You’ve used ERC20 +tokens if you’ve transacted with USDC, DAI, USDT, LINK or UNI. + +The ERC20 token we’re going to deploy will allow users to mint and burn tokens. The entire smart contract code is as +follows: + +```solidity +// SPDX-License-Identifier: Unlicensed +pragma solidity ^0.8.19; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; + +contract TestToken is ERC20, Ownable, ERC20Burnable { + constructor(string memory name, string memory symbol) ERC20(name, symbol) { + _mint(msg.sender, 100 * 10 ** decimals()); + } + + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } +} +``` + +::callout{icon="i-heroicons-light-bulb"} +zkSync is [EVM compatible](/build/resources/glossary#evm-compatible), so you can use existing popular libraries like OpenZeppelin. +:: + +The most important features are: + +- `Ownable` : this extension sets the deployer account as owner of the smart contract. It also introduces the + `onlyOwner` modifier that restricts the execution of certain functions to the owner of the contract. +- `ERC20Burnable`: this extension adds the `burn` and `burnFrom` functions to the smart contract. These functions + destroy tokens from a given account. +- `constructor`: called on deployment, the constructor will assign the given name and symbol to the token and mint 100 + units of it to the account that deployed the contract. +- `mint` : this function creates new token units to a given account. It uses the `onlyOwner` modifier so it can only be + called from the owner account. + +## Deploy the smart contract + +Atlas is a browser-based IDE with an integrated AI assistant that allows you to write, test and deploy smart contracts +directly from your browser. Click the button below to open the project in Atlas. + +:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false" +to="https://app.atlaszk.com/projects?template=https://github.com/uF4No/zksync-101-atlas&open=/contracts/TestToken.sol&chainId=300" +target="_blank" label="Open smart contract in Atlas"} + +You can see the contract in the Atlas code editor. In the right sidebar, make sure the selected network is “zkSync Sepolia +tesnet“ and click on **"Deploy"** to trigger the smart contract compilation and deployment. + +::callout{icon="i-heroicons-light-bulb"} +Behind the scenes, Atlas is using the zkSync Era custom solidity compiler +(named `zksolc` ) to generate ZKEVM compatible bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview). +:: + +Once compiled sign the transaction with your wallet and wait until its processed. You’ll see the contract in the +**“Deployed contracts”** section. + +## Interact with the ERC20 contract + +In the `scripts` folder you can find the `interact.ts` script containing the following code: + +```ts +import { AtlasEnvironment } from "atlas-ide"; +import TokenArtifact from "../artifacts/TestToken"; +import * as ethers from "ethers"; + +// Address of the ERC20 token contract +const TOKEN_CONTRACT_ADDRESS = "" +// Wallet that will receive tokens +const RECEIVER_WALLET = ""; +// Amount of tokens to mint in ETH format, e.g. 1.23 +const TOKEN_AMOUNT = ""; + +export async function main (atlas: AtlasEnvironment) { + const provider = new ethers.providers.Web3Provider(atlas.provider); + const wallet = provider.getSigner(); + + // initialise token contract with address, abi and signer + const tokenContract= new ethers.Contract( + TOKEN_CONTRACT_ADDRESS, + TokenArtifact.TestToken.abi, + wallet + ); + + console.log("Minting tokens..."); + const tx = await tokenContract.mint( + RECEIVER_WALLET, + ethers.utils.parseEther(TOKEN_AMOUNT) + ); + await tx.wait(); + + + console.log("Success!"); + console.log(` + The account ${RECEIVER_WALLET} now has + ${await tokenContract.balanceOf(RECEIVER_WALLET)} tokens` + ); + +} +``` + +This scripts uses `ethers` to interact with the contract we’ve just deployed. + +::callout{icon="i-heroicons-light-bulb"} +Existing libraries like `ethers` , `viem` and `web3.js` can be used to interact with smart contracts deployed on zkSync. +:: + +Fill the following variables: + +- `TOKEN_CONTRACT_ADDRESS`: the contract address of the ERC20 token we just deployed. +- `RECEIVER_WALLET`: address of a different account that will receive new tokens. +- `TOKEN_AMOUNT`: the amount of tokens we’ll send to the account. + +With the `interact.ts` file open in the Atlas editor, click on the “Deploy” button to run the script and see the output +in the terminal. + +![ERC20 interact script in Atlas](/images/101-erc20/atlas-erc20-interact.png) + +To confirm the account has received the tokens, visit the zkSync Sepolia explorer and search the receiver wallet +address. You’ll see the new token balance in the assets table: + +![ERC20 tokens in account balance](/images/101-erc20/erc20-tokens-minted.png) diff --git a/content/00.build/00.zksync-101/_erc20_tutorial/_remix_erc20_tutorial.md b/content/00.build/00.zksync-101/_erc20_tutorial/_remix_erc20_tutorial.md new file mode 100644 index 00000000..726f558e --- /dev/null +++ b/content/00.build/00.zksync-101/_erc20_tutorial/_remix_erc20_tutorial.md @@ -0,0 +1,145 @@ +--- +title: ERC20 with Remix +--- +## Custom ERC20 token code + +ERC20 tokens are a standard for fungible tokens, which can be traded and represent a fixed value. You’ve used ERC20 +tokens if you’ve transacted with USDC, DAI, USDT, LINK or UNI. + +The ERC20 token we’re going to deploy will allow users to mint and burn tokens. The entire smart contract code is as +follows: + +```solidity +// SPDX-License-Identifier: Unlicensed +pragma solidity ^0.8.19; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; + +contract TestToken is ERC20, Ownable, ERC20Burnable { + constructor(string memory name, string memory symbol) + ERC20(name, symbol) Ownable(msg.sender) { + _mint(msg.sender, 100 * 10 ** decimals()); + } + + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } +} +``` + +::callout{icon="i-heroicons-light-bulb"} +zkSync is [EVM compatible](/build/resources/glossary#evm-compatible), so you can use existing popular libraries like OpenZeppelin. +:: + +The most important features are: + +- `Ownable` : this extension sets the deployer account as owner of the smart contract. It also introduces the + `onlyOwner` modifier that restricts the execution of certain functions to the owner of the contract. +- `ERC20Burnable`: this extension adds the `burn` and `burnFrom` functions to the smart contract. These functions + destroy tokens from a given account. +- `constructor`: called on deployment, the constructor will assign the given name and symbol to the token and mint 100 + units of it to the account that deployed the contract. +- `mint` : this function creates new token units to a given account. It uses the `onlyOwner` modifier so it can only be + called from the owner account. + +## Deploy the smart contract + +The Remix IDE is an open-source web and desktop application that supports Ethereum smart contract development and +deployment, offering tools for writing, testing, debugging, and deploying smart contracts written in Solidity to EVM +compatible protocols. + +:display-partial{path="/_partials/_enable-remix-zksync-plugin"} + +Click the button below to open the project in Remix and see the contract in the Remix code editor. + +:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false" +to="https://remix.ethereum.org/#url=https://github.com/uF4No/zksync-101-remix/blob/main/contracts/TestToken.sol" +target="_blank" label="Open smart contract in Remix" } + +To compile the contract, click on Compile TestToken.sol. If you get a popup message requesting permissions to access +**`ACCESS TO "WRITEFILE" OF "FILE MANAGER"`,** click on Accept. + +::callout{icon="i-heroicons-light-bulb"} +Behind the scenes, Remix is using the zkSync Era custom solidity compiler (named `zksolc` ) to generate ZKEVM compatible +bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview). +:: + +We will use our wallet’s configured network to connect and deploy our smart contract so make sure your wallet is +currently connected to the %%zk_testnet_name%%. In Remix, under the Environment Section, select “Wallet” and click on +“Connect Wallet”. + +To deploy the contract, click on “Deploy” and sign the transaction on your wallet. Congratulations, your ERC20 token +contract is now deployed on %%zk_testnet_name%%! + +## Interact with the ERC20 contract + +In the `scripts` folder you can find the `interact.ts` script containing the following code: + +```typescript +import {ethers} from "ethers"; + +// Address of the ERC20 token contract +const TOKEN_CONTRACT_ADDRESS = "" +// Wallet that will receive tokens +const RECEIVER_WALLET = ""; +// Amount of tokens to mint in ETH format, e.g. 1.23 +const TOKEN_AMOUNT = "123.55"; + +(async () => { + try { + + // Note that the script needs the ABI which is generated from the compilation artifact. + // Make sure contract is compiled for zkSync and artifacts are generated + const artifactsPath = `browser/contracts/artifacts/TestToken.json` // Change this for different path + + const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath)) + + // 'web3Provider' is a remix global variable object + const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner(0) + + // initialise token contract with address, abi and signer + const tokenContract= new ethers.Contract(TOKEN_CONTRACT_ADDRESS, metadata.abi, signer); + + console.log("Minting tokens..."); + const tx = await tokenContract.mint( + RECEIVER_WALLET, + ethers.utils.parseEther(TOKEN_AMOUNT) + ); + console.log(`Mint transaction is ${tx.hash}`) + await tx.wait(); + console.log("Success!"); + + const balance = await tokenContract.balanceOf(RECEIVER_WALLET) + + console.log(`The account ${RECEIVER_WALLET} now has ${balance} tokens`) + + } catch (e) { + console.log(e.message) + } +})() + +``` + +This scripts uses `ethers` to interact with the contract we’ve just deployed. + +::callout{icon="i-heroicons-light-bulb"} +Existing libraries like `ethers` , `viem` and `web3.js` can be used to interact with smart contracts deployed on zkSync. +:: + +Fill the following variables: + +- `TOKEN_CONTRACT_ADDRESS`: the contract address of the ERC20 token we just deployed. +- `RECEIVER_WALLET`: address of a different account that will receive new tokens. +- `TOKEN_AMOUNT`: the amount of tokens we’ll send to the account. + +With the `interact.ts` file open in the editor, click on the “▶️” button to run the script and see the output in the +terminal. + +![ERC20 interact script in Remix](/images/101-erc20/remix-erc20-interact.png) + +To confirm the account has received the tokens, visit the zkSync Sepolia explorer and search the receiver wallet +address. You’ll see the new token balance in the assets table: + +![ERC20 tokens in account balance](/images/101-erc20/erc20-tokens-minted.png) diff --git a/content/00.build/00.zksync-101/_paymaster_intro/_atlas_paymaster_intro.md b/content/00.build/00.zksync-101/_paymaster_intro/_atlas_paymaster_intro.md new file mode 100644 index 00000000..0fd94293 --- /dev/null +++ b/content/00.build/00.zksync-101/_paymaster_intro/_atlas_paymaster_intro.md @@ -0,0 +1,133 @@ +--- +title: Paymaster with Atlas +--- + +Click the following button to open the project in Atlas: + +:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false" +to="https://app.atlaszk.com/projects?template=https://github.com/uF4No/zksync-101-atlas&open=/scripts/paymaster-transaction.ts&chainId=300" +target="_blank" label="Open script in Atlas"} + +It’ll open the script to send a transaction via the paymaster. Let’s go through the most important parts: + +### Retrieve the token balance + +```typescript +// retrieve and print the current balance of the wallet +let ethBalance = await provider.getBalance(walletAddress) +let tokenBalance = await tokenContract.balanceOf(walletAddress) +console.log(`Account ${walletAddress} has ${ethers.utils.formatEther(ethBalance)} ETH`); +console.log(`Account ${walletAddress} has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`); +``` + +In this part we’re retrieving the ETH and ERC20 token balances of the account. We’ll compare them after the transaction +is executed to see the difference. + +### Estimate transaction fee + +```typescript +// retrieve the testnet paymaster address +const testnetPaymasterAddress = await zkProvider.getTestnetPaymasterAddress(); + +console.log(`Testnet paymaster address is ${testnetPaymasterAddress}`); + +const gasPrice = await provider.getGasPrice(); + +// define paymaster parameters for gas estimation +const paramsForFeeEstimation = utils.getPaymasterParams(testnetPaymasterAddress, { + type: "ApprovalBased", + token: TOKEN_CONTRACT_ADDRESS, + // set minimalAllowance to 1 for estimation + minimalAllowance: ethers.BigNumber.from(1), + // empty bytes as testnet paymaster does not use innerInput + innerInput: new Uint8Array(0), +}); + +// estimate gasLimit via paymaster +const gasLimit = await messagesContract.estimateGas.sendMessage(NEW_MESSAGE, { + customData: { + gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + paymasterParams: paramsForFeeEstimation, + }, +}); + +// fee calculated in ETH will be the same in +// ERC20 token using the testnet paymaster +const fee = gasPrice * gasLimit; +``` + +1. Retrieve the testnet paymaster address. +2. Generate the paymaster parameters to estimate the transaction fees passing the paymaster address, token address, and + `ApprovalBased` as the paymaster flow type. +3. Retrieve the `gasLimit` of sending the transaction with the paymaster params. +4. Calculate the final estimated fee which is equal to `gasPrice` multiplied by `gasLimit`. + +### Send the transaction + +```typescript +// new paymaster params with fee as minimalAllowance + const paymasterParams = utils.getPaymasterParams(testnetPaymasterAddress, { + type: "ApprovalBased", + token: TOKEN_CONTRACT_ADDRESS, + // provide estimated fee as allowance + minimalAllowance: fee, + // empty bytes as testnet paymaster does not use innerInput + innerInput: new Uint8Array(0), + }); + + // full overrides object including maxFeePerGas and maxPriorityFeePerGas + const txOverrides = { + maxFeePerGas: gasPrice, + maxPriorityFeePerGas: "1", + gasLimit, + customData: { + gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + paymasterParams, + } + } + + console.log(`Sign the transaction in your wallet`); + + // send transaction with additional paymaster params as overrides + const txHandle = await messagesContract.sendMessage(NEW_MESSAGE, txOverrides); +``` + +1. Create the new paymaster params with the calculated `fee` as `minimalAllowance` . +2. Complete the transaction overrides object with `maxFeePerGas`, `maxPriorityFeePerGas` and `gasPerPubdata` +3. Send the transaction including the `txOverrides` + +### Compare the final balance + +```typescript +ethBalance = await provider.getBalance(walletAddress) +tokenBalance = await tokenContract.balanceOf(walletAddress) +console.log(`Account ${walletAddress} now has ${ethers.utils.formatEther(ethBalance)} ETH`); +console.log(`Account ${walletAddress} now has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`); +``` + +Finally we retrieve and print the ETH and ERC20 balances to see how they’ve changed. + +## Run the script + +To run the script, first enter the addresses of the `ZeekSecretMessages.sol` and `TestToken.sol` contracts that we +deployed previously ([here](/build/zksync-101/quickstart) and +[here](/build/zksync-101/erc20-token)) in the following variables at the beginning of +the script: + +```typescript +// Address of the ZeekMessages contract +const ZEEK_MESSAGES_CONTRACT_ADDRESS = ""; +// Address of the ERC20 token contract +const TOKEN_CONTRACT_ADDRESS = "" +// Message to be sent to the contract +const NEW_MESSAGE = "This tx cost me no ETH!"; +``` + +Next, make sure the script file is selected in the Atlas editor and click on the “Deploy” button. + +![ERC20 interact script in Remix](/images/101-paymasters/atlas-paymaster-script.png) + +You’ll see the progress in the console. + +If everything worked as expected, only the ERC20 balance will decrease, meaning the fee was paid with the ERC20 token +instead of ETH. diff --git a/content/00.build/00.zksync-101/_paymaster_intro/_remix_paymaster_intro.md b/content/00.build/00.zksync-101/_paymaster_intro/_remix_paymaster_intro.md new file mode 100644 index 00000000..9c51f482 --- /dev/null +++ b/content/00.build/00.zksync-101/_paymaster_intro/_remix_paymaster_intro.md @@ -0,0 +1,139 @@ +--- +title: Paymaster with Remix +--- + +::callout{icon="i-heroicons-exclamation-triangle" color="amber"} +Remix does not support `zksync-ethers` yet so you can not use it to run this script. Use Atlas instead. +:: + +To open the project in Remix, use the “Clone” option from the file explorer to import it from the following GitHub +repository:`https://github.com/uF4No/zksync-101-remix` + +![Clone repo in Remix](/images/remix-plugin-clone-repo.gif) + +Once the project is imported, open the `scripts/paymaster-transaction.ts` file, which contains the code to send a +transaction via the paymaster. Let’s go through the most important parts: + +### Retrieve the token balance + +```typescript +// retrieve and print the current balance of the wallet +let ethBalance = await provider.getBalance(walletAddress) +let tokenBalance = await tokenContract.balanceOf(walletAddress) +console.log(`Account ${walletAddress} has ${ethers.utils.formatEther(ethBalance)} ETH`); +console.log(`Account ${walletAddress} has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`); +``` + +In this part we’re retrieving the ETH and ERC20 token balances of the account. We’ll compare them after the transaction +is executed to see the difference. + +### Estimate transaction fee + +```typescript +// retrieve the testnet paymaster address +const testnetPaymasterAddress = await zkProvider.getTestnetPaymasterAddress(); + +console.log(`Testnet paymaster address is ${testnetPaymasterAddress}`); + +const gasPrice = await provider.getGasPrice(); + +// define paymaster parameters for gas estimation +const paramsForFeeEstimation = utils.getPaymasterParams(testnetPaymasterAddress, { + type: "ApprovalBased", + token: TOKEN_CONTRACT_ADDRESS, + // set minimalAllowance to 1 for estimation + minimalAllowance: ethers.BigNumber.from(1), + // empty bytes as testnet paymaster does not use innerInput + innerInput: new Uint8Array(0), +}); + +// estimate gasLimit via paymaster +const gasLimit = await messagesContract.estimateGas.sendMessage(NEW_MESSAGE, { + customData: { + gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + paymasterParams: paramsForFeeEstimation, + }, +}); + +// fee calculated in ETH will be the same in +// ERC20 token using the testnet paymaster +const fee = gasPrice * gasLimit; +``` + +In this part of the script we: + +1. Retrieve the testnet paymaster address. +2. Generate the paymaster parameters to estimate the transaction fees passing the paymaster address, token address, and + `ApprovalBased` as the paymaster flow type. +3. Retrieve the `gasLimit` of sending the transaction with the paymaster params. +4. Calculate the final estimated fee which is equal to `gasPrice` multiplied by `gasLimit`. + +### Send the transaction + +```typescript +// new paymaster params with fee as minimalAllowance +const paymasterParams = utils.getPaymasterParams(testnetPaymasterAddress, { + type: "ApprovalBased", + token: TOKEN_CONTRACT_ADDRESS, + // provide estimated fee as allowance + minimalAllowance: fee, + // empty bytes as testnet paymaster does not use innerInput + innerInput: new Uint8Array(0), +}); + +// full overrides object including maxFeePerGas and maxPriorityFeePerGas +const txOverrides = { + maxFeePerGas: gasPrice, + maxPriorityFeePerGas: "1", + gasLimit, + customData: { + gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT, + paymasterParams, + } +} + +console.log(`Sign the transaction in your wallet`); + +// send transaction with additional paymaster params as overrides +const txHandle = await messagesContract.sendMessage(NEW_MESSAGE, txOverrides); +``` + +1. Create the new paymaster params with the calculated `fee` as `minimalAllowance` . +2. Complete the transaction overrides object with `maxFeePerGas`, `maxPriorityFeePerGas` and `gasPerPubdata` +3. Send the transaction including the `txOverrides` + +### Compare the final balance + +```typescript +ethBalance = await provider.getBalance(walletAddress) +tokenBalance = await tokenContract.balanceOf(walletAddress) +console.log(`Account ${walletAddress} now has ${ethers.utils.formatEther(ethBalance)} ETH`); +console.log(`Account ${walletAddress} now has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`); +``` + +Finally we retrieve and print the ETH and ERC20 balances to see how they’ve changed. + +## Run the script + +To run the script, first enter the addresses of the `ZeekSecretMessages.sol` and `TestToken.sol` contracts that we +deployed previously ([here](/build/zksync-101/quickstart) and +[here](/build/zksync-101/erc20-token)) in the following variables at the beginning of +the script: + +```typescript +// Address of the ZeekMessages contract +const ZEEK_MESSAGES_CONTRACT_ADDRESS = ""; +// Address of the ERC20 token contract +const TOKEN_CONTRACT_ADDRESS = "" +// Message to be sent to the contract +const NEW_MESSAGE = "This tx cost me no ETH!"; +``` + +Next, make sure the script file is selected in the Remix editor and click on the “▶️” button. + + + +You’ll see the progress in the console. + +If everything worked as expected, only the ERC20 balance will decrease, meaning the fee was paid with the ERC20 token +instead of ETH. diff --git a/content/00.build/00.zksync-101/_quickstart/_atlas_deploy_contract.md b/content/00.build/00.zksync-101/_quickstart/_atlas_deploy_contract.md new file mode 100644 index 00000000..d9179e74 --- /dev/null +++ b/content/00.build/00.zksync-101/_quickstart/_atlas_deploy_contract.md @@ -0,0 +1,31 @@ +--- +title: Quickstart with Atlas +--- +Atlas is a browser-based IDE with an integrated AI assistant that allows you to write, test and deploy smart contracts +directly from your browser. Click the button below to open the project in Atlas. + +:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false" +to="https://app.atlaszk.com/projects?template=https://github.com/uF4No/zksync-101-atlas&open=/contracts/ZeekSecretMessages.sol&chainId=300" +target="_blank" label="Open smart contract in Atlas"} + +You can see the contract in the Atlas code editor. On the right side, make sure the selected network is “zkSync Sepolia +tesnet“ and click on **“Deploy”** to trigger the smart contract compilation and deployment. + +::callout{icon="i-heroicons-light-bulb"} +Behind the scenes, Atlas is using the zkSync Era custom solidity compiler +(named `zksolc` ) to generate ZKEVM compatible bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview). +:: + +![Contract in Atlas](/images/101-quickstart/101-atlas-contract.png) + +Once compiled sign the transaction with your wallet and wait until its processed. You’ll see the contract in the +“Deployed contracts” section. Congratulations, you’ve deployed your first smart contract to %%zk_testnet_name%%! + +Below the contract name you can find its deployment address. The “Live Contract State” section displays the smart +contract balance and the value returned by the `getTotalMessages` function. + +![Contract deployed](/images/101-quickstart/101-atlas-deployed.png) + +The “Write Functions” section contains the form to interact with the `sendMessage` function. Write a message, click the +“Run” button and confirm the transaction in your wallet. You’ll see that the `getTotalMessages` is updated to `1`. That +means our contract is storing the messages as expected! But how can we see the replies from Zeek? diff --git a/content/00.build/00.zksync-101/_quickstart/_remix_deploy_contract.md b/content/00.build/00.zksync-101/_quickstart/_remix_deploy_contract.md new file mode 100644 index 00000000..9a14bc44 --- /dev/null +++ b/content/00.build/00.zksync-101/_quickstart/_remix_deploy_contract.md @@ -0,0 +1,39 @@ +--- +title: Quickstart with Remix +--- + +The Remix IDE is an open-source web and desktop application that supports Ethereum smart contract development and +deployment, offering tools for writing, testing, debugging, and deploying smart contracts written in Solidity to EVM +compatible protocols. + +:display_partial{path="/_partials/_enable-remix-zksync-plugin"} + +Click the button below to open the project in Remix and see the contract in the Remix code editor. + +:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false" +to="https://remix.ethereum.org/#url=https://github.com/uF4No/zksync-101-remix/blob/master/contracts/ZeekSecretMessages.sol" +target="_blank" label="Open smart contract in Remix"} + +To compile the contract, click on Compile ZeeksSecretMessages.sol. If you get a popup message requesting permissions to +access **`ACCESS TO "WRITEFILE" OF "FILE MANAGER"`,** click on Accept. + +::callout{icon="i-heroicons-light-bulb"} +Behind the scenes, Remix is using the zkSync Era custom solidity compiler +(named `zksolc` ) to generate ZKEVM compatible bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview). +:: + +We will use our wallet’s configured network to connect and deploy our smart contract so make sure your wallet is +currently connected to the %%zk_testnet_name%%. In Remix, under the Environment Section, select “Wallet” and click on +“Connect Wallet”. + +To deploy the contract, click on “Deploy” and sign the transaction on your wallet. Congratulations, you’ve deployed your +first contract to %%zk_testnet_name%%! + +Below the contract name you can find the address where the contract is deployed. The “Interact” section displays the +forms to interact with the `getTotalMessages` and `sendMessage` functions. + +![Remix interact zkSync contract](/images/101-quickstart/101-remix-interact.png) + +Write a message in the form, click the “sendMessage” button and confirm the transaction in your wallet. Once processed, +click the `getTotalMessages` and check the response in the terminal, which should be `1`. That means our contract is +storing the messages as expected! But how can we see the replies from Zeek? diff --git a/content/00.build/10.quick-start/00.index.md b/content/00.build/10.quick-start/00.index.md index b8a82653..46ae2f8f 100644 --- a/content/00.build/10.quick-start/00.index.md +++ b/content/00.build/10.quick-start/00.index.md @@ -46,7 +46,7 @@ If you are unfamiliar with both, choose Node.js. ### Setup era local node (optional) Our Quickstart series will have you compile and deploy contracts to -zkSync Sepolia testnet which requires you to have ETH in your wallet for funding transactions. +%%zk_testnet_name%% which requires you to have ETH in your wallet for funding transactions. Alternatively, our `zksync-cli` tool provides a way for you to setup a test node locally. This era local node allows for quicker testing and debugging processes without incurring testnet transaction costs. @@ -123,18 +123,18 @@ Quickly set up `foundry-zksync` by following these steps: ## Fund your wallet -If you did not set up a local era node for development and plan to use zkSync Sepolia testnet, you will need testnet ETH to fund transactions. +If you did not set up a local era node for development and plan to use %%zk_testnet_name%%, you will need testnet ETH to fund transactions. 1. Obtaining Testnet ETH: - Use the [LearnWeb3 faucet](https://learnweb3.io/faucets/zksync_sepolia/) - to directly receive testnet ETH on zkSync Sepolia. + to directly receive testnet ETH on %%zk_testnet_name%%. - Alternatively, acquire SepoliaETH from [recommended faucets](https://www.notion.so/tooling/network-faucets.md) and - transfer it to the zkSync Sepolia testnet via the [zkSync bridge](https://portal.zksync.io/bridge/?network=sepolia). + transfer it to the %%zk_testnet_name%% via the [zkSync bridge](https://portal.zksync.io/bridge/?network=sepolia). 1. Verify your balance: - - Check your wallet's balance using the [zkSync Sepolia explorer](https://sepolia.explorer.zksync.io/). + - Check your wallet's balance using the [%%zk_testnet_name%% explorer](https://sepolia.explorer.zksync.io/). --- diff --git a/content/00.build/10.quick-start/_partials/_setup-wallet.md b/content/00.build/10.quick-start/_partials/_setup-wallet.md index 9f4712ad..c9715ecd 100644 --- a/content/00.build/10.quick-start/_partials/_setup-wallet.md +++ b/content/00.build/10.quick-start/_partials/_setup-wallet.md @@ -2,7 +2,7 @@ title: Set up your wallet --- -Deploying contracts on the zkSync Sepolia testnet requires having testnet ETH. +Deploying contracts on the %%zk_testnet_name%% requires having testnet ETH. If you're working within the local development environment, you can utilize pre-configured rich wallets and skip this step. For testnet deployments, you should have your wallet funded from the [previous step](/build/quick-start#fund-your-wallet). diff --git a/content/00.build/40.tooling/20.hardhat/10.getting-started.md b/content/00.build/40.tooling/20.hardhat/10.getting-started.md index 11b7c1c7..4bdef4c0 100644 --- a/content/00.build/40.tooling/20.hardhat/10.getting-started.md +++ b/content/00.build/40.tooling/20.hardhat/10.getting-started.md @@ -41,7 +41,7 @@ or the [vyper-example](%%zk_git_repo_hardhat-zksync%%/tree/main/examples/vyper-e - You are already familiar with deploying smart contracts on zkSync. -- A wallet with sufficient Sepolia `ETH` on Ethereum and zkSync Era Testnet to pay for deploying smart contracts. +- A wallet with sufficient Sepolia `ETH` on Ethereum and %%zk_testnet_name%% to pay for deploying smart contracts.
-To transfer Sepolia ETH to zkSync testnet use [bridges](https://zksync.io/explore#bridges). +To transfer Sepolia ETH to %%zk_testnet_name%% use [bridges](https://zksync.io/explore#bridges). :: Include your deployment script in the `deploy` folder and execute it running: diff --git a/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md b/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md index 5b7a172b..74ba473e 100644 --- a/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md +++ b/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md @@ -14,7 +14,7 @@ To use the `hardhat-zksync-deploy` in your project, we recommend that: - You are already familiar with deploying smart contracts on zkSync Era. -- A wallet with sufficient Sepolia `ETH` on Ethereum and zkSync Era Testnet to pay for deploying smart contracts on testnet. +- A wallet with sufficient Sepolia `ETH` on Ethereum and %%zk_testnet_name%% to pay for deploying smart contracts on testnet. - Get testnet `ETH` for zkSync Era using [bridges](https://zksync.io/explore#bridges) to bridge funds to zkSync. diff --git a/content/00.build/40.tooling/30.foundry/10.overview.md b/content/00.build/40.tooling/30.foundry/10.overview.md index aeb8f546..64fcda45 100644 --- a/content/00.build/40.tooling/30.foundry/10.overview.md +++ b/content/00.build/40.tooling/30.foundry/10.overview.md @@ -23,7 +23,7 @@ For more details and contributions, visit the [GitHub repository](%%zk_git_repo_ - **Smart Contract Deployment**: Easily deploy smart contracts to zkSync mainnet, testnet, or a local test node. - **Asset Bridging**: Bridge assets between L1 and L2, facilitating seamless transactions across layers. -- **Contract Interaction**: Call and send transactions to deployed contracts on zkSync testnet or local test node. +- **Contract Interaction**: Call and send transactions to deployed contracts on %%zk_testnet_name%% or local test node. - **Solidity Testing**: Write tests in Solidity for a familiar testing environment. - **Fuzz Testing**: Benefit from fuzz testing, complete with shrinking of inputs and printing of counter-examples. - **Remote RPC Forking**: Utilize remote RPC forking mode. diff --git a/content/00.build/40.tooling/30.foundry/20.getting-started.md b/content/00.build/40.tooling/30.foundry/20.getting-started.md index 68ec2f93..581a8e50 100644 --- a/content/00.build/40.tooling/30.foundry/20.getting-started.md +++ b/content/00.build/40.tooling/30.foundry/20.getting-started.md @@ -143,7 +143,7 @@ forge create [OPTIONS] --rpc-url --chain --priva - `--factory-deps `: Specify factory dependencies. **Example:** -Deploy `Greeter.sol` to zkSync Sepolia testnet: +Deploy `Greeter.sol` to %%zk_testnet_name%%:
Click to view the `Greeter.sol` contract @@ -269,15 +269,15 @@ Learn how to query chain IDs, retrieve client versions, check L2 ETH balances, o Expected Output: `270`, indicating the Chain ID of your local zkSync node. -- **zkSync Sepolia Testnet:** +- **%%zk_testnet_name%%:** - For the zkSync Sepolia Testnet, use: + For the %%zk_testnet_name%%, use: ```sh cast chain-id --rpc-url %%zk_testnet_rpc_url%% ``` - Expected Output: `300`, the Chain ID for the zkSync Sepolia Testnet. + Expected Output: `300`, the Chain ID for the %%zk_testnet_name%%. ### Client Version Information diff --git a/content/00.build/60.test-and-debug/40.hardhat.md b/content/00.build/60.test-and-debug/40.hardhat.md index 663b04c9..bbd71d29 100644 --- a/content/00.build/60.test-and-debug/40.hardhat.md +++ b/content/00.build/60.test-and-debug/40.hardhat.md @@ -121,7 +121,7 @@ Our aim is comprehensive coverage. Here are the test scenarios we will cover: 4. **Event Emission**: Ensure an event is emitted when changing the greeting. Each of these test cases will rely on a common setup, -which involves creating a provider connected to the zkSync testnet, initializing a wallet with a known private key, +which involves creating a provider connected to the %%zk_testnet_name%%, initializing a wallet with a known private key, and deploying the `Greeter` contract. Let's refactor our test file with the provided script: diff --git a/content/00.build/70.api-reference/00.index.md b/content/00.build/70.api-reference/00.index.md index d283cf47..3e651274 100644 --- a/content/00.build/70.api-reference/00.index.md +++ b/content/00.build/70.api-reference/00.index.md @@ -26,7 +26,7 @@ Generally, these limits are ample, ranging from 10 to 100 requests per second (R ## Testnet -- **Network Name**: zkSync Era Testnet +- **Network Name**: %%zk_testnet_name%% - **RPC URL**: https://testnet.era.zksync.dev - **WebSocket URL**: wss://testnet.era.zksync.dev/ws - **Chain ID**: 280 diff --git a/content/00.build/70.api-reference/20.zks-rpc.md b/content/00.build/70.api-reference/20.zks-rpc.md index 453d1ea7..1c25060d 100644 --- a/content/00.build/70.api-reference/20.zks-rpc.md +++ b/content/00.build/70.api-reference/20.zks-rpc.md @@ -186,8 +186,8 @@ curl --request POST \ ## `zks_getTestnetPaymaster` -Retrieves the testnet paymaster address, specifically for interactions within the zkSync Sepolia Testnet environment. -**Note: This method is only applicable for zkSync Sepolia Testnet.** +Retrieves the testnet paymaster address, specifically for interactions within the %%zk_testnet_name%% environment. +**Note: This method is only applicable for %%zk_testnet_name%%.** #### Parameters diff --git a/content/_partials/_enable-remix-zksync-plugin.md b/content/_partials/_enable-remix-zksync-plugin.md new file mode 100644 index 00000000..341f9049 --- /dev/null +++ b/content/_partials/_enable-remix-zksync-plugin.md @@ -0,0 +1,15 @@ +--- +title: Enable zkSync plugin in Remix +--- +### Enable the Remix zkSync plugin + +To deploy smart contracts to zkSync via Remix you need to enable the zkSync plugin. + +1. Open :external-link{text="the Remix website" href="https://remix.ethereum.org/"} +2. Click on the **“🔌 Plugin Manager”** button in the bottom-left corner +3. Search “zksync” and click on the **"Activate"** button. + +![Enable zkSync plugin in Remix](/images/enable-remix-plugin.gif) + +Once activated, you’ll see a new menu item with the zkSync logo. Click on it to see the different options to compile, +deploy, and interact with smart contracts on zkSync. diff --git a/content/_zksync.json b/content/_zksync.json index 968972f8..d711b872 100644 --- a/content/_zksync.json +++ b/content/_zksync.json @@ -12,7 +12,7 @@ "block_explorer_url": "https://explorer.zksync.io" }, "testnet": { - "name": "zkSync Era Testnet", + "name": "zkSync Sepolia Testnet", "identifier": "sepolia", "rpc_url": "https://sepolia.era.zksync.dev", "websocket_url": "wss://sepolia.era.zksync.dev/ws", diff --git a/cspell-config/cspell-blockchain.txt b/cspell-config/cspell-blockchain.txt index 52d59646..e87b2d03 100644 --- a/cspell-config/cspell-blockchain.txt +++ b/cspell-config/cspell-blockchain.txt @@ -1,3 +1,4 @@ +Aave arithmetization BoxUups Buterin @@ -31,5 +32,7 @@ viem Vitalik vyper Weth +IERC +mload Yul Zeeve diff --git a/cspell-config/cspell-dev.txt b/cspell-config/cspell-dev.txt index 6561d367..2ba40f08 100644 --- a/cspell-config/cspell-dev.txt +++ b/cspell-config/cspell-dev.txt @@ -22,6 +22,11 @@ dockerized Diataxis ewasm fontaine +zksolc +zkvyper +ZKEVM +zkout +nomicfoundation .getu128 .interm inttoptr @@ -79,6 +84,13 @@ tokio .umin. Vue vue +Viem +viem +Zerion +Rabby +tesnet +devs + zext // devs diff --git a/cspell-config/cspell-zksync.txt b/cspell-config/cspell-zksync.txt index 1cee5f54..c5ca94cd 100644 --- a/cspell-config/cspell-zksync.txt +++ b/cspell-config/cspell-zksync.txt @@ -1,7 +1,9 @@ // zkSync-related words boojum +Zeek MatterLabs Zeek +Zeeks zkcast ZKEVM zkevm diff --git a/nuxt.config.ts b/nuxt.config.ts index c80f06c4..9aa5fbcd 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,5 +1,6 @@ import { getIconCollections } from '@egoist/tailwindcss-icons'; import { zksyncIcons } from './assets/zksync-icons'; +import { customIcons } from './assets/custom-icons'; // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ @@ -45,6 +46,7 @@ export default defineNuxtConfig({ icons: { collections: { ...zksyncIcons, + ...customIcons, ...getIconCollections(['heroicons', 'simple-icons', 'logos', 'devicon']), }, }, diff --git a/package.json b/package.json index d6df4047..aef2aaba 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "@iconify-json/devicon": "^1.1.39", "@iconify-json/heroicons": "^1.1.20", "@iconify-json/simple-icons": "^1.1.95", - "@iconify-json/zondicons": "^1.1.8", "@nuxt/content": "^2.12.1", "@nuxt/fonts": "^0.3.0", "@nuxt/image": "^1.6.0", diff --git a/public/images/101-erc20/atlas-erc20-interact.png b/public/images/101-erc20/atlas-erc20-interact.png new file mode 100644 index 00000000..ceacfd19 Binary files /dev/null and b/public/images/101-erc20/atlas-erc20-interact.png differ diff --git a/public/images/101-erc20/erc20-tokens-minted.png b/public/images/101-erc20/erc20-tokens-minted.png new file mode 100644 index 00000000..c9a90746 Binary files /dev/null and b/public/images/101-erc20/erc20-tokens-minted.png differ diff --git a/public/images/101-erc20/remix-erc20-interact.png b/public/images/101-erc20/remix-erc20-interact.png new file mode 100644 index 00000000..c085f6bc Binary files /dev/null and b/public/images/101-erc20/remix-erc20-interact.png differ diff --git a/public/images/101-paymasters/atlas-paymaster-script.png b/public/images/101-paymasters/atlas-paymaster-script.png new file mode 100644 index 00000000..e6c189f0 Binary files /dev/null and b/public/images/101-paymasters/atlas-paymaster-script.png differ diff --git a/public/images/101-paymasters/zksync-paymaster.png b/public/images/101-paymasters/zksync-paymaster.png new file mode 100644 index 00000000..c9fc4b20 Binary files /dev/null and b/public/images/101-paymasters/zksync-paymaster.png differ diff --git a/public/images/101-quickstart/101-atlas-contract.png b/public/images/101-quickstart/101-atlas-contract.png new file mode 100644 index 00000000..624c7b3e Binary files /dev/null and b/public/images/101-quickstart/101-atlas-contract.png differ diff --git a/public/images/101-quickstart/101-atlas-deployed.png b/public/images/101-quickstart/101-atlas-deployed.png new file mode 100644 index 00000000..75502858 Binary files /dev/null and b/public/images/101-quickstart/101-atlas-deployed.png differ diff --git a/public/images/101-quickstart/101-contract-deployed.png b/public/images/101-quickstart/101-contract-deployed.png new file mode 100644 index 00000000..69dcf922 Binary files /dev/null and b/public/images/101-quickstart/101-contract-deployed.png differ diff --git a/public/images/101-quickstart/101-contract-events.png b/public/images/101-quickstart/101-contract-events.png new file mode 100644 index 00000000..84c0f4ab Binary files /dev/null and b/public/images/101-quickstart/101-contract-events.png differ diff --git a/public/images/101-quickstart/101-remix-interact.png b/public/images/101-quickstart/101-remix-interact.png new file mode 100644 index 00000000..c6511fae Binary files /dev/null and b/public/images/101-quickstart/101-remix-interact.png differ diff --git a/public/images/enable-remix-plugin.gif b/public/images/enable-remix-plugin.gif new file mode 100644 index 00000000..0ff173e6 Binary files /dev/null and b/public/images/enable-remix-plugin.gif differ diff --git a/public/images/remix-plugin-clone-repo.gif b/public/images/remix-plugin-clone-repo.gif new file mode 100644 index 00000000..a7d422ee Binary files /dev/null and b/public/images/remix-plugin-clone-repo.gif differ