TRC-20 approve और दूसरे TRON अनुबंध कॉलों के लिए ऊर्जा
ऊर्जा वह है जो TRON अनुबंध का कोड चलाने के लिए लेता है, और USDT ट्रांसफ़र बहुत-से अनुबंध कॉलों में से एक है। approve भी उसे ख़र्च करता है, और वह transferFrom भी जो बाद में approve की गई रक़म को हिलाता है। 28 अक्टूबर 2026 को हमने दोनों को USDT अनुबंध पर ड्राई-रन किया: approve ने अलाउंस शून्य होने पर 99,764 इकाई ऊर्जा ली और पहले से कोई सेट होने पर 33,764, और transferFrom ने असीमित अलाउंस के सामने 65,123 ली और सीमित के सामने 89,325। दूसरे अनुबंधों के कॉलों के अपने आँकड़े हैं, और किराए की ऊर्जा उनमें से किसी का भी दाम वैसे ही चुकाती है जैसे ट्रांसफ़र का।
सौंपना उस खाते की ऊर्जा-सीमा बढ़ाता है जिस पर वह पहुँचता है, और वह खाता जो भी अनुबंध कॉल हस्ताक्षरित करता है वह कोई भी TRX जलने से पहले उसी सीमा में से ख़र्च करता है (TRON ऊर्जा क्या है)। सौंपने में कहीं नहीं लिखा होता कि वह किस अनुबंध या फ़ंक्शन के लिए है। ट्रांसफ़र के सिवा कोई कॉल इस बात में अलग होता है कि वह कितना ख़र्च करता है, जो इस पर निर्भर है कि वह किस अनुबंध और फ़ंक्शन को कॉल करता है और वहाँ उसे कैसी स्थिति मिलती है, और कुछ अनुबंधों पर इस पर भी कि उसमें से कितना हस्ताक्षर करने वाला चुकाता है।
ड्राई रन में USDT कॉलों ने क्या ख़र्च किया
ड्राई रन एक कॉन्स्टेंट कॉल है: नोड कॉल को चेन की अपनी प्रति पर चलाता है, इस्तेमाल हुई ऊर्जा बताता है और नतीजा फेंक देता है। कुछ हस्ताक्षर या प्रसारित नहीं होता, और उसमें कुछ नहीं लगता। हमने अपने ड्राई रन 28 अक्टूबर 2026 को 08:29 और 08:34 UTC के बीच एक सार्वजनिक फ़ुल नोड से किए। मालिक असली खाते थे, जिन्हें सबसे नए ब्लॉकों में से तब चुना गया जब हर एक ने अभी-अभी किसी स्पेंडर को approve किया था, और खींचने वाले कॉल उन्हीं स्पेंडरों से ड्राई-रन किए गए। शून्य से approve एक ऐसे पते को गया जो हमने अपनी सितंबर की माप के लिए बनाया था और जिसे किसी मालिक ने approve नहीं किया था। हमने हर अलाउंस और बैलेंस कॉल से कुछ ही पल पहले पढ़ा। नीचे का हर आँकड़ा ऐसे कॉल से आया जो सफल होता। ट्रांसफ़र और दोनों खींचने वाले कॉल एक इकाई, यानी एक USDT का दस लाखवाँ हिस्सा, उसी पते को ले गए, जिसके पास USDT है।
| USDT कॉल, 28 अक्टूबर 2026 | ख़र्च हुई ऊर्जा | उसमें से, energy_penalty के रूप में बताई गई | 100 sun प्रति इकाई पर जलाने पर |
|---|---|---|---|
USDT रखने वाले पते को transfer | 64,285 | 49,635 | 6.4285 TRX |
approve, अलाउंस शून्य पर | 99,764 | 77,076 | 9.9764 TRX |
approve, अलाउंस पहले से सेट | 33,764 | 26,076 | 3.3764 TRX |
स्पेंडर का transferFrom, असीमित अलाउंस के सामने | 65,123 | 50,281 | 6.5123 TRX |
दूसरे स्पेंडर का transferFrom, सीमित अलाउंस के सामने | 89,325 | 68,976 | 8.9325 TRX |
दोनों तरह के approve एक ही मालिक से एक ही नई रक़म के लिए आए। एक स्पेंडर के पास अभी कोई अलाउंस नहीं था और दूसरे के पास एक खड़ा था, और पहले वाले का कॉल 66,000 इकाई ज़्यादा पड़ा। यह वही अंतर है जो USDT-रहित पते को ट्रांसफ़र और USDT रखने वाले को ट्रांसफ़र के बीच है, जिसे हमने सितंबर में 130,285 और 64,285 नापा था (दोनों ट्रांसफ़र आँकड़े)। दोनों जोड़ियों में सस्ते कॉल ने ऐसी संख्या को ओवरराइट किया जो पहले से वहाँ थी, और महँगे ने शून्य के ऊपर लिखा।
जब तक अनुबंध के डिप्लॉयर ने उसका कुछ हिस्सा उठाने पर सहमति न दी हो, जैसे JustLend DAO के डिप्लॉयर ने दी है (नीचे), कॉल पर हस्ताक्षर करने वाला उसकी ऊर्जा चुकाता है। जिस प्रवाह में ग्राहक किसी मर्चेंट के अनुबंध को approve करता है और मर्चेंट बाद में रक़म खींचता है, वहाँ हर approve का दाम ग्राहक चुकाता है, और खींचने वाले कॉल पर जो हस्ताक्षर करता है वह उसका: तालिका का transferFrom, और खींचना जब मर्चेंट अनुबंध के भीतर चले तो उसका अपना कोड भी। जिन दो खींचने वाले कॉलों का हम ड्राई रन कर सके वे अपने अलाउंस में अलग थे। असीमित अलाउंस के साथ, स्पेंडर का transferFrom उसी पते को उसी रक़म के सादे ट्रांसफ़र से 838 इकाई ज़्यादा आया, और सीमित के साथ उससे 24,202 ऊपर पड़ा। यह हर तरह की एक-एक जोड़ी है, और जोड़ियों के मालिक और स्पेंडर भी अलग थे।
हर आँकड़े का तीन-चौथाई से कुछ ऊपर उस फ़ील्ड में बैठा है जिसे नोड energy_penalty कहता है, और यह हिस्सा पाँचों कॉलों के लिए एक ही है, approve के लिए भी उतना ही जितना transfer के लिए।
एक उधार-अनुबंध: JustLend DAO के दो कॉल
JustLend DAO से ऊर्जा किराए पर लेना ख़ुद अनुबंध कॉलों की एक जोड़ी है, एक जो पोज़ीशन खोलता है और एक जो उसे लौटाता है (उस किराए में कितना पड़ता है)। हमने 2 सितंबर 2026 की शाम को ख़त्म हुए 24 घंटों के लिए अनुबंध के सार्वजनिक रिकॉर्ड से 30 किरायों को उनकी वापसियों के साथ जोड़ा, और हर कॉल ने कुल मिलाकर क्या ख़र्च किया यह उसकी रसीद से पढ़ा।
| JustLend DAO कॉल, 2 सितंबर 2026 | सबसे कम | माध्यिका | सबसे ज़्यादा |
|---|---|---|---|
किराया, rentResource | 52,672 | 69,306 | 84,290 |
वापसी, returnResource | 67,195 | 74,135 | 74,135 |
तालिका कुल देती है क्योंकि हस्ताक्षर करने वाला हमेशा सब कुछ नहीं चुकाता। अनुबंध ऐसे तय है कि वह कॉल करने वालों से ऊर्जा का दसवाँ हिस्सा ले और बाक़ी अपने डिप्लॉयर की अपनी ऊर्जा से ढके, हर कॉल पर 90,000 इकाई तक, जब तक वह ऊर्जा चले। उस शाम हमारे अपने किराए ने 84,290 इकाइयाँ लीं और उसके हस्ताक्षर करने वाले ने उनमें से 8,429 चुकाईं। तीन घंटे से कम पहले किसी तीसरे पक्ष के किराए ने सारी 52,672 ख़ुद चुकाईं, क्योंकि डिप्लॉयर की ऊर्जा ख़त्म हो चुकी थी, और बारह सेकंड बाद उसकी वापसी ने 74,135 में से 62,200 चुकाईं। ड्राई रन बताता है कि कॉल क्या इस्तेमाल करता है, जबकि हस्ताक्षर करने वाला उस दसवें हिस्से से, जो अनुबंध कॉल करने वालों से लेता है, लेकर सब कुछ तक कुछ भी चुकाता है, उस पल डिप्लॉयर की ऊर्जा पर निर्भर, इसलिए कॉल के लिए ऊर्जा पूरी की पूरी के हिसाब से आँकिए।
ऐसे कॉल का आकार आँकना जिसे किसी ने आपके लिए नहीं नापा
कोई तालिका हर अनुबंध को नहीं ढकती, और ऊपर के आँकड़े उस स्थिति के साथ हिलते हैं जो कॉल को मिलती है। जिस संख्या पर भरोसा करना चाहिए वह ठीक उसी कॉल का ड्राई रन है, उस खाते से जो उस पर हस्ताक्षर करेगा, भेजने से कुछ ही पहले किया हुआ। कोई भी फ़ुल नोड उसका जवाब देता है:
POST /wallet/triggerconstantcontract
{"owner_address": "T… (वह खाता जो हस्ताक्षर करेगा)",
"contract_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"function_selector": "approve(address,uint256)",
"parameter": "… (आर्ग्युमेंट, ABI-एन्कोडेड)",
"visible": true}
संख्या लेने से पहले जवाब जाँचिए, क्योंकि जो कॉल रिवर्ट होता वह भी ऊर्जा बताता है। हमारी पहली transferFrom कोशिशों में से दो ऐसी जोड़ियों पर गईं जो अब चुका नहीं सकती थीं: एक अलाउंस हमारे पूछने से कुछ सेकंड पहले खींचा जा चुका था, और एक मालिक के पास USDT था ही नहीं। वे उस काम के लिए 5,947 और 4,845 इकाइयाँ लेकर लौटीं जो नाकामी पर ख़त्म होता है। उनका result.result फिर भी true पढ़ा गया। जिसने उन्हें अलग बताया वह FAILED था, transaction.ret में, जहाँ सफल होने वाला कॉल एक ख़ाली प्रविष्टि छोड़ता है।
आँकड़े के ऊपर गुंजाइश छोड़िए, क्योंकि ड्राई रन और ब्लॉक के बीच कोई अलाउंस ख़र्च हो सकता है और कोई प्राप्तकर्ता ख़ाली हो सकता है। अपनी तरफ़ से हम भी गुंजाइश छोड़ते हैं: हमारे मानक ट्रांसफ़र आँकड़े, 65,000 और 131,000, दोनों ट्रांसफ़रों की माप से 715 इकाई ऊपर बैठते हैं, और जब mode B में हमें सौंपा गया हस्ताक्षरित USDT ट्रांसफ़र ड्राई रन में ख़ाली पते को ट्रांसफ़र की माप से ऊपर निकलता है, तो हम माप और उसके ऊपर एक गुंजाइश ख़रीदते हैं और डिलीवरी को ख़ुद माप के सामने परखते हैं।
लेन-देन का fee_limit इतना रखिए कि वह नेटवर्क की 100 sun प्रति इकाई की क़ीमत पर पूरे आँकड़े को ढके, तब भी जब ऊर्जा किराए की हो। नोड कॉल पर उसके fee_limit को ऊर्जा की क़ीमत से भाग देकर सीमा लगाता है और सौंपी हुई ऊर्जा को उस सीमा के भीतर गिनता है, इसलिए कम सीमा उस कॉल को रोक देती है जिसके पास खाते पर अपनी हर ज़रूरी इकाई है। बैंडविड्थ एक अलग मीटर है: हर कॉल अपने बाइटों का भी दाम चुकाता है, और ऊर्जा उन्हें नहीं ढकती (ऊर्जा और बैंडविड्थ)।
किसी एक्सचेंज अनुबंध के ज़रिए स्वैप वही गणित है जिसमें एक अनुबंध और जुड़ा है: एक approve जो एक्सचेंज को टोकन हिलाने दे, फिर एक्सचेंज को कॉल। हमने ऐसा कोई ड्राई रन नहीं किया।
किसी कॉल के लिए इकाई के हिसाब से ऊर्जा किराए पर लेना
हमारे mode A और B USDT ट्रांसफ़र के इर्द-गिर्द बने हैं, और mode B हस्ताक्षरित USDT transfer स्वीकार करता है और कुछ नहीं। Mode A में, जब किसी ट्रांसफ़र का प्राप्तकर्ता एक अनुबंध निकलता है, तो ड्राई रन हम आपके लिए चलाते हैं: आइटम kind: custom के साथ लौटता है, उसकी energy_units माप हैं, और एक contract_recipient चेतावनी बताती है कि क्यों (custom आइटम, कुछ भी हस्ताक्षरित होने से पहले)।
बाक़ी हर कॉल के लिए mode C है। आप वॉलेट और वॉल्यूम का नाम लेते हैं, और हम ऊर्जा उस वॉलेट को सौंप देते हैं, किसी प्राप्तकर्ता के बिना (API वॉकथ्रू में mode C)। वॉल्यूम energy_units हो सकता है, प्रति वॉलेट 65,000 से 50,000,000 तक कोई भी पूर्ण संख्या, और आइटम kind: bulk के रूप में लौटता है। Mode C custom नहीं लेता, क्योंकि हमारे ड्राई रन के लिए कोई प्राप्तकर्ता है ही नहीं, इसलिए माप आपकी है। वॉलेट का on-chain सक्रिय होना ज़रूरी है, और जो वॉलेट सक्रिय नहीं उसका ऑर्डर inactive_wallet के साथ ठुकरा दिया जाता है।
पाँच मिनट का पट्टा 131,000 तक का वॉल्यूम लेता है। उससे बड़ा कुछ भी एक घंटे वाले पट्टे पर जाना होगा, और छोटे पट्टे पर हम उसे bulk_needs_longer_lease के साथ ठुकराते हैं: बड़ा वॉल्यूम कई स्रोतों से जोड़ा जाता है और सेकंडों के अंतर पर टुकड़ों में पहुँचता है। शून्य से approve अकेला उस रेखा के नीचे गुंजाइश के साथ समा जाता है। उसके पीछे USDT रखने वाले को एक ट्रांसफ़र जोड़ दीजिए तो जोड़ी उस रेखा को पार कर जाती है, इसलिए वह घंटे पर जाती है। हम जो सबसे छोटा वॉल्यूम बेचते हैं वह पहले से सेट अलाउंस पर एक approve को ढक लेता है, और लगभग उतना ही और बचा रहता है।
POST /v1/estimate उसी energy_units के साथ यह जवाब देता है कि इस पल उस वॉल्यूम का क्या शुल्क लगेगा और, coverage में, कि बाज़ार के पास वह अभी है या नहीं। पहुँचा दिए जाने के बाद, आइटम ready रहता है send_before तक और फिर expired पढ़ता है, जिसका यहाँ मतलब है कि पट्टा ख़त्म हो गया: सामान्य अंत। शुल्क डिलीवरी का है, और वॉलेट जो ऊर्जा बिना ख़र्च छोड़ देता है वह सौंपने के साथ लौट जाती है।
जो हमने नहीं नापा: एक स्वैप, USDT और JustLend DAO के सिवा किसी भी अनुबंध को कॉल, USDT-रहित पते को transferFrom, और यह कि ये आँकड़े हफ़्तों तक टिकते हैं या नहीं। यहाँ का हर USDT आँकड़ा एक कॉन्स्टेंट कॉल है जिसका जवाब एक नोड ने दिया; हमने कोई लेन-देन नहीं भेजा, इसलिए इनमें से किसी को रसीद से नहीं जाँचा गया है।
कॉल का ड्राई रन कीजिए, फिर वह वॉल्यूम उस वॉलेट पर रखिए जो उस पर हस्ताक्षर करेगा: POST /v1/orders पर mode c और energy_units →