प्रत्येक Virtual Environment 0xc100000000000000000000000000000000000000 पर एक precompile contract उजागर करता है। एक transaction के अंदर से इस precompile पर functions को call करने से आपके contracts on-chain state को सीधे manipulate कर सकते हैं, storage slots, balances, nonces, और event logs, बिना accounts को impersonate किए या helper proxies deploy किए।
ये cheatcodes Admin RPC methods के पूरक हैं। Admin RPC methods transaction के बाहर से state को manipulate करते हैं (JSON-RPC के माध्यम से)। precompile transaction के अंदर से state को manipulate करता है (Solidity call के माध्यम से)। precompile का उपयोग तब करें जब आपके setup को atomic रहने, tx hash से replayable होने, या कई slots पर एक loop में चलने की आवश्यकता हो।
Interface
इस file को अपने project में IVnetPrecompile.sol के रूप में जोड़ें:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IVnetPrecompile {
function setStorageAt(address target, bytes32 slot, bytes32 value) external returns (bool);
function getStorageAt(address target, bytes32 slot) external view returns (bytes32);
function setBalance(address target, uint256 balance) external returns (bool);
function addBalance(address target, uint256 amount) external returns (bool);
function setNonce(address target, uint256 value) external returns (bool);
function emitEvent(address target, bytes calldata data) external returns (bool);
function emitEvent(address target, bytes32 topic1) external returns (bool);
function emitEvent(address target, bytes32 topic1, bytes calldata data) external returns (bool);
function emitEvent(address target, bytes32 topic1, bytes32 topic2) external returns (bool);
function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes calldata data) external returns (bool);
function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3) external returns (bool);
function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3, bytes calldata data) external returns (bool);
function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3, bytes32 topic4) external returns (bool);
function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3, bytes32 topic4, bytes calldata data) external returns (bool);
}
अपने contract में fixed address पर इसे reference करें:
IVnetPrecompile constant VNET = IVnetPrecompile(0xc100000000000000000000000000000000000000);
Functions
Storage
| Function | Parameters | Returns | विवरण |
|---|
setStorageAt | address target, bytes32 slot, bytes32 value | bool | target पर slot में value लिखता है। |
getStorageAt | address target, bytes32 slot | bytes32 | target पर slot का वर्तमान मान पढ़ता है। |
VNET.setStorageAt(tokenContract, balanceSlot, bytes32(uint256(1000e18)));
bytes32 val = VNET.getStorageAt(tokenContract, balanceSlot);
Balance
| Function | Parameters | Returns | विवरण |
|---|
setBalance | address target, uint256 balance | bool | target का ETH balance एक exact मान पर सेट करता है। |
addBalance | address target, uint256 amount | bool | target के वर्तमान ETH balance में amount जोड़ता है। |
VNET.setBalance(account, 10 ether);
VNET.addBalance(account, 2 ether);
Nonce
| Function | Parameters | Returns | विवरण |
|---|
setNonce | address target, uint256 value | bool | target की transaction count सेट करता है। |
VNET.setNonce(account, 42);
Events
emitEvent एक log fire करता है जिसका address field target है, न कि calling contract। Downstream consumers (indexers, subgraphs, webhooks) log को target से real emission के रूप में मानते हैं।
नौ overloads एक वैकल्पिक unindexed data payload के साथ शून्य से चार indexed topics कवर करते हैं:
| Overload | Topics | Data |
|---|
emitEvent(target, data) | 0 | ✓ |
emitEvent(target, t1) | 1 | , |
emitEvent(target, t1, data) | 1 | ✓ |
emitEvent(target, t1, t2) | 2 | , |
emitEvent(target, t1, t2, data) | 2 | ✓ |
emitEvent(target, t1, t2, t3) | 3 | , |
emitEvent(target, t1, t2, t3, data) | 3 | ✓ |
emitEvent(target, t1, t2, t3, t4) | 4 | , |
emitEvent(target, t1, t2, t3, t4, data) | 4 | ✓ |
topic1 आमतौर पर keccak256("EventName(type,type,...)") होता है। उदाहरण, एक USDC Transfer spoof करें:
VNET.emitEvent(
USDC,
keccak256("Transfer(address,address,uint256)"),
bytes32(uint256(uint160(from))),
bytes32(uint256(uint160(to))),
abi.encode(amount)
);
precompile address = 0xc100000000000000000000000000000000000000 के साथ अपने स्वयं के diagnostic logs (balance set, nonce set, storage written) भी उत्सर्जित करता है। spoofed log के लिए receipt का निरीक्षण करते समय, precompile की अपनी entries को अनदेखा करने के लिए logs[] को target address द्वारा filter करें।
ज्ञात सीमाएँ
- Arbitrum-आधारित Virtual Environments। Arbitrum internals के कारण
eth_call के माध्यम से किए गए Cheatcode calls काम नहीं करते। Transactions, gas estimates, और simulations अपेक्षित रूप से काम करते हैं।
यह भी देखें
- Admin RPC, transaction के बाहर से state manipulation के लिए equivalent JSON-RPC methods।
- Foundry cheatcode tutorial, एक reusable cheatcode playground deploy करने के लिए end-to-end walkthrough।