Skip to content

Commit 5116e8d

Browse files
committed
Data structure for collectibles
1 parent cc355f8 commit 5116e8d

4 files changed

Lines changed: 43 additions & 15 deletions

File tree

contracts/collection/src/contract.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! NFC Collection
22
3-
use soroban_sdk::{contractimpl, contracttype, panic_with_error, Address, Bytes, BytesN, Env, String, Vec};
4-
use soroban_sdk::xdr::ToXdr;
5-
use crate::{errors, events, Collection, CollectionArgs, CollectionClient, CollectionTrait};
3+
use soroban_sdk::{contractimpl, contracttype, Address, BytesN, Env, String, Vec};
4+
use crate::{Collection, CollectionArgs, CollectionClient, CollectionTrait};
65

76
#[contracttype]
87
pub enum DataKey {
@@ -13,7 +12,8 @@ pub enum DataKey {
1312
pub enum CollectionKey {
1413
NFTContract,
1514
Collections,
16-
Collectibles(Address),
15+
Collectibles(Address, u32), // (contract ID; Token ID) - Owner
16+
OwnerCollectibles(Address), // Owner - (contract ID; Token ID)
1717
}
1818

1919

@@ -31,29 +31,43 @@ impl CollectionTrait for Collection {
3131
e.deployer().update_current_contract_wasm(wasm_hash.clone());
3232
}
3333

34-
fn create_collection(e: &Env, wasm_hash: BytesN<32>, name: String, symbol: String, uri: String, max_tokens: u32) {
34+
fn create_collection(e: &Env, wasm_hash: BytesN<32>, name: String, symbol: String, uri: String, max_tokens: u32) -> Address {
3535
let admin: Address = e.storage().instance().get(&DataKey::Admin).unwrap();
3636
admin.require_auth();
3737

3838
let salt: BytesN<32> = e.crypto().sha256(&symbol.to_bytes()).into();
3939
let deployer = e.deployer().with_current_contract(salt);
40-
let contract_address = deployer.deploy_v2(wasm_hash, (name, symbol, uri, max_tokens));
40+
let contract_address = deployer.deploy_v2(wasm_hash, (admin, name, symbol, uri, max_tokens));
4141

4242
let mut collections: Vec<Address> = e.storage().instance().get(&CollectionKey::Collections).unwrap_or(Vec::new(&e));
4343
collections.push_back(contract_address.clone());
44-
e.storage().instance().set(&CollectionKey::Collections, &contract_address);
44+
e.storage().instance().set(&CollectionKey::Collections, &contract_address.clone());
45+
contract_address
4546
}
4647

4748
fn assign_collectible(e: &Env, collection: Address, to: Address, token_id: u32) {
4849
collection.require_auth();
4950

50-
let mut collectibles: Vec<(Address, u32)> = e.storage().instance().get(&CollectionKey::Collectibles(to.clone())).unwrap_or(Vec::new(&e));
51-
collectibles.push_back((collection, token_id));
52-
e.storage().instance().set(&CollectionKey::Collectibles(to), &collectibles);
51+
let collectible = (collection.clone(), token_id);
52+
53+
let owned_collectible: Option<Address> = e.storage().instance().get(&CollectionKey::Collectibles(collection.clone(), token_id.clone())).unwrap();
54+
e.storage().instance().set(&CollectionKey::Collectibles(collection.clone(), token_id.clone()), &to.clone());
55+
56+
// transferring the collectible by removing from previous owner if any
57+
if owned_collectible.is_some() {
58+
let mut owner_collectibles: Vec<(Address, u32)> = e.storage().instance().get(&CollectionKey::OwnerCollectibles(owned_collectible.unwrap().clone())).unwrap_or(Vec::new(&e));
59+
let idx_collectible = owner_collectibles.first_index_of(collectible.clone()).unwrap();
60+
owner_collectibles.remove(idx_collectible);
61+
e.storage().instance().set(&CollectionKey::OwnerCollectibles(to.clone()), &owner_collectibles);
62+
}
63+
64+
let mut owner_collectibles: Vec<(Address, u32)> = e.storage().instance().get(&CollectionKey::OwnerCollectibles(to.clone())).unwrap_or(Vec::new(&e));
65+
owner_collectibles.push_back(collectible);
66+
e.storage().instance().set(&CollectionKey::OwnerCollectibles(to), &owner_collectibles);
5367
}
5468

5569
fn collectibles(e: &Env, from: Address) -> Vec<(Address, u32)> {
56-
e.storage().instance().get(&CollectionKey::Collectibles(from.clone())).unwrap_or(Vec::new(&e))
70+
e.storage().instance().get(&CollectionKey::OwnerCollectibles(from.clone())).unwrap_or(Vec::new(&e))
5771
}
5872

5973
}

contracts/collection/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![no_std]
22
#![allow(dead_code)]
33

4-
use soroban_sdk::{contract, contractmeta, Env, Address, String, BytesN, Bytes, Vec};
4+
use soroban_sdk::{contract, contractmeta, Env, Address, String, BytesN, Vec};
55

66
contractmeta!(key = "Description", val = "ChimpDAO Collection");
77

@@ -21,7 +21,7 @@ pub trait CollectionTrait {
2121

2222
fn upgrade(e: &Env, wasm_hash: BytesN<32>);
2323

24-
fn create_collection(e: &Env, wasm_hash: BytesN<32>, name: String, symbol: String, uri: String, max_tokens: u32);
24+
fn create_collection(e: &Env, wasm_hash: BytesN<32>, name: String, symbol: String, uri: String, max_tokens: u32) -> Address;
2525

2626
fn assign_collectible(e: &Env, collection: Address, to: Address, token_id: u32);
2727

contracts/collection/src/test.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
use soroban_sdk::{testutils::Address as _, Address, Env};
1+
use soroban_sdk::{testutils::Address as _, Address, Env, String};
22

33
use crate::{Collection, CollectionClient};
44

5+
mod nfc_nft_contract {
6+
soroban_sdk::contractimport!(file = "../nfc_nft.wasm");
7+
}
8+
9+
510
fn create_client<'a>(e: &Env, admin: &Address) -> CollectionClient<'a> {
611
let address = e.register(
712
Collection,
@@ -13,11 +18,20 @@ fn create_client<'a>(e: &Env, admin: &Address) -> CollectionClient<'a> {
1318
}
1419

1520
#[test]
16-
fn test_metadata() {
21+
fn test_create_collection() {
1722
let e = Env::default();
1823
e.mock_all_auths();
1924

2025
let admin = Address::generate(&e);
2126
let client = create_client(&e, &admin);
2227

28+
let wasm = e.deployer().upload_contract_wasm(nfc_nft_contract::WASM);
29+
30+
let _collection_address = client.create_collection(
31+
&wasm,
32+
&String::from_str(&e, "TestNFT"),
33+
&String::from_str(&e, "TNFT"),
34+
&String::from_str(&e, "ipfs://abcd"),
35+
&10u32,
36+
);
2337
}

contracts/nfc_nft.wasm

7.78 KB
Binary file not shown.

0 commit comments

Comments
 (0)