ERC-20 Token Standard
آخر تحديث للصفحة: 26 فبراير 2026
مقدمة
ما هو الرمز المميز؟
يمكن أن تمثل الرموز أي شيء تقريبًا في إيثريوم:
- نقاط السمعة في منصة عبر الإنترنت
- مهارات شخصية في اللعبة
- الأصول المالية مثل حصة في شركة
- عملة ورقية مثل الدولار الأمريكي
- أونصة من الذهب
- وغير ذلك...
يجب أن تُدار ميزة بهذه القوة في شبكة إيثريوم وفق معيار قوي وموثوق، أليس كذلك؟ وهنا تحديدًا يأتي دور معيار ERC-20! يتيح هذا المعيار للمطورين إنشاء تطبيقات رمزية متوافقة مع المنتجات والخدمات الأخرى. يُستخدم معيار ERC-20 أيضًا لتوفير وظائف إضافية لـ .
ما هو معيار ERC-20؟
يُقدّم معيار ERC-20 نموذجًا موحدًا لـ الرموز القابلة للاستبدال (Fungible Tokens)، أي أنها تتمتع بخاصية تجعل كل رمز مطابقًا تمامًا (بالنوع والقيمة) للرمز الآخر. على سبيل المثال، يعمل رمز ERC-20 تمامًا مثل الإيثر، أي أن رمزًا واحدًا يساوي دائمًا جميع الرموز الأخرى من نفس النوع.
المتطلبات الأساسية
- الحسابات
- العقود الذكية
- معايير الرمز
الجسد
يُعد ERC-20 (طلب الإيثريوم للتعليقات 20)، الذي اقترحه فابيان فوجيلستيلر في نوفمبر 2015، معيارًا للرموز يُنفذ واجهة برمجة تطبيقات للرموز داخل العقود الذكية.
أمثلة على الوظائف التشغيلية التي توفرها رموز ERC-20:
- تحويل الرموز من حساب إلى حساب آخر
- الحصول على الرصيد الحالي للحساب
- الحصول على العرض الإجمالي المتاح للعملة على الشبكة
- الموافقة على ما إذا كان يمكن إنفاق عملات لحساب معين من قبل حساب من طرف ثالث
إذا نفذ العقد الذكي الأساليب والأحداث التالية، فيمكن تسميته بعقد رمز ERC-20، وبمجرد نشره، سيكون مسؤولاً عن تتبع الرموز التي تم إنشاؤها على إيثريوم.
من EIP-20 (opens in a new tab):
طرق
1function name() public view returns (string)2function symbol() public view returns (string)3function decimals() public view returns (uint8)4function totalSupply() public view returns (uint256)5function balanceOf(address _owner) public view returns (uint256 balance)6function transfer(address _to, uint256 _value) public returns (bool success)7function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)8function approve(address _spender, uint256 _value) public returns (bool success)9function allowance(address _owner, address _spender) public view returns (uint256 remaining)إظهار الكلالأحداث
1event Transfer(address indexed _from, address indexed _to, uint256 _value)2event Approval(address indexed _owner, address indexed _spender, uint256 _value)أمثلة
دعونا نرى كيف أن المعيار مهم جداً لجعل الأمور بسيطة بالنسبة لنا لفحص أي عقد توكن ERC-20 على Ethereum. We just need the Contract Application Binary Interface (ABI) to create an interface to any ERC-20 Token. كما ترى أدناه، سنستخدم واجهة برمجة تطبيقات (ABI) مبسطة، لجعلها مثالاً منخفض الاحتكاك.
مثال ويب3.باي
أولاً، تأكد من تثبيت مكتبة ويب3.باي (opens in a new tab) الخاصة بلغة بايثون:
1pip install web31from web3 import Web323w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))45dai_token_addr = "0x6B175474E89094C44Da98b954EedeAC495271d0F" # DAI6weth_token_addr = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" # الإيثر المغلّف (WETH)78acc_address = "0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11" # Uniswap V2: DAI 2910# هذه واجهة تطبيق ثنائية (ABI) مبسطة لعقد رمزي مميز بمعيار ERC-20.11# ستكشف فقط عن الدوال التالية: balanceOf(address)، وdecimals()، وsymbol()، وtotalSupply()12simplified_abi = [13 {14 'inputs': [{'internalType': 'address', 'name': 'account', 'type': 'address'}],15 'name': 'balanceOf',16 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],17 'stateMutability': 'view', 'type': 'function', 'constant': True18 },19 {20 'inputs': [],21 'name': 'decimals',22 'outputs': [{'internalType': 'uint8', 'name': '', 'type': 'uint8'}],23 'stateMutability': 'view', 'type': 'function', 'constant': True24 },25 {26 'inputs': [],27 'name': 'symbol',28 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],29 'stateMutability': 'view', 'type': 'function', 'constant': True30 },31 {32 'inputs': [],33 'name': 'totalSupply',34 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],35 'stateMutability': 'view', 'type': 'function', 'constant': True36 }37]3839dai_contract = w3.eth.contract(address=w3.to_checksum_address(dai_token_addr), abi=simplified_abi)40symbol = dai_contract.functions.symbol().call()41decimals = dai_contract.functions.decimals().call()42totalSupply = dai_contract.functions.totalSupply().call() / 10**decimals43addr_balance = dai_contract.functions.balanceOf(acc_address).call() / 10**decimals4445# DAI46print("===== %s =====" % symbol)47print("Total Supply:", totalSupply)48print("Addr Balance:", addr_balance)4950weth_contract = w3.eth.contract(address=w3.to_checksum_address(weth_token_addr), abi=simplified_abi)51symbol = weth_contract.functions.symbol().call()52decimals = weth_contract.functions.decimals().call()53totalSupply = weth_contract.functions.totalSupply().call() / 10**decimals54addr_balance = weth_contract.functions.balanceOf(acc_address).call() / 10**decimals5556# WETH57print("===== %s =====" % symbol)58print("Total Supply:", totalSupply)59print("Addr Balance:", addr_balance)إظهار الكلمشكلات معروفة
مشكلة استقبال الرموز المميزة بمعيار ERC-20
اعتبارًا من 20/06/2024، فُقِد ما لا يقل عن 83,656,418 دولارًا من الرموز المميزة بمعيار ERC-20 بسبب هذه المشكلة. لاحظ أن التنفيذ الخالص لمعيار ERC-20 عرضة لهذه المشكلة ما لم تنفذ مجموعة من القيود الإضافية على المعيار كما هو موضح أدناه.
عندما يتم إرسال رموز ERC-20 إلى عقد ذكي غير مصمم للتعامل مع رموز ERC-20، فقد يتم فقدان هذه الرموز بشكل دائم. يحدث هذا لأن العقد المستلم لا يحتوي على الوظيفة اللازمة للتعرف على الرموز الواردة أو الاستجابة لها، ولا توجد آلية في معيار ERC-20 لإخطار العقد المستلم بالرموز الواردة. والطرق الرئيسية التي تتشكل بها هذه المشكلة هي من خلال:
- آلية نقل الرمز
- يتم نقل رموز ERC-20 باستخدام وظائف النقل أو النقل من
- عندما يرسل المستخدم رموزًا إلى عنوان عقد باستخدام هذه الوظائف، يتم نقل الرموز بغض النظر عما إذا كان العقد المستلم مصممًا للتعامل معها أم لا
- عدم وجود الإخطار
- لا يتلقى العقد المستلم إشعارًا أو مكالمة هاتفية تفيد بإرسال الرموز إليه
- إذا كان العقد المستلم يفتقر إلى آلية للتعامل مع الرموز (على سبيل المثال، وظيفة احتياطية أو وظيفة مخصصة لإدارة استقبال الرموز)، فإن الرموز عالقة فعليًا في عنوان العقد
- لا يوجد معالجة مدمجة
- لا يتضمن معيار ERC-20 وظيفة إلزامية لعقود الاستلام للتنفيذ، مما يؤدي إلى موقف حيث لا تتمكن العديد من العقود من إدارة الرموز الواردة بشكل صحيح
الحلول الممكنة
على الرغم من أنه من غير الممكن منع هذه المشكلة تمامًا باستخدام ERC-20، إلا أن هناك طرقًا تسمح بتقليل احتمالية فقدان الرموز بشكل كبير للمستخدم النهائي:
- المشكلة الأكثر شيوعًا هي عندما يرسل المستخدم الرموز المميزة إلى عنوان عقد الرمز المميز نفسه (على سبيل المثال، إيداع USDT إلى عنوان عقد الرمز المميز USDT). يوصى بتقييد دالة
transfer(..)لإبطال محاولات التحويل هذه. فكر في إضافة التحققrequire(_to != address(this));ضمن تنفيذ دالةtransfer(..). - بشكل عام، دالة
transfer(..)ليست مصممة لإيداع الرموز المميزة في العقود.approve(..) ويُستخدم نمطtransferFrom(..)لإيداع الرموز المميزة بمعيار ERC-20 في العقود بدلاً من ذلك. من الممكن تقييد دالة التحويل لمنع إيداع الرموز المميزة في أي عقود باستخدامها، ولكن هذا قد يكسر التوافق مع العقود التي تفترض أنه يمكن إيداع الرموز المميزة في العقود باستخدام دالةtrasnfer(..)` (مثل مجمعات سيولة يوني سواب). - افترض دائمًا أن رموز ERC-20 يمكن أن تظهر في عقدك حتى لو لم يكن من المفترض أن يتلقى عقدك أيًا منها على الإطلاق. لا توجد طريقة لمنع أو رفض الإيداعات العرضية من جانب المستلمين يوصى بتنفيذ وظيفة تسمح باستخراج رموز ERC-20 المودعة عن طريق الخطأ.
- فكر في استخدام معايير رمزية بديلة
لقد ظهرت بعض المعايير البديلة نتيجة لهذه المشكلة مثل ERC-223 أو ERC-1363.
قراءة إضافية
- EIP-20: معيار توكن ERC-20 (opens in a new tab)
- أوبن زبلين - الرموز المميزة (opens in a new tab)
- أوبن زبلين - تنفيذ ERC-20 (opens in a new tab)
- ألكيمي - دليل رموز سوليديتي ERC20 المميزة (opens in a new tab)