ERC-223 ٹوکن کا معیار
صفحہ کی آخری تازہ کاری: 14 فروری، 2026
تعارف
ERC-223 کیا ہے؟
ERC-223 فنجیبل ٹوکنز کا ایک معیار ہے، جو ERC-20 معیار کی طرح ہے۔ کلیدی فرق یہ ہے کہ ERC-223 نہ صرف ٹوکن API کی وضاحت کرتا ہے بلکہ بھیجنے والے سے وصول کنندہ تک ٹوکن منتقل کرنے کی منطق کی بھی وضاحت کرتا ہے۔ یہ ایک کمیونیکیشن ماڈل پیش کرتا ہے جو وصول کنندہ کی طرف سے ٹوکن کی منتقلی کو سنبھالنے کی اجازت دیتا ہے۔
ERC-20 سے فرق
ERC-223, ERC-20 کی کچھ حدود کو دور کرتا ہے اور ٹوکن کنٹریکٹ اور ایک ایسے کنٹریکٹ کے درمیان تعامل کا ایک نیا طریقہ متعارف کراتا ہے جو ٹوکن وصول کر سکتا ہے۔ کچھ چیزیں ہیں جو ERC-223 کے ساتھ ممکن ہیں لیکن ERC-20 کے ساتھ نہیں:
- وصول کنندہ کی طرف سے ٹوکن کی منتقلی کو سنبھالنا: وصول کنندگان یہ پتہ لگا سکتے ہیں کہ ایک ERC-223 ٹوکن جمع کیا جا رہا ہے۔
- غلط طریقے سے بھیجے گئے ٹوکنز کو مسترد کرنا: اگر کوئی صارف ERC-223 ٹوکنز کو ایک ایسے کنٹریکٹ میں بھیجتا ہے جسے ٹوکنز وصول نہیں کرنے چاہئیں، تو کنٹریکٹ ٹرانزیکشن کو مسترد کر سکتا ہے، جس سے ٹوکن کا نقصان رک جاتا ہے۔
- منتقلی میں میٹا ڈیٹا: ERC-223 ٹوکنز میں میٹا ڈیٹا شامل ہو سکتا ہے، جس سے ٹوکن ٹرانزیکشنز کے ساتھ من مانی معلومات منسلک کی جا سکتی ہیں۔
شرائط
باڈی
ERC-223 ایک ٹوکن معیار ہے جو سمارٹ کنٹریکٹس کے اندر ٹوکنز کے لیے ایک API نافذ کرتا ہے۔ یہ ان کنٹریکٹس کے لیے بھی ایک API کا اعلان کرتا ہے جنہیں ERC-223 ٹوکنز وصول کرنے ہوتے ہیں۔ وہ کنٹریکٹس جو ERC-223 رسیور API کو سپورٹ نہیں کرتے ہیں، وہ ERC-223 ٹوکنز وصول نہیں کر سکتے، جس سے صارف کی غلطی کو روکا جا سکتا ہے۔
اگر کوئی سمارٹ کنٹریکٹ مندرجہ ذیل طریقوں اور ایونٹس کو نافذ کرتا ہے تو اسے ERC-223 ہم آہنگ ٹوکن کنٹریکٹ کہا جا سکتا ہے۔ ایک بار تعینات ہونے کے بعد، یہ Ethereum پر بنائے گئے ٹوکنز کا ٹریک رکھنے کا ذمہ دار ہوگا۔
کنٹریکٹ صرف ان فنکشنز کو رکھنے کا پابند نہیں ہے اور ایک ڈویلپر مختلف ٹوکن معیارات سے کوئی دوسری خصوصیت اس کنٹریکٹ میں شامل کر سکتا ہے۔ مثال کے طور پر، approve اور transferFrom فنکشنز ERC-223 معیار کا حصہ نہیں ہیں لیکن ضرورت پڑنے پر ان فنکشنز کو نافذ کیا جا سکتا ہے۔
طریقے
ERC-223 ٹوکن کو مندرجہ ذیل طریقوں کو نافذ کرنا ہوگا:
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 transfer(address _to, uint256 _value, bytes calldata _data) public returns (bool success)ایک کنٹریکٹ جسے ERC-223 ٹوکنز وصول کرنے ہیں، اسے مندرجہ ذیل طریقہ کو نافذ کرنا ہوگا:
1function tokenReceived(address _from, uint _value, bytes calldata _data)اگر ERC-223 ٹوکنز کو ایک ایسے کنٹریکٹ میں بھیجا جاتا ہے جو tokenReceived(..) فنکشن کو نافذ نہیں کرتا ہے، تو منتقلی ناکام ہونی چاہئے اور ٹوکنز کو بھیجنے والے کے بیلنس سے منتقل نہیں کیا جانا چاہئے۔
ایونٹس
1event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data)مثالیں
ERC-223 ٹوکن کا API، ERC-20 کے API کی طرح ہے، لہذا UI ڈویلپمنٹ کے نقطہ نظر سے کوئی فرق نہیں ہے۔ یہاں واحد استثناء یہ ہے کہ ERC-223 ٹوکنز میں approve + transferFrom فنکشنز نہیں ہو سکتے ہیں کیونکہ یہ اس معیار کے لیے اختیاری ہیں۔
Solidity کی مثالیں
مندرجہ ذیل مثال واضح کرتی ہے کہ ایک بنیادی ERC-223 ٹوکن کنٹریکٹ کیسے کام کرتا ہے:
1pragma solidity ^0.8.19;2abstract contract IERC223Recipient {3 function tokenReceived(address _from, uint _value, bytes memory _data) public virtual;4}5contract VeryBasicERC223Token {6 event Transfer(address indexed from, address indexed to, uint value, bytes data);7 string private _name;8 string private _symbol;9 uint8 private _decimals;10 uint256 private _totalSupply;11 mapping(address => uint256) private balances;12 function name() public view returns (string memory) { return _name; }13 function symbol() public view returns (string memory) {return _symbol; }14 function decimals() public view returns (uint8) { return _decimals; }15 function totalSupply() public view returns (uint256) { return _totalSupply; }16 function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; }17 function isContract(address account) internal view returns (bool) {18 uint256 size;19 assembly { size := extcodesize(account) }20 return size > 0;21 }22 function transfer(address _to, uint _value, bytes calldata _data) public returns (bool success){23 balances[msg.sender] = balances[msg.sender] - _value;24 balances[_to] = balances[_to] + _value;25 if(isContract(_to)) {26 IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data);27 }28 emit Transfer(msg.sender, _to, _value, _data);29 return true;30 }31 function transfer(address _to, uint _value) public returns (bool success){32 bytes memory _empty = hex"00000000";33 balances[msg.sender] = balances[msg.sender] - _value;34 balances[_to] = balances[_to] + _value;35 if(isContract(_to)) {36 IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty);37 }38 emit Transfer(msg.sender, _to, _value, _empty);39 return true;40 }41}سب دکھائیںاب ہم چاہتے ہیں کہ ایک اور کنٹریکٹ tokenA کے ڈپازٹس کو قبول کرے، یہ فرض کرتے ہوئے کہ tokenA ایک ERC-223 ٹوکن ہے۔ کنٹریکٹ کو صرف tokenA کو قبول کرنا چاہئے اور کسی بھی دوسرے ٹوکن کو مسترد کرنا چاہئے۔ جب کنٹریکٹ کو tokenA موصول ہوتا ہے تو اسے ایک Deposit() ایونٹ جاری کرنا چاہئے اور اندرونی deposits متغیر کی قدر میں اضافہ کرنا چاہئے۔
یہاں کوڈ ہے:
1contract RecipientContract is IERC223Recipient {2 event Deposit(address whoSentTheTokens);3 uint256 deposits = 0;4 address tokenA; // واحد ٹوکن جسے ہم قبول کرنا چاہتے ہیں۔5 function tokenReceived(address _from, uint _value, bytes memory _data) public override6 {7 // یہ سمجھنا ضروری ہے کہ اس فنکشن کے اندر8 // msg.sender موصول ہونے والے ٹوکن کا پتہ ہے،9 // msg.value ہمیشہ 0 ہوتا ہے کیونکہ ٹوکن کنٹریکٹ زیادہ تر معاملات میں ایتھر کا مالک نہیں ہوتا یا بھیجتا نہیں ہے،10 // _from ٹوکن کی منتقلی کا بھیجنے والا ہے،11 // _value جمع کیے گئے ٹوکنز کی رقم ہے۔12 require(msg.sender == tokenA);13 deposits += _value;14 emit Deposit(_from);15 }16}سب دکھائیںاکثر پوچھے جانے والے سوالات
اگر ہم کچھ tokenB کنٹریکٹ کو بھیجیں تو کیا ہوگا؟
ٹرانزیکشن ناکام ہو جائے گی، اور ٹوکنز کی منتقلی نہیں ہوگی۔ ٹوکنز بھیجنے والے کے پتے پر واپس کر دیے جائیں گے۔
ہم اس کنٹریکٹ میں ڈپازٹ کیسے کر سکتے ہیں؟
ERC-223 ٹوکن کے transfer(address,uint256) یا transfer(address,uint256,bytes) فنکشن کو RecipientContract کا پتہ بتا کر کال کریں۔
اگر ہم اس کنٹریکٹ میں ERC-20 ٹوکن منتقل کریں تو کیا ہوگا؟
اگر ایک ERC-20 ٹوکن RecipientContract کو بھیجا جاتا ہے، تو ٹوکنز منتقل ہو جائیں گے، لیکن منتقلی کو تسلیم نہیں کیا جائے گا (کوئی Deposit() ایونٹ فائر نہیں ہوگا، اور ڈپازٹس کی قدر تبدیل نہیں ہوگی)۔ ناپسندیدہ ERC-20 ڈپازٹس کو فلٹر یا روکا نہیں جا سکتا۔
اگر ہم ٹوکن ڈپازٹ مکمل ہونے کے بعد کوئی فنکشن عمل میں لانا چاہتے ہیں تو کیا ہوگا؟
ایسا کرنے کے کئی طریقے ہیں۔ اس مثال میں ہم اس طریقے پر عمل کریں گے جو ERC-223 کی منتقلی کو ایتھر کی منتقلی کے مترادف بناتا ہے:
1contract RecipientContract is IERC223Recipient {2 event Foo();3 event Bar(uint256 someNumber);4 address tokenA; // واحد ٹوکن جسے ہم قبول کرنا چاہتے ہیں۔5 function tokenReceived(address _from, uint _value, bytes memory _data) public override6 {7 require(msg.sender == tokenA);8 address(this).call(_data); // آنے والی ٹرانزیکشن کو ہینڈل کریں اور بعد میں ایک فنکشن کال کریں۔9 }10 function foo() public11 {12 emit Foo();13 }14 function bar(uint256 _someNumber) public15 {16 emit Bar(_someNumber);17 }18}سب دکھائیںجب RecipientContract کو ایک ERC-223 ٹوکن موصول ہوگا تو کنٹریکٹ ٹوکن ٹرانزیکشن کے _data پیرامیٹر کے طور پر انکوڈ کردہ ایک فنکشن کو عمل میں لائے گا، بالکل اسی طرح جیسے ایتھر ٹرانزیکشنز فنکشن کالز کو ٹرانزیکشن data کے طور پر انکوڈ کرتی ہیں۔ مزید معلومات کے لیے ڈیٹا فیلڈ پڑھیں۔
اوپر دی گئی مثال میں، ایک ERC-223 ٹوکن کو transfer(address,uin256,bytes calldata _data) فنکشن کے ساتھ RecipientContract کے پتے پر منتقل کیا جانا چاہئے۔ اگر ڈیٹا پیرامیٹر 0xc2985578 (foo() فنکشن کا دستخط) ہوگا، تو ٹوکن ڈپازٹ موصول ہونے کے بعد foo() فنکشن کو طلب کیا جائے گا اور Foo() ایونٹ فائر ہو جائے گا۔
پیرامیٹرز کو ٹوکن کی منتقلی کے data میں بھی انکوڈ کیا جا سکتا ہے، مثال کے طور پر ہم _someNumber کے لیے 12345 کی قدر کے ساتھ bar() فنکشن کو کال کر سکتے ہیں۔ اس صورت میں data کو 0x0423a13200000000000000000000000000000000000000000000000000000000000004d2 ہونا چاہئے جہاں 0x0423a132 bar(uint256) فنکشن کا دستخط ہے اور 00000000000000000000000000000000000000000000000000000000000004d2 بطور uint256 کے 12345 ہے۔
حدود
اگرچہ ERC-223, ERC-20 معیار میں پائے جانے والے کئی مسائل کو حل کرتا ہے، یہ اپنی حدود سے خالی نہیں ہے:
- اختیار اور مطابقت: ERC-223 کو ابھی تک وسیع پیمانے پر اپنایا نہیں گیا ہے، جو موجودہ ٹولز اور پلیٹ فارمز کے ساتھ اس کی مطابقت کو محدود کر سکتا ہے۔
- پسماندہ مطابقت: ERC-223, ERC-20 کے ساتھ پسماندہ مطابقت نہیں رکھتا، جس کا مطلب ہے کہ موجودہ ERC-20 کنٹریکٹس اور ٹولز بغیر کسی ترمیم کے ERC-223 ٹوکنز کے ساتھ کام نہیں کریں گے۔
- گیس کی لاگت: ERC-223 کی منتقلی میں اضافی جانچ اور افعال ERC-20 ٹرانزیکشنز کے مقابلے میں گیس کی زیادہ لاگت کا باعث بن سکتے ہیں۔