Solidity / Өвлөлт (inheritance)
Өвлөлт (inheritance)
Өвлөлт нь нэг contract-ын код, функц, state-ийг нөгөөд дамжуулах механизм юм. Кодын давхардлыг багасгаж, дахин ашиглалтыг нэмэгдүүлнэ.
is — өвлөх
is түлхүүр үгээр нэг contract нөгөөгөөсөө өвлөнэ.
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Эцэг contract
contract Animal {
string public name;
constructor(string memory _name) {
name = _name;
}
function speak() public pure virtual returns (string memory) {
return "...";
}
}
// Хүү contract — Animal-аас өвлөнэ
contract Dog is Animal {
constructor(string memory _name) Animal(_name) {}
function speak() public pure override returns (string memory) {
return "Хав хав!";
}
}
Dog contract нь Animal-ын name state variable болон constructor-ыг өвлөнө.
virtual ба override
virtual— эцэг contract-д: энэ функцийг хүүд дахин тодорхойлж болно гэсэн утгаoverride— хүү contract-д: эцгийн функцийг дахин тодорхойлж байна гэсэн утга
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Shape {
function area() public pure virtual returns (uint256) {
return 0;
}
}
contract Square is Shape {
uint256 public side;
constructor(uint256 _side) {
side = _side;
}
function area() public view override returns (uint256) {
return side * side;
}
}
contract Circle is Shape {
uint256 public radius;
constructor(uint256 _radius) {
radius = _radius;
}
// π ≈ 314, хялбарчилсан тооцоо
function area() public view override returns (uint256) {
return (314 * radius * radius) / 100;
}
}
super — эцгийн функцийг дуудах
super түлхүүр үгээр эцгийн функцийг хүүгийн дотроос дуудаж болно.
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Ownable {
address public owner;
constructor() {
owner = msg.sender;
}
function transferOwnership(address newOwner) public virtual {
require(newOwner != address(0), "Хүчингүй хаяг");
owner = newOwner;
}
}
contract SecureOwnable is Ownable {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function transferOwnership(address newOwner) public override {
emit OwnershipTransferred(owner, newOwner);
super.transferOwnership(newOwner); // Эцгийн функцийг дуудна
}
}
Олон өвлөлт (multiple inheritance)
Solidity нь олон contract-аас зэрэг өвлөх боломжтой. Солилцооны дараалал нь C3 linearization алгоритмаар тодорхойлогдоно.
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract A {
function greet() public pure virtual returns (string memory) {
return "A";
}
}
contract B is A {
function greet() public pure virtual override returns (string memory) {
return "B";
}
}
contract C is A {
function greet() public pure virtual override returns (string memory) {
return "C";
}
}
// B, C хоёроос өвлөхдөө override(B, C) хэлбэрээр бичнэ
contract D is B, C {
function greet() public pure override(B, C) returns (string memory) {
return super.greet(); // C-ийн greet()-г дуудна (хамгийн сүүлийн эцэг)
}
}
Олон өвлөлтийн үед is дараах эцгүүдийг баруун тийш нь хамгийн ерөнхий нь байхаар жагсаана.
Практик жишээ — Ownable + Pausable
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Ownable {
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Зөвхөн эзэмшигч");
_;
}
constructor() {
owner = msg.sender;
}
}
contract Pausable is Ownable {
bool public paused;
modifier whenNotPaused() {
require(!paused, "Contract түр зогсоогдсон");
_;
}
function pause() public onlyOwner {
paused = true;
}
function unpause() public onlyOwner {
paused = false;
}
}
contract Token is Pausable {
mapping(address => uint256) public balances;
function transfer(address to, uint256 amount) public whenNotPaused {
require(balances[msg.sender] >= amount, "Үлдэгдэл хүрэлцэхгүй");
balances[msg.sender] -= amount;
balances[to] += amount;
}
}
Token нь Pausable-аас, Pausable нь Ownable-аас өвлөж гинжин байдлаар бүх функц, modifier-ийг дамжуулна.
Дараагийн хичээлд:
Interface ашиглан contract хоорондын харилцааг стандартчилах аргыг судална.