-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Yunseongpyo] NFT Contract 작성 #3
base: develop
Are you sure you want to change the base?
Changes from 1 commit
4caec2e
99d98a4
4762cd2
8a752c3
0beedda
d3f7208
4ee326c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1127,8 +1127,10 @@ contract KIP17Metadata is KIP13, KIP17, IKIP17Metadata { | |
|
||
// Optional mapping for token URIs | ||
mapping(uint256 => string) private _tokenURIs; | ||
// 🔥 mapping for token Level | ||
mapping(uint256 => uint) private _tokenLevel; | ||
// 🔥 mapping for nftType | ||
mapping(uint256 => uint) private _nftType; | ||
|
||
mapping(uint256 => string) private _menuType; | ||
/* | ||
* bytes4(keccak256('name()')) == 0x06fdde03 | ||
* bytes4(keccak256('symbol()')) == 0x95d89b41 | ||
|
@@ -1179,18 +1181,27 @@ contract KIP17Metadata is KIP13, KIP17, IKIP17Metadata { | |
} | ||
|
||
/** | ||
* @dev 🔥 Returns an level for a given token ID. | ||
* @dev 🔥 Returns an nftType for a given token ID. | ||
* Throws if the token ID does not exist. May return an empty string. | ||
* @param tokenId uint256 ID of the token to query | ||
*/ | ||
function tokenLevel(uint256 tokenId) external view returns (uint) { | ||
function nftType(uint256 tokenId) external view returns (uint) { | ||
require(_exists(tokenId), "KIP17Metadata: URI query for nonexistent token"); | ||
return _tokenLevel[tokenId]; | ||
return _nftType[tokenId]; | ||
} | ||
|
||
function menuType(uint256 tokenId) external view returns (string memory) { | ||
require( | ||
_exists(tokenId), | ||
"KIP17Metadata: URI query for nonexistent token" | ||
); | ||
return _menuType[tokenId]; | ||
} | ||
|
||
|
||
//소유한 토큰 종류 확인(맞으면 true, 아니면 false) | ||
function _ownTokenLevel(uint256 tokenId, uint level) internal returns (bool){ | ||
return _tokenLevel[tokenId]==level; | ||
function _ownNftType(uint256 tokenId, string memory menuType) internal returns (bool){ | ||
return keccak256(abi.encodePacked(_menuType[tokenId])) == keccak256(abi.encodePacked(menuType)); | ||
} | ||
|
||
/** | ||
|
@@ -1207,16 +1218,19 @@ contract KIP17Metadata is KIP13, KIP17, IKIP17Metadata { | |
_tokenURIs[tokenId] = uri; | ||
} | ||
|
||
/** | ||
* @dev 🔥 Internal function to set the token level for a given token. | ||
* Reverts if the token ID does not exist. | ||
* @param tokenId uint256 ID of the token to set its URI | ||
* @param level uint to assign | ||
*/ | ||
function _setTokenLevel(uint256 tokenId, uint level) internal { | ||
|
||
function _setNftType(uint256 tokenId, uint nftType) internal { | ||
require(_exists(tokenId), "KIP17Metadata: URI set of nonexistent token"); | ||
_tokenLevel[tokenId] = level; | ||
_nftType[tokenId] = nftType; | ||
} | ||
|
||
|
||
function _setMenuType(uint256 tokenId, string memory menuType) internal{ | ||
require(_exists(tokenId), "KIP17Metadata: URI set of nonexistent token"); | ||
_menuType[tokenId] = menuType; | ||
} | ||
|
||
|
||
/** | ||
* @dev Internal function to burn a specific token. | ||
* Reverts if the token does not exist. | ||
|
@@ -1225,10 +1239,14 @@ contract KIP17Metadata is KIP13, KIP17, IKIP17Metadata { | |
* @param tokenId uint256 ID of the token being burned by the msg.sender | ||
*/ | ||
//마스터 발급을 위한 기존 메뉴 NFT삭제 | ||
function _burnForMasterNFT(address owner, uint256 tokenId, uint level) internal{ | ||
if(level == _tokenLevel[tokenId]) | ||
function _burnForMasterNFT(address owner, uint256 tokenId, string memory menuType) internal returns (bool){ | ||
if(keccak256(abi.encodePacked(_menuType[tokenId])) == keccak256(abi.encodePacked(menuType))) | ||
{ | ||
_burn(owner, tokenId); | ||
return true; | ||
} | ||
else{ | ||
return false; | ||
} | ||
} | ||
|
||
|
@@ -1240,8 +1258,12 @@ contract KIP17Metadata is KIP13, KIP17, IKIP17Metadata { | |
if (bytes(_tokenURIs[tokenId]).length != 0) { | ||
delete _tokenURIs[tokenId]; | ||
} | ||
if (_tokenLevel[tokenId] > 0) { | ||
delete _tokenLevel[tokenId]; | ||
if (_nftType[tokenId] > 0) { | ||
delete _nftType[tokenId]; | ||
} | ||
if (bytes(_menuType[tokenId]).length != 0){ | ||
delete _menuType[tokenId]; | ||
|
||
} | ||
|
||
} | ||
|
@@ -1392,16 +1414,17 @@ contract KIP17MetadataMintable is KIP13, KIP17, KIP17Metadata, MinterRole { | |
* @param tokenURI The token URI of the minted token. | ||
* @return A boolean that indicates if the operation was successful. | ||
*/ | ||
// tokenLevel 추가 | ||
function mintWithTokenURI( | ||
address to, | ||
uint256 tokenId, | ||
string memory tokenURI, | ||
uint level | ||
uint nftType, | ||
string memory menuType | ||
) public onlyMinter returns (bool) { | ||
_mint(to, tokenId); | ||
_setTokenURI(tokenId, tokenURI); | ||
_setTokenLevel(tokenId, level); | ||
_setNftType(tokenId, nftType); | ||
_setMenuType(tokenId, menuType); | ||
return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nftType == 1 : 일반 NFT function mintWithTokenURI(
address to,
uint256 tokenId,
string memory tokenURI,
string memory menuType
) public onlyMinter returns (bool) {
uint256 userBalance = balanceOf(to);
//특정 NFT(ex: 국밥 NFT)를 19개 이상 소유했는지 판별해서 19개를 삭제한 후 마스터 NFT 배지 발행
if(_checkMenu(to, menuType, userBalance) >= 19) {
_removeOwnToken(to, menuType);
_mint(to, tokenId);
_setTokenURI(tokenId, tokenURI);
_setNftType(tokenId, 2); // nftType을 인자로 넘겨받지 않고 2로 세팅해서 실행
_setMenuType(tokenId, menuType);
} else {
//메뉴 NFT 19개 보유자가 아니라면 그냥 일반 mint 실행
_mint(to, tokenId);
_setTokenURI(tokenId, tokenURI);
_setNftType(tokenId, 1); // nftType을 인자로 넘겨받지 않고 1로 세팅해서 실행
_setMenuType(tokenId, menuType);
}
return true;
} mintMasterBadge 함수 호출 대신 mintWithTokenURI 에서 한번에 처리해봤어요! |
||
} | ||
|
||
|
@@ -1410,21 +1433,22 @@ contract KIP17MetadataMintable is KIP13, KIP17, KIP17Metadata, MinterRole { | |
address to, | ||
uint256 tokenId, | ||
string memory tokenURI, | ||
uint level, | ||
uint nftType, | ||
string memory menuType, | ||
address payable reciver | ||
) public payable returns (bool) { | ||
// reciver = Ownable(NFT).owner(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 저도 찾아보려고 했는데 Ownable을 상속받을 때 순서가 중요한데 잘 안되더라구요 ㅠㅠ 그래서 그냥 인자로 넣어주는 방식으로 가죠! |
||
reciver.transfer(10**17*5); | ||
mintWithTokenURI(to,tokenId, tokenURI,level); | ||
mintWithTokenURI(to,tokenId, tokenURI,nftType, menuType); | ||
return true; | ||
} | ||
//마스터 뱃지 mint (수정사항 : 마스터 뱃지레벨, 일반 뱃지(메뉴별 레벨)로 구분) | ||
//마스터 뱃지 mint | ||
function mintMasterBadge( | ||
address to, | ||
uint256 tokenId, | ||
string memory tokenURI, | ||
uint setLevel, | ||
uint delLevel, | ||
uint nftType, | ||
string memory menuType, | ||
address NFT | ||
) public returns (bool){ | ||
uint256 userBalance; | ||
|
@@ -1433,17 +1457,17 @@ contract KIP17MetadataMintable is KIP13, KIP17, KIP17Metadata, MinterRole { | |
_listOfUserToeknId(userBalance, to, NFT); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. _listOfUserToeknId 함수는 필요 없을 것 같아요! function getOwnedTokens(address owner) public view returns (uint256[] memory) {
return _ownedTokens[owner];
} 기존에 있는 위 함수를 써서 owner 에 소유자 address를 인자로 넣으면 tokenId 배열 리스트를 가져올 수 있습니다 :) |
||
|
||
//특정 NFT(국밥 마스터 뱃지 인지)가 20개 이상 소유한지 판별 | ||
require(_checkMenu(delLevel, userBalance) >= 20, "You must have menu20NFTs"); | ||
_removeOwnToken(to, delLevel); | ||
mintWithTokenURI(to,tokenId, tokenURI,setLevel); | ||
require(_checkMenu(menuType, userBalance) >= 20, "You must have menu20NFTs"); | ||
_removeOwnToken(to, menuType); | ||
mintWithTokenURI(to,tokenId, tokenURI,nftType,menuType); | ||
return true; | ||
} | ||
|
||
//소유한 특정메뉴 갯수 확인 | ||
function _checkMenu(uint level, uint256 balance) private returns(uint256){ | ||
function _checkMenu(string memory menuType, uint256 balance) private returns(uint256){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. //소유한 특정 메뉴 NFT 갯수 확인
function _checkMenu(address owner, string memory menuType, uint256 balance) private returns(uint256){
uint256 result = 0;
uint256[] memory owendAllTokenList = getOwnedTokens(owner);
for (uint256 i = 0; i< balance; i++){
if(_ownNftType(owendAllTokenList[i], menuType)){
result++;
}
}
return result;
} userId라는 배열을 굳이 만들지 않고 getOwnedTokens함수를 활용해서 토큰 리스트를 가져올 수 있어요. |
||
uint256 result = 0; | ||
for (uint256 i =0 ; i< balance; i++){ | ||
if(_ownTokenLevel(_userid[i], level)){ | ||
if(_ownNftType(_userid[i], menuType)){ | ||
result++; | ||
} | ||
} | ||
|
@@ -1459,11 +1483,19 @@ contract KIP17MetadataMintable is KIP13, KIP17, KIP17Metadata, MinterRole { | |
} | ||
} | ||
// 소유한 20개의 메뉴 NFT 삭제 | ||
function _removeOwnToken(address to, uint level) private{ | ||
|
||
function _removeOwnToken(address to, string memory menuType) private{ | ||
uint256 count =0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. //소유한 19개 메뉴 NFT burn
function _removeOwnToken(address to, string memory menuType) private{
uint256 count = 0;
uint256[] memory owendAllTokenList = getOwnedTokens(to);
//유저가 가지고 있는 기존 NFT 19개 삭제
for (uint256 i = 0; i < owendAllTokenList.length; i++) {
bool isSucess = _burnForMasterNFT(to, owendAllTokenList[i], menuType);
if(isSucess) {
count ++;
}
if(count == 19) {
break;
}
}
} 여기도 마찬가지로 getOwnedTokens 함수를 활용했습니다. |
||
//유저가 가지고 있는 기존 NFT 삭제(20개 이상을 소유할 수도 있으니 20개만 삭제) | ||
for (uint256 i = 0; i < 20; i++) { | ||
_burnForMasterNFT(to, _userid[i],level); | ||
for (uint256 i = 0; i < _userid.length; i++) { | ||
bool isSucess = _burnForMasterNFT(to, _userid[i],menuType); | ||
if(isSucess) | ||
{ | ||
count ++; | ||
} | ||
if(count ==20) | ||
{ | ||
break; | ||
} | ||
} | ||
|
||
_useridInit(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위와 같이 보완했어요! mintWithTokenURI 에서 nftType을 인자로 넣지 않는 것을 반영했어요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그리고 receiver를 인자로 받지 않기 위해 아래와 같이 다시 수정했습니다.