# OpenZeppelin Contracts — Solidity के लिए Standard Library
जब आप smart contracts बना रहे हों, तो आपको wheel को reinvent नहीं करना चाहिए। OpenZeppelin Contracts industry-standard library है जो common patterns के secure, audited, और gas-optimized implementations provide करती है। ERC20 tokens से लेकर access control, upgradeable contracts से लेकर security utilities तक, OpenZeppelin हजारों production contracts की foundation है जो billions of dollars को secure करती हैं।
OpenZeppelin Contracts क्या है?
OpenZeppelin Contracts, Ethereum और EVM-compatible chains के लिए reusable smart contract components की एक open-source library है। OpenZeppelin द्वारा developed और maintained, हर contract है:
- Audited multiple security firms द्वारा
- Battle-tested major protocols द्वारा production में
- Gas-optimized efficiency के लिए
- Well-documented comprehensive guides के साथ
- Actively maintained security updates के साथ
Library modular है — केवल वही उपयोग करें जो आपको चाहिए और small, focused components से contracts compose करें।
Installation
npm का उपयोग करना
npm install @openzeppelin/contracts
Foundry का उपयोग करना
forge install OpenZeppelin/openzeppelin-contracts
foundry.toml में add करें:
[dependencies]
openzeppelin-contracts = "5.2.0"
अपने Contracts में Import करें
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
Solidity package को node_modules में find करता है।
Token Standards
ERC20 — Fungible Tokens
ERC20, fungible tokens (cryptocurrencies, stablecoins, governance tokens) के लिए standard है।
Basic ERC20 Token:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
_mint(msg.sender, initialSupply);
}
}
बस इतना ही! अब आपके पास एक fully functional ERC20 token है:
totalSupply()
balanceOf(address)
transfer(address, uint256)
approve(address, uint256)
transferFrom(address, address, uint256)
allowance(address, address)
Minting और Burning add करना:
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Ownable {
constructor() ERC20("MyToken", "MTK") Ownable(msg.sender) {}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
function burn(uint256 amount) public {
_burn(msg.sender, amount);
}
}
Pausable add करना:
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Pausable, Ownable {
constructor() ERC20("MyToken", "MTK") Ownable(msg.sender) {}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
function _update(address from, address to, uint256 value)
internal
override
whenNotPaused
{
super._update(from, to, value);
}
}
ERC721 — Non-Fungible Tokens (NFTs)
ERC721, unique, non-fungible tokens (NFTs) के लिए standard है।
Basic NFT:
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyNFT is ERC721, Ownable {
uint256 private _tokenIdCounter;
constructor() ERC721("MyNFT", "MNFT") Ownable(msg.sender) {}
function mint(address to) public onlyOwner {
uint256 tokenId = _tokenIdCounter++;
_safeMint(to, tokenId);
}
}
Metadata URI add करना:
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract MyNFT is ERC721URIStorage, Ownable {
uint256 private _tokenIdCounter;
constructor() ERC721("MyNFT", "MNFT") Ownable(msg.sender) {}
function mint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _tokenIdCounter++;
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
}
Enumerable add करना:
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
contract MyNFT is ERC721Enumerable, Ownable {
constructor() ERC721("MyNFT", "MNFT") Ownable(msg.sender) {}
// अब आपको मिलता है:
// - totalSupply()
// - tokenByIndex(uint256 index)
// - tokenOfOwnerByIndex(address owner, uint256 index)
}
ERC1155 — Multi-Token Standard
ERC1155 एक single contract में fungible और non-fungible दोनों tokens को support करता है।
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyMultiToken is ERC1155, Ownable {
uint256 public constant GOLD = 0;
uint256 public constant SILVER = 1;
uint256 public constant SWORD = 2;
constructor() ERC1155("https://game.example/api/item/{id}.json") Ownable(msg.sender) {}
function mint(address to, uint256 id, uint256 amount) public onlyOwner {
_mint(to, id, amount, "");
}
function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts) public onlyOwner {
_mintBatch(to, ids, amounts, "");
}
}
Access Control
Ownable — Single Owner
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyContract is Ownable {
constructor() Ownable(msg.sender) {}
function restrictedFunction() public onlyOwner {
// केवल owner इसे call कर सकता है
}
function transferOwnership(address newOwner) public override onlyOwner {
super.transferOwnership(newOwner);
}
}
AccessControl — Role-Based Access
Multi-role systems (admin, minter, pauser, etc.) के लिए:
import "@openzeppelin/contracts/access/AccessControl.sol";
contract MyToken is AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MINTER_ROLE, msg.sender);
}
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
function pause() public onlyRole(PAUSER_ROLE) {
_pause();
}
}
Ownable2Step — Safer Ownership Transfer
गलत address में accidental ownership transfer को रोकता है:
import "@openzeppelin/contracts/access/Ownable2Step.sol";
contract MyContract is Ownable2Step {
constructor() Ownable(msg.sender) {}
// Owner transferOwnership(newOwner) को call करता है
// नए owner को confirm करने के लिए acceptOwnership() call करना होगा
}
Security Utilities
ReentrancyGuard — Reentrancy Attacks को रोकें
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract Bank is ReentrancyGuard {
mapping(address => uint256) public balances;
function withdraw(uint256 amount) public nonReentrant {
require(balances[msg.sender] >= amount);
balances[msg.sender] -= amount;
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
}
}
nonReentrant modifier execution के दौरान reentrant calls को रोकता है।
Pausable — Emergency Stop
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyContract is Pausable, Ownable {
constructor() Ownable(msg.sender) {}
function criticalFunction() public whenNotPaused {
// Paused होने पर इसे call नहीं किया जा सकता
}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
}
SafeERC20 — Safe Token Transfers
कुछ tokens ERC20 standard को correctly follow नहीं करते (USDT bool return नहीं करता)। SafeERC20 इन edge cases को handle करता है:
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract Vault {
using SafeERC20 for IERC20;
function deposit(IERC20 token, uint256 amount) public {
token.safeTransferFrom(msg.sender, address(this), amount);
// Transfer fail होने पर revert करता है, भले ही token bool return न करे
}
}
Upgradeable Contracts
OpenZeppelin proxy pattern का उपयोग करके सभी contracts के upgradeable versions provide करता है।
Installation
npm install @openzeppelin/contracts-upgradeable @openzeppelin/hardhat-upgrades
Upgradeable ERC20
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
contract MyTokenUpgradeable is Initializable, ERC20Upgradeable, OwnableUpgradeable {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize(uint256 initialSupply) public initializer {
__ERC20_init("MyToken", "MTK");
__Ownable_init(msg.sender);
_mint(msg.sender, initialSupply);
}
}
Key differences:
*Upgradeableversions से inherit करें
constructor()की जगहinitialize()का उपयोग करें
- Initializer में
__ContractName_init()को call करें
- Constructor में initializers को disable करें
Upgradeable Contracts को Deploy करना
Hardhat के साथ:
const { ethers, upgrades } = require("hardhat");
async function main() {
const MyToken = await ethers.getContractFactory("MyTokenUpgradeable");
const token = await upgrades.deployProxy(MyToken, [1000000], {
initializer: "initialize"
});
await token.waitForDeployment();
console.log("Token deployed to:", await token.getAddress());
}
Upgrading:
const MyTokenV2 = await ethers.getContractFactory("MyTokenUpgradeableV2");
const upgraded = await upgrades.upgradeProxy(proxyAddress, MyTokenV2);
Utilities
Cryptography
ECDSA signature verification:
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
contract SignatureVerifier {
using ECDSA for bytes32;
using MessageHashUtils for bytes32;
function verify(address signer, bytes32 messageHash, bytes memory signature) public pure returns (bool) {
bytes32 ethSignedHash = messageHash.toEthSignedMessageHash();
address recoveredSigner = ethSignedHash.recover(signature);
return recoveredSigner == signer;
}
}
Merkle proofs:
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract Whitelist {
bytes32 public merkleRoot;
constructor(bytes32 _merkleRoot) {
merkleRoot = _merkleRoot;
}
function claim(bytes32[] calldata proof) public {
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
require(MerkleProof.verify(proof, merkleRoot, leaf), "Invalid proof");
// Access grant करें
}
}
Counters (Deprecated, native uint256 का उपयोग करें)
पुराने versions में, Counters को auto-incrementing IDs के लिए उपयोग किया जाता था। Modern Solidity यह natively कर सकता है:
contract NFT {
uint256 private _tokenIdCounter; // Counters से सस्ता
function mint() public {
uint256 tokenId = _tokenIdCounter++;
_safeMint(msg.sender, tokenId);
}
}
Math Utilities
import "@openzeppelin/contracts/utils/math/Math.sol";
contract Calculator {
function average(uint256 a, uint256 b) public pure returns (uint256) {
return Math.average(a, b); // Overflow को रोकता है
}
function sqrt(uint256 x) public pure returns (uint256) {
return Math.sqrt(x);
}
}
Best Practices
1. Latest Stable Version का उपयोग करें
npm install @openzeppelin/contracts@latest
Releases को github.com/OpenZeppelin/openzeppelin-contracts/releases पर check करें
2. जो Import करते हैं उसे समझें
Blindly contracts को inherit न करें। Behavior को समझने के लिए source code पढ़ें, विशेष रूप से:
- Tokens में
_update()hooks
- Virtual functions जिन्हें आप override कर सकते हैं
- Internal functions जिन्हें आप call कर सकते हैं
3. सावधानी से Override करें
Functions को override करते समय, हमेशा super को call करें:
function _update(address from, address to, uint256 value) internal override {
super._update(from, to, value); // Parent implementation को call करें
// आपका custom logic
}
4. Compose करें, Modify न करें
OpenZeppelin code को modify करने की जगह, contracts को compose करें:
// Good
contract MyToken is ERC20, Ownable, Pausable {
// Existing contracts को compose करें
}
// Bad - OZ internals को modify करना
contract MyToken is ERC20 {
function transfer() public override {
// Transfer logic को rewrite करना = खतरनाक
}
}
5. Updates के लिए Check करें
OpenZeppelin security advisories को subscribe करें और regularly update करें।
Wizard — Visually Contracts Generate करें
OpenZeppelin Contracts Wizard ready-to-deploy contracts generate करता है:
wizard.openzeppelin.com पर visit करें
Wizard perfect है:
- यह सीखने के लिए कि कौन से contracts को combine करें
- नए projects को bootstrap करने के लिए
- Contract composition को समझने के लिए
Conclusion
OpenZeppelin Contracts secure smart contract development की foundation है। Battle-tested, audited implementations का leverage करके, आप common vulnerabilities से बचते हैं और अपने unique business logic पर focus कर सकते हैं। Simple tokens से लेकर complex governance systems तक, OpenZeppelin आपको वे building blocks provide करता है जो आपको चाहिए।
Confidence के साथ building शुरू करें — OpenZeppelin Contracts install करें और library को explore करें। फिर Solingo के smart contract challenges के साथ अपनी skills को sharp करें ताकि secure development patterns में master बन सकें।
अगले steps:
- OpenZeppelin का उपयोग करके अपना पहला ERC20 token deploy करें
- Multi-role systems के लिए AccessControl pattern को explore करें
- Upgradeable contracts और proxy pattern के बारे में सीखें
- docs.openzeppelin.com पर OpenZeppelin documentation पढ़ें