ربما تكون قد سمعت من قبل أن أي شخص يمكنه إنشاء عملة مشفرة مثل بتكوين أو إيثريوم، بل ربما سمعت أن أغلب العملات المشفرة ما هي إلا توكنات على شبكة الإيثريوم، ولكن هل حقاً الأمر بهذه السهولة؟
في هذه المقالة سنشرح بالتفصيل والخطوات كيف يمكنك إنشاء توكن أو عملة مشفرة خاصة بك على شبكة الإيثريوم باستخدام بروتوكول ERC-20.
الإيثريوم وقفزة الطرح الأولي للعملة
يستخدم الطرح الأولي للعملة كوسيلة لجمع التمويل باستخدام العملات المشفرة. ففي الطرح الأولي للعملة، يتم بيع كمية معينة من العملات المشفرة في صورة "توكنات" (عملات) للمضاربين أو المستثمرين، في مقابل عملة قانونية أو في مقابل عملات مشفرة أخرى مثل البتكوين (BTC) أو الإيثريوم (ETH).
ويتم تسويق التوكنات المباعة باعتبارها وحدات مستقبلية للعملة إذا أو متى نجح الطرح الأولي للعملة في تحقيق هدف التمويل الهادف له وعند إطلاق المشروع.
فتحت العقود الذكية عالماً جديداً تماماً للمطورين لتسمح لهم بالابتكار والتجريب. إلا أن المطورين احتاجوا إلى طريقة جديدة لتمويل مشاريعهم.
وكان الحل هو الطرح الأولي للعملة.
وفي عام 2017، كان الطرح الأولي للعملة مزدهراً، وظهرت العديد من المشاريع بشكل شبه يومي مع وعود حماسية بشأن ما يرغبون في تحقيقه، وتحمس المستثمرون لهم نتيجة لذلك.
خبا الحماس نحو الطرح الأولي للعملات منذ ذلك الوقت مع نضج فضاء العملات المشفرة، واختفى المستثمرون المتحمسون، وفشلت الكثير من الطروحات الأولية للعملات في الوفاء بما وعدت به، إلا أن هذه قصة أخرى، فما نحن بصدده حالياً هو مناقشة الجانب التقني من الأمر.
ما التوكن؟
بشكل جوهري، فالتوكن هو عقد ذكي يتواجد على بلوكتشين الإيثريوم، ويمكن أن تعدد استخداماته ووظائفه.
ولا ينحصر دور التوكن في أداء وظيفة واحدة فقط، فيمكنه القيام بالعديد من الوظائف في النظام الإيكولوجي الأصلي الخاص به. إليكم قائمة من الوظائف التي يمكن للتوكن أن يؤديها.
- الرسوم: يمكن أن تكون التوكن بوابة إلى التطبيق اللامركزي. بشكل أساسي، من أجل ولوج التطبيق اللامركزي، سيتوجب عليك حيازة التوكنات.
- حقوق التصويت: كما يمكن أن تؤهل حيازة التوكنات أصحابها إلى أن يكون لهم حقوق التصويت. يمكن ضرب المثال بتوكن إيوس الذي يؤهلك حيازته إلى التصويت لمنتجي البلوكات. يهدف بلوكتشين إيوس إلى أن يصبح نظام تشغيل لا مركزياً لدعم التطبيقات اللامركزية ذات السعة الكبيرة.
- تبادل القيمة: تعد تلك أحد التطبيقات الأكثر شيوعاً للتوكنات داخل النظام الإيكولوجي. يمكن للتوكنات أن تساعد النظام الاقتصادي الداخلي في التطبيق.
- تحسين تجربة المستخدم: كما تمكن التوكنات حائزيها من إثراء تجربة المستخدمين داخل حدود البيئة الخاصة بالتوكن. فعلى سبيل المثال، ففي متصفح بريف Brave، يحق لأصحاب توكن بات (وهو التوكن المستعمل في المتصفح) أن يثروا تجربة المستخدمين عن طريق استخدام التوكنات من أجل إضافة إعلانات أو الخدمات القائمة على جذب الاهتمام على منصة بريف.
- العملة: يمكن استخدام التوكن كمخزن للقيمة وإجراء المعاملات داخل وخارج النظام الإيكولوجي الخاص به.
ما هو بروتوكول ERC-20؟
الـERC-20 هو معيار تقني يستعمل في العقود الذكية على بلوكتشين الإيثريوم لتنفيذ التوكنات. معظم التوكنات الصادرة في بلوكتشين الإيثريوم متوافقة مع بروتوكول ERC-20.
معيار بروتوكول ERC-20 يحدد بعض القواعد والمعايير لإصدار التوكنات على شبكة الإيثريوم. تعني كلمة ERC-20: Ethereum Request for Comments، بينما يشير رقم 20 إلى رقم الهوية اللازم لتمييز هذا البروتوكول عن باقي البروتوكولات.
من أجل الحفاظ على بساطة الأمور، فإن بروتوكول ERC-20 ما هو إلا دليل إرشادات للقواعد والتنظيمات المستخدمة للمساعدة في إنشاء النسخ الأولية من العقود الذكية المرتكزة على الإيثريوم من أجل إنشاء التوكنات.
فالتوكن على الإيثريوم ليس إلا عقداً ذكياً يتبع بعض القواعد العامة، بشكل أكثر تحديداً، فإنه ينفذ مجموعة معيارية من الوظائف يتشارك فيها مع باقي عقود عقود التوكنات، مثل خاصية TransferFrom (address _from, address _to, uint256 _tokenId) أو BalanceOf (address _owner).
لذا، فإن التوكن ما هو إلا عقد يسجل كم يملك كل شخص من التوكنات، بالإضافة إلى بعض الوظائف التي تتيح لحائزي التوكن نقل توكناتهم إلى عناوين أخرى.
لِمَ يعد بروتوكول ERC-20 مهماً؟
نظراً لتشارك كل توكنات بروتوكول ERC-20 في مجموعة الوظائف بنفس الأسماء، فإنه من الممكن لها أن تتفاعل بنفس الطرق.
يعني ذلك أنه في حال قيامك ببناء تطبيق قادر على التفاعل مع توكن بروتوكول ERC-20، فإنه سيكون قادراً على التفاعل مع أي توكن بروتوكول ERC-20 أيضاً. وبذلك يمكن إضافة المزيد من التوكنات إلى تطبيقك في المستقبل دون الحاجة إلى إعادة كتابة الكود المرجعي الخاص بالتطبيق. يمكنك وضع عنوان عقد التوكن الجديد فحسب، وبذلك يصبح من الممكن لتطبيقك أن يستخدم توكن جديداً.
وتعد منصات التداول أحد الأمثلة على الفكرة السابقة. فعندما تضيف إحدى منصات التداول توكن بروتوكول ERC-20 جديداً، فكل ما تحتاجه هو إضافة عقد ذكي جديد تتفاعل معه. يتسنى بعد ذلك للمستخدمين أن يخبروا العقد برغبتهم في إرسال التوكنات إلى عنوان محفظة منصة التداول، وبدورها ستخبر المنصة العقد بإرسال التوكنات إلى المستخدمين حال إرسالهم طلب سحب.
لا تحتاج المنصة إلى تنفيذ الخطوات السابقة إلا مرة واحدة، وإذا رغبت في إضافة توكن بروتوكول ERC-20 جديد، فإن الأمر لن يتعدى إضافة عنوان العقد الجديد على قاعدة البيانات.
لنبدأ في إنشاء توكن
سنستعمل بيئة التطوير التكاملية ريمكس Remix من أجل تطوير عقد ذكي لتوكن بروتوكول ERC-20 خاصتنا.
تسمح لك ريمكس، وهي أداة متوافرة على الإنترنت، بكتابة عقد ذكي بلغة سوليدتي Solidity، ثم تدشينه وتشغيله.
كل ما عليك فعله هو الذهاب إلى موقع https://remix.etherum.org من المتصفح خاصتك لكي تبدأ بكتابة الكود.
قم بالضغط على زر Solidity، ثم اضغط على علامة + في الركن العلوي إلى اليسار.
سنسمي التوكن خاصتنا في هذا المشروع "بت-تشين توكن"، يمكنك اختيار الاسم الذي ترغب فيه لعملتك المشفرة الخاصة.
والآن أصبح كل شيء جاهزاً.
قواعد توكن بروتوكول ERC-20
تتبع توكنات بروتوكول ERC-20 مجموعة من القوانين لكي يمكن مشاركتها واستبدالها بالتوكنات الأخرى، أو نقلها إلى محفظة العملات المشفرة.
يتكون بروتوكول ERC-20 من 3 قواعد اختيارية، و6 قواعد إجبارية.
لتبسيط الأمر، إذا أردت أن يتضمن العقد الذكي الخاص بالتوكن وظائف معينة، فستصبح ممتثلاً لبروتوكول ERC-20. أما إذا لم تقم بتضمين تلك الخصائص داخل العقد الذكي، فإنك لن تصبح ممتثلاً لبروتوكول ERC-20.
القواعد الإجبارية هي التالي:
- totalSupply العرض الكلي
- BalanceOf رصيد لـ
- Transfer النقل
- TransferFrom النقل من
- Approve الموافقة
- Allowance الحصة
على صعيد آخر، فإن القواعد الاختيارية هي التالي:
- اسم التوكن
- الرمز
- الرقم العشري (حتى 18 رقماً عشرياً)
يشيع تعريف تلك القواعد في الواجهة. لا وجود لما يسمى بالواجهة في سوليديتي، إذ أنها ليست إلا عقد ذكي آخر. ولحسن الحظ، يمكن توارث العقود الذكية في لغة برمجة سوليديتي.
التوارث في سوليديتي
في لغة برمجة سوليديتي، لا يختلف مفهوم التوارث كثيراً عن المفهوم الكلاسيكي للبرمجة الشيئية. ستقوم في البداية بكتابة أساس العقد والتوجيه بأن يرث عقدك الجديد العقد الأساسي الذي قمت بكتابته.
contract IBank { // base contract code... } contract Bank is IBank { // inherited contract code... }
ستحتاج أيضاً لأن تعرف أن سوليديتي تدعم التوارث المتعدد عن طريق نسخ الكود الذي يتضمن الأشكال المتعددة.
كل استدعاءات الدوال افتراضية، وهو ما يعني أن حتّى أكثر الدوال اشتقاقاً يتم استدعاؤها، يستثنى من ذلك الحالة التي يكتب فيها اسم العقد بشكل صريح.
عندما يرث العقد من عقود متعددة، لا ينشأ إلا عقد واحد على البلوكتشين، ويتم نسخ كل الكود البرمجي من العقود القاعدية في العقد المُنشأ على البلوكتشين.
لنعد مجدداً إلى توكن بروتوكول ERC-20 خاصتنا. لدينا قواعد إلزامية من أجل إنشاء توكن بروتوكول ERC-20.
سنقوم بتعريف الدوال الست وكتابتها في الواجهة. وسيقوم العقد الفعلي للتوكن بتوارث ما سميناه بالواجهة.
سيبدو شكل الكود خاصتك كالتالي:
contract ERC20Interface { function totalSupply() public view returns (uint); function balanceOf(address tokenOwner) public view returns (uint balance); function allowance (address tokenOwner, address spender) public view returns (uint remaining); function transfer(address to, uint tokens) public returns (bool success); function approve(address spender, uint tokens) public returns (bool success); function transferFrom (address from, address to, uint tokens) public returns (bool success); event Transfer(address indexed from, address indexed to, uint tokens); event Approval(address indexed tokenOwner, address indexed spender, uint tokens); }
عقد التوكن
لنقم الآن بإنشاء عقد التوكن. اكتب Contract
والآن، سنقوم بشرح القواعد الثلاث الاختيارية.
بينما لا يعد من الضروري أن تسمي التوكنات خاصتك، فإنه من المهم أن تمنحها هوية.
بعد ذلك، سنتعامل مع الرموز. يعد الرمز مهماً للغاية. يساعد الرمز الجذاب على التسويق الجيد للتوكن.
وأخيراً، سندرس القسمة والتي ستساعدك على تقرير أقل قيمة ممكنة للتوكن. تعني القسمة على 0 أن أقل قيمة ممكنة للتوكن هي 1. بينما تعني القسمة على 2، أن أقل قيمة ممكنة للتوكن هي 0.01. لا يسمح برقم مكون من أكثر من 18 رقماً. ويشيع استخدام 18 رقماً، تجنب تغيير ذلك.
سنقوم بتعريفها في الكود بالشكل التالي
contract BlockonomiToken is ERC20Interface { string public name; string public symbol; uint8 public decimals; constructor() public { name = "BlockonomiToken"; symbol = "BKM"; decimals = 18; } }
سيحتاج التوكن خاصتنا إلى كمية مبدئية منه، وسجل بالأرصدة. سنقوم بتخزين تلك المعلومات في جدول.
في دالة constructor، سنقوم ببدء تشغيل العقد بإمداد مبدئي من التوكنات لصاحب العقد (والمشار إليه في msg.sender). قم بإضافة سطور الكود التالية إلى الكود خاصتك وسنناقش الغرض منهم تالياً.
contract BlockonomiToken is ERC20Interface { string public name; string public symbol; uint8 public decimals; uint256 public _totalSupply; mapping(address => uint) balances; mapping(address => mapping(address => uint)) allowed; constructor() public { name = "BlockonomiToken"; symbol = "BKM"; decimals = 18; _totalSupply = 100000000000000000000000000; balances[msg.sender] = _totalSupply; emit Transfer(address(0), msg.sender, _totalSupply); } }
أنواع البيانات على سوليديتي
كما ترى، فإن _totalSupply لديها نوع البيانات uint256، والأرقام العشرية لديها نوع بيانات uint8.
تعد سوليديتي لغة مكتوبة بشكل ستاتيكي، وهو ما يعني أن نوع كل متغير (الحالة والوضع) يجب أن يتم تحديده في وقت التشغيل. توفر سوليديتي العديد من الأنواع المبدئية والتي يمكن دمجها معاً لتشكيل أنواع أكثر تعقيداً.
لنناقش نوع الأرقام الصحيحة.
يمكن للأرقام الصحيحة أن تكون int أو uint: أرقام موقعة أو غير موقعة باحجام متنوعة. إذا كنت قد درست نظرية الحاسب أو تعرف الفارق بين الأرقام الصحيحة الموقعة وغير الموقعة بلغة برمجة سي C، فالأمر في لغة سوليديتي متطابق تماماً معها.
إذا لم تكن على علم بما سبق، فيمكن القول إن الرقم الصحيح غير الموقع هو رقم صحيح لا يمكن أن يكون سلبياً. بينما يمكن للأرقام الموقعة أن تكون سلبية أو إيجابية، إلا أننا سنستخدم الأرقام غير الموقعة فقط في العقد خاصتنا.
الكلمات المفتاحية uint8 حتى uint256 بتدرج مقداره 8 (غير موقع لـ8 حتى 256 بت) وint8 حتى int256. يعد كل من uint وint اسماً رمزياً لـuint256 وint256 على الترتيب.
تكلمنا أننا سنقوم بتخزين الأرصدة في جدول. إلا أنه من الأفضل استخدام جداول الهاش، أو التعيينات الخاصة بسوليديتي.
بشكل أساسي، نقوم بتعيين address (وهو نوع من البيانات) مع uint.
Msg.sender (العنوان): مُرسل الرسالة (الاستدعاء الحالي)
سيكون msg.sender هو الشخص المتصل حالياً بالعقد.
على الأرجح، ستتعامل في وقت لاحق مع عقود متصلة بعقود أخرى. في هذه الحالة، سيكون العقد الذي ينشأ الاستدعاء هو msg.sender.
التعيينات
يتم توضيح أنواع التعيينات عن طريق mapping (_KeyType=>_ValueType). في هذه الحالة يمكن لـ_KeyType أن يكون أي نوع تقريباً باستثناء أن يكون تعييناً، أو جدول له حجم ديناميكي، أو عقد، أو نوع البيانات المحدد مسبقاً (enum)، أو نوع البيانات الذي يمكن تخزين أكثر من قيمة عليه (struct). يمكن لـ_ValueType أن تكون أي نوع، بما فيها التعيينات.
يمكن اعتبار التعيينات كما لو أنها جداول هاش مشغلة افتراضياً بما يسمح لكل المفاتيح الممكنة الموجودة والمعينة بقيمة وتمثل بالبايت بقيمة صفر: وهي القيمة الاعتيادية للنوع. تتوقف التشابهات هنا، إذ لا يخزن المفتاح في التعيينات، وإنما يخزن هاش keccak256 من أجل البحث عن القيمة.
نتيجة لذلك، فإن التعيينات ليس لديها طول أو مفهوم "مثبت" للمفتاح أو القيمة.
يسمح باستخدام التعيينات فقط لحالة المتغيرات (أو لأنواع مرجع التخزين في الوظائف الداخلية).
من الممكن أن نقوم بتمييز التعيينات باعتباره عامة وإنشاء حماية (getter). سيصبح _KeyType مدخلاً مطلوباً للحماية وسيعطينا في المقابل _ValueType.
يمكن لـ_ValueType أن تكون تعييناً أيضاً. سيكون للحماية (getter) معيار واحد لكل _KeyType بشكل تكراري.
الأحداث
البلوكتشين عبارة عن سلسلة من البلوكات والتي تقوم بتخزين المعاملات. يلحق بكل معامة إيصال والذي قد يحتوي على مدخلات. تمثل مدخلات السجل نتيجة الأحداث المنطلقة من العقد الذكي.
في الكود المرجعي لسوليديتي، من أجل تعريف الحدث، تقوم بفعل ذلك عن طريق تحديده بوضع الكلمة المفتاحية event قبله (بما يتشابه مع استخدام الكلمة المفتاحية للدالة).
تقوم بعد ذلك باستدعاء أو إطلاق الحدث بداخل الدالة التي ترغب في توليد الحدث بداخلها. (لا توجد كلمة معينة لوصف ذلك الحدث). يمكن إطلاق الأحداث من أي دالة باستعمال الكلمة المفتاحية emit.
واجهة بروتوكول ERC-20
لنقم الآن بتنفيذ واجهة بروتوكول ERC-20. من أجل القيام بذلك، سيتوجب علينا كتابة الكود لكل الوظائف الخمس الإلزامية.
- TotalSupply العرض الكلي
تعرف تلك الوظيفة العدد الكلي لتوكنات بروتوكول ERC-20. تهدف هذه الطريقة إلى تحديد الرقم الكلي للتوكنات الموجودة داخل النظام الإيكولوجي.
function totalSupply() public view returns (uint) { return _totalSupply - balances[address(0)]; }
- BalanceOf رصيد لـ
تقوم تلك الوظيفة بإعطائنا عدد التوكنات التي يملكها عنوان معين، في حالتنا هذه، مالك العقد، في حسابه.
function balanceOf(address tokenOwner) public view returns (uint balance) { return balances[tokenOwner]; }
- Allowance الرصيد
من أجل القيام بالمعاملات فإن أحد أهم البيانات التي يجب على العقد أن يعرفها هو رصيد المستخدم. إذ يجب أن يمتلك المستخدم الحد الأدنى من التوكنات اللازم للقيام بالمعاملة.
ولذلك، فإن عقد بروتوكول ERC-20 يتضمن وظيفة allowance (). إذا لم يمتلك المستخدم الحد الأدنى المطلوب من التوكنات، فإن الدالة تلغي المعاملة.
function allowance
(address tokenOwner, address spender)
public
view
returns (uint remaining)
{
return allowed[tokenOwner][spender];
}
- Approve الموافقة
بمجرد التحقق من الرصيد، فإن صاحب العقد يمكنه السماح للمستخدم بجمع العدد اللازم من التوكنات من عنوان العقد.
كما تتحقق دالة approve من المعاملات بالمقارنة بالعدد الكلي من التوكنات للتأكد من عدم وجود توكنات زائدة أو مفقودة.
بما يعني أن تلك الدالة تجعل من التزوير مستحيلاً.
function approve(address spender, uint tokens) public returns (bool success) { allowed[msg.sender][spender] = tokens; emit Approval(msg.sender, spender, tokens); return true;}
مكتبة الحساب الآمن
من أجل تنفيذ الوظيفتين الباقيتين بشكل صحيح، فنحن بحاجة إلى مكتبة الحساب الآمن.
تحيط مكتبة الحساب الآمن بالعمليات الرياضية لسوليديتي مع وجود تحققات إضافية للفيضان الحسابي.
العمليات الرياضية في سوليديتي تحيط بالفيضان الحسابي. قد يتسبب ذلك في ثغرات لأن المبرمجين يميلون إلى افتراض أن الفيضان الحسابي سيشير إلى وقوع خطأ، وهو الإجراء المعتاد في لغات البرمجة العالية.
يستعيد الحساب الآمن هذا الافتراض عن طريق عكس المعاملات عندما يحدث الفيضان الحسابي في إحدى العمليات.
باستعمال هذه المكتبة بدلاً من العمليات التي لا تتم مراجعتها، سنتمكن من تجنب قدر كبير من الثغرات أو العيوب البرمجية، لذا فمن الأفضل أن يتم استخدامها.
كل ما نحتاجه الآن هو نسخ الكود الموجود فوق العقد، ثم نقوم بتوريثه.
contract SafeMath { function safeAdd(uint a, uint b) public pure returns (uint c) { c = a + b; require(c >= a); } function safeSub(uint a, uint b) public pure returns (uint c) { require(b <= a); c = a - b; } function safeMul(uint a, uint b) public pure returns (uint c) { c = a * b; require(a == 0 || c / a == b); } function safeDiv(uint a, uint b) public pure returns (uint c) { require(b > 0); c = a / b; } }
لا تنسَ القيام بتوريثه
contract BlockonomiToken is ERC20Interface, SafeMath
5. Transfer النقل
والآن، وبعد قيامنا بالتحقق اللازم، وبعدما عرف العقد أن المستخدم لديه العدد المطلوب من التوكنات من أجل إتمام المعاملة، يمكن لصاحب العقد أن يرسل التوكنات باستعمال دالة transfer().
تسمح هذه الدالة لصاحب العقد بإرسال كمية معينة من التوكنات إلى عنوان آخر بنفس الطريقة التي تتم بها معاملات العملات المشفرة، وتسمح بنقل عدد معين من التوكنات من العدد الإجمالي إلى حساب المستخدم.
function transfer(address to, uint tokens) public returns (bool success) { balances[msg.sender] = safeSub(balances[msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); emit Transfer(msg.sender, to, tokens); return true; }
6. Transferfrom النقل من
قمنا بالفعل بشرح دالة النقل، فلِمَ نشرح دالة أخرى لها نفس الوظيفة؟
حسناً، لنتناول مثالاً لنرى لِمَ تعد دالة transferFrom إضافة عبقرية إلى عقد بروتوكول ERC-20.
يتوجب علينا دفع مبلغ من المال كل شهر بشكل منتظم. ندفع المال للإيجار، الفواتير.. إلخ. لا تحتاج إلى دفع كل الفواتير بنفسك. يمكنك إنشاء نظام دفع أوتوماتيكي عن طريق البنك الخاص بك من أجل إتمام تلك المدفوعات.
هذا هو ما تسمح به دالة transferFrom(). تساعدك هذه الدالة على أتمتة نقل المدفوعات إلى حساب معين.
function transferFrom (address from, address to, uint tokens) public returns (bool success) { balances[from] = safeSub(balances[from], tokens); allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); emit Transfer(from, to, tokens); return true; }
الكود الكلي
إليك الكود الكلي لتوكن بت تشين.
pragma solidity ^0.5.0; // ---------------------------------------------------------------------------- // ERC Token Standard #20 Interface // // ---------------------------------------------------------------------------- contract ERC20Interface { function totalSupply() public view returns (uint); function balanceOf(address tokenOwner) public view returns (uint balance); function allowance(address tokenOwner, address spender) public view returns (uint remaining); function transfer(address to, uint tokens) public returns (bool success); function approve(address spender, uint tokens) public returns (bool success); function transferFrom(address from, address to, uint tokens) public returns (bool success); event Transfer(address indexed from, address indexed to, uint tokens); event Approval(address indexed tokenOwner, address indexed spender, uint tokens); } // ---------------------------------------------------------------------------- // Safe Math Library // ---------------------------------------------------------------------------- contract SafeMath { function safeAdd(uint a, uint b) public pure returns (uint c) { c = a + b; require(c >= a); } function safeSub(uint a, uint b) public pure returns (uint c) { require(b <= a); c = a - b; } function safeMul(uint a, uint b) public pure returns (uint c) { c = a * b; require(a == 0 || c / a == b); } function safeDiv(uint a, uint b) public pure returns (uint c) { require(b > 0); c = a / b; } } contract BlockonomiToken is ERC20Interface, SafeMath { string public name; string public symbol; uint8 public decimals; // 18 decimals is the strongly suggested default, avoid changing it uint256 public _totalSupply; mapping(address => uint) balances; mapping(address => mapping(address => uint)) allowed; /** * Constrctor function * * Initializes contract with initial supply tokens to the creator of the contract */ constructor() public { name = "BlockonomiToken"; symbol = "BKM"; decimals = 18; _totalSupply = 100000000000000000000000000; balances[msg.sender] = _totalSupply; emit Transfer(address(0), msg.sender, _totalSupply); } function totalSupply() public view returns (uint) { return _totalSupply - balances[address(0)]; } function balanceOf(address tokenOwner) public view returns (uint balance) { return balances[tokenOwner]; } function allowance(address tokenOwner, address spender) public view returns (uint remaining) { return allowed[tokenOwner][spender]; } function approve(address spender, uint tokens) public returns (bool success) { allowed[msg.sender][spender] = tokens; emit Approval(msg.sender, spender, tokens); return true; } function transfer(address to, uint tokens) public returns (bool success) { balances[msg.sender] = safeSub(balances[msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); emit Transfer(msg.sender, to, tokens); return true; } function transferFrom(address from, address to, uint tokens) public returns (bool success) { balances[from] = safeSub(balances[from], tokens); allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens); balances[to] = safeAdd(balances[to], tokens); emit Transfer(from, to, tokens); return true; } }
هنيئاً لك! لقد قمت للتو بإنشاء توكن الإيثريوم الخاص بك.
الخطوة الأخيرة هي تدشينه على الشبكة نفسها.
تدشين التوكن خاصتك
من أجل القيام بذلك، سنحتاج إلى محفظة ميتاماسك Metamask.
ميتاماسك عبارة عن ملحق يسمح لك بتشغيل تطبيقات الإيثريوم اللامركزية على المتصفح خاصتك دون الحاجة إلى تشغيل عقدة إيثريوم كاملة.
اذهب إلى https://metamask.io باستخدام المتصفح خاصتك (كروم Chrome، فايرفوكس Firefox أو أوبرا Opera) وقم بإضافته.
إنشاء محفظة جديدة على ميتاماسك
بمجرد تنصيب الملحق، اضغط على الأيقونة الخاصة به في الركن الأيمن العلوي من المتصفح من أجل البدء بإنشاء المحفظة.
قم بقراءة الشروط واقبلها ثم استخدم كلمة سر قوية واضغط على "إنشاء" Create.
ستظهر أمامك 12 كلمة مبدئية. قم بحفظ الكلمات المبدئية في ملف أو قم بنسخها في مكان آمن واضغط على "لقد قمت بحفظها في مكان آمن" I've copied it somewhere safe.
قمت لتوك بإنشاء حساب على ميتاماسك مع عنوان محفظة جديد!
ستلاحظ أن حسابك في الوقت الحالي 0 عملة إيثريوم. من أجل تنفيذ عقد على شبكة الإيثريوم، يحتاج الشخص إلى كمية معينة من عملة الإيثريوم. لن نقوم بتنفيذ العقد خاصتنا على الشبكة الرئيسية لأننا بصدد عرض توضيحي لا أكثر.
سنقوم بنشر العقد على الشبكة التجريبية. هناك عدد كبير من شبكات الإيثريوم التجريبية، مثل روبستين Ropsten، رنكيبي Rinkeby، كوفان Kovan، إلخ..
لنستعمل روبستين في هذا المثال.
أولاً، ستحتاج لعدد من عملات الإيثريوم، أليس كذلك؟ نستخدم في الشبكات التجريبية عملات إيثريوم مزيفة مجانية. كل ما عليك فعله الحصول عليها من الصنبور.
اذهب إلى https://faucet.ropsten.be، وقم بلصق عنوان المحفظة خاصتك واضغط على "أرسل لي بعض عملات الإيثريوم" Send me test Ether.
بعد بضعة ثوانٍ، ستظهر عملات الإيثريوم في محفظتك.
وضع التوكن على الشبكة
الآن، حان الوقت لوضع التوكن على الشبكة الرئيسية.
اذهب إلى ريميكس وقم بتنفيذ العقد. إذا لم تكن هناك أي أخطاء، ستصبح جاهزاً لتدشينه.
اختر Injected Web3 في خانة البيئة. سيتعرف ريميكس تلقائياً على محفظة ميتاماسك خاصتك.
اضغط على زر تنفيذ Deploy.
سيطلب منك ميتاماسك أن يسحب بعض العملات من محفظتك من أجل شراء هذه المعاملة.
قم بالتأكيد عليه. ثم اذهب مجدداً إلى ريميكس، وانظر بعناية إلى الواجهة لتلاحظ أن المعاملة قد تمت بنجاح.
حصلت على هاش المعاملة نتيجة لذلك. قم بالضغط على الرابط من الواجهة والتي ستبدو كالتالي: ropsten.etherscan.io/
سيذهب بنا هذا الرابط إلى etherscan.io، وهو المتصفح الخاص ببلوكتشين الإيثريوم ومنه يمكنك تعقّب كل ما يجري على الشبكتين الرئيسية والتجريبية، لأن كل شيء عام ومتاح على البلوكتشين.
بذهابك إلى الرابط سترى تفاصيل المعاملة خاصتك. اضغط على هاش العقد من أجل الحصول على مزيد من التفاصيل.
كل شيء عام على البلوكتشين، بما في ذلك الكود الخاص بك. لا يمكن لمطوري سوليديتي أن يرتكبوا أي أخطاء!
اضغط على علامة التبويب "عقد" وسترى البايتكود Bytecode خاصتك بعد تنفيذه.
يمكنك الآن الذهاب إلى متعقب التوكن من أجل الحصول على التفاصيل الخاصة بتوكن بت تشين خاصتك. يمكنك أيضاً رؤية القواعد الثلاث الاختيارية التي أشرنا إليها سابقاً.
الآن، قم بتفقد محفظتك. سترى أن الإيثريوم الذي دفعناه لتنفيذ العقد الذكي قد تمت إزالته.
الخلاصة
ننهي بذلك العرض التعليمي خاصتنا. عن طريق اتباع هذه الخطوات واتباع الأكواد الإرشادية، ستتمكن من تنفيذ توكن بروتوكول ERC-20 الخاص بالإيثريوم.
وقتاً سعيداً!