دليل عملي لإنشاء عقود NFT باستخدام Hardhat وSolidity
إذا كنت تعمل في تطوير الويب وتعتمد كثيرًا على JavaScript، فقد تبدو بيئة تطوير Solidity معقّدة في البداية. لكن مع ظهور Hardhat أصبحت تجربة بناء العقود الذكية أكثر سلاسة ووضوحًا، خصوصًا عند تطوير مشاريع NFT. في هذا الدليل العملي، ستتعرّف على طريقة إعداد مشروع جديد، وكتابة عقد بسيط، ثم تجميعه واختباره وتصحيحه، وأخيرًا نشره على الشبكة المحلية.
الهدف من هذا المقال هو مساعدتك على فهم أساسيات العمل مع Hardhat في مشروع حقيقي ومباشر، دون التعمق في تفاصيل صياغة Solidity أو منهجيات الاختبار المتقدمة. وإذا كنت تجيد كتابة JavaScript، فستتمكن من متابعة الخطوات بسهولة.
لماذا يُعد Hardhat خيارًا ممتازًا لتطوير عقود NFT؟
يمنحك Hardhat بيئة تطوير حديثة تركّز على الإنتاجية وسهولة التصحيح. وهو مفيد بشكل خاص عند بناء عقود Ethereum الذكية للأسباب التالية:
- إعداد سريع للمشروع.
- دعم قوي لعمليات التجميع والاختبار.
- إمكانية استخدام
console.log()داخل عقودSolidityلأغراض التصحيح. - سهولة النشر على الشبكات المحلية أو الاختبارية أو الرئيسية.
- تكامل ممتاز مع مكتبات مثل
ethers.jsوOpenZeppelin.
إعداد مشروع Hardhat من الصفر
بدء مشروع npm
ابدأ أولًا بإنشاء مشروع جديد باستخدام npm:
npm init --yes
تثبيت حزمة Hardhat
بعد ذلك ثبّت الحزمة الأساسية الخاصة بـ Hardhat:
npm install --save-dev hardhat
إنشاء مشروع Hardhat جديد
شغّل الأمر التالي لإنشاء المشروع:
npx hardhat
اختر الخيار الخاص بإنشاء ملف إعداد فارغ hardhat.config.js.

