Solidity তে Multiple Inheritance এবং Contract Inheritance Chain এর মাধ্যমে একাধিক কন্ট্রাক্ট থেকে ফাংশন এবং প্রোপার্টি (ভেরিয়েবল) পাওয়া যায়। Solidity তে কন্ট্রাক্টগুলির মধ্যে উত্তরাধিকার (inheritance) সম্পর্ক স্থাপন করে কোড পুনঃব্যবহারযোগ্যতা, সিস্টেমের সুনির্দিষ্টতা, এবং স্থায়িত্ব বৃদ্ধি করা যায়।
এই দুটি ধারণা বুঝতে এবং সঠিকভাবে ব্যবহার করতে হলে, কন্ট্রাক্টের মধ্যে কীভাবে ইনহেরিট করা যায় এবং কিভাবে একাধিক কন্ট্রাক্টের ফাংশন এবং বৈশিষ্ট্য একত্রে ব্যবহৃত হতে পারে তা জানা প্রয়োজন।
1. Multiple Inheritance (একাধিক উত্তরাধিকার)
Solidity তে Multiple Inheritance হল একাধিক কন্ট্রাক্ট থেকে একই কন্ট্রাক্টে ফাংশন এবং প্রোপার্টি (ভেরিয়েবল) উত্তরাধিকার (inherit) করার প্রক্রিয়া। Solidity তে একাধিক কন্ট্রাক্ট থেকে ফাংশন এবং ভেরিয়েবল মিশ্রিত (combine) করা যায়, তবে এই প্রক্রিয়ায় কিছু সতর্কতা অবলম্বন করা প্রয়োজন, যেমন diamond problem (যা কিছু ক্ষেত্রে সমস্যা তৈরি করতে পারে)।
গঠন:
contract ContractA {
function functionA() public pure returns (string memory) {
return "Function A from ContractA";
}
}
contract ContractB {
function functionB() public pure returns (string memory) {
return "Function B from ContractB";
}
}
contract MyContract is ContractA, ContractB {
// ContractA এবং ContractB এর সব ফাংশন এবং প্রোপার্টি উপলব্ধ
}এখানে, MyContract কন্ট্রাক্টটি ContractA এবং ContractB কন্ট্রাক্ট থেকে ফাংশন ইনহেরিট করেছে। তাই MyContract কন্ট্রাক্টে উল্লিখিত দুটি কন্ট্রাক্টের সব ফাংশন এবং বৈশিষ্ট্য একত্রে ব্যবহার করা যাবে।
উদাহরণ:
pragma solidity ^0.8.0;
contract A {
uint public a = 10;
}
contract B {
uint public b = 20;
}
contract C is A, B {
function getSum() public view returns (uint) {
return a + b; // A এবং B থেকে ইনহেরিটেড ভেরিয়েবল
}
}এখানে, C কন্ট্রাক্টটি A এবং B কন্ট্রাক্ট থেকে a এবং b ভেরিয়েবল ইনহেরিট করেছে। getSum ফাংশনটি এই ভেরিয়েবলগুলো যোগ করে আউটপুট দেয়।
2. Contract Inheritance Chain (কন্ট্রাক্ট উত্তরাধিকার চেইন)
Contract Inheritance Chain এর মাধ্যমে একটি কন্ট্রাক্ট অন্য কন্ট্রাক্ট থেকে ইনহেরিট করা হয়, এবং এই উত্তরাধিকার চেইন এমনভাবে তৈরি হয় যে, একাধিক স্তরের কন্ট্রাক্টের মধ্যে কার্যকরী সম্পর্ক থাকে। Solidity তে এটি multilevel inheritance নামে পরিচিত, যেখানে একটি কন্ট্রাক্ট অন্য কন্ট্রাক্ট থেকে ইনহেরিট করার পর সেই কন্ট্রাক্ট আবার অন্য কন্ট্রাক্ট থেকে ইনহেরিট করতে পারে।
গঠন:
contract Parent {
function parentFunction() public pure returns (string memory) {
return "Function from Parent contract";
}
}
contract Child is Parent {
function childFunction() public pure returns (string memory) {
return "Function from Child contract";
}
}
contract Grandchild is Child {
function grandchildFunction() public pure returns (string memory) {
return "Function from Grandchild contract";
}
}এখানে, Grandchild কন্ট্রাক্টটি Child কন্ট্রাক্ট থেকে ইনহেরিট করে, যা আবার Parent কন্ট্রাক্ট থেকে ইনহেরিট করা হয়েছে। এর ফলে Grandchild কন্ট্রাক্টের কাছে Parent এবং Child কন্ট্রাক্টের সকল ফাংশন পাওয়া যাবে।
3. Diamond Problem (ডায়মন্ড প্রবলেম)
Solidity তে diamond problem একটি সমস্যা হতে পারে যখন একাধিক কন্ট্রাক্ট একই ফাংশন বা বৈশিষ্ট্য মঞ্জুর করে। একাধিক উত্তরাধিকার ব্যবহারের ক্ষেত্রে যদি দুইটি কন্ট্রাক্ট একই ফাংশন বা ভেরিয়েবল ডিফাইন করে, তবে Solidity কোন কন্ট্রাক্টের ফাংশনটি ব্যবহার করবে তা নির্ধারণ করতে পারে না।
Diamond Problem এ উদাহরণ:
pragma solidity ^0.8.0;
contract A {
function myFunction() public pure returns (string memory) {
return "Function from A";
}
}
contract B is A {
function myFunction() public pure returns (string memory) {
return "Function from B";
}
}
contract C is A {
function myFunction() public pure returns (string memory) {
return "Function from C";
}
}
contract D is B, C {
// কোন `myFunction` ফাংশনটি ব্যবহার করা হবে?
}এখানে, কন্ট্রাক্ট D B এবং C থেকে ইনহেরিট করেছে, এবং উভয় কন্ট্রাক্টেই myFunction নামে একটি ফাংশন ডিফাইন করা রয়েছে। এ ক্ষেত্রে, Solidity নির্ধারণ করতে পারে না কোন ফাংশনটি ব্যবহার করা হবে।
সমাধান: Solidity তে এই সমস্যা সমাধানের জন্য virtual এবং override কিওয়ার্ড ব্যবহার করা হয়।
4. virtual এবং override কিওয়ার্ড
virtual কিওয়ার্ড ব্যবহার করা হয় ফাংশন বা ভেরিয়েবল ডিফাইন করার সময়, যা নির্দেশ করে যে এই ফাংশন বা ভেরিয়েবলটি ভবিষ্যতে অন্য কন্ট্রাক্ট দ্বারা ওভাররাইড (override) করা যেতে পারে। আর override কিওয়ার্ড ব্যবহার করা হয় যে ফাংশন বা ভেরিয়েবলটি পূর্বের কন্ট্রাক্টের কোনো একটি ফাংশন বা ভেরিয়েবলকে ওভাররাইড করছে।
উদাহরণ:
pragma solidity ^0.8.0;
contract A {
function myFunction() public pure virtual returns (string memory) {
return "Function from A";
}
}
contract B is A {
function myFunction() public pure override returns (string memory) {
return "Function from B";
}
}
contract C is A {
function myFunction() public pure override returns (string memory) {
return "Function from C";
}
}
contract D is B, C {
function myFunction() public pure override returns (string memory) {
return "Function from D";
}
}এখানে, myFunction ফাংশনটি প্রথমে A কন্ট্রাক্টে virtual হিসেবে ডিফাইন করা হয়েছে, এবং পরে B, C, এবং D কন্ট্রাক্টে override করা হয়েছে। D কন্ট্রাক্টে ফাংশনটি শেষ পর্যন্ত override হয়ে নতুন মান প্রদান করবে।
সারাংশ
Multiple Inheritance এবং Contract Inheritance Chain Solidity তে কোড পুনঃব্যবহারযোগ্যতা এবং কোড কাঠামোকে আরও সুষম ও সুসংগঠিত করতে সহায়তা করে। Multiple Inheritance একাধিক কন্ট্রাক্ট থেকে ফাংশন এবং প্রোপার্টি গ্রহণ করতে ব্যবহৃত হয়, এবং Contract Inheritance Chain এর মাধ্যমে একাধিক স্তরের কন্ট্রাক্ট সম্পর্ক তৈরি করা যায়। যদিও diamond problem কিছু সমস্যা সৃষ্টি করতে পারে, তবে virtual এবং override কিওয়ার্ড ব্যবহার করে এই সমস্যার সমাধান করা সম্ভব।
Read more