Move 튜토리얼 (4) — BasicCoin 모듈 설계
이전 글 : Move 튜토리얼 (3) — 모듈에 단위 테스트 추가하기 (링크)
안녕하세요, CC Lab 입니다. 이번에는 본격적으로 BasicCoin 모듈 설계를 해보겠습니다. 해당 글은 Move 공식 깃허브를 참고하여 작성되었습니다.
이제 기본 코인 및 잔액 인터페이스를 구현하는 모듈을 설계할 것입니다. 여기에서 코인을 발행하고 다른 주소로 잔액을 전송할 수 있습니다.
Move 함수의 공통적 서명은 다음과 같습니다.
/// 계정의 주소로 빈 잔액 리소스를 선언합니다.
/// 이 함수는 계정을 생성하거나 이체하기 전에 필수적으로 호출되어야 합니다.
public fun publish_balance(account: &signer) { ... }
/// amount 만큼의 토큰을 'mint_addr'로 입금합니다. 이 함수는 module_owner 만 가능합니다.
public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance { ... }
/// 'owner'의 잔액을 반환합니다.
public fun balance_of(owner: address): u64 acquires Balance { ... }
/// 토큰을 amount 만큼 from 에서 to 로 전송합니다.
public fun transfer(from: &signer, to: address, amount: u64) acquires Balance { ... }
다음으로 이 모듈에 필요한 데이터 구조체를 살펴보겠습니다.
Move 모듈에는 자체 저장소가 없습니다. 대신 Move 에는 ‘Global Storage’(block state)라는 주소로 인덱싱됩니다. 각 주소 아래에는 Move모듈(코드) 및 Move 리소스(값)가 있습니다.
Global Storage는 Rust 구문에서 대략 다음과 같습니다.
struct GlobalStorage {
resources: Map<address, Map<ResourceType, ResourceValue>>
modules: Map<address, Map<ModuleName, ModuleBytecode>>
}
각 주소 아래의 Move 리소스 저장소는 type 과 value 의 map 입니다. 각 주소는 각 유형의 값을 하나만 가질 수 있으며, 이것은 주소별로 인덱싱 된 네이티브 매핑을 편리하게 제공합니다. BaseCoin 모듈에 있는 Balance (주소 아래에 있는 특정 코인의 잔액) 는 다음과 같습니다.
/// 주소에 있는 특정 Coin의 잔액
struct Balance has key {
coin: Coin // same Coin from Step 1
}
** key 는 Move에 있는 ability 이며 아래의 링크에서 자세하게 볼 수 있습니다.
- https://move-language.github.io/move/abilities.html?highlight=key#key
- https://move-book.com/advanced-topics/types-with-abilities.html
이더리움과 비교
대부분의 이더리움 ERC-20 계약에서 코인의 잔액은 Smart Contract 안에 있는 balances 에 위치하게 되며 그 아래 각각의 주소로 잔액이 저장됩니다. 하지만 Move는 상위에 주소가 있으며 아래로 잔액과 모듈이 존재합니다. 아래 그림을 보면 더 쉽게 이해할 수 있습니다.