Capy 프로토타입 빌드 Sui

Sui 미스텐 랩스의 새로운 프로토타입인 Capys는 개발자 프리뷰로 제공되며 Sui 에코시스템의 주요 기능을 시연합니다.

Capy 프로토타입 빌드 Sui

Sui Capys는 미스텐 랩스의 새로운 프로토타입으로, 개발자 프리뷰 역할을 하며 Sui 생태계의 주요 기능을 보여줍니다. 이 탈중앙화 게임에서 플레이어는 귀여운 남미 반수생 설치류인 카피바라를 구매, 거래, 번식, 액세서리로 꾸밀 수 있습니다. Sui 개발자는 여기에 설명된 많은 원칙과 코드 예제를 자신의 프로젝트에 맞게 적용할 수 있습니다.

Sui 블록체인의 프로그래밍 가능한 객체로, Capys 는 자산 소유권, 양도 가능성, 그리고 동적 객체 필드. 모자, 자전거, 스카프 등의 액세서리와 함께 플레이어의 지갑에 나타납니다. 지금 캐피를 미리 보려면 다음 주소로 이동하세요. Capy.art.

Sui 에서 Move 을 사용하여 Sui 카피를 개발하려면 기본 모듈을 정의하고, 유형을 만들고, 가장 중요한 것은 카피를 기록하고 검증할 수 있는 레지스트리를 구축하는 것이 필요했습니다. 프로토타입의 독특한 기능 중 하나는 기존 카피 두 마리를 번식시켜 번식 쌍의 특성에 따라 완전히 새로운 카피를 생성할 수 있다는 것입니다.

다시 한 번 말씀드리지만, 이것은 Sui 의 고유한 측면을 보여드리고 개발자가 자체 프로젝트를 구축할 때 참고할 수 있도록 하기 위한 개발자 프리뷰입니다. 캐피는 판매되지 않습니다.

고지 사항

  • 이 디앱은 현재 초기 알파 버전으로 간주되므로 가장자리가 약간 거칠 수 있습니다.
  • 디앱은 메인넷의 성숙도와 안정성을 갖추지 못한 Sui 의 데브넷에서 실행됩니다.
  • 알려진 버그가 있습니다. 알려진 Sui 지갑 버그 이 발견되었으며, 다음 주에 이 문제를 해결하기 위한 지갑 수정이 제공될 예정입니다.
  • 저희는 capy.art를 지갑 어댑터 표준인 지갑 어댑터 표준 로 업데이트할 계획입니다.
  • Sui Capys는 개발자 커뮤니티에 영감을 주기 위해 특별히 제작된 데모입니다. 이것은 에어드롭이 아닙니다. 책임감 있게 사용하시기 바랍니다. 스팸을 보내지 마세요.

카피 아키텍처

The Capy 애플리케이션(Github) 는 세 가지 모듈로 구성됩니다: capy, capy_itemscapy_market. 이러한 모듈은 Capys, 액세서리 및 거래 메커니즘을 정의합니다.

저희는 프로토타입의 재미와 성능을 높이기 위한 구체적인 원칙을 정의하는 것으로 개발 프로세스를 시작했습니다. 다음 원칙은 아키텍처 및 구현 선택을 결정하는 데 도움이 되었습니다:

  • 캐피는 모든 온체인 애플리케이션에서 자유롭게 전송하고 사용할 수 있어야 합니다.
  • 유형은 성능을 유지하기 위해 최소한의 데이터를 포함해야 합니다.
  • 이벤트를 사용하여 인덱서에서 가져올 정적 데이터를 방출할 수 있습니다.
  • 프로토타입은 나중에 새로운 프로퍼티를 추가할 수 있도록 확장 가능해야 합니다.

Sui 에서 게임과 애플리케이션을 개발하려는 개발자는 개발 프로세스를 안내할 핵심 개념을 정의하는 것부터 시작해야 합니다.

카피 코어

The capy 모듈은 Sui Capys의 핵심 기능을 정의합니다. Capy 유형을 부여하고 게시자에게 CapyManagerCap를 사용하여 무기명에 대한 관리자 기능을 엽니다. 이는 다음을 정의합니다. CapyRegistry중앙 집중식 프로토타입 상태와 이를 발전시킬 수 있는 방법에 대해 설명합니다.

유형: Capy

