Skip to content

Commit b041926

Browse files
authored
[stdlib] Support update NFTTypeInfo metadata. (starcoinorg#2952)
* [stdlib] Support update NFTTypeInfo metadata. * [test] Use NFT v2 function in functional test. * [stdlib & genesis] Generate stdlib and genesis.
1 parent 5cf6ad2 commit b041926

File tree

9 files changed

+86
-29
lines changed

9 files changed

+86
-29
lines changed

genesis/generated/halley/genesis

200 Bytes
Binary file not shown.

vm/functional-tests/tests/testsuite/nft/identifier_nft.move

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module creator::XMembership {
2020
use 0x1::Signer;
2121
use 0x1::Option;
2222

23-
struct XMembershipInfo has copy, store, drop{
23+
struct XMembershipInfo has copy, store, drop, key{
2424
price_per_millis: u128,
2525
}
2626

@@ -47,7 +47,9 @@ module creator::XMembership {
4747

4848
public fun init(sender: &signer){
4949
assert(Signer::address_of(sender) == @creator, 1000);
50-
NFT::register<XMembership,XMembershipInfo>(sender, XMembershipInfo{ price_per_millis:2 }, NFT::empty_meta());
50+
51+
NFT::register_v2<XMembership>(sender, NFT::empty_meta());
52+
move_to(sender, XMembershipInfo{ price_per_millis:2 });
5153
let cap = NFT::remove_mint_capability<XMembership>(sender);
5254
move_to(sender, XMembershipMintCapability{ cap});
5355

@@ -58,14 +60,14 @@ module creator::XMembership {
5860
move_to(sender, XMembershipUpdateCapability{ cap});
5961
}
6062

61-
public fun join(sender: &signer, fee: u128) acquires XMembershipMintCapability{
63+
public fun join(sender: &signer, fee: u128) acquires XMembershipMintCapability, XMembershipInfo{
6264
let token = Account::withdraw<STC>(sender, fee);
6365
let cap = borrow_global_mut<XMembershipMintCapability>(@creator);
6466
let metadata = NFT::new_meta_with_image(b"xmembership", b"ipfs:://xxxxxx", b"This is a XMembership nft.");
65-
let info = NFT::nft_type_info_ex_info<XMembership,XMembershipInfo>();
67+
let info = borrow_global<XMembershipInfo>(@creator);
6668
let join_time = Timestamp::now_milliseconds();
6769
let end_time = join_time + ((Token::value(&token)/info.price_per_millis) as u64);
68-
let nft = NFT::mint_with_cap<XMembership,XMembershipBody,XMembershipInfo>(@creator, &mut cap.cap, metadata, XMembership{ join_time, end_time}, XMembershipBody{ fee: token});
70+
let nft = NFT::mint_with_cap_v2<XMembership,XMembershipBody>(@creator, &mut cap.cap, metadata, XMembership{ join_time, end_time}, XMembershipBody{ fee: token});
6971
IdentifierNFT::grant(&mut cap.cap, sender, nft);
7072
}
7173

vm/functional-tests/tests/testsuite/nft/nft_boxminer.move

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ module creator::BoxMiner {
88
use 0x1::Account;
99
use 0x1::NFTGallery;
1010
use 0x1::STC::STC;
11+
use 0x1::Signer;
1112

1213
struct BoxMiner has copy, store, drop{
1314
price: u128,
1415
}
1516

16-
struct NFTInfo has copy, store, drop{
17+
struct NFTInfo has copy, store, drop, key{
1718
total_supply: u64,
1819
price: u128,
1920
}
@@ -24,8 +25,10 @@ module creator::BoxMiner {
2425
}
2526

2627
public fun init(sender: &signer, total_supply:u64, price: u128){
28+
assert(Signer::address_of(sender) == @creator, 1000);
2729
let meta = NFT::new_meta_with_image(b"stc_box_miner_nft", b"ipfs:://xxx", b"This is the starcoin boxminer nft");
28-
NFT::register<BoxMiner, NFTInfo>(sender, NFTInfo{total_supply, price}, meta);
30+
NFT::register_v2<BoxMiner>(sender, meta);
31+
move_to(sender, NFTInfo{total_supply, price});
2932
let cap = NFT::remove_mint_capability<BoxMiner>(sender);
3033
move_to(sender, BoxMinerMintCapability{cap});
3134
}
@@ -34,17 +37,17 @@ module creator::BoxMiner {
3437
NFTGallery::accept<BoxMiner, BoxMinerBody>(sender);
3538
}
3639

37-
public fun mint(sender: &signer): NFT<BoxMiner, BoxMinerBody> acquires BoxMinerMintCapability{
38-
let ex_info = NFT::nft_type_info_ex_info<BoxMiner, NFTInfo>();
39-
let counter = NFT::nft_type_info_counter<BoxMiner, NFTInfo>();
40+
public fun mint(sender: &signer): NFT<BoxMiner, BoxMinerBody> acquires BoxMinerMintCapability, NFTInfo{
41+
let ex_info = borrow_global<NFTInfo>(@creator);
42+
let counter = NFT::nft_type_info_counter_v2<BoxMiner>();
4043
let total_supply = ex_info.total_supply;
4144
let price = ex_info.price;
4245
assert(total_supply >= counter, 1000);
4346
let tokens = Account::withdraw<STC>(sender, price);
4447
Account::deposit<STC>(@creator, tokens);
4548
let cap = borrow_global_mut<BoxMinerMintCapability>(@creator);
4649
let metadata = NFT::new_meta(b"stc_box_miner", b"This is the starcoin boxminer.");
47-
let nft = NFT::mint_with_cap<BoxMiner, BoxMinerBody, NFTInfo>(@creator, &mut cap.cap, metadata, BoxMiner{price}, BoxMinerBody{});
50+
let nft = NFT::mint_with_cap_v2<BoxMiner, BoxMinerBody>(@creator, &mut cap.cap, metadata, BoxMiner{price}, BoxMinerBody{});
4851
return nft
4952
}
5053
}

vm/functional-tests/tests/testsuite/nft/nft_card.move

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ module creator::Card {
2020
second: L1Card,
2121
}
2222

23-
struct NFTInfo has copy, store, drop{}
24-
2523
struct L1CardMintCapability has key{
2624
cap: MintCapability<L1CardMeta>,
2725
}
@@ -39,13 +37,13 @@ module creator::Card {
3937
}
4038

4139
public fun init(sender: &signer){
42-
NFT::register<L1CardMeta, NFTInfo>(sender,NFTInfo{}, NFT::empty_meta());
40+
NFT::register_v2<L1CardMeta>(sender, NFT::empty_meta());
4341
let cap = NFT::remove_mint_capability<L1CardMeta>(sender);
4442
move_to(sender, L1CardMintCapability{ cap});
4543

4644
let cap = NFT::remove_burn_capability<L1CardMeta>(sender);
4745
move_to(sender, L1CardBurnCapability{ cap});
48-
NFT::register<L2CardMeta, NFTInfo>(sender,NFTInfo{}, NFT::empty_meta());
46+
NFT::register_v2<L2CardMeta>(sender, NFT::empty_meta());
4947
let cap = NFT::remove_mint_capability<L2CardMeta>(sender);
5048
move_to(sender, L2CardMintCapability{ cap});
5149

@@ -56,7 +54,7 @@ module creator::Card {
5654
public fun mint_l1(_sender: &signer): NFT<L1CardMeta, L1Card> acquires L1CardMintCapability{
5755
let cap = borrow_global_mut<L1CardMintCapability>(@creator);
5856
let metadata = NFT::new_meta_with_image(b"l1_card", b"ipfs:://xxxxxx", b"This is a L1CardMeta nft.");
59-
NFT::mint_with_cap<L1CardMeta, L1Card, NFTInfo>(@creator, &mut cap.cap, metadata, L1CardMeta{ gene: Timestamp::now_milliseconds()}, L1Card{})
57+
NFT::mint_with_cap_v2<L1CardMeta, L1Card>(@creator, &mut cap.cap, metadata, L1CardMeta{ gene: Timestamp::now_milliseconds()}, L1Card{})
6058
}
6159

6260
public fun mint_l2(_sender: &signer, first: NFT<L1CardMeta, L1Card>, second: NFT<L1CardMeta, L1Card>): NFT<L2CardMeta,L2Card> acquires L1CardBurnCapability, L2CardMintCapability {
@@ -70,7 +68,7 @@ module creator::Card {
7068
let s = NFT::burn_with_cap(&mut burn_cap.cap, second);
7169
let mint_cap = borrow_global_mut<L2CardMintCapability>(@creator);
7270
let metadata = NFT::new_meta_with_image(b"l2_card", b"ipfs:://xxxxxx", b"This is a L2CardMeta nft.");
73-
NFT::mint_with_cap<L2CardMeta, L2Card, NFTInfo>(@creator, &mut mint_cap.cap, metadata, L2CardMeta{
71+
NFT::mint_with_cap_v2<L2CardMeta, L2Card>(@creator, &mut mint_cap.cap, metadata, L2CardMeta{
7472
gene: new_gene,
7573
}, L2Card{
7674
first:f,

vm/functional-tests/tests/testsuite/nft/nft_metadata.move

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
address creator = {{creator}};
66
module creator::Card {
77
use 0x1::Timestamp;
8-
use 0x1::NFT::{Self, NFT, MintCapability, BurnCapability, UpdateCapability};
8+
use 0x1::NFT::{Self, NFT, Metadata, MintCapability, BurnCapability, UpdateCapability};
9+
use 0x1::Signer;
910

1011
struct Card has copy, store, drop{
1112
upgrade_time: u64,
@@ -23,8 +24,6 @@ module creator::Card {
2324
cap: BurnCapability<Card>,
2425
}
2526

26-
struct NFTInfo has copy, drop, store{}
27-
2827
struct CardUpdateCapability has key{
2928
cap: UpdateCapability<Card>,
3029
}
@@ -38,7 +37,8 @@ module creator::Card {
3837
}
3938

4039
public fun init(sender: &signer){
41-
NFT::register<Card, NFTInfo>(sender, NFTInfo{}, NFT::empty_meta());
40+
assert(Signer::address_of(sender) == @creator, 1000);
41+
NFT::register_v2<Card>(sender, NFT::empty_meta());
4242
let cap = NFT::remove_mint_capability<Card>(sender);
4343
move_to(sender, CardMintCapability{ cap});
4444

@@ -52,7 +52,7 @@ module creator::Card {
5252
public fun mint(_sender: &signer): NFT<Card, CardBody> acquires CardMintCapability{
5353
let cap = borrow_global_mut<CardMintCapability>(@creator);
5454
let metadata = NFT::new_meta_with_image(b"card", b"ipfs:://xxxxxx", b"This is a Card nft.");
55-
NFT::mint_with_cap<Card, CardBody, NFTInfo>(@creator, &mut cap.cap, metadata, Card{ upgrade_time: Timestamp::now_milliseconds()}, CardBody{ level: 1})
55+
NFT::mint_with_cap_v2<Card, CardBody>(@creator, &mut cap.cap, metadata, Card{ upgrade_time: Timestamp::now_milliseconds()}, CardBody{ level: 1})
5656
}
5757

5858
/// upgrade the first card by burn the second card.
@@ -76,6 +76,12 @@ module creator::Card {
7676
let body = NFT::borrow_body_mut_with_cap(&mut update_cap.cap, first);
7777
body.level = level;
7878
}
79+
80+
public fun update_type_info_meta(sender: &signer, meta: Metadata) acquires CardUpdateCapability{
81+
assert(Signer::address_of(sender) == @creator, 1000);
82+
let update_cap = borrow_global_mut<CardUpdateCapability>(@creator);
83+
NFT::update_nft_type_info_meta_with_cap(&mut update_cap.cap, meta);
84+
}
7985
}
8086

8187
// check: EXECUTED
@@ -152,4 +158,34 @@ script {
152158
}
153159
}
154160

161+
// check: EXECUTED
162+
163+
164+
//! new-transaction
165+
//! sender: creator
166+
address creator = {{creator}};
167+
script {
168+
use creator::Card::{Self, Card};
169+
use 0x1::NFT;
170+
171+
fun main(sender: signer) {
172+
let type_meta = NFT::nft_type_info_meta<Card>();
173+
assert(NFT::meta_name(&type_meta) == b"", 1004);
174+
assert(NFT::meta_image(&type_meta) == b"", 1005);
175+
assert(NFT::meta_description(&type_meta) == b"", 1006);
176+
177+
let name = b"card";
178+
let image = b"ipfs://image_hash";
179+
let description = b"a card game nft";
180+
let new_meta = NFT::new_meta_with_image(*&name, *&image, *&description);
181+
182+
Card::update_type_info_meta(&sender, new_meta);
183+
184+
let type_meta = NFT::nft_type_info_meta<Card>();
185+
assert(NFT::meta_name(&type_meta) == name, 1007);
186+
assert(NFT::meta_image(&type_meta) == image, 1008);
187+
assert(NFT::meta_description(&type_meta) == description, 1009);
188+
}
189+
}
190+
155191
// check: EXECUTED

vm/functional-tests/tests/testsuite/nft/test_gallery.move

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ module creator::AnyNFT {
1010
struct AnyNFT has copy, store, drop{}
1111
struct AnyNFTBody has store{
1212
}
13-
struct AnyNFTInfo has copy,store,drop{}
1413

1514
struct AnyNFTMintCapability has key{
1615
cap: MintCapability<AnyNFT>,
@@ -21,7 +20,7 @@ module creator::AnyNFT {
2120
}
2221

2322
public fun init(sender: &signer){
24-
NFT::register<AnyNFT,AnyNFTInfo>(sender, AnyNFTInfo{}, NFT::empty_meta());
23+
NFT::register_v2<AnyNFT>(sender,NFT::empty_meta());
2524
let cap = NFT::remove_mint_capability<AnyNFT>(sender);
2625
move_to(sender, AnyNFTMintCapability{cap});
2726
let cap = NFT::remove_burn_capability<AnyNFT>(sender);
@@ -33,7 +32,7 @@ module creator::AnyNFT {
3332
let sender_addr = Signer::address_of(sender);
3433
let cap = borrow_global_mut<AnyNFTMintCapability>(@creator);
3534
let metadata = NFT::new_meta_with_image(b"test_nft_1", b"ipfs:://xxxxxx", b"This is a test nft.");
36-
let nft = NFT::mint_with_cap<AnyNFT,AnyNFTBody,AnyNFTInfo>(sender_addr, &mut cap.cap, metadata, AnyNFT{}, AnyNFTBody{});
35+
let nft = NFT::mint_with_cap_v2<AnyNFT,AnyNFTBody>(sender_addr, &mut cap.cap, metadata, AnyNFT{}, AnyNFTBody{});
3736
NFTGallery::deposit(sender, nft);
3837
}
3938

vm/functional-tests/tests/testsuite/nft/test_nft.move

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,14 @@ module creator::TestNFT {
99
struct TestNFT has copy, store, drop{}
1010
struct TestNFTBody has store{
1111
}
12-
struct NFTInfo has copy,store,drop{}
1312
public fun init(sender: &signer){
14-
NFT::register<TestNFT,NFTInfo>(sender, NFTInfo{},NFT::empty_meta());
13+
NFT::register_v2<TestNFT>(sender, NFT::empty_meta());
1514
Self::do_accept(sender);
1615
}
1716

1817
public fun mint(sender: &signer){
1918
let metadata = NFT::new_meta_with_image(b"test_nft_1", b"ipfs:://xxxxxx", b"This is a test nft.");
20-
let nft = NFT::mint<TestNFT,TestNFTBody,NFTInfo>(sender, metadata, TestNFT{}, TestNFTBody{});
19+
let nft = NFT::mint_v2<TestNFT,TestNFTBody>(sender, metadata, TestNFT{}, TestNFTBody{});
2120
NFTGallery::deposit(sender, nft);
2221
}
2322

200 Bytes
Binary file not shown.

vm/stdlib/modules/NFT.move

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ module NFT {
8282
}
8383
}
8484

85+
/// Note: this function is deprecated, please use nft_type_info_counter_v2
8586
public fun nft_type_info_counter<NFTMeta: copy + store + drop, NFTTypeInfoExt: copy + store + drop>(): u64 acquires NFTTypeInfo, NFTTypeInfoV2 {
8687
if(exists<NFTTypeInfoV2<NFTMeta>>(CoreAddresses::GENESIS_ADDRESS())){
8788
Self::nft_type_info_counter_v2<NFTMeta>()
@@ -96,6 +97,11 @@ module NFT {
9697
*&info.counter
9798
}
9899

100+
public fun nft_type_info_meta<NFTMeta: copy + store + drop>(): Metadata acquires NFTTypeInfoV2 {
101+
let info = borrow_global_mut<NFTTypeInfoV2<NFTMeta>>(CoreAddresses::GENESIS_ADDRESS());
102+
*&info.meta
103+
}
104+
99105
public fun upgrade_nft_type_info_from_v1_to_v2<NFTMeta: copy + store + drop, NFTTypeInfoExt: copy + store + drop>(sender: &signer, _cap: &mut MintCapability<NFTMeta>) acquires NFTTypeInfo{
100106
if(exists<NFTTypeInfo<NFTMeta, NFTTypeInfoExt>>(CoreAddresses::GENESIS_ADDRESS())) {
101107
let nft_type_info = move_from<NFTTypeInfo<NFTMeta, NFTTypeInfoExt>>(CoreAddresses::GENESIS_ADDRESS());
@@ -120,7 +126,7 @@ module NFT {
120126
let NFTTypeInfoCompat{info} = compat_info;
121127
info
122128
}
123-
129+
/// deprecated.
124130
struct GenesisSignerCapability has key {
125131
cap: Account::SignerCapability,
126132
}
@@ -424,6 +430,20 @@ module NFT {
424430
let UpdateCapability {} = cap;
425431
}
426432

433+
/// Update the NFTTypeInfoV2 metadata with UpdateCapability<NFTMeta>
434+
public fun update_nft_type_info_meta_with_cap<NFTMeta: copy + store + drop>(_cap: &mut UpdateCapability<NFTMeta>, new_meta: Metadata) acquires NFTTypeInfoV2{
435+
let info = borrow_global_mut<NFTTypeInfoV2<NFTMeta>>(CoreAddresses::GENESIS_ADDRESS());
436+
info.meta = new_meta;
437+
}
438+
439+
/// Update the NFTTypeInfoV2 metadata, the `sender` must have UpdateCapability<NFTMeta>
440+
public fun update_nft_type_info_meta<NFTMeta: copy + store + drop, NFTBody: store>(sender: &signer, new_meta: Metadata) acquires UpdateCapability, NFTTypeInfoV2 {
441+
let addr = Signer::address_of(sender);
442+
assert(exists<UpdateCapability<NFTMeta>>(addr), Errors::requires_capability(ERR_NO_UPDATE_CAPABILITY));
443+
let cap = borrow_global_mut<UpdateCapability<NFTMeta>>(addr);
444+
update_nft_type_info_meta_with_cap(cap, new_meta)
445+
}
446+
427447
/// Update the nft's base_meta and type_meta with UpdateCapability<NFTMeta>
428448
public fun update_meta_with_cap<NFTMeta: copy + store + drop, NFTBody: store>(_cap: &mut UpdateCapability<NFTMeta>, nft: &mut NFT<NFTMeta, NFTBody>, base_meta: Metadata, type_meta: NFTMeta) {
429449
nft.base_meta = base_meta;

0 commit comments

Comments
 (0)