Sui 개발자 치트 시트
Sui Network 개발자를 위한 모범 사례 빠른 참조이다.
Move
Sui에서 Move 스마트 계약을 작성할 때의 모범 사례이다.
일반
- Move 개발 모범 사례는 Code Quality Checklist를 읽는다.
- 일관된 이름 지정과 코딩 스타일을 위해 Move 모범 사례을 따른다.
- 최대 크기를 1000개 이하로 알 수 있는 컬렉션에는
vector기반 컬렉션(vector,VecSet,VecMap,PriorityQueue)을 사용한다.- 제3자 추가를 허용하는 컬렉션, 더 큰 컬렉션, 크기를 알 수 없는 컬렉션에는 동적 필드 기반 컬렉션(
Table,Bag,ObjectBag,ObjectTable,LinkedTable)을 사용한다. - Move 객체의 최대 크기는 250KB이다. 더 큰 객체를 생성하려고 하면 트랜잭션이 중단된다. 객체에 계속 커지는
vector기반 컬렉션이 없도록 한다.
- 제3자 추가를 허용하는 컬렉션, 더 큰 컬렉션, 크기를 알 수 없는 컬렉션에는 동적 필드 기반 컬렉션(
- 함수
f가 호출자로부터 예를 들어 SUI 결제를 받아야 한다면fun f(payment: Coin<SUI>)가 아니라fun f(payment: &mut Coin<SUI>, amount: u64)를 사용한다. 이 방식이 호출자에게 더 안전하다. 호출자는 정확히 얼마를 지불하는지 알 수 있으며,f가 올바른 금액을 꺼낼 것이라고 신뢰할 필요가 없다.
Composability
- 지갑, 앱, explorer에서 객체가 표시되는 방식을 사용자 지정하려면 Sui Object Display를 사용한다.
- self-transfer를 피한다. 가능하면 현재 함수에서 객체를 반환하여 PTB 구성하기에서 다른 명령에 사용할 수 있게 한다.
패키지 업그레이드
- 패키지를 게시하기 전에 패키지 업그레이드를 읽는다.
- 패키지는 불변이므로 게시된 모든 패키지는 영구적으로 호출될 수 있다. 이전 버전이 호출되지 않도록 객체 버전 관리를 사용한다.
- 패키지
P1을P2로 업그레이드해도P1에 의존하는 다른 패키지와 클라이언트는 계속P1을 사용한다. 이들은P2로 자동 업데이트되지 않는다. 의존 패키지와 클라이언트 코드 모두P2를 가리키도록 명시적으로 업데이트해야 한다. - 의존 패키지가 확장할 것으로 예상되는 패키지는 모든 버전이 따르는 표준(변하지 않는) 인터페이스를 제공하여 업그레이드 때마다 확장이 깨지지 않게 할 수 있다. Wormhole의 bridge 예제 전반에 걸친 message sending을 참고한다. 아웃바운드 메시지를 생성하는 확장 패키지는 Wormhole 패키지의 모든 버전에서
prepare_message를 사용해MessageTicket을 생성할 수 있다. 메시지를 보내는 클라이언트 코드는 그MessageTicket을 패키지 최신 버전의publish_message에 전달해야 한다.public함수 signature는 삭제하거나 변경할 수 없지만public(package)함수는 그럴 수 있다. 영구적으로 유지될 라이브러리 함수를 노출하는 경우가 아니라면public(package)또는 private visibility를 적극적으로 사용한다.struct타입을 삭제하거나, 그 정의를 변경하거나, 업그레이드를 통해 새 abilities를 추가하는 것은 불가능하다. 새 타입은 영구적으로 유지되므로 신중하게 도입한다.
테스트
- 다중 트랜잭션, 다중 송신자 테스트 시나리오를 모방하려면
sui::test_scenario모듈을 사용한다. - 더 나은 테스트 오류 메시지를 위해
std::unit_test및assert_eq!매크로에는assert_ref_eq!모듈을 사용한다. - black-hole 함수
sui::test_utils에는destroy모듈을 사용한다. std::debug를 통한 디버그 출력에는print모듈을 사용한다.- 테스트의 코드 커버리지 정보를 계산하려면
sui move test --coverage를 사용하고, 빨간색으로 강조된 미커버 line을 보려면sui move coverage source --module <name>를 사용한다. 가능하다면 코드 커버리지를 100%까지 끌어올린다.
앱
- 최적의 성능과 데이터 일관성을 위해 같은 풀 노드에 쓰기와 읽기를 제출한다. TS SDK에서는 지갑의
signTransactionBlockAPI를 사용한 뒤, 지갑의execute_transactionBlockAPI 대신 앱의 풀 노드에서signAndExecuteTransactionBlock