मुख्य सामग्री पर जाएं
इन पर काम करता है: Virtual Environments और सार्वजनिक नेटवर्क (mainnets और testnets)। समान plugin दोनों को संभालता है; hardhat.config.ts में इसे सही नेटवर्क पर इंगित करें।
Tenderly-Hardhat plugin, Hardhat से deploy किए गए contracts को Virtual Environments या सार्वजनिक नेटवर्क्स के विरुद्ध सत्यापित करता है। हर deploy पर सत्यापित करने के लिए automatic verification का उपयोग करें, या अपने scripts से स्पष्ट रूप से tenderly.verify() कॉल करने के लिए manual verification का उपयोग करें।
सार्वजनिक नेटवर्क्स पर, plugin डिफ़ॉल्ट रूप से सार्वजनिक रूप से सत्यापित करता है। निजी रूप से सत्यापित करने के लिए (केवल आपके प्रोजेक्ट/organization के अंदर दिखाई देने के लिए), hardhat.config.ts में privateVerification: true सेट करें। Configure authentication and verification visibility देखें।

संस्करण और अनुकूलता

Hardhat के साथ आप जिस Ethers संस्करण का उपयोग कर रहे हैं, उसके आधार पर, आपको Tenderly-Hardhat plugin का संबंधित संस्करण download करना होगा।
Ethers 6 पर switch करने और Tenderly-Hardhat plugin के latest संस्करण का उपयोग करने की अत्यधिक अनुशंसा की जाती है security और performance कारणों के साथ-साथ अतिरिक्त सुविधाओं के लिए।
आपका stackHardhat संस्करणTenderly-Hardhat plugin संस्करण
Ethers 6+ Hardhat Ignition के साथ>=2.19.0 <=2.22.0@tenderly/hardhat-tenderly@^2.3.0
Ethers 6+ hardhat-verify के साथ>=2.19.0 <=2.22.0@tenderly/hardhat-tenderly@^2.2.1
Ethers 5+ hardhat-verify के साथ< 2.19.0@tenderly/hardhat-tenderly@1.8.0

सत्यापन विधियाँ

Tenderly-Hardhat plugin contract सत्यापन के लिए तीन तरीकों का समर्थन करता है।
  • स्वचालित सत्यापन (अनुशंसित): बस plugin को import करें और सेट अप करें। यह विधि deployment के दौरान सत्यापन के लिए आदर्श है क्योंकि यह प्रक्रिया पूरी तरह से स्वचालित है। स्वचालित सत्यापन plain hardhat deployment सेटअप के साथ-साथ hardhat-ignition का उपयोग करके भी काम करता है। TENDERLY_AUTOMATIC_VERIFICATION environment variable का उपयोग करके स्वचालित सत्यापन को नियंत्रित करें।
  • Manual verification (low-code): आपके code के भीतर एक स्पष्ट सत्यापन चरण प्रदान करता है, जो post-deployment verification, conditional verification (जैसे केवल failing test के बाद), या factory contracts के instances को सत्यापित करने जैसे परिदृश्यों के लिए उपयोगी है।
  • Verbose manual verification (high-code): सत्यापन प्रक्रिया पर विस्तृत नियंत्रण प्रदान करता है, library addresses, source codes, और compiler configurations को निर्दिष्ट करता है। यह विभिन्न compiler संस्करणों या settings के साथ कई contracts को सत्यापित करने के लिए आवश्यक है।

उदाहरण

स्वचालित सत्यापन प्रक्रिया का पता लगाने का सबसे अच्छा तरीका एक उदाहरण से गुजरना है, जो आप हमारे GitHub repo में कर सकते हैं। सभी उदाहरण sample Greeter contract का उपयोग करते हैं। उदाहरण projects को सीधे browse करें:

Tenderly-Hardhat plugin सेटअप