سيُنشئ ذلك ملف hardhat.config.js في المجلد الرئيسي للمشروع. يمكنك ضبط إصدار مترجم Solidity كما يلي:
/**
* @type import('Hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.7.3",
};
كتابة عقد NFT باستخدام ERC721
إنشاء مجلد العقود
أنشئ مجلدًا باسم contracts ثم ملف العقد:
mkdir contracts && cd contracts && touch MyCryptoLions.sol
تثبيت مكتبة OpenZeppelin
بدلًا من بناء معيار ERC721 من الصفر، من الأفضل الاعتماد على مكتبات موثوقة ومجرّبة مثل OpenZeppelin:
npm install --save-dev @openzeppelin/contracts
كود العقد الذكي
فيما يلي عقد NFT بسيط يرث من ERC721:
pragma solidity ^0.7.3;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyCryptoLions is ERC721 {
constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
}
يبدأ أي ملف Solidity عادةً بتحديد إصدار المترجم. بعد ذلك نستورد عقد ERC721 من مكتبة OpenZeppelin. ثم نعرّف عقدًا جديدًا باسم MyCryptoLions يرث خصائص معيار NFT الجاهزة.
يحتوي العقد هنا على constructor فقط، وهو الجزء الذي يُنفَّذ عند نشر العقد. وتُمرَّر إليه قيمتا name وsymbol ليتم تمريرهما بدورهما إلى عقد ERC721. هاتان القيمتان تحددان اسم الرمز غير القابل للاستبدال واختصاره.
تجميع العقد والتحقق من نجاح البناء
بعد كتابة العقد، نفّذ أمر التجميع التالي:
npx hardhat compile
قد تظهر بعض التنبيهات، لكن ما يهمنا هنا هو ظهور رسالة نجاح التجميع. كذلك ستلاحظ إنشاء مجلدين مثل artifacts وcache. يحتوي مجلد artifacts على ملفات مهمّة مثل abi التي تُستخدم لاحقًا عند ربط العقد مع الواجهة الأمامية.
اختبار عقد NFT محليًا
اختبار العقود الذكية خطوة أساسية، لأن أي خطأ فيها قد يكون مكلفًا جدًا، خصوصًا أنها غالبًا تتعامل مع أصول رقمية أو منطق مالي يصعب تعديله بعد النشر.
تثبيت حزم الاختبار
ثبّت الأدوات المطلوبة للاختبار:
npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
وظيفة هذه الحزم باختصار:
ethereum-waffle: إطار لاختبار العقود الذكية.chai: مكتبة لإجراء عمليات التحقق والمقارنات.ethers: مكتبةJavaScriptللتفاعل مع شبكةEthereum.@nomiclabs/hardhat-ethersو@nomiclabs/hardhat-waffle: إضافات تربط الأدوات السابقة بـHardhat.
إعداد مجلد الاختبارات
أنشئ مجلد test ثم ملف الاختبار:
mkdir test && cd test && touch test.js
وأضف السطر التالي إلى ملف hardhat.config.js حتى تصبح إضافة ethers متاحة داخل المشروع:
require("@nomiclabs/hardhat-ethers");
مثال على اختبار بسيط
const { expect } = require("chai");
describe("MyCryptoLions", function () {
it("Should return the right name and symbol", async function () {
const MyCryptoLions = await hre.ethers.getContractFactory("MyCryptoLions");
const myCryptoLions = await MyCryptoLions.deploy("MyCryptoLions", "MCL");
await myCryptoLions.deployed();
expect(await myCryptoLions.name()).to.equal("MyCryptoLions");
expect(await myCryptoLions.symbol()).to.equal("MCL");
});
});
يقوم هذا الاختبار بنشر العقد على شبكة Hardhat المحلية، ثم يتحقق من أن قيمتي name وsymbol تطابقان ما تم تمريره عند النشر.
لتشغيل الاختبار، استخدم الأمر:

npx hardhat test
إذا مرّ الاختبار بنجاح، فهذا يعني أن الإعداد الأساسي للعقد والمشروع يعمل كما ينبغي.
تصحيح العقود الذكية باستخدام console.log()
من الميزات القوية جدًا في Hardhat إمكانية استخدام console.log() داخل كود Solidity أثناء التطوير. هذه الميزة تسهّل تتبّع القيم الداخلية وفهم سلوك العقد دون الحاجة إلى وسائل تصحيح معقدة.
إضافة أدوات التصحيح إلى العقد
عد إلى ملف العقد وأضف الاستيراد التالي:
pragma solidity ^0.7.3;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "hardhat/console.sol";
contract MyCryptoLions is ERC721 {
constructor(string memory name, string memory symbol) ERC721(name, symbol) {
console.log("name", name);
console.log("symbol", symbol);
console.log("msg.sender", msg.sender);
// msg.sender هو عنوان الجهة التي قامت بنشر العقد أول مرة
}
}
بعد ذلك شغّل الاختبارات مرة أخرى:
npx hardhat test
سيُعاد تجميع العقد ثم ستظهر القيم المسجّلة في الطرفية، ما يمنحك رؤية أوضح أثناء التصحيح.

تدعم هذه الميزة مجموعة محددة من أنواع البيانات مثل:
uintstringbooladdress
ورغم هذا القيد البسيط، فإنها كافية جدًا في كثير من سيناريوهات التطوير اليومي.
نشر عقد NFT على الشبكة المحلية
بعد الانتهاء من الكتابة والتجميع والاختبار، تأتي مرحلة النشر. في هذا المثال سننشر العقد على النسخة المحلية داخل الذاكرة من شبكة Hardhat Network، لأنها مناسبة للتجارب السريعة وسهلة الاستخدام.
إنشاء سكربت النشر
أنشئ مجلد scripts ثم ملف deploy.js:
mkdir scripts && cd scripts && touch deploy.js
كود النشر
async function main() {
const MyCryptoLions = await hre.ethers.getContractFactory("MyCryptoLions");
const myCryptoLions = await MyCryptoLions.deploy("MyCryptoLions", "MCL");
await myCryptoLions.deployed();
console.log("MyCryptoLions deployed to:", myCryptoLions.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
ينشئ هذا السكربت نسخة من مصنع العقد عبر getContractFactory()، ثم ينشر العقد مع تمرير قيم name وsymbol، وبعد اكتمال النشر يطبع عنوان العقد.
ويُفضّل إزالة تعليمات console.log() من عقد Solidity قبل النشر في البيئات التي لا تحتاج إلى تصحيح.
تشغيل أمر النشر
نفّذ الأمر التالي:
npx hardhat run scripts/deploy.js
وقد تحصل على نتيجة مشابهة لما يلي:
MyCryptoLions deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
بهذا يكون عقد NFT قد نُشر بنجاح على الشبكة المحلية. ويمكنك لاحقًا توجيه نفس السكربت إلى أي شبكة أخرى حسب الإعدادات الموجودة في ملف hardhat.config.js.
ماذا بعد نشر العقد؟
بعد نجاح النشر، يمكنك الانتقال إلى مراحل أكثر تقدمًا مثل:
- إضافة دوال لسكّ الرموز
mint. - ربط العقد بواجهة أمامية باستخدام
abiوethers.js. - تخزين البيانات الوصفية الخاصة بالرموز
metadata. - النشر على شبكة اختبارية مثل
Goerliأو شبكة رئيسية لاحقًا. - التحقق من العقد عبر منصات الاستكشاف مثل
Etherscan.
مزايا إضافية تجعل Hardhat أداة قوية
لا يقتصر دور Hardhat على التجميع والاختبار فقط، بل يوفّر مزايا متقدمة مفيدة للمطورين المحترفين، منها:
- رسائل أخطاء أوضح وتتبع أفضل للمشكلات.
- دعم أكثر من إصدار لمترجم
Solidity. - إمكانات قوية لمحاكاة الشبكة الرئيسية
Mainnet Forking. - تكامل ممتاز مع
TypeScript. - مرونة عالية في إعدادات الشبكات والنشر.
الخلاصة التقنية
يُعد Hardhat من أفضل بيئات تطوير العقود الذكية للمبتدئين والمحترفين على حد سواء، لأنه يختصر كثيرًا من التعقيد المرتبط بتطوير Solidity. وعند دمجه مع مكتبات موثوقة مثل OpenZeppelin وأدوات مثل ethers.js، يصبح بناء مشروع NFT أكثر تنظيمًا وأمانًا وقابلية للتوسع. إذا كنت تبحث عن نقطة انطلاق عملية لإنشاء عقود NFT واختبارها ونشرها محليًا، فإن هذا المسار باستخدام Hardhat يُعد خيارًا ذكيًا واحترافيًا.