Capy는 애플리케이션의 기본 유형으로, 정의된 속성 집합을 가진 소유 객체입니다: 32개의 유전자와 프로토타입 기능에 필요한 추가 유틸리티 정보. Capy 에는 두 가지 능력이 있습니다, 그리고 store. 전자는 소유 가능한 자산이 되고 후자는 자유로운 양도 및 포장이 가능합니다.

  • The gen 속성은 카피의 세대를 표시합니다. 첫 번째 카피는 0세대새로운 품종은 부모 세대에 한 세대를 더합니다. 1세대, 2세대
  • The src 속성을 사용하면 탐색기에서 이미지를 표시할 수 있습니다. 캐피 자체는 동적이며 새 항목이 추가될 때 변경될 수 있으므로 전체 이미지를 저장하지 않습니다.
  • The 유전자 속성은 32바이트 벡터인 유전자 서열을 저장하며, 이는 번식 중에 특성을 계산하고 신생아의 유전자를 선택하는 데 사용됩니다.
  • The item_count 는 각 Capy에 연결된 오브젝트 수를 추적하는 유틸리티 프로퍼티입니다.
  • The 속성 속성은 번식 중에 생성된 사람이 읽을 수 있는 속성을 저장합니다. 예를 들어 { “name": "pattern", "value": "panda" }.

이 필드 집합은 번식 또는 항목 추가/제거를 포함한 Sui Capys 기능에 필요한 최소한의 요구 사항입니다.

제목 없음.png
/// The Capy itself. Every Capy has its unique set of genes,
/// as well as generation and utility information. Ownable, tradeable.
struct Capy has key, store {
    id: UID,
    gen: u64,
    url: Url,
    genes: Genes,
    item_count: u8,
    attributes: vector<Attribute>,
}

유형: 캐피 레지스트리

CapyRegistry는 번식에 필요한 공유 객체로, 지금까지 태어난 카피의 총 수를 저장하며 번식 중 유전자 선택에 사용되는 아래 유전자 과학 섹션에 설명된 의사 무작위 씨앗을 포함합니다. 여기에는 번식 단계에서 신생아에게 할당된 모든 속성 정의가 포함되어 있습니다.

아래 관리자 기능 섹션에 설명된 대로 새 속성을 프로토타입에 추가할 수 있습니다.

/// Every capybara is registered here. CapyRegistry acts as a source of randomness
/// as well as the storage for the main information about the game state.
struct CapyRegistry has key {
    id: UID,
    capy_born: u64,
    capy_hash: vector<u8>,
    genes: vector<GeneDefinition>
}

유형: CapyManagerCap

The CapyManagerCap 는 모듈이 게시될 때 모듈 게시자(게시 트랜잭션의 발신자)에게 전송되는 기능입니다. 다음을 포함한 모든 모듈의 관리자 작업에 권한을 부여합니다. capy_items 그리고 capy_market.

이니셜라이저

Capys는 독립형(일반적이지 않은) 애플리케이션이므로 모듈 이니셜라이저에서 주요 로직을 시작할 수 있습니다. 모듈 초기화 프로그램에서 init 함수는 두 가지 작업을 수행합니다:

  1. 를 생성합니다. CapyManagerCap 를 생성하여 모듈 게시자에게 보냅니다.
  2. 생성 및 공유 CapyRegistry.

관리자 기능

애플리케이션을 재생할 수 있게 하고 의미를 부여하려면 관리자가 일련의 작업을 수행해야 합니다:

  • The add_gene 함수는 새로운 유전자 정의 에서 CapyRegistry. 번식하는 동안 레지스트리의 모든 기존 속성이 새 Capy에 할당됩니다. 새로운 유전자 정의 (속성)이 프로토타입에 추가되었으며, 이 속성 추가 이전에 태어난 카피는 이 속성을 얻지 못하지만 그 자손은 얻게 됩니다. 각 유전자 정의에는 이름과 각 속성의 값을 선택하는 데 사용되는 선택기 세트가 있습니다.
  • The 배치 기능을 사용하면 미리 정의된 유전자를 가진 Capy를 일괄 생성할 수 있습니다. 이 기능은 초기화 및 이후 단계에서 신규 사용자를 위해 더 많은 Capys를 마켓플레이스에 채우는 데 사용됩니다.

번식

예측 불가능성을 생성하고 프로토타입의 진화를 돕는 주요 로직은 다음과 같습니다. capy::breed 기능을 사용할 수 있습니다. 캐피가 두 개 있는 플레이어라면 누구나 이 기능을 수행할 수 있습니다. 이 함수의 로직은 다음과 같습니다:

  1. 기준 CapyRegistry.capy_hash 새로운 유전자를 위한 부모 유전자 선택 Capy.
  2. 현재 목록 가져오기 유전자 정의 에서 CapyRegistry 를 클릭하고 속성을 설정합니다.
  3. 새 Capy의 데이터로 이벤트를 발생시킵니다.
  4. 새로운 Capy (사용 BREED_AND_KEEP 를 클릭하여 발신자에게 보냅니다).
 public fun breed(
    reg: &mut CapyRegistry, c1: &mut Capy, c2: &mut Capy, ctx: &mut TxContext
): Capy {
    let id = object::new(ctx);

    // Update capy hash in the registry
    vec::append(&mut reg.capy_hash, object::uid_to_bytes(&id));
    reg.capy_hash = hash(reg.capy_hash);

    // compute genes
    let genes = compute_genes(&reg.capy_hash, &c1.genes, &c2.genes, GENES);
    let gen = math::max(c1.gen, c2.gen) + 1;
    let attributes = get_attributes(&reg.genes, &genes);
    let sender = tx_context::sender(ctx);

    emit(CapyBorn { /* ... */ }); 

    // Send newborn to parents.
    Capy {
        url: img_url(&id),
        id,
        gen,
        genes,
        attributes,
        item_count: 0,
    }
}

유전자 과학

애플리케이션의 가장 흥미로운 부분을 살펴보기 전에, 이 솔루션은 절대적인 예측 불가능성을 제공하지 않으므로 위험이 큰 애플리케이션에 사용해서는 안 된다는 점에 유의해야 합니다. 하지만 사용자 입력을 의사 무작위 수정자로 전환하여 어느 정도의 무작위성을 생성합니다.

제목 없음 (1).png

이 프로토타입의 정말 재미있고 독특한 기능은 다음과 같은 기능입니다. 품종 두 개의 기존 카피가 세 번째 카피를 생성합니다. 새 카피는 부모 카피의 특성을 상속받습니다.

번식 함수는 두 개의 부모 카피를 가져와 신생아를 위한 유전자를 계산합니다. 이 작업이 공정하고 무작위로 이루어지려면 선택 알고리즘과 시드가 필요합니다. CapyRegistry 는 시드( capy_hash)에 저장되며 각 품종마다 업데이트됩니다. 알고리즘은 다음과 같습니다:

83C758FA-D971-4CAB-BE6D-346DDA6B9C5F.jpeg
  1. 해시 함수 사용(sha3_256)를 소금으로 세 번 반복하여 32바이트의 벡터 세 개(A, B, C로 표시)를 생성합니다. capy_hash.
  2. 첫 번째 벡터(A)를 부모 유전자 선택에 사용합니다. N번째 바이트의 값이 126보다 크면 첫 번째 부모 유전자를 선택합니다. 그렇지 않으면 두 번째 부모 유전자를 선택합니다. 위 다이어그램과 같이 첫 번째 유전자는 P2, 두 번째는 P1, 세 번째는 P2, 네 번째는 다시 P1이 됩니다(최대 N=32까지).
  3. 두 번째 벡터(B)는 돌연변이 확률을 정의합니다. 위치 N의 값이 250보다 크면 세 번째 벡터(C)에서 같은 위치를 사용하여 돌연변이 값을 선택합니다. 이 예에서는 세 번째 유전자가 돌연변이를 일으키고 그 값은 42가 됩니다.
/// Computes genes for the newborn based on the 'random' seed r0, and parents' genes.
///
/// The `max` parameter affects how many genes should be changed.
/// For example, if the number of genes is 32 but only 4 Attributes defined in the
/// registry, the `max` should be set to 4. Remainder genes should not mutate.
fun compute_genes(r0: &vector<u8>, g1: &Genes, g2: &Genes, max: u64): Genes {
    let i = 0;

    let s1 = &g1.sequence;
    let s2 = &g2.sequence;
    let s3 = vec::empty();

    let r1 = derive(r0, 1); // for parent gene selection
    let r2 = derive(r0, 2); // chance of random mutation
    let r3 = derive(r0, 3); // value selector for random mutation

    while (i < max) {
        let rng = *vec::borrow(&r1, i);
        let gene = if (lor(rng, 127)) {
            *vec::borrow(s1, i)
        } else {
            *vec::borrow(s2, i)
        };

        // There's a tiny chance that a mutation will happen.
        if (lor(*vec::borrow(&r2, i), MUTATION_CHANCE)) {
            gene = *vec::borrow(&r3, i);
        };

        vec::push_back(&mut s3, gene);
        i = i + 1;
    };

    Genes { sequence: s3 }
}

캐피 아이템

이 매우 간단한 모듈은 각 Capy에 추가할 수 있는 웨어러블 아이템과 프론트엔드 디스플레이를 구현하는 방법을 정의합니다. 아이템은 Capy 관리자만 추가할 수 있습니다. CapyManagerCap.

제목 없음 (2).png
/// Wearable item. Has special display in capy.art application
struct CapyItem has key, store {
  id: UID,
  url: Url,
  type: String,
  name: String,
}

항목 관리

Capys에 액세서리를 추가하고 제거하려면 동적 객체 필드를 사용하여 Sui 에서 부모-자식 객체를 보다 효율적이고 사용자 친화적으로 대체할 수 있습니다. 동적 필드는 임의의 이름을 허용하며 즉석에서 추가 및 제거할 수 있습니다.


다음 코드는 Capy에 아이템을 추가합니다:

entry fun add_item<T: key + store>(capy: &mut Capy, item: T) {
    emit(ItemAdded<T> {
        capy_id: object::id(capy),
        item_id: object::id(&item)
    });

    dof::add(&mut capy.id, object::id(&item), item);
}

카피 마켓

인수 및 판매 CapyCapyItems에서 캐피 마켓을 만들었습니다. 이 모듈은 동적 객체 필드를 사용하고 아이템을 결제한 후에만 획득할 수 있도록 잠급니다. 가격. 이 마켓플레이스 아키텍처에서는 하나의 아이템 유형당 하나의 마켓플레이스 개체가 존재합니다(CapyMarket<Capy> 판매 Capy를 다른 객체와 함께 사용합니다, CapyMarket<CapyItem>)의 경우, 리스팅은 동적 개체 필드로 마켓플레이스에 첨부되며, 리스팅에 첨부된 개체는 리스팅에 첨부됩니다.

+--> Listing --> T
CapyMarket<T> +--> Listing --> T
+--> Listing --> T

마켓플레이스 및 목록 기능

각 마켓플레이스 인스턴스는 하나의 유형만 지원합니다. 이 애플리케이션에서는 마켓플레이스 인스턴스 하나에 대해 Capy 유형과 다른 하나는 CapyItem 유형입니다.

/// A generic marketplace for anything. T marks the type for Listings.
struct CapyMarket<phantom T: key + store> has key { id: UID }

/// A listing for the marketplace. Contains the price and owner of the Listing.
struct Listing<phantom T: key + store> has key, store {
    id: UID,
    price: u64,
    owner: address
}

The 목록 함수는 동적 필드. 나열된 항목을 리스팅 그런 다음 리스팅 의 분야 카피마켓.

/// List a new item on the `CapyMarket`.
public entry fun list<T: key + store>(
    market: &mut CapyMarket<T>,
    item: T,
    price: u64,
    ctx: &mut TxContext
) {
    let id = object::new(ctx);
    let item_id = object::id(&item);
    let owner = tx_context::sender(ctx);

    emit(ItemListed<T> { /* ... */ });

    // First attach Item to the Listing with a boolean `true` value;
    // Then attach listing to the marketplace through `item.id`;
    dynamic_object_field::add(&mut id, true, item);
    dynamic_object_field::add(&mut market.id, item_id, Listing<T> { 
id, price, owner 
});
}

카피 영감

유니티는 Sui 의 주요 기능 몇 가지를 선보이고 개발자들의 프로젝트에 영감을 주기 위해 Capy 프로토타입을 만들었습니다. Capy는 Sui의 객체 지향적 특성을 활용하여 플레이어가 거래하고 구매할 수 있는 휴대용 액세서리와 부모의 속성을 기반으로 새로운 Capy를 생성할 수 있도록 합니다. 유니티는 사용자와 개발자가 모두 만족할 수 있도록 프로토타입을 무한대로 확장할 수 있도록 설계했습니다.

이 예제와 코드가 Sui 개발자에게 도움이 되길 바랍니다. 주목해야 할 몇 가지 구현에는 Capy Market, 액세서리, 번식이 포함됩니다. 카피 마켓은 모든 거래 또는 상점 메커니즘의 모델 역할을 합니다. 액세서리는동적 필드. 번식은 무한히 응용할 수 있는 새로운 오브젝트를 자동으로 생성하는 독특한 수단을 제공합니다.