Tenderly-Hardhat plugin को install और initialize करने के लिए नीचे दिए गए चरणों का पालन करें।
1
Install करें
2
Tenderly-Hardhat plugin को install करें और इसे dependency के रूप में जोड़ें।
3
Ethers 6 (plugin v2.x)
yarn add -D @tenderly/hardhat-tenderly@^2.2.2
Ethers 5 (plugin v1.x)
yarn add -D @tenderly/hardhat-tenderly@^1.8.0
4
Tenderly CLI में Log करें
5
Plugin आपको Tenderly CLI में login होने की आवश्यकता होती है।
6
macOS
curl https://raw.githubusercontent.com/Tenderly/tenderly-cli/master/scripts/install-macos.sh | sudo sh
Linux
curl https://raw.githubusercontent.com/Tenderly/tenderly-cli/master/scripts/install-linux.sh | sudo sh
7
यह जांचने के लिए कि क्या आप पहले से ही logged in हैं, इस command का उपयोग करें:
8
tenderly whoami
9
Log in करने के लिए, चलाएँ:
10
tenderly login
11
Initialize करें
12
Tenderly-Hardhat package को अपनी hardhat.config.ts या hardhat.config.js फ़ाइल में एक साधारण import statement के साथ शामिल करें और setup method को कॉल करें।
13
सुनिश्चित करें कि @tenderly/hardhat-tenderly को अन्य packages जैसे कि @nomicfoundation/hardhat-toolbox, @nomiclabs/hardhat-ethers, @openzeppelin/hardhat-upgrades और इसी तरह के अन्य के बाद import करें।
14
संस्करण 2.4.0 और 1.10.0 तक, plugin को initialize करने के लिए tdly.setup() कॉल करना आवश्यक था:
tdly.setup({automaticVerifications: !!process.env.TENDERLY_AUTOMATIC_VERIFICATION});
15


const config: HardhatUserConfig = {
solidity: "0.8.19",
};

