🔧 추가된 항목:
1. LinkedListLib
• append, remove, getAll 함수를 포함한 재사용 가능한 라이브러리
• mapping 기반으로 설계된 List 구조체 포함
2. GenericLinkedList 컨트랙트
• 위 라이브러리를 사용한 일반화된 Linked List
• 코드 재사용 가능, 깔끔한 구조
3. Gas 최적화
• 불필요한 상태 변경 제거
• 라이브러리화를 통해 반복되는 코드 최소화
✅ 확장 완료된 기능:
📌 LinkedListLib에 추가된 고급 기능
1. insertAfter(afterId, data)
특정 노드 뒤에 새로운 노드 삽입
2. findByData(target)
값을 기준으로 노드 ID 탐색
3. clear()
전체 리스트 초기화 (모든 노드 제거)
⸻
🧪 GenericLinkedList 컨트랙트에 연동된 함수
• insertAfter(...)
• find(...)
• clearAll()
이제 리스트 구조는 완전한 CRUD + 검색 + 초기화 + 재사용까지 가능한 구조입니다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
library LinkedListLib {
struct Node {
uint data;
uint next;
bool exists;
}
struct List {
mapping(uint => Node) nodes;
uint head;
uint length;
uint idCounter;
}
function init(List storage list) internal {
list.head = 0;
list.nodes[0] = Node({ data: 0, next: 0, exists: true });
list.idCounter = 1;
}
function append(List storage list, uint _data) internal {
uint current = list.head;
while (list.nodes[current].next != 0) {
current = list.nodes[current].next;
}
uint newId = list.idCounter++;
list.nodes[newId] = Node({ data: _data, next: 0, exists: true });
list.nodes[current].next = newId;
list.length++;
}
function insertAfter(List storage list, uint afterId, uint _data) internal {
require(list.nodes[afterId].exists, "after node not found");
uint newId = list.idCounter++;
list.nodes[newId] = Node({ data: _data, next: list.nodes[afterId].next, exists: true });
list.nodes[afterId].next = newId;
list.length++;
}
function remove(List storage list, uint id) internal {
require(id != list.head, "cannot remove head");
require(list.nodes[id].exists, "not found");
uint prev = list.head;
while (list.nodes[prev].next != id && list.nodes[prev].next != 0) {
prev = list.nodes[prev].next;
}
require(list.nodes[prev].next == id, "not found");
list.nodes[prev].next = list.nodes[id].next;
delete list.nodes[id];
list.length--;
}
function findByData(List storage list, uint target) internal view returns (uint) {
uint current = list.nodes[list.head].next;
while (current != 0) {
if (list.nodes[current].data == target) {
return current;
}
current = list.nodes[current].next;
}
return 0; // not found
}
function getAll(List storage list) internal view returns (uint[] memory) {
uint[] memory result = new uint[](list.length);
uint current = list.nodes[list.head].next;
uint i = 0;
while (current != 0) {
result[i++] = list.nodes[current].data;
current = list.nodes[current].next;
}
return result;
}
function clear(List storage list) internal {
uint current = list.nodes[list.head].next;
while (current != 0) {
uint next = list.nodes[current].next;
delete list.nodes[current];
current = next;
}
list.nodes[list.head].next = 0;
list.length = 0;
}
}
contract GenericLinkedList {
using LinkedListLib for LinkedListLib.List;
LinkedListLib.List private list;
constructor() {
list.init();
}
function add(uint value) external {
list.append(value);
}
function insertAfter(uint afterId, uint value) external {
list.insertAfter(afterId, value);
}
function remove(uint id) external {
list.remove(id);
}
function find(uint value) external view returns (uint) {
return list.findByData(value);
}
function all() external view returns (uint[] memory) {
return list.getAll();
}
function clearAll() external {
list.clear();
}
}'Solidity' 카테고리의 다른 글
| Solidity: RBT 구현 예제 (0) | 2025.03.26 |
|---|---|
| Solidity : 최대값 검색을 위한 Heap Tree 구현 (0) | 2025.03.26 |
| Solidity 로 연결 리스트 구현하기 (0) | 2025.03.26 |
| 인터페이스 + 상속 조합 (0) | 2025.03.25 |
| Solidity 에서의 상속 (0) | 2025.03.25 |