diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 256e4ef94..968c8274c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -39,6 +39,7 @@ - [Gas Overview](./zksync-specifics/gas.md) - [Paymaster Overview](./zksync-specifics/paymaster-overview.md) - [Examples](./zksync-specifics/examples/README.md) + - [General Flow Paymaster](./zksync-specifics/examples/general-paymaster.md) - [Paymaster Approval Based](./zksync-specifics/examples/paymaster-approval-based.md) - [Ledger](./zksync-specifics/examples/ledger.md) - [Multisig Smart Account](./zksync-specifics/examples/smart-account.md) @@ -77,9 +78,12 @@ - [Overview of Cast](./cast/README.md) +# Anvil-ZKsync Overview + +- [Anvil-ZKsync](./anvil-zksync/README.md) + # Not Supported -- [Anvil](./anvil/README.md) - [Chisel](./chisel/README.md) # Configuration @@ -409,8 +413,8 @@ - [cast wallet verify](./reference/cast/cast-wallet-verify.md) - [cast wallet import](./reference/cast/cast-wallet-import.md) - [cast wallet list](./reference/cast/cast-wallet-list.md) --> - - + - [`anvil-zksync` Reference](./reference/anvil-zksync/README.md) --> + + +#### Using `genesis.json` + +The `genesis.json` file in Anvil serves a similar purpose as in Geth, defining the network's initial state, consensus rules, and preallocated accounts to ensure all nodes start consistently and maintain network integrity. All values, including balance, gas limit and such, are to be defined as hexadecimals. + +--- + +### GENESIS BLOCK FIELDS + +- `hash`: The hash of the block. +- `parent_hash`: The hash of the parent block. All zeros for the genesis block since there is no parent. +- `block_number`: The block number, with the genesis block being `0`. +- `timestamp`: The creation time of the genesis block in Unix time. +- `l1_batch_env`: The environment configuration for the Layer 1 batch, containing: + - `previous_batch_hash`:The hash of the previous batch. `null` for the first batch. + - `number`: The batch number. + - `timestamp`: The timestamp of the batch in Unix time. + - `fee_input`: Details of the fee inputs: + - `PubdataIndependent`: Contains independent fee parameters: + - `l1_gas_price`: The gas price for Layer 1 transactions. + - `fair_l2_gas_price`: The fair gas price for Layer 2 transactions. + - `fair_pubdata_price`: The fair pubdata price. + - `fee_account`: The address designated for fee collection. Defaults to `0x0000000000000000000000000000000000000000`. + + - `enforced_base_fee`: The enforced base fee for transactions. `null` if not enforced. + - `first_l2_block`: Details of the first Layer 2 block: + - `number`: The block number. + - `timestamp`: The timestamp of the block in Unix time. + - `prev_block_hash`: The hash of the previous block. All zeros for the genesis block. + - `max_virtual_blocks_to_create`: The maximum number of virtual blocks that can be created. +- `transactions`: An array of transactions included in the block. Empty array for the genesis block. +- `gas_used`: The total amount of gas used in the block. +- `logs_bloom`: The bloom filter for logs in the block. + +--- +**Example:** + +```json +{ + "hash": null, + "parent_hash": null, + "block_number": 0, + "timestamp": 1638316800, + "l1_batch_env": { + "previous_batch_hash": null, + "number": 0, + "timestamp": 1732653220, + "fee_input": { + "PubdataIndependent": { + "l1_gas_price": 1, + "fair_l2_gas_price": 2, + "fair_pubdata_price": 1000000000000000 + } + }, + "fee_account": "0x0000000000000000000000000000000000000000", + "enforced_base_fee": null, + "first_l2_block": { + "number": 0, + "timestamp": 1638316800, + "prev_block_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "max_virtual_blocks_to_create": 0 + } + }, + "transactions": [], + "gas_used": null, + "logs_bloom": null +} +``` diff --git a/src/reference/anvil/README.md b/src/reference/anvil/README.md deleted file mode 100644 index d76d37c92..000000000 --- a/src/reference/anvil/README.md +++ /dev/null @@ -1,502 +0,0 @@ -## anvil - -### NAME - -anvil - Create a local testnet node for deploying and testing smart contracts. It can also be used to fork other EVM compatible networks. - -### SYNOPSIS - -`anvil` [*options*] - -### DESCRIPTION - -Create a local testnet node for deploying and testing smart contracts. It can also be used to fork other EVM compatible networks. - -This section covers an extensive list of information about Mining Modes, Supported Transport Layers, Supported RPC Methods, Anvil flags and their usages. You can run multiple flags at the same time. - -#### Mining Modes -Mining modes refer to how frequent blocks are mined using Anvil. By default, it automatically generates a new block as soon as a transaction is submitted. - -You can change this setting to interval mining if you will, which means that a new block will be generated in a given period of time selected by the user. If you want to go for this type of mining, you can do it by adding the `--block-time ` flag, like in the following example. -```sh -# Produces a new block every 10 seconds -anvil --block-time 10 -``` - -There's also a third mining mode called never. In this case, it disables auto and interval mining, and mine on demand instead. You can do this by typing: -```sh -# Enables never mining mode -anvil --no-mining -``` - -To speed up the finalization of blocks, you can use the `--slots-in-an-epoch` flag with a value of `1` for example. This will lead to the block at height `N-2` being finalized, where `N` is the latest block. - -#### Supported Transport Layers -HTTP and Websocket connections are supported. The server listens on port 8545 by default, but it can be changed by running the following command: - -```sh -anvil --port -``` - -#### Default CREATE2 Deployer -Anvil, when used without forking, includes the [default CREATE2 deployer proxy](https://github.com/Arachnid/deterministic-deployment-proxy) at the address `0x4e59b44847b379578588920ca78fbf26c0b4956c`. - -This allows you to test CREATE2 deployments locally without forking. - -#### Supported RPC Methods -##### Standard Methods -The standard methods are based on [this](https://eth.wiki/json-rpc/API) reference. - -* `web3_clientVersion` - -* `web3_sha3` - -* `eth_chainId` - -* `eth_networkId` - -* `eth_gasPrice` - -* `eth_accounts` - -* `eth_blockNumber` - -* `eth_getBalance` - -* `eth_getStorageAt` - -* `eth_getBlockByHash` - -* `eth_getBlockByNumber` - -* `eth_getTransactionCount` - -* `eth_getBlockTransactionCountByHash` - -* `eth_getBlockTransactionCountByNumber` - -* `eth_getUncleCountByBlockHash` - -* `eth_getUncleCountByBlockNumber` - -* `eth_getCode` - -* `eth_sign` - -* `eth_signTypedData_v4` - -* `eth_sendTransaction` - -* `eth_sendRawTransaction` - -* `eth_call` - -* `eth_createAccessList` - -* `eth_estimateGas` - -* `eth_getTransactionByHash` - -* `eth_getTransactionByBlockHashAndIndex` - -* `eth_getTransactionByBlockNumberAndIndex` - -* `eth_getTransactionReceipt` - -* `eth_getUncleByBlockHashAndIndex` - -* `eth_getUncleByBlockNumberAndIndex` - -* `eth_getLogs` - -* `eth_newFilter` - -* `eth_getFilterChanges` - -* `eth_newBlockFilter` - -* `eth_newPendingTransactionFilter` - -* `eth_getFilterLogs` - -* `eth_uninstallFilter` - -* `eth_getWork` - -* `eth_subscribe` - -* `eth_unsubscribe` - -* `eth_syncing` - -* `eth_submitWork` - -* `eth_submitHashrate` - -* `eth_feeHistory` - -* `eth_getProof` - -* `debug_traceTransaction` -Use `anvil --steps-tracing` to get `structLogs` - -* `debug_traceCall` -Note that non-standard traces are not yet supported. This means you can't pass any arguments to the `trace` parameter. - -* `trace_transaction` - -* `trace_block` - -##### Custom Methods -The `anvil_*` namespace is an alias for `hardhat`. For more info, refer to the [Hardhat documentation](https://hardhat.org/hardhat-network/reference#hardhat-network-methods). - -`anvil_impersonateAccount` -Send transactions impersonating an externally owned account or contract. - -`anvil_stopImpersonatingAccount` -Stops impersonating an account or contract if previously set with `anvil_impersonateAccount`. - -`anvil_autoImpersonateAccount` -Accepts `true` to enable auto impersonation of accounts, and `false` to disable it. When enabled, any transaction's sender will be automatically impersonated. Same as `anvil_impersonateAccount`. - -`anvil_getAutomine` -Returns true if automatic mining is enabled, and false if it is not. - -`anvil_mine` -Mines a series of blocks. - -`anvil_dropTransaction` -Removes transactions from the pool. - -`anvil_reset` -Reset the fork to a fresh forked state, and optionally update the fork config. - -`anvil_setRpcUrl` -Sets the backend RPC URL. - -`anvil_setBalance` -Modifies the balance of an account. - -`anvil_setCode` -Sets the code of a contract. - -`anvil_setNonce` -Sets the nonce of an address. - -`anvil_setStorageAt` -Writes a single slot of the account's storage. - -`anvil_setCoinbase` -Sets the coinbase address. - -`anvil_setLoggingEnabled` -Enable or disable logging. - -`anvil_setMinGasPrice` -Set the minimum gas price for the node. - -`anvil_setNextBlockBaseFeePerGas` -Sets the base fee of the next block. - -`anvil_setChainId` -Sets the chain ID of the current EVM instance. - -`anvil_dumpState` -Returns a hex string representing the complete state of the chain. Can be re-imported into a fresh/restarted instance of Anvil to reattain the same state. - -`anvil_loadState` -When given a hex string previously returned by `anvil_dumpState`, merges the contents into the current chain state. Will overwrite any colliding accounts/storage slots. - -`anvil_nodeInfo` -Retrieves the configuration params for the currently running Anvil node. - -##### Special Methods -The special methods come from Ganache. You can take a look at the documentation [here](https://github.com/trufflesuite/ganache-cli-archive/blob/master/README.md). - -`evm_setAutomine` -Enables or disables, based on the single boolean argument, the automatic mining of new blocks with each new transaction submitted to the network. - -`evm_setIntervalMining` -Sets the mining behavior to interval with the given interval (seconds). - -`evm_snapshot` -Snapshot the state of the blockchain at the current block. - -`evm_revert` -Revert the state of the blockchain to a previous snapshot. Takes a single parameter, which is the snapshot id to revert to. - -`evm_increaseTime` -Jump forward in time by the given amount of time, in seconds. - -`evm_setNextBlockTimestamp` -Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block. - -`anvil_setBlockTimestampInterval` -Similar to `evm_increaseTime` but sets a block timestamp `interval`. The timestamp of the next block will be computed as `lastBlock_timestamp + interval`. - -`evm_setBlockGasLimit` -Sets the block gas limit for the following blocks. - -`anvil_removeBlockTimestampInterval` -Removes an `anvil_setBlockTimestampInterval` if it exists. - -`evm_mine` -Mine a single block. - -`anvil_enableTraces` -Turn on call traces for transactions that are returned to the user when they execute a transaction (instead of just txhash/receipt). - -`eth_sendUnsignedTransaction` -Execute a transaction regardless of signature status. - -For the next three methods, make sure to read [Geth's documentation](https://geth.ethereum.org/docs/rpc/ns-txpool). - -`txpool_status` -Returns the number of transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only. - -`txpool_inspect` -Returns a summary of all the transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only. - -`txpool_content` -Returns the details of all transactions currently pending for inclusion in the next block(s), as well as the ones that are being scheduled for future execution only. - -##### Otterscan Methods -The `ots_*` namespace implements the [Otterscan specification](https://github.com/otterscan/otterscan/blob/develop/docs/custom-jsonrpc.md). - -`ots_getApiLevel` -Used by Otterscan to check if it\'s connecting to a compatible node and display a friendly message if it is not. - -`ots_getInternalOperations` -Returns the internal ETH transfers inside a transaction. - -`ots_hasCode` -Check if a certain address contains a deployed code. - -`ots_getTransactionError` -Extract the transaction raw error output. - -`ots_traceTransaction` -Extract all variations of calls, contract creation and self-destructs and returns a call tree. - -`ots_getBlockDetails` -Tailor-made and expanded version of eth_getBlock* for block details page in Otterscan. - -`ots_getBlockTransactions` -Get paginated transactions for a certain block, And removes some verbose fields such logs. - -`ots_searchTransactionsBefore` -Gets paginated inbound/outbound transaction calls for a certain address, and before a given target block. - -`ots_searchTransactionsAfter` -Gets paginated inbound/outbound transaction calls for a certain address, and after a given target block. - -`ots_getTransactionBySenderAndNonce` -Gets the transaction hash for a certain sender address, given its nonce. - -`ots_getContractCreator` -Gets the transaction hash and the address which created a contract. - - -### OPTIONS -#### General Options -`-a, --accounts ` -     Set the number of accounts. [default: 10] - -`--auto-impersonate` -     Enable autoImpersonate on startup. - -`-b, --block-time ` -     Block time in seconds for interval mining. - -`--balance ` -     Set the balance of the accounts. [default: 10000] - -`--derivation-path ` -     Set the derivation path of the child key to be derived. [default: m/44'/60'/0'/0/] - -`-h, --help` -     Print help information. - -`--hardfork ` -     Choose the EVM hardfork to use e.g. `shanghai`, `paris`, `london`, etc... [default: latest] - -`--init ` -     Initialize the genesis block with the given `genesis.json` file. - -`-m, --mnemonic ` -     BIP39 mnemonic phrase used for generating accounts. - -`--no-mining` -     Disable auto and interval mining, and mine on demand instead. - -`--order ` -     How transactions are sorted in the mempool. [default: fees] - -`-p, --port ` -     Port number to listen on. [default: 8545] - -`--steps-tracing` -     Enable steps tracing used for debug calls returning geth-style traces. [aliases: tracing] - -`--ipc []` -     Starts an IPC endpoint at the given `PATH` argument or the default path: unix: `tmp/anvil.ipc`, windows: `\\.\pipe\anvil.ipc`. - -`--silent` -     Don't print anything on startup. - -`--timestamp ` -     Set the timestamp of the genesis block. - -`-V, --version` -     Print version information. - -`--disable-default-create2-deployer` -     Disables deploying the default CREATE2 factory when running Anvil without forking. - -#### EVM Options -`-f, --fork-url ` -     Fetch state over a remote endpoint instead of starting from an empty state. - -`--fork-block-number ` -     Fetch state from a specific block number over a remote endpoint (Must pass `--fork-url` in the same command-line). - -`--fork-retry-backoff ` -     Initial retry backoff on encountering errors. - -`--fork-transaction-hash ` -     Fetch state from a specific transaction hash over a remote endpoint (Must pass `--fork-url` in the same command-line). - -`--retries ` -     Number of retry requests for spurious networks (timed out requests). [default: 5] - -`--timeout ` -     Timeout in ms for requests sent to remote JSON-RPC server in forking mode. [default: 45000] - -`--compute-units-per-second ` -     Sets the number of assumed available compute units per second for this provider. [default: 330] -     See also, [Alchemy Ratelimits](https://github.com/alchemyplatform/alchemy-docs/blob/master/documentation/compute-units.md#rate-limits-cups). - -`--no-rate-limit` -     Disables rate limiting for this node's provider. Will always override `--compute-units-per-second` if present. [default: false] -     See also, [Alchemy Ratelimits](https://github.com/alchemyplatform/alchemy-docs/blob/master/documentation/compute-units.md#rate-limits-cups). - -`--no-storage-caching` -     Disables RPC caching; all storage slots are read from the endpoint. This flag overrides the project's configuration file (Must pass --fork-url in the same command-line). - - -#### Executor Environment Config -`--base-fee ` -`--block-base-fee-per-gas ` -     The base fee in a block. - -`--chain-id ` -     The chain ID. [default: 31337] - -`--code-size-limit ` -     EIP-170: Contract code size limit in bytes. Useful to increase for tests. [default: 0x6000 (~25kb)] - -`--gas-limit ` -     The block gas limit. - -`--gas-price ` -     The gas price. - -#### Server Options -`--allow-origin ` -     Set the CORS `allow_origin`. [default: *] - -`--no-cors` -     Disable CORS. - -`--host ` -     The IP address the server will listen on. - -`--config-out ` -     Writes output of `anvil` as json to user-specified file. - -`--prune-history` -     Don't keep full chain history. - -### EXAMPLES -1. Set the number of accounts to 15 and their balance to 300 ETH - ```sh - anvil --accounts 15 --balance 300 - ``` - -2. Choose the address which will execute the tests - ```sh - anvil --sender 0xC8479C45EE87E0B437c09d3b8FE8ED14ccDa825E - ``` - -3. Change how transactions are sorted in the mempool to FIFO - ```sh - anvil --order fifo - ``` - -### Shell Completions - -``anvil completions`` *shell* - -Generates a shell completions script for the given shell. - -Supported shells are: - -- bash -- elvish -- fish -- powershell -- zsh - -#### EXAMPLES - -1. Generate shell completions script for zsh: - ```sh - anvil completions zsh > $HOME/.oh-my-zsh/completions/_anvil - ``` - - -### Usage within Docker - -In order to run anvil as a service in Github Actions with the [Docker container](../../tutorials/foundry-docker.md), where passing arguments to the entrypoint command is not possible, use the `ANVIL_IP_ADDR` environment variable to set the host's IP. `ANVIL_IP_ADDR=0.0.0.0` is equivalent to providing the `--host ` option. - -#### Using `genesis.json` - -The `genesis.json` file in Anvil serves a similar purpose as in Geth, defining the network's initial state, consensus rules, and preallocated accounts to ensure all nodes start consistently and maintain network integrity. All values, including balance, gas limit and such, are to be defined as hexadecimals. - -- `chainId`: Identifier for the blockchain, unique to each network. -- `nonce`: A counter used in hashing algorithms to ensure data integrity. -- `timestamp`: The creation time of the genesis block in Unix time. -- `extraData`: Additional data that can be included by the creator of the genesis block. -- `gasLimit`: The maximum amount of gas that can be used in the block. -- `difficulty`: A measure of how difficult it is to mine a new block. -- `mixHash`: A unique identifier proving a sufficient amount of computation for the block. -- `coinbase`: The Ethereum address of the miner who mined this block. -- `stateRoot`: The root of the state trie, reflecting the final state after all transactions. -- `alloc`: Allows pre-allocating Ether to a set of addresses with predefined balances. -- `number`: The block number, with the genesis block being 0. -- `gasUsed`: The total gas used in the block. -- `parentHash`: The hash of the parent block, all zeros for the genesis block since there is no parent. - -A sample for simulating mainnet via genesis can be found [here](https://github.com/paradigmxyz/reth/blob/8f3e4a15738d8174d41f4aede5570ecead141a77/crates/primitives/res/genesis/mainnet.json). - -```json -{ - "chainId": "0x2323", - "nonce": "0x42", - "timestamp": "0x0", - "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", - "gasLimit": "0x1388", - "difficulty": "0x400000000", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544", - "alloc": { - "000d836201318ec6899a67540690382780743280": { - "balance": "0xad78ebc5ac6200000" - } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" -} -``` diff --git a/src/zksync-specifics/examples/README.md b/src/zksync-specifics/examples/README.md index a275c95e0..6413bfcc5 100644 --- a/src/zksync-specifics/examples/README.md +++ b/src/zksync-specifics/examples/README.md @@ -1,3 +1,4 @@ # ZKsync specific examples - [Paymaster Approval Based](paymaster-approval-based.md) +- [General Flow Paymaster](general-paymaster.md) diff --git a/src/zksync-specifics/examples/general-paymaster.md b/src/zksync-specifics/examples/general-paymaster.md new file mode 100644 index 000000000..fe35bc5d5 --- /dev/null +++ b/src/zksync-specifics/examples/general-paymaster.md @@ -0,0 +1,150 @@ +## Using the zkUsePaymaster Cheatcode in General Flow Paymaster Contracts + +This example covers the use of a general flow paymaster contract. +For this example we will use the `GaslessPaymaster` contract from the paymaster example repository [here](https://github.com/matter-labs/paymaster-examples). + + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "@matterlabs/era-contracts/interfaces/IPaymaster.sol"; +import "@matterlabs/era-contracts/interfaces/IPaymasterFlow.sol"; +import "@matterlabs/era-contracts/Constants.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +/// @author Matter Labs +/// @notice This contract does not include any validations other than using the paymaster general flow. +contract GaslessPaymaster is IPaymaster, Ownable { + constructor() Ownable(msg.sender) {} + + modifier onlyBootloader() { + require( + msg.sender == BOOTLOADER_FORMAL_ADDRESS, + "Only bootloader can call this method" + ); + // Continue execution if called from the bootloader. + _; + } + + function validateAndPayForPaymasterTransaction( + bytes32, + bytes32, + Transaction calldata _transaction + ) + external + payable + onlyBootloader + returns (bytes4 magic, bytes memory context) + { + // By default we consider the transaction as accepted. + magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; + 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.general.selector) { + // Note, that while the minimal amount of ETH needed is tx.gasPrice * tx.gasLimit, + // neither paymaster nor account are allowed to access this context variable. + uint256 requiredETH = _transaction.gasLimit * + _transaction.maxFeePerGas; + // The bootloader never returns any data, so it can safely be ignored here. + (bool success, ) = payable(BOOTLOADER_FORMAL_ADDRESS).call{ + value: requiredETH + }(""); + require( + success, + "Failed to transfer tx fee to the Bootloader. Paymaster balance might not be enough." + ); + } else { + revert("Unsupported paymaster flow in paymasterParams."); + } + } + + function postTransaction( + bytes calldata _context, + Transaction calldata _transaction, + bytes32, + bytes32, + ExecutionResult _txResult, + uint256 _maxRefundedGas + ) external payable override onlyBootloader { + // Refunds are not supported yet. + } + + function withdraw(address payable _to) external onlyOwner { + // send paymaster funds to the owner + uint256 balance = address(this).balance; + (bool success, ) = _to.call{value: balance}(""); + require(success, "Failed to withdraw funds from paymaster."); + } + + receive() external payable {} +} +``` + +This contract is a general flow paymaster, which means that it can pay for any account. To be able to use this paymaster we need to first deploy it in the intended network. + +For this example we will deploy it in the era-test-node and then use the `zkUsePaymaster` cheatcode to pay for a transaction using a script. + +```solidity +pragma solidity ^0.8.0; + +import {Script} from "forge-std/Script.sol"; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "../src/GeneralPaymaster.sol"; +// We need to import the TestExt to use the zkUsePaymaster cheatcode +// as this is a ZKsync specific cheatcode +import "../src/Counter.sol"; +import {TestExt} from "forge-zksync-std/TestExt.sol"; + +contract PaymasterUsageScript is Script, TestExt { + Counter public counter; + + function run() public { + vm.startBroadcast(); + + GaslessPaymaster paymaster = new GaslessPaymaster(); + + // fund the paymaster + address(paymaster).call{value: 0.05 ether}(""); + + bytes memory paymaster_encoded_input = abi.encodeWithSelector( + bytes4(keccak256("general(bytes)")), + bytes("0x") + ); + vmExt.zkUsePaymaster( + address(paymaster), + paymaster_encoded_input + ); + + counter = new Counter(); + + vm.stopBroadcast(); + } +} +``` + +The key part of this script is encoding the paymaster call with the `general(bytes)` selector and then using the `zkUsePaymaster` cheatcode to pay for the transaction. This will vary depending on the paymaster contract that you are using. + +```solidity + // This is the encoding for the GaslessPaymaster + bytes memory paymaster_encoded_input = abi.encodeWithSelector( + bytes4(keccak256("general(bytes)")), + bytes("0x") + ); + + // Using the encoded parameters to call the zkUsePaymaster cheatcode + vmExt.zkUsePaymaster( + address(paymaster), + paymaster_encoded_input + ); +``` +After calling the `zkUsePaymaster` cheatcode, the paymaster will pay for the following transaction. + +