export default config;
16
Authentication और verification visibility को configure करें
17
आपको account जानकारी और verification visibility पास करके Tenderly को configure करना होगा।
18
  • privateVerification parameter सुनिश्चित करता है कि आपका सोर्स कोड केवल आपके प्रोजेक्ट के collaborators या organization को दिखाई दे।
  • Verification visibility को environment variable TENDERLY_PUBLIC_VERIFICATION सेट करके भी नियंत्रित किया जा सकता है।
  • 19
    hardhat.config.ts फ़ाइल में निम्नलिखित code snippet जोड़कर Tenderly को configure करें:
    20
    
    
    const config: HardhatUserConfig = {
    solidity: "0.8.19",
    tenderly: {
    username: "Your account slug" ?? "error",
    project: "Your project slug",
    
    // Contract visible only in Tenderly.
    // Omitting or setting to `false` makes it visible to the whole world.
    // Alternatively, configure verification visibility using
    // an environment variable `TENDERLY_PUBLIC_VERIFICATION`.
    privateVerification: process.env.TENDERLY_PUBLIC_VERIFICATION !== 'true',
    },
    };
    
    export default config;
    
    21
    अपनी deployment सेट अप करें
    22
    Tenderly-Hardhat plugin के आपके Hardhat project में सेट अप होने के साथ, आप विभिन्न development और production नेटवर्क्स पर deploy किए गए contracts को सत्यापित कर सकते हैं:
    23
  • सार्वजनिक mainnets या testnets Node RPC के माध्यम से
  • development, staging, और demoing के लिए Virtual Environments
  • 24
    hardhat-ignition के साथ काम करते समय सत्यापन को सक्षम करने के लिए, etherscan configuration निर्दिष्ट करें। apiUrl के लिए verification URL का उपयोग करें: $TENDERLY_VIRTUAL_TESTNET_RPC/verify/etherscan
    25
    With Hardhat Ignition
    hardhat.config.ts
    
    const config: HardhatUserConfig = {
    solidity: "0.8.19",
    networks: {
    mainnet_base: {
    url: "https://base.gateway.tenderly.co",
    chainId: 8453
    },
    tenderly_base_testnet: {
    // your Tenderly Virtual Environment RPC
    url: "https://virtual.base.rpc.tenderly.co/872ac073-1de1-4422-b01d-8d057781d77d",
    chainId: 888
    }
    },
    tenderly: {
    username: "Your account slug",
    project: "Your project slug",
    
    // Mainnet contract verification visible only in Tenderly.
    // Omitting or setting to `false` makes it visible to the whole world.
    // Alternatively, configure verification visibility using
    // an environment variable `TENDERLY_PUBLIC_VERIFICATION`.
    privateVerification: process.env.TENDERLY_PUBLIC_VERIFICATION !== 'true',
    },
    etherscan:{
    apiKey: "YOUR_API_KEY",
    customChains: [
    {
    network: "tenderly_base_testnet",
    chainId: 888,
    urls:{
    apiURL: `https://virtual.base.rpc.tenderly.co/872ac073-1de1-4422-b01d-8d057781d77d/verify/etherscan`,
    browserURL: "https://virtual.base.rpc.tenderly.co/872ac073-1de1-4422-b01d-8d057781d77d"
    }
    }
    ]
    },
    };
    
    export default config;
    
    Standard setup
    hardhat.config.ts
    
    
    const config: HardhatUserConfig = {
    solidity: "0.8.19",
    networks: {
    mainnet_base: {
    url: "https://base.gateway.tenderly.co",
    chainId: 8453
    },
    tenderly_base_testnet: {
    // your Tenderly Virtual Environment RPC
    url: "https://virtual.base.rpc.tenderly.co/872ac073-1de1-4422-b01d-8d057781d77d",
    chainId: 888
    }
    },
    tenderly: {
    username: "Your account name",
    project: "Your project name",
    
    // Mainnet contract verification visible only in Tenderly.
    // Omitting or setting to `false` makes it visible to the whole world.
    // Alternatively, configure verification visibility using
    // an environment variable `TENDERLY_PUBLIC_VERIFICATION`.
    privateVerification: process.env.TENDERLY_PUBLIC_VERIFICATION !== 'true',
    },
    };
    
    export default config;
    
    निम्नलिखित अनुभागों में, आप विभिन्न सत्यापन विधियों का उपयोग करके contracts को सत्यापित करना सीखेंगे।

    स्वचालित सत्यापन

    स्वचालित सत्यापन तब निर्बाध रूप से होता है जब आप Ethers.js का उपयोग करके एक contract को deploy करते हैं। स्वचालित सत्यापन दृष्टिकोण compiler settings, deploy किए गए contract के address, और सोर्स कोड को इकट्ठा करने के बाद स्वचालित रूप से सत्यापन करेगा। स्वचालित सत्यापन को सक्षम या अक्षम करने के लिए, plugin द्वारा पहचाने जाने वाले TENDERLY_AUTOMATIC_VERIFICATION environment variable का उपयोग करें। Tenderly-Hardhat plugin contracts को तब सत्यापित करेगा जब वह पता लगाता है कि contract deploy किया गया है, और Ethers को deployment transaction की receipt मिल गई है। इसे सक्षम करने के लिए, आपको Ethers की helper methods ethers.deployContract() और ethers.getContractFactory() का उपयोग करके contracts deploy करते समय deployment के लिए await करने की आवश्यकता होती है, contract instance पर क्रमशः waitForDeployment() या deployed() को कॉल करके।
    यदि आप उस contract के साथ interact करने का इरादा रखते हैं तो आपको waitForDeployment() (Ethers 6) और deployed() (Ethers 5) द्वारा लौटाए गए contract object के reference को capture करने की आवश्यकता है।
    1
    deployment script को Modify करें
    2
    Ethers 6
    waitForDeployment() से लौटाए गए मान को capture करने के लिए Hardhat script को Modify करें।
    deploy.ts
    
    export async function main() {
    console.log("🖖🏽[ethers] Deploying and Verifying Greeter in Tenderly");
    
    -   const greeter = await ethers.deployContract("Greeter", ["Hello, Hardhat!"]);
    +   let greeter = await ethers.deployContract("Greeter", ["Hello, Hardhat!"]);
    
    -   await greeter.waitForDeployment();
    +   greeter = await greeter.waitForDeployment();
    
    const greeterAddress = await greeter.getAddress();
    console.log("{Greeter} deployed to", greeterAddress);
    }
    
    main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
    });
    
    अधिक कॉम्पैक्ट रूप में:
    const greeter = await (
    await ethers.deployContract("Greeter", ["Hello, Hardhat!"])
    ).waitForDeployment();
    
    Ethers 5
    स्वचालित सत्यापन प्रक्रिया कैसे काम करती है, यह जानने का सबसे अच्छा तरीका हमारे GitHub repo में एक उदाहरण से गुजरना है।यह उदाहरण हमारे sample Greeter contract का उपयोग करता है।deployed() से लौटाए गए मान को capture करने के लिए Hardhat script को Modify करें।
    deploy.ts
    
    export async function main() {
    console.log("🖖🏽[ethers] Deploying and Verifying Greeter in Tenderly");
    
    const Greeter = await ethers.getContractFactory("Greeter");
    
    -   const greeter = await Greeter.deploy("Hello, Hardhat!");
    +   let greeter = await Greeter.deploy("Hello, Hardhat!");
    
    -   await greeter.deployed();
    +   greeter = await greeter.deployed();
    
    const greeterAddress = await greeter.address;
    console.log("{Greeter} deployed to", greeterAddress);
    }
    
    main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
    });
    
    अधिक कॉम्पैक्ट रूप में:
    const greeter = await (
    await Greeter.deploy("Hello, Hardhat!")
    ).deployed();
    
    3
    script चलाएँ
    4
    Hardhat scripts चलाते समय, आप प्रति-रन आधार पर स्वचालित सत्यापन को सक्षम करने के लिए TENDERLY_AUTOMATIC_VERIFICATION environment variable को true पर सेट कर सकते हैं।
    5
    नीचे दिए गए commands के साथ script चलाएँ। सत्यापित contract का link Terminal output में प्रदर्शित होगा।
    6
    Hardhat Ignition (Virtual Environment)
    TENDERLY_AUTOMATIC_VERIFICATION=true \
    npx hardhat ignition deploy ./ignition/modules/Lock.ts --network virtual_base --deployment-id deploy-to-virtual-base
    
    command चलाते समय एक specific value के साथ --deployment-id जोड़ना सुनिश्चित करें।
    Hardhat (Virtual Environment)
    TENDERLY_AUTOMATIC_VERIFICATION=true \
    npx hardhat run scripts/deploy.ts --network virtual_base
    
    Public network
    किसी सार्वजनिक mainnet या testnet पर deploy करते समय, यह निर्दिष्ट करें कि आप सार्वजनिक या निजी सत्यापन चाहते हैं। सुनिश्चित करें कि आपका hardhat.config.ts tenderly अनुभाग में इस env variable को पढ़ता है।
    TENDERLY_PUBLIC_VERIFICATION=true \ # Verify publicly. Omit to verify privately.
    TENDERLY_AUTOMATIC_VERIFICATION=true \
    npx hardhat run scripts/deploy.ts --network mainnet_base
    

    Proxy contracts का सत्यापन

    hardhat-upgrades के साथ deploy और upgrade किए गए proxy contracts का स्वचालित सत्यापन @tenderly/hardhat-tenderly package के निम्नलिखित संस्करणों के साथ संभव है:
    • >= 1.10.0
    • >= 2.1.0
    संस्करण 1.x.x < 1.10.0 और 2.x.x < 2.1.0 के लिए proxy verification guide का पालन करें।

    Manual सत्यापन

    tenderly.verify() के माध्यम से low-code सत्यापन आपको एक deployment script या Hardhat test के भीतर सत्यापन के सटीक बिंदु के बारे में स्पष्ट होने की अनुमति देता है। यह विधि विशेष रूप से इनके लिए फायदेमंद है:
    • Custom scripts के माध्यम से पहले deploy किए गए contracts को सत्यापित करना।
    • Factory contracts द्वारा बनाए गए instances को सत्यापित करना।
    • Test runs को बढ़ाना, failing suite (after) के अंत में contracts को चुनिंदा रूप से सत्यापित करना, जो execution को तेज़ करता है।
    सत्यापन को manually नियंत्रित करने के लिए, scripts चलाते समय TENDERLY_AUTOMATIC_VERIFICATION को false में बदलकर स्वचालित सत्यापन को अक्षम करें।

    verify function

    verify() function एक object लेता है जहाँ आपको यह प्रदान करना होगा:
    • contract का name
    • address जहाँ contract deploy किया गया है
    • contract द्वारा उपयोग की जाने वाली libraries (वैकल्पिक)
    Tenderly-Hardhat plugin आपके द्वारा निर्दिष्ट contracts के सत्यापन को करने के लिए मौजूदा compiler configuration और contract source code को उठा लेगा।
    Contract deploy होने के बाद verify() को invoke करना आवश्यक है।यदि आप deployment के साथ सत्यापन कर रहे हैं, तो आपको Ethers 6 के मामले में waitForDeployment() के लिए, और Ethers 5 के मामले में deployed() के लिए await करना होगा।
    let greeter = await ethers.deployContract("Greeter", ["Hello, Hardhat!"]);
    greeter = await greeter.waitForDeployment();
    
    await tenderly.verify({
      name: 'Greeter',
      address: await greeter.getAddress(),
      libraries: {
        AwsomeLib: "0x...",
      }
    });
    
    यदि आप कई contracts सत्यापित कर रहे हैं, तो function में variadic arguments हैं:
    let greeter = await ethers.deployContract("Greeter", ["Hello, Hardhat!"]);
    greeter = await greeter.waitForDeployment();
    
    const counter = (await ethers.deployContract("Counter", [42])).waitForDeployment();
    
    await tenderly.verify(
      {
        name: 'Greeter',
        address: await greeter.getAddress(),
      },
      {
        name: 'Counter',
        address: await counter.getAddress(),
        libraries: {
            KickAssLib: "0x...",
        }
      },
    );
    
    1
    hardhat.config.ts में स्वचालित mode को अक्षम करें
    2
    यदि आप स्वचालित सत्यापन को बंद करना पसंद करते हैं:
    3
    
    - tdly.setup();
    + tdly.setup({automaticVerifications: false});
    
    const config: HardhatUserConfig = {
    
    4
    deployment script को Modify करें
    5
    यह स्वचालित सत्यापन में समान उदाहरणों का उपयोग करता है, लेकिन इस बार contract को सत्यापित करने के लिए tenderly.verify() method के साथ।
    6
    Ethers 6
    deploy.ts
        + import { tenderly } from "hardhat";
    
        async function main() {
        console.log("🖖🏽[ethers] Deploying and Verifying Greeter in Tenderly");
    
        -   const greeter = await ethers.deployContract("Greeter", ["Hello, Manual Hardhat!",]);
        +   let greeter = await ethers.deployContract("Greeter", ["Hello, Manual Hardhat!",]);
    
        -   await greeter.waitForDeployment();
        +   greeter = await greeter.waitForDeployment();
    
        const address = await greeter.getAddress();
        console.log("Manual Simple: {Greeter} deployed to:", address);
    
        +    await tenderly.verify({
        +        address,
        +        name: "Greeter",
        +    });
      }
    
        main().catch((error) => {
        console.error(error);
        process.exitCode = 1;
      });
    
    Ethers 5
    deploy.ts
        + import { tenderly } from "hardhat";
    
        async function main() {
        console.log("🖖🏽[ethers] Deploying and Verifying Greeter in Tenderly");
    
        const Greeter = await ethers.getContractFactory("Greeter");
    
        -   const greeter = await Greeter.deploy("Hello, Manual Hardhat!");
        +   let greeter = await Greeter.deploy("Hello, Manual Hardhat!");
    
        -   await greeter.deployed();
        +   greeter = await greeter.deployed();
    
        const address = await greeter.address;
        console.log("Manual Simple: {Greeter} deployed to:", address);
    
        await tenderly.verify({
        address,
        name: "Greeter",
      });
      }
    
        main().catch((error) => {
        console.error(error);
        process.exitCode = 1;
      });
    
    7
    script चलाएँ
    8
    Hardhat scripts चलाते समय, आप स्वचालित सत्यापन को अक्षम करने के लिए TENDERLY_AUTOMATIC_VERIFICATION environment variable को false पर सेट कर सकते हैं।
    9
    Virtual Environment
    TENDERLY_AUTOMATIC_VERIFICATION=false \
    npx hardhat run scripts/deploy.ts --network virtual_base
    
    Public network
    किसी सार्वजनिक mainnet या testnet पर deploy करते समय, यह निर्दिष्ट करें कि आप सार्वजनिक या निजी सत्यापन चाहते हैं।
    TENDERLY_PUBLIC_VERIFICATION=false \ # Omit or set to true to verify publicly.
    TENDERLY_AUTOMATIC_VERIFICATION=false \
    npx hardhat run scripts/deploy.ts --network mainnet_base
    

    Verbose manual सत्यापन

    Method verifyMultiCompilerAPI() आपको सत्यापन प्रक्रिया पर पूर्ण नियंत्रण देती है, जिससे आप सत्यापन प्रक्रिया के हर विवरण को निर्दिष्ट कर सकते हैं। यह शायद ही कभी अनुशंसित है, लेकिन यदि आप विभिन्न compiler संस्करणों या configurations के साथ compile किए गए contracts को सत्यापित कर रहे हैं तो उपयोगी हो सकता है। पूरी तरह से नियंत्रित सत्यापन विधि आपको स्पष्ट रूप से यह करने की अनुमति देती है:
    • Contracts के सोर्स कोड को निर्दिष्ट करें (sources)
    • Compilation arguments सेट करें (compiler)
    • Linked libraries सेट करें (libraries)
    निम्नलिखित उदाहरण दर्शाता है कि पूरी तरह से नियंत्रित सत्यापन कैसे किया जाए।
    await tenderly.verifyMultiCompilerAPI({
      contracts: [
        {
          contractToVerify: 'Greeter',
          sources: {
            'contracts/Greeter.sol': {
              name: 'Greeter',
              code: readFileSync('contracts/Greeter.sol', 'utf-8').toString(),
            },
            'hardhat/console.sol': {
              name: 'console',
              code: readFileSync('node_modules/hardhat/console.sol', 'utf-8').toString(),
            },
          },
          // solidity format compiler with a little modification at libraries param
          compiler: {
            version: '0.8.17',
            settings: {
              optimizer: {
                enabled: true,
                runs: 200,
              },
            },
            libraries: {
              'path/to/lib.sol': {
                addresses: {
                  LibName1: '0x...',
                  LibName2: '0x...',
                },
              },
            },
          },
          networks: {
            [NETWORK_ID]: {
              address: greeterAddress,
            },
          },
        },
      ],
    });
    

    सत्यापन arguments

    verifyMultiCompilerAPI() method एक argument लेती है — contract objects की एक array। प्रत्येक contract object में निम्नलिखित शामिल हैं:
    contractToVerifystringसत्यापित किए जाने वाले contract का नाम। यह Greeter जैसा एक छोटा नाम हो सकता है या contracts/A/Greeter.sol:Greeter जैसा एक पूरी तरह से योग्य contract नाम हो सकता है।
    sourcesmapcontract को compile करने के लिए आवश्यक सभी sources का एक map। map की key contract का source path है, जबकि value name और UTF-8-encoded contract source वाला एक object है। js sources: { 'contracts/Greeter.sol': { name: 'Greeter', code: readFileSync('contracts/Greeter.sol', 'utf-8').toString(), }, 'hardhat/console.sol': { name: 'console', code: readFileSync('node_modules/hardhat/console.sol', 'utf-8').toString(), }, },
    networksmapकई नेटवर्क्स पर सभी deployment addresses वाला एक map। js { networks: { [NETWORK_ID]: { address: greeterAddress, }, }, }
    librariesmaplibraries के deployments के बारे में जानकारी वाला एक map। key contracts folder के सापेक्ष library source का सापेक्ष path है। js compiler.settings.libraries = { "path/to/lib.sol": { addresses: { "LibName1": "0x...", "LibName2": "0x..." } } }