स्टोरेज स्पेस आवंटित करते समय, भुगतानकर्ता को प्रति आवंटित बाइट के लिए एक निश्चित संख्या में SOL का भुगतान करना होता है।
Solana इसे “rent” (किराया) कहता है। यह नाम थोड़ा भ्रामक है क्योंकि इसका मतलब यह लगता है कि हर महीने टॉप-अप की आवश्यकता है, लेकिन हमेशा ऐसा नहीं होता। एक बार rent का भुगतान हो जाने के बाद, दो साल बीत जाने पर भी किसी और भुगतान की आवश्यकता नहीं होती है। जब दो साल का rent चुका दिया जाता है, तो अकाउंट को “rent exempt” माना जाता है।
यह नाम इस तथ्य से आता है कि Solana शुरुआत में बाइट्स प्रति वर्ष के आधार पर अकाउंट्स से शुल्क लेता था। यदि आपने केवल आधे साल के लिए ही rent दिया है, तो आपका अकाउंट छह महीने बाद मिटा दिया जाता था। यदि आपने दो साल का rent एडवांस में चुका दिया, तो अकाउंट “rent exempt” हो जाता था। इसके बाद अकाउंट को कभी भी rent नहीं देना पड़ता था। आजकल, सभी अकाउंट्स का rent-exempt होना अनिवार्य है; आप 2 साल से कम का rent नहीं दे सकते।
हालांकि rent की गणना “प्रति बाइट” के आधार पर की जाती है, फिर भी शून्य डेटा वाले अकाउंट मुफ्त नहीं होते; Solana को अभी भी उन्हें इंडेक्स करना होता है और उनके बारे में मेटाडेटा स्टोर करना होता है।
जब अकाउंट्स इनिशियलाइज़ किए जाते हैं, तो आवश्यक rent की गणना बैकग्राउंड में हो जाती है; आपको अलग से rent कैलकुलेट करने की आवश्यकता नहीं है।
हालांकि, आप यह अनुमान लगाने में सक्षम होना चाहेंगे कि स्टोरेज की कीमत कितनी होगी ताकि आप अपने एप्लिकेशन को ठीक से डिज़ाइन कर सकें।
यदि आप एक त्वरित अनुमान चाहते हैं, तो कमांड लाइन में solana rent <number of bytes> रन करने से आपको तुरंत उत्तर मिल जाएगा:

जैसा कि पहले बताया गया है, शून्य बाइट्स आवंटित करना मुफ्त नहीं है:

