컬렉션 사용
이전 챕터에서 언급했듯이, 온라인 Rust Book은 Rust를 시작하는 사람들에게 훌륭한 참고 자료이지만, 블록체인을 다룰 때는 다른 개념이 필요합니다. 이러한 것들 중 하나는, 컬렉션을 사용하는 것입니다.
Rust SDK의 문서에 이 개념이 잘 설명되어 있습니다.
이는** 기본 블록체인 trie 스토리지를 보다 효율적으로 활용**하여 [Rust의] std::collections::* 내 표준 컨테이너에 대한 대안을 제공하는 컬렉션입니다.
예를 들어, 다음 스마트 컨트랙트는 호출 시작 시 전체 HashMap을 로드하고 상태 수정이 있는 경우 마지막에 전체 HashMap을 저장하기 때문에, 상태와 효율적으로 작동하지 않습니다. 이는 적은 수의 요소에는 적합하지만 많은 수의 요소가 있을 경우 매우 비효율적입니다.
— NEAR SDK 참조 문서 :::
챕터 1에서는 처음 컨트랙트를 배포할 때 십자말풀이 퍼즐 정답 해시를 설정하고, 초기화 메서드 new
를 호출하여 전달했습니다. 이는 우리가 단 하나의 퍼즐만 설정할 수 있도록 하지만, 이외에 많은 것을 허용합시다.
여러 십자말풀이를 저장하는 컨트랙트인 경우, 추가하고 싶은 항목을 높은 수준에서 논의해 봅시다. 먼저, 우리는 퍼즐 중 일부가 서로 다른 상태(미완성 및 완료됨)를 갖는 많은 퍼즐의 개념을 갖게 될 것이며, 어떤 퍼즐이 빨리 풀리지 않았는지 알고 싶을 것입니다. 스마트 컨트랙트를 작성할 때 일반적인 경험 법칙 중 하나인 또 다른 사항은, 사용량이 많을 경우 발생할 수 있는 일을 예상하는 것입니다. 자말 풀이가 10,000개가 되면 어떻게 될까요? 그것이 우리가 사용하는 자료 구조의 수와 형태에 어떤 영향을 미칠 수 있을까요?
LookupMap 및 UnorderedSet
두 가지 특수 NEAR 컬렉션을 사용해 봅시다.
- LookupMap: 키-값 쌍을 저장 (정답 해시 » 퍼즐 객체)
- UnorderedSet: 아직 풀리지지 않은 퍼즐에 대한 정답 해시 집합(중복이 없는 목록)을 포함
Rust SDK의 특수 컬렉션 목록을 보면 일부는 Lookup
로 시작하고, 다른 일부는 Unordered
를 가지고 있다는 것을 알 수 있습니다. 참조 문서에 기록된 대로, Lookup
은 반복할 수 없지만 Unordered
컬렉션은 반복할 수 있습니다. 즉, 이 자료 구조의 내용 목록을 반복해야 하는 경우, 반복 가능한 자료 구조를 사용할 수 있습니다. 키로만 데이터를 추가 및 검색하고 키가 항상 알려진 경우, 반복 불가능한 컬렉션을 사용하는 것이 더 효율적입니다.
그렇다면 여기에 두 개의 자료 구조가 있는 이유는 무엇일까요? 다시 말하지만, 많은 수의 퍼즐이 존재한다면, 모든 퍼즐을 반복하여 해결되지 않은 퍼즐을 찾을 수 없을 수도 있습니다. 트랜잭션 당 가스 실행의 한계 때문에, 우리는 결국 이 한계를 초과하게 될 작업이 있을 수 있음을 인식해야 합니다. 해결되지 않은 퍼즐의 UnorderedSet
에 수만 개의 퍼즐이 포함되어 있지 않을 것이라고 생각할 수도 있습니다. 이는 한계에 부딪히는 것을 피하는 한 가지 방법이지만, 나중에 다룰 UnorderedSet
과 같은 반복 가능한 컬렉션을 통해 페이지 매김을 활용하는 방법을 배울 수도 있습니다.
이전 챕터에서 기억했듯이, 모든 스마트 컨트랙트에는 #[near_bindgen]
매크로를 포함하는 기본 구조체가 있습니다.
NEAR의 스마트 컨트랙트들에서 사용되는 여러 규칙을 볼 수 있지만, 구조체의 이름은 중요하지 않으며, 이를 Contract
라고 지정하는 데에 특별한 이유는 없습니다. 특별한 것이 없다는 것을 설명하기 위해, 다른 이름을 붙였을 뿐입니다. 그러나, 우리의 impl
블록이 Crossword
라고 이름 붙여진 것은 의미가 있습니다. :::
반복 가능/불가능한 NEAR 컬렉션에서 구조체가 구성된 방식은 다음과 같습니다.
loading...
Above, we have the puzzles
and unsolved_puzzles
fields which are collections.
We also have an owner_id
so we can exercise a common pattern in smart contract development: implementing a rudimentary permission system which can restrict access to certain functions. We'll expand on this thought in a moment.
The snippet below shows the first method in the implementation of the Crossword
struct, where the new
function sets up these two specialized collections.
loading...
따라서 초기화 함수(new
) 실행 중에 owner_id
를 설정합니다. 우리의 목적을 위해, 소유자는 컨트랙트 자체일 가능성이 높지만, 이는 DAO 또는 다른 사용자가 될 수도 있습니다. 다음으로 컬렉션 필드의 b"c"
및 b"u"
비트를 살펴보겠습니다.