Token-2022 इंटरेस्ट-बियरिंग एक्सटेंशन एक टोकन मिंट को उस विशिष्ट मिंट के लिए सभी टोकन खातों पर स्वचालित रूप से ब्याज अर्जित करने में सक्षम बनाता है। यह मिंट के ऑन-चेन कॉन्फ़िगरेशन में परिभाषित वार्षिक दर (annual rate) का उपयोग करता है।
हालाँकि, यह ब्याज एक कंप्यूटेड व्यू (computed view) है: वास्तविक टोकन बैलेंस ऑन-चेन कभी नहीं बदलता है। इसके बजाय, वॉलेट और एप्लिकेशन अर्जित ब्याज के शुद्ध बैलेंस की गणना करने के लिए प्रत्येक उपयोगकर्ता के ऑन-चेन बैलेंस पर एक निरंतर कंपाउंडिंग फॉर्मूला लागू करते हैं। डेवलपर कंप्यूट किए गए ब्याज और ऑन-चेन बैलेंस को एक ही वैल्यू में मिला सकता है या उन्हें अलग-अलग प्रदर्शित कर सकता है।
यह एक्सटेंशन ब्याज अर्जित करने के लिए अकाउंटिंग मैकेनिज्म प्रदान करता है; यह ब्याज के लिए आर्थिक समर्थन (economic backing) प्रदान करने के लिए अलग-अलग DeFi एप्लिकेशन पर निर्भर करता है।
इस लेख में, हम इंटरेस्ट-बियरिंग एक्सटेंशन के आर्किटेक्चर का विश्लेषण करेंगे, गणनाओं के पीछे के गणित की व्याख्या करेंगे, वॉलेट अनुकूलता (compatibility) को कवर करेंगे, और Anchor के साथ एक व्यावहारिक कार्यान्वयन उदाहरण के माध्यम से चलेंगे।
इंटरेस्ट-बियरिंग एक्सटेंशन आर्किटेक्चर
जैसा कि हमने अपने Token-2022 लेख में चर्चा की थी, टोकन एक्सटेंशन मॉड्यूलर फीचर हैं जिन्हें मिंट या टोकन खाते में जोड़ा जाता है। एक मिंट खाते का बेस लेआउट 82 बाइट्स होता है, और एक टोकन खाते का बेस लेआउट 165 बाइट्स होता है। एक्सटेंशन डेटा को उन बेस आकारों के बाद जोड़ा जाता है, इसलिए आपको मिंट या टोकन खाता बनाने से पहले बेस आकार और किसी भी सक्षम एक्सटेंशन के आकार के बराबर स्थान आवंटित (allocate) करना होगा।
इंटरेस्ट-बियरिंग एक्सटेंशन के लिए आवंटित स्थान एक्सटेंशन के डेटा को स्टोर करता है, जिसमें एक अथॉरिटी अकाउंट फ़ील्ड भी शामिल है जो ब्याज दरों को अपडेट कर सकता है। यदि अथॉरिटी अकाउंट फ़ील्ड पूरी तरह से शून्य है, तो इसे None माना जाता है, जिसका अर्थ है कि ब्याज दर अपरिवर्तनीय (immutable) रहती है। व्यवहार में, अथॉरिटी को एक DeFi एप्लिकेशन पर सेट किया जा सकता है, जो फिर ऐप में वास्तविक आर्थिक गतिविधि को दर्शाने के लिए ब्याज दर निर्धारित करता है।
अथॉरिटी फ़ील्ड के अलावा, नीचे दिया गया Rust स्ट्रक्चर (जिसे हमने सीधे source code for the extension से लिया है) पूर्ण इंटरेस्ट-बियरिंग एक्सटेंशन डेटा को परिभाषित करता है:
- इनिशियलाइज़ेशन टाइमस्टैम्प (
initialization_timestamp), जो सभी ब्याज गणनाओं के लिए शुरुआती समय के रूप में कार्य करता है - इनिशियलाइज़ेशन से लेकर पिछली बार दर अपडेट होने तक की औसत ब्याज दर (
pre_update_average_rate)। - ब्याज दर में अंतिम बदलाव का टाइमस्टैम्प (
last_update_timestamp), जिसका उपयोग अर्जित ब्याज की गणना के लिए किया जाता है - अंतिम अपडेट टाइमस्टैम्प के बाद से लागू वर्तमान ब्याज दर (
current_rate)।
/// Annual interest rate, expressed as basis points
pub type BasisPoints = PodI16;
const ONE_IN_BASIS_POINTS: f64 = 10_000.;
const SECONDS_PER_YEAR: f64 = 60. * 60. * 24. * 365.24;
pub struct InterestBearingConfig {
/// Authority that can set the interest rate and authority
pub rate_authority: OptionalNonZeroPubkey,
/// Timestamp of initialization, from which to base interest calculations
pub initialization_timestamp: UnixTimestamp,
/// Average rate from initialization until the last time the rate was updated
pub pre_update_average_rate: BasisPoints,
/// Timestamp of the last update, used to calculate the total amount accrued
pub last_update_timestamp: UnixTimestamp,
/// Current rate, since the last update
pub current_rate: BasisPoints,
}
इंटरेस्ट-बियरिंग एक्सटेंशन का Type-Length-Value (TLV) लेआउट
सभी Token-2022 एक्सटेंशन Type-Length-Value (TLV) प्रारूप का पालन करते हैं, जो प्रोग्राम्स को किसी खाते में संग्रहीत विभिन्न एक्सटेंशन डेटा को आसानी से पढ़ने और छोड़ने की अनुमति देता है।
InterestBearingConfig TLV एंट्री को इस प्रकार एन्कोड किया गया है:
- T (
type):0x0A(InterestBearingConfigके लिए टाइप आइडेंटिफायर) - L (
length):0x34(u8, मान = 52 दशमलव) - V (
value): क्रम में संयोजित (concatenated) सीरियलाइज़्ड फ़ील्ड्स:rate_authority(32 बाइट्स)initialization_timestamp(8 बाइट्स)pre_update_average_rate(2 बाइट्स)last_update_timestamp(8 बाइट्स)current_rate(2 बाइट्स)
pre_update_average_rate और current_rate फ़ील्ड्स फ्लोटिंग-पॉइंट नंबरों के रूप में संग्रहीत नहीं होते हैं। इसके बजाय, वे बेसिस पॉइंट्स (basis points) के रूप में संग्रहीत होते हैं।
1 basis point = 1/100 (0.01%)
इसलिए, 2.50% की वार्षिक ब्याज दर का प्रतिनिधित्व करने के लिए, आप current_rate फ़ील्ड में पूर्णांक 250 संग्रहीत करेंगे (क्योंकि 250 बेसिस पॉइंट्स 250*1/100=2.5% है)। प्रतिशत को बेसिस पॉइंट्स में बदलने के लिए, बस 0.01 से विभाजित करें (या समान रूप से, 100 से गुणा करें)। इस उदाहरण में, 2.5 / 0.01=250।
InterestBearingConfig एक्सटेंशन TLV लेआउट में, V भाग क्रम में संयोजित सभी एक्सटेंशन फ़ील्ड्स का सीरियलाइज़्ड मान है, जैसा कि हमारे Token-2022 लेख में पहले समझाया गया है।
उदाहरण के लिए, मान लें कि एक्सटेंशन में निम्नलिखित मान हैं:
rate_authority:7xKXtg2CW87d9LN6HBUtjQVSiJ9MCrgdGubbyiTZRjrwb(32 बाइट्स)initialization_timestamp:1672531200(Jan 1, 2023; 8 बाइट्स)pre_update_average_rate:500(5.00% बेसिस पॉइंट्स में; 2 बाइट्स)last_update_timestamp:1704067200(Jan 1, 2024; 8 बाइट्स)current_rate:500(5.00% बेसिस पॉइंट्स में; 2 बाइट्स)
जब हम उपरोक्त फ़ील्ड्स को एक निरंतर बाइट अनुक्रम (sequence) के रूप में जोड़ते हैं, तो TLV का V (हेक्स) भाग होता है:
0x689536DF68C2FB0A61A08DEDC9797145C969328A05D68A2A8C06E15A3AB6BD5200CDB06300000000F4018000926500000000F401
पूर्ण TLV एंट्री T(0x0A) | L(0x34) | V(...) है और इसे सीधे Mint खाते के डेटा के बाद जोड़ा जाता है।

