Staticcall एक सामान्य Ethereum कॉल की तरह है, सिवाय इसके कि यदि कोई state change होता है तो यह revert हो जाता है। इसका उपयोग Ether ट्रांसफर करने के लिए नहीं किया जा सकता है। EVM opcode, Yul assembly फ़ंक्शन, और बिल्ट-इन Solidity फ़ंक्शन सभी का नाम staticcall है।
EIP 214
Staticcall को EIP 214 में पेश किया गया था और 2017 में Byzantium hard fork के हिस्से के रूप में Ethereum में जोड़ा गया था। उन फ़ंक्शंस के लिए जहाँ केवल एक return value वांछित है और state changes अवांछित हैं, यह सुरक्षा की एक परत जोड़ता है। यदि कॉल किया गया कॉन्ट्रैक्ट कोई state change करता है तो Staticcall revert हो जाएगा, जिसमें शामिल हैं: किसी इवेंट को लॉग करना, Ether भेजना, कॉन्ट्रैक्ट बनाना, कॉन्ट्रैक्ट को नष्ट करना, या storage variable सेट करना। Storage variable को पढ़ना ठीक है। एक कॉल जो Ether को ट्रांसफर नहीं करती है, तब तक अनुमत है जब तक कि इसके परिणामस्वरूप कोई state change न हो।
View functions
Solidity उन view functions को कंपाइल करती है जो बाहरी कॉन्ट्रैक्ट्स को कॉल करते हैं ताकि वे बैकग्राउंड (under the hood) में staticcall का उपयोग कर सकें।
यहाँ एक छोटा सा उदाहरण दिया गया है
contract ERC20User {
IERC20 public token;
// rest of the code
function myBalance() public view returns (uint256 balance) {
balance = token.balanceOf(address(this));
}
function myBalanceLowLevelEquivalent() public view returns (uint256 balance) {
(bool ok, bytes memory result) = token.staticcall(abi.encodeWithSignature("balanceOf(address)", address(this)));
require(ok);
balance = abi.decode(result, (uint256));
}
}
यदि balanceOf state को बदलता है, तो कोड revert हो जाएगा।
Meta Arguments
फॉरवर्ड की गई gas की मात्रा को निम्नलिखित तरीके से निर्दिष्ट किया जा सकता है। फॉरवर्ड की गई gas की मात्रा EIP 150 में वर्णित 63/64 नियम के अधीन है।
staticcall{gas: gasAmount}(abiEncodedArguments);
Attack Vectors
यद्यपि staticcall कुछ मायनों में एक सामान्य कॉल की तुलना में “सुरक्षित” (safer) है, लेकिन इसका मतलब यह नहीं है कि इसका उपयोग करते समय कोई सुरक्षा की उपेक्षा कर सकता है।
Denial of Service
Staticcall अभी भी gas griefing के साथ denial of service हमलों के अधीन है। उस स्थिति पर विचार करें जहाँ ऊपर दिए गए ERC20 टोकन ने balanceOf फ़ंक्शन के अंदर एक infinite loop डाल दिया है। कॉल करने वाले कॉन्ट्रैक्ट के पास अभी भी gas बची होगी, लेकिन EIP 150 के अनुसार मूल मात्रा का केवल 1/64 वां हिस्सा।
Read-only reentrancy
Static call के लिए एक और attack vector गलत values वापस प्राप्त करना है। read-only reentrancy attack में, टोकन values को flashloan के साथ अस्थायी रूप से मैनिपुलेट किया जाता है, ताकि जो भी स्मार्ट कॉन्ट्रैक्ट (staticcall के माध्यम से) values को देख रहा है, उसे oracle manipulation के साथ हैक किया जा सके।
Staticcall in Yul Assembly
Yul assembly में, staticcall के लिए arguments इस प्रकार हैं:
let ok := staticcall(gas, addressToCall, in, insize, out, outsize)
Arguments out और outsize मेमोरी में वह क्षेत्र हैं जहाँ return value को कॉपी किया जाएगा। हालाँकि, दोनों values आमतौर पर शून्य (zero) पर सेट होते हैं और variable return sizes को लचीले ढंग से संभालने के लिए इसके बजाय “returndatacopy” और “returndatasize” का उपयोग किया जाता है।
इन opcodes को EIP 211 में पेश किया गया था, जिससे दूसरे स्मार्ट कॉन्ट्रैक्ट से return value की लंबाई का अनुमान लगाने की आवश्यकता समाप्त हो गई।
यह उदाहरण देखें:
returndatacopy(0, 0, returndatasize())
Variables in और insize मेमोरी के उस क्षेत्र को इंगित करते हैं जहाँ बाहरी कॉन्ट्रैक्ट को की गई कॉल का डेटा हिस्सा (आमतौर पर abi-encoded) होता है।
यदि staticcall सफल होता है तो variable ok true रिटर्न करता है और यदि यह revert होता है तो false। Reverts को बबल अप (bubbled up) नहीं किया जाता है।
Usage with precompiled smart contracts
Staticcall Ethereum precompiled contracts (एड्रेस 0x01 से 0x09 तक) के साथ इंटरैक्ट करने का सही तरीका है क्योंकि उनमें से कोई भी state change नहीं करता है।
निम्नलिखित उदाहरण एक uint के SHA256 की गणना करेगा। ध्यान दें कि यह precompile डेटा को सीधे हैश करता है, और इसे ABI-encoded नहीं किया जाना चाहिए।
function getSha256(uint256 x) public view returns (bytes32 hashOut) {
(bool ok, bytes memory result) = address(0x02).staticcall(abi.encode(x));
require(ok);
hashOut = abi.decode(result, (bytes32));
}
Learn more
अधिक उन्नत Ethereum डेवलपमेंट कॉन्सेप्ट्स सीखने के लिए हमारे विशेषज्ञ Solidity developer bootcamp को देखें। हमारे पास free Solidity course भी है।
मूल रूप से 10 अप्रैल, 2023 को प्रकाशित