इस ट्यूटोरियल में हम anchor के पर्दे के पीछे देखेंगे कि एक Solana प्रोग्राम कैसे डिप्लॉय किया जाता है।
आइए उस टेस्ट फाइल पर नज़र डालें जिसे anchor हमारे लिए बनाता है जब हम anchor init deploy_tutorial चलाते हैं:
describe("deploy_tutorial", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
const program = anchor.workspace.DeployTutorial as Program<DeployTutorial>;
it("Is initialized!", async () => {
// Add your test here.
const tx = await program.methods.initialize().rpc();
console.log("Your transaction signature", tx);
});
});
इसके द्वारा जनरेट किया गया स्टार्टर प्रोग्राम जाना-पहचाना लगना चाहिए:
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod deploy_tutorial {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}
ऊपर दिया गया प्रोग्राम कहाँ और कब डिप्लॉय किया जाता है?
टेस्ट फाइल में केवल एक ही संभावित जगह है जहाँ कॉन्ट्रैक्ट डिप्लॉय किया जा सकता था, और वह यह लाइन है:
const program = anchor.workspace.DeployTutorial as Program<DeployTutorial>;
लेकिन इसका कोई मतलब नहीं बनता, क्योंकि हम उम्मीद करेंगे कि यह एक async फ़ंक्शन होगा।
Anchor बैकग्राउंड में चुपचाप प्रोग्राम को डिप्लॉय कर रहा है।
Solana प्रोग्राम्स में कंस्ट्रक्टर नहीं होते हैं
यह उन लोगों को असामान्य लग सकता है जो अन्य ऑब्जेक्ट-ओरिएंटेड भाषाओं से आ रहे हैं। Rust में ऑब्जेक्ट या क्लास नहीं होते हैं।
एक Ethereum स्मार्ट कॉन्ट्रैक्ट में, एक कंस्ट्रक्टर स्टोरेज को कॉन्फ़िगर कर सकता है या बाइटकोड और इम्यूटेबल वेरिएबल्स सेट कर सकता है।
तो वास्तव में “डिप्लॉयमेंट स्टेप” कहाँ है?
(यदि आप अभी भी Solana वैलिडेटर और Solana लॉग्स चला रहे हैं, तो हम सुझाव देते हैं कि आप दोनों टर्मिनलों को रीस्टार्ट और क्लियर करें)
आइए सामान्य सेटअप करें। program-deploy नामक एक नया Anchor प्रोजेक्ट बनाएं, और सुनिश्चित करें कि वैलिडेटर और लॉग्स अन्य शेल में चल रहे हैं।
anchor test चलाने के बजाय, टर्मिनल में निम्नलिखित कमांड चलाएँ:
anchor deploy

ऊपर दिए गए लॉग्स के स्क्रीनशॉट में, हम वह बिंदु देख सकते हैं जहाँ प्रोग्राम डिप्लॉय किया गया था।
अब यहाँ दिलचस्प बात है। anchor deploy को फिर से चलाएँ:

प्रोग्राम को उसी एड्रेस पर डिप्लॉय किया गया था, लेकिन इस बार इसे डिप्लॉय नहीं किया गया, बल्कि अपग्रेड (upgraded) किया गया था।
प्रोग्राम आईडी नहीं बदली है, प्रोग्राम ओवरराइट हो गया है।
Solana प्रोग्राम डिफ़ॉल्ट रूप से म्यूटेबल (mutable) होते हैं
यह उन Ethereum डेवलपर्स के लिए एक झटके के रूप में आ सकता है जहाँ इम्यूटेबिलिटी (immutability) को मान लिया जाता है।
अगर ऑथर इसे आसानी से बदल सकता है तो किसी प्रोग्राम का क्या मतलब है? एक Solana प्रोग्राम को इम्यूटेबल बनाना संभव है। यह माना जाता है कि ऑथर पहले म्यूटेबल वर्ज़न को डिप्लॉय करेगा, और समय बीतने के बाद जब कोई बग नहीं मिलेगा, तो वे इसे इम्यूटेबल के रूप में फिर से डिप्लॉय करेंगे।
कार्यात्मक रूप से, यह एक एडमिनिस्ट्रेटर-नियंत्रित प्रॉक्सी से अलग नहीं है जहाँ ओनर (owner) बाद में ज़ीरो एड्रेस के लिए ओनरशिप छोड़ देता है। लेकिन तर्कसंगत रूप से, Solana मॉडल बहुत अधिक साफ-सुथरा है क्योंकि Ethereum प्रॉक्सी के साथ बहुत कुछ गलत हो सकता है।
इसका एक और निहितार्थ: Solana में delegatecall नहीं होता है, क्योंकि इसे इसकी आवश्यकता नहीं है।
Solidity कॉन्ट्रैक्ट्स में delegatecall का मुख्य उपयोग एक नए इम्प्लीमेंटेशन कॉन्ट्रैक्ट को delegatecalls जारी करके प्रॉक्सी कॉन्ट्रैक्ट की कार्यक्षमता को अपग्रेड करने में सक्षम होना है। हालाँकि, चूँकि Solana में किसी प्रोग्राम के बाइटकोड को अपग्रेड किया जा सकता है, इसलिए इम्प्लीमेंटेशन कॉन्ट्रैक्ट्स को delegatecalling करने की कोई आवश्यकता नहीं है।
एक और परिणाम: Solana में उस तरह के इम्यूटेबल वेरिएबल नहीं होते हैं जैसे Solidity उन्हें समझता है (ऐसे वेरिएबल जो केवल कंस्ट्रक्टर में सेट किए जा सकते हैं)।
प्रोग्राम को फिर से डिप्लॉय किए बिना टेस्ट चलाना
चूँकि anchor डिफ़ॉल्ट रूप से प्रोग्राम को फिर से डिप्लॉय करता है, आइए दिखाएं कि बिना रीडिप्लॉय किए टेस्ट कैसे चलाए जाएं।
टेस्ट को बदलकर निम्नलिखित करें:
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import fs from 'fs'
let idl = JSON.parse(fs.readFileSync('target/idl/deployed.json', 'utf-8'))
describe("deployed", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
// Change this to be your programID
const programID = "6p29sM4hEK8ZFT5AvsGJQG5nKUtHBKs13iVL6juo5Uqj";
const program = new Program(idl, programID, anchor.getProvider());
it("Is initialized!", async () => {
// Add your test here.
const tx = await program.methods.initialize().rpc();
console.log("Your transaction signature", tx);
});
});
टेस्ट चलाने से पहले, हम सुझाव देते हैं कि Solana लॉग्स के टर्मिनल को क्लियर करें और solana-test-validator को रीस्टार्ट करें।
अब, इसके साथ टेस्ट चलाएँ:
anchor test --skip-local-validator --skip-deploy
अब लॉग्स टर्मिनल को देखें:

हम देखते हैं कि initialize इंस्ट्रक्शन निष्पादित किया गया था, लेकिन प्रोग्राम को न तो डिप्लॉय किया गया और न ही अपग्रेड किया गया, क्योंकि हमने anchor test के साथ --skip-deploy आर्ग्यूमेंट का उपयोग किया था।
अभ्यास (Exercise): यह देखने के लिए कि प्रोग्राम का बाइटकोड वास्तव में बदल गया है, दो कॉन्ट्रैक्ट्स डिप्लॉय करें जो अलग-अलग msg! वैल्यूज़ प्रिंट करते हैं। विशेष रूप से,
- lib.rs में
initializeफ़ंक्शन को अपडेट करें ताकि उसमें एकmsg!स्टेटमेंट शामिल हो जो लॉग्स में एक स्ट्रिंग लिखता हो। anchor deployanchor test --skip-local-validator --skip-deploy- लॉग किए गए मैसेज को देखने के लिए लॉग चेक करें
- 1 से 4 तक दोहराएं, लेकिन
msg!में स्ट्रिंग को बदलें - सत्यापित करें कि प्रोग्राम आईडी नहीं बदली है
आप देखेंगे कि मैसेज स्ट्रिंग बदल जाती है लेकिन प्रोग्राम आईडी वही रहती है।
सारांश (Summary)
- Solana में कोई कंस्ट्रक्टर नहीं होता, प्रोग्राम “बस डिप्लॉय” किए जाते हैं
- Solana में इम्यूटेबल वेरिएबल नहीं होते हैं
- Solana में delegatecall नहीं होता है, प्रोग्राम्स को “बस अपडेट” किया जा सकता है
RareSkills के साथ और जानें
यह ट्यूटोरियल हमारे मुफ़्त Solana course का हिस्सा है।
मूल रूप से 12 फरवरी, 2024 को प्रकाशित