इंटरेस्ट-बियरिंग एक्सटेंशन इनिशियलाइज़ेशन
इंटरेस्ट-बियरिंग एक्सटेंशन को एक ही ऑपरेशन में सक्षम (enabled) और इनिशियलाइज़ किया जाता है, जो स्थान भी आरक्षित (reserve) करता है और एक्सटेंशन का TLV भी लिखता है। जैसा कि हमने पहले Token-2022 लेख में चर्चा की थी,
अन्य एक्सटेंशन के लिए आमतौर पर दो चरणों की आवश्यकता होती है:
- आवश्यक एक्सटेंशन को सक्षम करना और एक्सटेंशन के लिए स्थान आरक्षित करना
- और इसे कॉन्फ़िगर करने के लिए एक अलग इनिशियलाइज़ निर्देश (instruction)।
ब्याज गणना मॉडल
मान लीजिए कि आपका बैंक में एक बचत खाता है। जब आप 3% वार्षिक ब्याज दर पर $1,000 जमा करते हैं, तो आपके खाते के विवरण में यह नहीं दिखता कि आपका बैंक हर दिन नए डॉलर मिंट कर रहा है। इसके बजाय, बैंक का सिस्टम यह गणना करता है कि यदि इसमें चक्रवृद्धि (compounding) हो रही होती तो आपका बैलेंस कितना बढ़ गया होता और जब भी आप लॉग इन करते हैं तो आपको अपडेटेड आंकड़ा दिखाता है।
इंटरेस्ट-बियरिंग एक्सटेंशन आपके मिंट खाते को भी इसी तरह काम कराता है। आपका ऑन-चेन बैलेंस (आपके बैंक के बैलेंस के समकक्ष) कभी भी $1,000 से नहीं बदलता है। लेकिन आपका वॉलेट (ऑनलाइन बैंकिंग ऐप की तरह) छह महीने बाद **$1,015 या एक साल बाद $1,030 प्रदर्शित करने के लिए एक कंपाउंडिंग फॉर्मूले का उपयोग करता है।
यदि बैंक बाद में आपकी दर को 3% से बढ़ाकर 5% कर देता है, तो भविष्य का ब्याज तेज़ी से बढ़ता है, लेकिन 3% पर आपका पिछला वर्ष अभी भी “लॉक इन” रहता है, और अंतिम बैलेंस उस समयावधि के लिए 3% की वृद्धि दर को ठीक से दर्शाएगा।
इंटरेस्ट-बियरिंग एक्सटेंशन ब्याज की गणना करने के लिए निरंतर चक्रवृद्धि ब्याज सूत्र (continuous compound interest formula) ( ) का उपयोग करता है और यह सुनिश्चित करता है कि दर बदलने या न बदलने पर भी आपकी अर्जित यील्ड सटीक रहे (हम इस फॉर्मूले को बाद में विस्तार से समझेंगे)।
यह फॉर्मूला hard-coded into the Token-2022 program में दो रूपों में हार्ड-कोड किया गया है: सबसे हाल के दर अपडेट से before (पहले) और after (बाद)।
before भिन्नता (variation) पुरानी दर के तहत वृद्धि को कैप्चर करती है (यदि अथॉरिटी दर को अपडेट करती है), जबकि after भिन्नता वर्तमान दर के तहत वृद्धि को कैप्चर करती है। साथ में, वे एक निरंतर, समय-भारित (time-weighted) कंपाउंडिंग कारक (factor) उत्पन्न करते हैं जो सुनिश्चित करता है कि कई दर परिवर्तनों के बीच बैलेंस सटीक बना रहे।
आगे, आइए एक उदाहरण के साथ दिखाएं कि गणितीय रूप से इन ऑपरेशनों की गणना कैसे की जाती है।
इंटरेस्ट-बियरिंग एक्सटेंशन निरंतर चक्रवृद्धि ब्याज सूत्र का उपयोग कैसे करता है
सबसे पहले, यहाँ सूत्र में चर (variables) का विवरण दिया गया है:
- A = अंतिम राशि (मूलधन + ब्याज)
- P = मूलधन (प्रारंभिक राशि)
- e = यूलर की संख्या (Euler’s number) (लगभग 2.71828…)
- r = वार्षिक ब्याज दर (दशमलव के रूप में)
- t = वर्षों में समय (Token-2022 आंतरिक रूप से सेकंड के साथ काम करता है)
जहाँ SECONDS_PER_YEAR = 60 × 60 × 24 × 365.24
ऐसे परिदृश्य के लिए निम्नलिखित उदाहरण लें जहाँ दर नहीं बदली गई है:
- आप 1000 टोकन जमा करते हैं (P = 1000)
- ब्याज दर 5% है (r = 0.05)
- 1 वर्ष के बाद (t = 1)।
- प्रदर्शित बैलेंस की गणना इस प्रकार की जाती है:
आइए यह व्यवहार भी दिखाएं जब दर बदलती है
अब मान लें कि ब्याज दर 3% से शुरू होती है लेकिन पहले 3 महीनों के बाद बढ़कर 5% हो जाती है। Token-2022 गणना को खंडों (segments) में विभाजित करके इसे संभालता है।
नोट: हमारे गणितीय मॉडल में, हम तीन महीने को 0.25 के रूप में दर्शाते हैं (3 ÷ 12 = 0.25 के रूप में गणना की गई)
-
प्री-अपडेट ग्रोथ (Pre-update growth):
आइए बीता हुआ समय (elapsed time) (t) की गणना करके शुरू करें।
यदि हम अपनी उपरोक्त गणना से फॉर्मूले में t को 0.25 वर्ष से प्रतिस्थापित (substitute) करते हैं, तो हमें नीचे दिया गया परिणाम मिलेगा:
-
पोस्ट-अपडेट ग्रोथ (Post-update growth):
नई दर = 5% (r₂ = 0.05)
शेष बीता हुआ समय = 9 महीने जिसकी गणना 9/12 के रूप में की जाती है (t₂ = 0.75)
हमारी अब तक की गणना से, आप देखेंगे कि ब्याज एक वर्ष की यील्ड का प्रतिनिधित्व करता है। पहले तीन महीनों (प्री-अपडेट ग्रोथ पीरियड) में, उपयोगकर्ता ने 3% की दर से 7.53 टोकन कमाए, जिससे उनका कुल 1,007.53 टोकन हो गया। जब शेष नौ महीनों (पोस्ट-अपडेट ग्रोथ पीरियड) के लिए दर बढ़कर 5% हो गई, तो उन्होंने अतिरिक्त 38.5 टोकन अर्जित किए, जिसके परिणामस्वरूप अंतिम बैलेंस 1,046.03 टोकन हो गया।
एकाधिक (Multiple) ब्याज दर अपडेट्स को संभालना
हमने देखा है कि यह गणना दो समयावधियों के लिए कैसे काम करती है, लेकिन इंटरेस्ट-बियरिंग एक्सटेंशन टोकन के जीवनकाल के दौरान ब्याज दर को कई बार अपडेट कर सकता है। प्रत्येक अपडेट सुनिश्चित करता है कि अर्जित यील्ड पिछली और भविष्य की सभी दर परिवर्तनों के अनुरूप बनी रहे।
जब कोई नई दर निर्धारित की जाती है, तो प्रोग्राम InterestBearingConfig में फ़ील्ड्स को इस प्रकार अपडेट करता है:
- यह सभी पिछली दरों के समय-भारित औसत (time-weighted average) के रूप में
pre_update_average_rateकी पुनर्गणना करता है, जिसमें वह दर भी शामिल है जिसे अभी-अभी बदला गया है। - यह
last_update_timestampको वर्तमान ब्लॉक समय पर आगे ले जाता है। - यह
current_rateको नए दर मान (उदाहरण के लिए, 7% के लिए700बेसिस पॉइंट्स) पर सेट करता है।
गणितीय रूप से, हम नीचे दिए गए सूत्र के साथ सभी पिछली दरों के नए समय-भारित औसत (pre_update_average_rate) की पुनर्गणना कर सकते हैं:
जहाँ:
- r₁ →
pre_update_average_rate(पिछली औसत दर) - t₁ →
last_update_timestamp - initialization_timestamp(सभी पिछली दरों के तहत बीता हुआ समय) - r₂ →
current_rate(अपडेट से पहले की सबसे हाल की दर) - t₂ →
current_timestamp - last_update_timestamp(वर्तमान दर के तहत बीता हुआ समय)
समय भारित औसत की गणना का उदाहरण
मान लीजिए कि हम इसके साथ शुरू करते हैं:
initialization_timestamp = 0pre_update_average_rate = 300(3%)last_update_timestamp = 7889184सेकंड (~3 महीने।InterestBearingConfigएक्सटेंशन पूर्ण (absolute) यूनिक्स टाइमस्टैम्प संग्रहीत करता है, लेकिन इस उदाहरण में, हम ब्याज वृद्धि को दर्शाने के लिए सेकंड में 3-महीने की बीती हुई अवधि का उपयोग करते हैं, क्योंकि ब्याज केवल समय बीतने पर निर्भर करता है, विशिष्ट टाइमस्टैम्प मानों पर नहीं)current_rate = 500(5%)current_timestamp = 31556736(≈ 1 वर्ष)new_rate = 700(7%)
फिर:
अपडेट के बाद:
pre_update_average_rate = 450(4.50%)last_update_timestamp = 31556736current_rate = 700(7%)
फॉर्मूले का कोड इलस्ट्रेशन
प्री-अपडेट ग्रोथ पीरियड और पोस्ट-अपडेट ग्रोथ पीरियड को एक्सटेंशन के source code में pre_update_exp और post_update_exp फ़ंक्शन्स के रूप में लागू किया गया है। वह भाग जो दोनों फ़ंक्शन्स को परिभाषित करता है, नीचे दिखाया गया है।
pre_update_exp और post_update_exp फ़ंक्शन्स सीधे निरंतर चक्रवृद्धि ब्याज सूत्र () को लागू करते हैं, विशेष रूप से, दो अलग-अलग समयावधियों के लिए ब्याज वृद्धि कारक (interest growth factor) ( ) — सबसे हाल के ब्याज दर अपडेट से पहले और बाद में।
pre_update_expटोकन के इनिशियलाइज़ेशन और अंतिम दर अपडेट के बीच के समय के लिए चक्रवृद्धि ब्याज वृद्धि (compound interest growth) की गणना करता है।- यह उस अवधि के दौरान औसत दर (
pre_update_average_rate) को सेकंड में बीते हुए समय (elapsed time) से गुणा करता है।
- यह न्यूमरेटर (numerator) को इन दोनों से विभाजित करता है:
- एक वर्ष में सेकंड की संख्या (
SECONDS_PER_YEAR) ताकि समय को सेकंड से वर्षों में बदला जा सके, और - स्थिरांक (constant)
ONE_IN_BASIS_POINTS(जो 10,000 के बराबर है) ताकि दर को बेसिस पॉइंट्स से दशमलव में बदला जा सके।
- एक वर्ष में सेकंड की संख्या (
- अंत में, यह
exponent.exp()की गणना करता है जो उस अवधि के लिए निरंतर वृद्धि कारक (continuous growth factor) (एक्सपोनेंट की घात पर यूलर की संख्या) है। इसे गणितीय रूप से के रूप में दर्शाया जाता है।
- यह उस अवधि के दौरान औसत दर (
post_update_expसमान गणना करता है लेकिन वर्तमान दर (current_rate) और सबसे हाल के अपडेट के बाद से बीते हुए समय (post_update_timespan) का उपयोग करता है।
नीचे Token-2022 कोडबेस से pre_update_exp और post_update_exp फ़ंक्शन्स दिए गए हैं:
pub struct InterestBearingConfig {
/// Authority that can set the interest rate and authority
pub rate_authority: OptionalNonZeroPubkey,
/// Timestamp of initialization, from which to base interest calculations
pub initialization_timestamp: UnixTimestamp,
/// Average rate from initialization until the last time it was updated
pub pre_update_average_rate: BasisPoints,
/// Timestamp of the last update, used to calculate the total amount accrued
pub last_update_timestamp: UnixTimestamp,
/// Current rate, since the last update
pub current_rate: BasisPoints,
}
fn pre_update_exp(&self) -> Option<f64> {
let numerator = (i16::from(self.pre_update_average_rate) as i128)
.checked_mul(self.pre_update_timespan()? as i128)? as f64;
let exponent = numerator / SECONDS_PER_YEAR / ONE_IN_BASIS_POINTS;
Some(exponent.exp())
}
fn post_update_exp(&self, unix_timestamp: i64) -> Option<f64> {
let numerator = (i16::from(self.current_rate) as i128)
.checked_mul(self.post_update_timespan(unix_timestamp)? as i128)? as f64;
let exponent = numerator / SECONDS_PER_YEAR / ONE_IN_BASIS_POINTS;
Some(exponent.exp())
}
fn post_update_timespan(&self, unix_timestamp: i64) -> Option<i64> {
unix_timestamp.checked_sub(self.last_update_timestamp.into())
}
सटीक चक्रवृद्धि ब्याज की गणना करने के लिए—चाहे दर बदली हो या नहीं—इंटरेस्ट-बियरिंग एक्सटेंशन total_scale फ़ंक्शन का उपयोग करता है।
यह pre_update_exp और post_update_exp के परिणामों को गुणा करता है, जो क्रमशः अंतिम दर अपडेट से पहले और बाद के वृद्धि कारकों का प्रतिनिधित्व करते हैं।
गुणनफल (product) दोनों समय खंडों (time segments) में कुल घातीय वृद्धि कारक (exponential growth factor) देता है।
अंत में, total_scale फ़ंक्शन मान को टोकन की मानक सटीकता (standard precision) में स्केल करने के लिए परिणाम को 10^decimals से विभाजित करता है। उदाहरण के लिए, SOL टोकन में 9 दशमलव (decimals) होते हैं, इसलिए pre_update_exp और post_update_exp का परिणाम 10^9 से विभाजित होगा।
total_scale का परिणामी मान वह स्केलिंग फैक्टर (scaling factor) है जिसे निरंतर कंपाउंडिंग ब्याज को सटीक रूप से प्रदर्शित करने के लिए ऑन-चेन बैलेंस पर लागू किया जाता है।
fn total_scale(&self, decimals: u8, unix_timestamp: i64) -> Option<f64> {
Some(
self.pre_update_exp()? * self.post_update_exp(unix_timestamp)?
/ 10_f64.powi(decimals as i32),
)
}
दूसरे शब्दों में, इंटरेस्ट-बियरिंग एक्सटेंशन में प्रत्येक ब्याज गणना का परिणामी मान मूलधन और total_scale का गुणनफल होता है।
इंटरेस्ट-बियरिंग एक्सटेंशन आंतरिक रूप से फॉर्मूले को कैसे लागू करता है
यहाँ तीन महत्वपूर्ण फ़ील्ड्स हैं जो इस गणना को आंतरिक रूप से संभव बनाते हैं:
pre_update_average_rate: अंतिम दर अपडेट तक संचयी वृद्धि कारक (cumulative growth factor) (सूत्र से एक्सपोनेंट) को संग्रहीत करता है। हमारे उदाहरण में, 3 महीने के बाद यह0.03 × 0.25 = 0.0075को कैप्चर करता है।last_update_timestamp: सटीक समय को चिह्नित करता है जब अंतिम दर अपडेट हुआ था। उदाहरण में, यह 3-महीने के निशान पर टाइमस्टैम्प है।current_rate: वर्तमान में लागू ब्याज दर। उदाहरण में, यह 3 महीने के बाद0.03से स्विच होकर0.05हो जाता है।
जब कोई वॉलेट या प्रोग्राम बैलेंस को क्वेरी करता है, तो इंटरेस्ट-बियरिंग एक्सटेंशन फॉर्मूले का इस प्रकार पुनर्निर्माण (reconstruct) करता है:
यह उसी के समतुल्य है जो हमारे पास total_scale फ़ंक्शन में है जिसका उल्लेख हमने पहले किया था:
fn total_scale(&self, decimals: u8, unix_timestamp: i64) -> Option<f64> {
Some(
self.pre_update_exp()? * self.post_update_exp(unix_timestamp)?
/ 10_f64.powi(decimals as i32),
)
}
UI डिस्प्ले बैलेंस कन्वर्जन फ़ंक्शन्स
इंटरेस्ट-बियरिंग एक्सटेंशन two functions को उजागर करता है जिनका उपयोग वॉलेट और ऐप लगातार ऑफ-चेन बैलेंस प्रदर्शित करने के लिए करते हैं:
- कच्चे (raw) अमाउंट को UI अमाउंट में बदलने वाला फ़ंक्शन (
amount_to_ui_amount), जो पहले अर्जित ब्याज (टोकन राशि * कुल स्केल) की गणना करता है, फिर दी गई दशमलव सटीकता के साथ परिणाम को स्ट्रिंग में फॉर्मेट करता है और अनावश्यक शून्यों को हटा देता है।
/// Convert a raw amount to its UI representation using the given decimals
/// field. Excess zeroes or unneeded decimal point are trimmed.
pub fn amount_to_ui_amount(
&self,
amount: u64,
decimals: u8,
unix_timestamp: i64,
) -> Option<String> {
let scaled_amount_with_interest =
(amount as f64) * self.total_scale(decimals, unix_timestamp)?;
let ui_amount = format!("{scaled_amount_with_interest:.*}", decimals as usize);
Some(trim_ui_amount_string(ui_amount, decimals))
}
- और
try_ui_amount_into_amount, जो एक UI बैलेंस (जिसमें कंप्यूटेड ब्याज शामिल है) को वापस कच्चे अमाउंट (बिना ब्याज के) में परिवर्तित करता है जिसका आंतरिक रूप से उपयोग किया जाता है। यहाँ इंटरेस्ट-बियरिंग स्रोत कोड में मूल कार्यान्वयन दिया गया है।
/// Try to convert a UI representation of a token amount to its raw amount
/// using the given decimals field
pub fn try_ui_amount_into_amount(
&self,
ui_amount: &str,
decimals: u8,
unix_timestamp: i64,
) -> Result<u64, ProgramError> {
let scaled_amount = ui_amount
.parse::<f64>()
.map_err(|_| ProgramError::InvalidArgument)?;
let amount = scaled_amount
/ self
.total_scale(decimals, unix_timestamp)
.ok_or(ProgramError::InvalidArgument)?;
if amount > (u64::MAX as f64) || amount < (u64::MIN as f64) || amount.is_nan() {
Err(ProgramError::InvalidArgument)
} else {
// this is important, if you round earlier, you'll get wrong "inf"
// answers
Ok(amount.round() as u64)
}
}
उपरोक्त फ़ंक्शन्स (amount_to_ui_amount और try_ui_amount_into_amount) ऑन-चेन निष्पादित (executed) नहीं होते हैं। वे क्लाइंट-साइड हेल्पर्स हैं जिन्हें Rust SDK में लागू किया गया है (और TypeScript SDK में भी मिरर किया गया है)।
वॉलेट कम्पैटिबिलिटी (Wallet compatibility)
Token-2022 एक्सटेंशन अभी तक Solana इकोसिस्टम में वॉलेट्स द्वारा व्यापक रूप से समर्थित नहीं हैं। चूंकि एक इंटरेस्ट-बियरिंग टोकन का ऑन-चेन बैलेंस कभी नहीं बदलता है, इसलिए उपयोगकर्ता के बैलेंस को प्रदर्शित करने से पहले एक वॉलेट को मिंट पर इंटरेस्ट-बियरिंग एक्सटेंशन का पता लगाना चाहिए और कंपाउंडिंग फॉर्मूला लागू करना चाहिए। इस लॉजिक के बिना, वॉलेट हमेशा कच्ची मूलधन राशि (raw principal amount) दिखाएगा और अर्जित वृद्धि (accrued growth) को अनदेखा कर देगा।
इस अंतर का अर्थ है कि दो वॉलेट एक ही खाते को अलग-अलग परिणामों के साथ प्रदर्शित कर सकते हैं: एक केवल ऑन-चेन संग्रहीत निश्चित राशि दिखा रहा है, दूसरा एक्सटेंशन फ़ील्ड्स से प्राप्त निरंतर कंपाउंडिंग बैलेंस दिखा रहा है। जब तक वॉलेट्स Token-2022 एक्सटेंशन को शामिल करने के लिए अपने अकाउंट रेंडरिंग को अपडेट नहीं करते हैं, तब तक इंटरेस्ट-बियरिंग टोकन पर निर्भर एप्लिकेशन को अक्सर बैलेंस की गणना और प्रदर्शन स्वयं करना होगा।
निष्कर्ष
इस लेख के दौरान, हमने चर्चा की है कि इंटरेस्ट-बियरिंग टोकन एक्सटेंशन कैसे काम करता है, यह ऑन-चेन बैलेंस अपडेट या आवधिक (periodic) वितरण लेनदेन की आवश्यकता के बिना सीधे टोकन मिंट स्तर पर यील्ड का प्रतिनिधित्व करने का एक तरीका कैसे पेश करता है।
हमने इस बात पर भी चर्चा की कि कैसे सभी उपार्जन (accruals) ऑफ-चेन एक नियतात्मक सूत्र (deterministic formula) के माध्यम से होते हैं, जिससे सिस्टम कुशल बनता है और साथ ही उपयोगकर्ताओं को बढ़ते बैलेंस का अनुभव भी मिलता है।
डिस्प्ले के पीछे का गणित यह सुनिश्चित करता है कि अर्जित ब्याज सही ढंग से कंपाउंड होता है, और वॉलेट एकीकरण (integrations) बैलेंस को सुसंगत (consistent) रखने के लिए प्रदान किए गए कार्यों पर भरोसा कर सकते हैं।
वॉलेट और एक्सप्लोरर्स में समर्थन अभी भी सीमित है, इसलिए फिलहाल इस सुविधा को अपनाने वाले एप्लिकेशन को बैलेंस सही ढंग से प्रदर्शित करने की जिम्मेदारी लेनी चाहिए।
यह लेख tutorial series on Solana का एक हिस्सा है।