आइए देखें कि इस शुल्क की गणना कैसे की जाती है।
Anchor Rent Module हमें rent से संबंधित कुछ स्थिरांक (constants) देता है:
ACCOUNT_STORAGE_OVERHEAD: इस constant का मान 128 (बाइट्स) है और जैसा कि नाम से पता चलता है, एक खाली अकाउंट में 128 बाइट्स का ओवरहेड होता है।DEFAULT_EXEMPTION_THRESHOLD: इस constant का मान 2.0 (float 64) है और यह इस तथ्य को दर्शाता है कि दो साल का rent एडवांस में देने पर अकाउंट आगे rent देने से मुक्त हो जाता है।DEFAULT_LAMPORTS_PER_BYTE_YEAR: इस constant का मान 3,480 है जिसका अर्थ है कि प्रत्येक बाइट के लिए प्रति वर्ष 3,480 lamports की आवश्यकता होती है। चूंकि हमें दो साल के बराबर भुगतान करना अनिवार्य है, इसलिए प्रत्येक बाइट की लागत 6,960 lamports होगी।
नीचे दिया गया Rust प्रोग्राम प्रिंट करता है कि एक खाली अकाउंट की लागत कितनी होगी। ध्यान दें कि परिणाम ऊपर दिए गए solana rent 0 के स्क्रीनशॉट से मेल खाता है:
use anchor_lang::prelude::*;
use anchor_lang::solana_program::rent as rent_module;
declare_id!("BfMny1VwizQh89rZtikEVSXbNCVYRmi6ah8kzvze5j1S");
#[program]
pub mod rent {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let cost_of_empty_acc = rent_module::ACCOUNT_STORAGE_OVERHEAD as f64 *
rent_module::DEFAULT_LAMPORTS_PER_BYTE_YEAR as f64 *
rent_module::DEFAULT_EXEMPTION_THRESHOLD;
msg!("cost to create an empty account: {}", cost_of_empty_acc);
// 890880
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}
यदि हम यह गणना करना चाहते हैं कि एक गैर-खाली अकाउंट की लागत कितनी होगी, तो हम खाली अकाउंट की लागत में बाइट्स की संख्या को बस इस प्रकार जोड़ देते हैं:
use anchor_lang::prelude::*;
use anchor_lang::solana_program::rent as rent_module;
declare_id!("BfMny1VwizQh89rZtikEVSXbNCVYRmi6ah8kzvze5j1S");
#[program]
pub mod rent {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let cost_of_empty_acc = rent_module::ACCOUNT_STORAGE_OVERHEAD as f64 *
rent_module::DEFAULT_LAMPORTS_PER_BYTE_YEAR as f64 *
rent_module::DEFAULT_EXEMPTION_THRESHOLD;
msg!("cost to create an empty account: {}", cost_of_empty_acc);
// 890,880 lamports
let cost_for_32_bytes = cost_of_empty_acc +
32 as f64 *
rent_module::DEFAULT_LAMPORTS_PER_BYTE_YEAR as f64 *
rent_module::DEFAULT_EXEMPTION_THRESHOLD;
msg!("cost to create a 32 byte account: {}", cost_for_32_bytes);
// 1,113,600 lamports
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}
फिर से ध्यान दें कि इस प्रोग्राम का आउटपुट कमांड लाइन पर आने वाले आउटपुट से मेल खाता है।
ETH के साथ स्टोरेज लागत की तुलना
इस लेख को लिखते समय, ETH का मूल्य लगभग $2,425 है। एक नया अकाउंट इनिशियलाइज़ करने में 22,100 gas का खर्च आता है, इसलिए 15 gwei की gas लागत मानकर हम 32 बाइट्स की gas लागत $0.80 कैलकुलेट कर सकते हैं।
वर्तमान में, Solana की कीमत $90 / SOL है, इसलिए 32 बाइट स्टोरेज को इनिशियलाइज़ करने के लिए 1,113,600 lamports का भुगतान करने पर $0.10 की लागत आएगी।
हालांकि, ETH का मार्केट कैपिटलाइज़ेशन SOL से 7.5 गुना अधिक है, इसलिए यदि SOL का मार्केट कैपिटलाइज़ेशन ETH के समान होता, तो SOL की वर्तमान कीमत $675 होती, और 32 बाइट स्टोरेज की लागत $0.75 होती।
Solana में एक स्थायी मुद्रास्फीति (inflation) मॉडल है जो अंततः प्रति वर्ष 1.5% तक सीमित हो जाएगा, इसलिए यह इस तथ्य को दर्शाने में मदद करेगा कि मूर के नियम (Moore’s Law) के अनुसार समय के साथ स्टोरेज सस्ता होता जाता है, जो कहता है कि समान लागत के लिए ट्रांजिस्टर घनत्व हर 18 महीने में दोगुना हो जाता है।
याद रखें, बाइट्स से क्रिप्टो में परिवर्तन प्रोटोकॉल में सेट किए गए constants हैं जिन्हें हार्ड फोर्क (hard fork) किसी भी समय बदल सकता है।
2 साल के rent exempt थ्रेशोल्ड से कम बैलेंस वाले अकाउंट्स को तब तक कम किया जाता है जब तक कि अकाउंट डिलीट न हो जाए
एक उपयोगकर्ता के वॉलेट अकाउंट के धीरे-धीरे “खाली” होने का एक काफी हास्यपूर्ण Reddit थ्रेड यहां पढ़ा जा सकता है: https://www.reddit.com/r/solana/comments/qwin1h/my_sol_balance_in_the_wallet_is_decreasing/
इसका कारण यह है कि वॉलेट rent exception थ्रेशोल्ड से नीचे था, और Solana रनटाइम rent का भुगतान करने के लिए अकाउंट बैलेंस को धीरे-धीरे कम कर रहा है।
यदि rent exempt थ्रेशोल्ड से कम बैलेंस होने के कारण कोई वॉलेट डिलीट हो जाता है, तो उसे अधिक SOL भेजकर “पुनर्जीवित” (resurrect) किया जा सकता है, लेकिन यदि अकाउंट में डेटा स्टोर था, तो वह डेटा खो जाएगा।
साइज़ की सीमाएँ
जब हम किसी अकाउंट को इनिशियलाइज़ करते हैं, तो हम 10,240 बाइट्स से अधिक साइज़ इनिशियलाइज़ नहीं कर सकते।
अभ्यास (Exercise): एक बुनियादी स्टोरेज इनिशियलाइज़ेशन प्रोग्राम बनाएं और space=10241 सेट करें। यह सीमा से 1 बाइट अधिक है। आपको निम्न प्रकार की त्रुटि (error) दिखाई देनी चाहिए:

अकाउंट का साइज़ बदलना
यदि आपको अकाउंट का साइज़ बढ़ाने की आवश्यकता है, तो हम realloc मैक्रो (macro) का उपयोग कर सकते हैं। यह तब उपयोगी हो सकता है जब अकाउंट एक वेक्टर स्टोर कर रहा हो और उसे अधिक स्पेस की आवश्यकता हो। इसका एक उदाहरण increase_account_size फ़ंक्शन और IncreaseAccountSize context struct में है जो साइज़ को 1,000 बाइट्स बढ़ा देता है (नीचे दिए गए कोड में बड़े अक्षरों में लिखा गया कमेंट देखें):
use anchor_lang::prelude::*;
use std::mem::size_of;
declare_id!("GLKUcCtHx6nkuDLTz5TNFrR4tt4wDNuk24Aid2GrDLC6");
#[program]
pub mod basic_storage {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
Ok(())
}
pub fn increase_account_size(ctx: Context<IncreaseAccountSize>) -> Result<()> {
Ok(())
}
}
#[derive(Accounts)]
pub struct IncreaseAccountSize<'info> {
#[account(mut,
// ***** 1,000 BYTE INCREMENT IS OVER HERE *****
realloc = size_of::<MyStorage>() + 8 + 1000,
realloc::payer = signer,
realloc::zero = false,
seeds = [],
bump)]
pub my_storage: Account<'info, MyStorage>,
#[account(mut)]
pub signer: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init,
payer = signer,
space=size_of::<MyStorage>() + 8,
seeds = [],
bump)]
pub my_storage: Account<'info, MyStorage>,
#[account(mut)]
pub signer: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[account]
pub struct MyStorage {
x: u64,
}
अकाउंट का साइज़ बढ़ाते समय, यदि आप नहीं चाहते कि अकाउंट का डेटा मिटे, तो realloc::zero = false (ऊपर दिए गए कोड में) सेट करना सुनिश्चित करें। यदि आप चाहते हैं कि अकाउंट डेटा को पूरी तरह से शून्य पर सेट किया जाए, तो realloc::zero = true का उपयोग करें। आपको टेस्ट को बदलने की आवश्यकता नहीं है। मैक्रो आपके लिए यह सब बैकग्राउंड में संभाल लेगा।
अभ्यास (Exercise): टेस्ट में एक अकाउंट इनिशियलाइज़ करें, फिर increase_account_size फ़ंक्शन को कॉल करें। कमांड लाइन में solana account <addr> के साथ अकाउंट का साइज़ देखें। आपको यह स्थानीय वैलिडेटर (local validator) के साथ करना होगा ताकि अकाउंट बना रहे।
अधिकतम Solana अकाउंट साइज़
प्रति realloc अधिकतम अकाउंट साइज़ वृद्धि 10240 है। Solana में किसी अकाउंट का अधिकतम साइज़ 10 MB हो सकता है।
एक प्रोग्राम को डिप्लॉय करने की लागत का अनुमान लगाना
किसी Solana प्रोग्राम को डिप्लॉय करने की अधिकांश लागत बाइटकोड को स्टोर करने के लिए rent का भुगतान करने से आती है। बाइटकोड को anchor deploy से लौटाए गए एड्रेस से एक अलग अकाउंट में स्टोर किया जाता है।
नीचे दिया गया स्क्रीनशॉट दिखाता है कि यह जानकारी कैसे प्राप्त की जाए:

एक साधारण hello world प्रोग्राम को डिप्लॉय करने में वर्तमान में 2.47 SOL से थोड़ा अधिक खर्च आता है। Anchor फ्रेमवर्क का उपयोग करने के बजाय रॉ (raw) Rust कोड लिखकर इस लागत को काफी कम किया जा सकता है, लेकिन हम तब तक ऐसा करने की अनुशंसा नहीं करते जब तक कि आप उन सभी सुरक्षा जोखिमों (security risks) को पूरी तरह से नहीं समझ लेते जिन्हें Anchor डिफ़ॉल्ट रूप से समाप्त कर देता है।
RareSkills के साथ और जानें
अधिक जानने के लिए हमारा Solana developer course देखें।
मूल रूप से 28 फरवरी, 2024 को प्रकाशित