Move에 대해서 학습을 하고 있습니다.
개인적으로 예전에 Aptos
,Sui
쪽에 관심을 가지고 있어서 Move를 학습을 하였는데
다시 학습을 하려고 보니 너무 이해가 안가서 기록을 남기며 작성을 해나가고자 합니다.
대표적으로 사용했던 CLI에대해서 다루어 볼 것이고 해당 주제는 계속 업데이트가 가능합니다.
Aptos move init
--name <이름>
을 통해서 프로젝트 이름을 설정 합니다.Aptos move compile
Aptos move test
Aptos move publish
module BasicCoin::BasicCoin {
use std::signer;
struct Coin<phantom CoinType> has store{
value : u64
}
struct Balance<phantom CoinType> has key {
coin : Coin<CoinType>
}
public fun publish_balance<CoinType>(account : &signer) {
let empty_coin = Coin<CoinType> {value : 0};
assert!(!exists<Balance<CoinType>>(signer::address_of(account)), 0);
move_to(account, Balance<CoinType> {coin : empty_coin});
}
public fun mint<CoinType : drop>(mint_addr : address, amount : u64, _witness : CoinType) acquires Balance {
deposit(mint_addr, Coin<CoinType>{value :amount});
}
public fun balance_of<CoinType>(owner : address) : u64 acquires Balance{
borrow_global<Balance<CoinType>>(owner).coin.value
}
public fun transfer<CoinType : drop>(from : &signer, to : address, amount : u64, _witness:CoinType) acquires Balance {
let from_addr = signer::address_of(from);
assert!(from_addr != to, 0);
let check = withdraw<CoinType>(from_addr, amount);
deposit<CoinType>(to, check);
}
public fun withdraw<CoinType>(addr : address, amount : u64) : Coin<CoinType> acquires Balance {
let balance = balance_of<CoinType>(addr);
assert!(balance >= amount, 0);
let balance_ref = &mut borrow_global_mut<Balance<CoinType>>(addr).coin.value;
*balance_ref = balance - amount;
Coin<CoinType> { value: amount }
}
fun deposit<CoinType>(addr: address, check: Coin<CoinType>) acquires Balance{
let balance = balance_of<CoinType>(addr);
let balance_ref = &mut borrow_global_mut<Balance<CoinType>>(addr).coin.value;
let Coin { value } = check;
*balance_ref = balance + value;
}
}
use std::signer
기본적인 모듈중 signer라는 모듈을 사용한다는 의미 입니다.
std를 통해서 aptos에서 제공하는 기본적인 모듈을 사용 가능합니다.
Move.toml
확인
해당 모듈에서는 특정 account에 대한 주소값들을 확인하는 함수들이 있습니다.
struct
저희가 일반적으로 알고 있는 struct입니다.
Move에서는 해당 구조체에 다양한 특성들이 추가가 가능합니다.
copy
, store
, key
, drop
각각의 값들은 이름을 대변하며 추가적인 정보는 해당 링크를 참고하면 됩니다.
public fun publish_balance<CoinType>(account : &signer) {
let empty_coin = Coin<CoinType> {value : 0};
assert!(!exists<Balance<CoinType>>(signer::address_of(account)), 0);
move_to(account, Balance<CoinType> {coin : empty_coin});
}
Move에서는 특이하게도 특정 값을 미리 형성을 해주어야 합니다.
일반적으로 Solidity
에서 constructor와 같이 동작을 하는 것으로 이해를 하면 됩니다.
일단 empty_coin
이라는 값을 생성해 줍니다.
해당 값은 Coin이라는 구조체를 의미하며, 내부의 값은 0으로 설정이 됩니다.
이떄 assert
를 통해서 만약 신청하는 account
가 이미 Coin이라는 값이 있는지를 체크 합니다.
Solidity
에서는 일반적으로 msg.sender
라는 값을 통해서 sender를 인식하지만 move에서는 이런식으로 sender값이 들어가게 됩니다.그후 해당 값을 들어온 address에 할당해 줍니다.
signer::address_of(account)
값은 sender의 address를 return합니다.public entry fun mint<CoinType : drop>(mint_addr : address, amount : u64, _witness : CoinType) acquires Balance {
deposit(mint_addr, Coin<CoinType>{value :amount});
}
그후 mint를 실행시키는 함수 입니다.
_witness
를 통해서 어떠한 object = Coin
이 사용될지를 정의내리며, drop
옵션을 추가하여 사용되지 않은 _witness
를 DROP 시켜 줍니다.
public entry fun balance_of<CoinType>(owner : address) : u64 acquires Balance{
borrow_global<Balance<CoinType>>(owner).coin.value
}
특정 address
의 balance를 조회하는 함수 입니다. return타입이 존재하기 떄문에 : u64
가 추가된 모습이며,
단순히 값을 보는 역할을 수행하기 떄문에 borrow_global
이 사용되었습니다.
public entry fun transfer<CoinType : drop>(from : &signer, to : address, amount : u64, _witness:CoinType) acquires Balance {
let from_addr = signer::address_of(from);
assert!(from_addr != to, 0);
let check = withdraw<CoinType>(from_addr, amount);
deposit<CoinType>(to, check);
}
특정 address에서 다른 address로 전송을 하는 함수 입니다.
signer
을 통해서 transaction실행자를 가져올 수있으며, 어떤 obejct를 사용할건지에 대해서 mint와 동일하게 witness를 추가하였습니다.
public fun withdraw<CoinType>(addr : address, amount : u64) : Coin<CoinType> acquires Balance {
let balance = balance_of<CoinType>(addr);
assert!(balance >= amount, 0);
let balance_ref = &mut borrow_global_mut<Balance<CoinType>>(addr).coin.value;
*balance_ref = balance - amount;
Coin<CoinType> { value: amount }
}
entry 함수가 아니기 떄문에 외부에서 바로 실행이 불가능한 함수 입니다.
기본적으로 transfer에서 사용이 되며, balance를 수정하는 역할을 수행 합니다.
현재 addr
의 밸런스를 조회하고, 검증을 한뒤에 mut타입으로 바꾸어서 값을 수정을 합니다.
*balance_ref = balance - amount
fun deposit<CoinType>(addr: address, check: Coin<CoinType>) acquires Balance{
let balance = balance_of<CoinType>(addr);
let balance_ref = &mut borrow_global_mut<Balance<CoinType>>(addr).coin.value;
let Coin { value } = check;
*balance_ref = balance + value;
}
transfer 함수
에서 수령자에게 balance를 증가시키는 함수 입니다.
withdraw
함수와 유사하게 동작을 하기 떄문에 추가적인 설명은 하지 않겠습니다.
기본적으로 간단한 Contract에 대해서 알아보았습니다.
물론 설명이 부족한 부분도 있겠지만 현재 어떠한 것에 집중을 해야하는지에 대해서 고민을 하고 있는 시점이여서 크게 맘이 안가는 것도 사실입니다..
현재 생각하고 있는 기준은 Go에 대해서 다시 학습을 진행을 하고, 추가로 Move를 함께 학습을 진행해볼 예정입니다.