Skip to content
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

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open

Conversation

Yunseongpyo
Copy link

No description provided.

@Yunseongpyo Yunseongpyo changed the title Yunseongpyo [Yunseongpyo] NFT Contract 작성 Feb 14, 2022
README.md Outdated
- 기존 소유자가 지울수 있는 권한에서 발행자만 지울 수 있게 변경
```Solidity
function burn(uint256 tokenId) public onlyMinter{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onlyMinter를 추가한 이유를 알 수 있을까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존 코드는 NFT소유자가 지울수 있게 되어 있는데, 마스터뱃지를 발행할 경우 미리 발행해 둔 20개를 삭제를 해야하니 소유자가 아닌 관리자가 삭제를 해야한다고 생각을 해서 onlyMinter를 추가했습니다~

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

관리자만 삭제 권한을 가지게 되면 NFT 본연의 가치가 떨어질 것 같습니다. 탈중앙성을 성립시키려면 NFT 소유권자가 삭제를 하는게 맞는 것 같아요. 마스터뱃지 삭제에 관해서는 따로 상태값을 추가해서 보완하는 방법도 좋아보입니다!

README.md Outdated

```Solidity
function mintNft(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에 있는 mintWithTokenURI를 사용하거나 수정하면 될 것 같은데, mintNft라는 함수를 새로 만든 이유가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 함수 이름을 저희꺼에 맞춰서 바꿀려고 임의로 추가를 해봤습니다~ 저 함수명을 그대로 쓸거면 기존 함수를 그대로 써도 될거 같습니다~

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KIP 토큰 표준에 맞춰서 함수명을 일치 시키는게 이상 적일 것 같아요!

README.md Outdated
#### mintWithKlay : NFT 발행(수수료0.5Klay)
```Solidity
function mintNft(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mintWithKlay함수는 현재 미완성인 것 같은데, 수수료로 0.5 Klay를 받으려면 함수에 payable 제어자를 넣어야하고, 누가 돈을 받는지, 얼마를 받는지가 추가되어야 할 것 같아요.
저희가 강의에서 배웠던 buyNFT를 참고해보면 민팅하는 함수는 아래와 같이 작성할 수도 있겠네요. 참고용으로 작성해봤습니다.

function mintWithTokenURIWithKLAY(
    address to,
    uint256 tokenId,
    string memory tokenURI
) public payable onlyMinter returns (bool) {

    address payable receiver = owner(); //컨트랙트 owner를 receiver로 설정
    receiver.transfer(5*10**17); // 0.5klay 받도록 설정

    _mint(to, tokenId);
    _setTokenURI(tokenId, tokenURI);
    return true;
}

Copy link
Author

@Yunseongpyo Yunseongpyo Feb 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아구 이거 readme에 코드가 잘못 들어갔네요;;; sol에는 구현이 되어 있습니다!
저는 돈 받는 분을 직접 어드레스 입력하게 만들어 놨습니다~

//mint 유료, 0.5 klay 
    function mintWithKlay(
        address to,
        uint256 tokenId,
        string memory nftMetadata,
        address payable receiver // klay받는 주소
    ) public payable returns (bool) {

        receiver.transfer(10**17*5);
        mintNft(to,tokenId, nftMetadata);
        return true;
    }

README.md Outdated
userBalance = balanceOf(to);

//require(userBalance == 20, "You must have 20NFTs")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순히 20개 NFT를 소유헀는지만 파악하면 안되고, 예를 들어 국밥 마스터 뱃지를 발행해야하면 국밥 NFT를 20개 이상 소유했는지 파악해서 require문을 걸어야할 것 같아요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 네 그 부분은 생각은 못했네요~ 추가해 보겠습니다~

README.md Outdated
```
***
- 마스터 뱃지 발행 시 일반 nft와 마스터 nft 구분 필요
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 제가 작성한 setTokenLevel 함수를 참고하면 좋을 것 같아요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네네~ 수빈님이 올려주신거 확인했고 참고해서 작성해보겠습니다~

README.md Outdated
uint256 id = KIP17Enumerable(NFT).tokenOfOwnerByIndex(to,i);

userid.push(id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NFT 삭제하는 기능을 잘 넣으셨네요 👍 다만 위에 말씀드렸다시피 특정 음식의 NFT인지 구분해서 삭제해야 할 것 같아요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네~ 기능 추가해보겠습니다

Copy link
Contributor

@Hyunki6040 Hyunki6040 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼하게 잘 작성해 주셨어요!

README.md Outdated

```Solidity
function mintNft(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KIP 토큰 표준에 맞춰서 함수명을 일치 시키는게 이상 적일 것 같아요!

Copy link

@sapcy sapcy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컨트랙트 작성하시느라 고생하셨습니다!👍👍

README.md Outdated
- 기존 소유자가 지울수 있는 권한에서 발행자만 지울 수 있게 변경
```Solidity
function burn(uint256 tokenId) public onlyMinter{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

관리자만 삭제 권한을 가지게 되면 NFT 본연의 가치가 떨어질 것 같습니다. 탈중앙성을 성립시키려면 NFT 소유권자가 삭제를 하는게 맞는 것 같아요. 마스터뱃지 삭제에 관해서는 따로 상태값을 추가해서 보완하는 방법도 좋아보입니다!

README.md Outdated
for (uint256 i = 0; i < balance; i++) {

_burn(userid[i]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NFT 삭제 후 userid 리스트 안에 저장한 토큰 id값을 메모리 해제시켜주는 로직이 필요할 듯 싶습니다!

@@ -1433,17 +1457,17 @@ contract KIP17MetadataMintable is KIP13, KIP17, KIP17Metadata, MinterRole {
_listOfUserToeknId(userBalance, to, NFT);
Copy link
Member

Choose a reason for hiding this comment

The 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 배열 리스트를 가져올 수 있습니다 :)

) public onlyMinter returns (bool) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenURI);
_setTokenLevel(tokenId, level);
_setNftType(tokenId, nftType);
_setMenuType(tokenId, menuType);
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nftType == 1 : 일반 NFT
nftType == 2 : 마스터 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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 저도 찾아보려고 했는데 Ownable을 상속받을 때 순서가 중요한데 잘 안되더라구요 ㅠㅠ 그래서 그냥 인자로 넣어주는 방식으로 가죠!

@@ -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(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    //mint 유료: 0.5 klay 소모
    function mintWithKlay(
        address to,
        uint256 tokenId,
        string memory tokenURI,
        string memory menuType,
        address payable receiver
    ) public payable returns (bool) {
        receiver.transfer(10**17*5);

        mintWithTokenURI(to, tokenId, tokenURI, menuType);
        return true;
    }

위와 같이 보완했어요! mintWithTokenURI 에서 nftType을 인자로 넣지 않는 것을 반영했어요.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 receiver를 인자로 받지 않기 위해 아래와 같이 다시 수정했습니다.

   address private _owner;

    /**
     * @dev Constructor function.
     */
    constructor () public {
        // register the supported interface to conform to KIP17Mintable via KIP13
        _registerInterface(_INTERFACE_ID_KIP17_METADATA_MINTABLE);
        _owner = msg.sender;
    }

    function owner() public view returns (address) {
        return _owner;
    }
   //mint 유료: 0.5 klay 소모
    function mintWithKlay(
        address to,
        uint256 tokenId,
        string memory tokenURI,
        string memory menuType
    ) public payable returns (bool) {
        address payable receiver = address(uint160(owner())); //receiver 세팅
        receiver.transfer(10**17*5);

        mintWithTokenURI(to, tokenId, tokenURI, menuType);
        return true;
    }

return true;
}

//소유한 특정메뉴 갯수 확인
function _checkMenu(uint level, uint256 balance) private returns(uint256){
function _checkMenu(string memory menuType, uint256 balance) private returns(uint256){
Copy link
Member

Choose a reason for hiding this comment

The 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함수를 활용해서 토큰 리스트를 가져올 수 있어요.
그래서 위와 같이 보완해봤어요 :)

function _removeOwnToken(address to, uint level) private{

function _removeOwnToken(address to, string memory menuType) private{
uint256 count =0;
Copy link
Member

Choose a reason for hiding this comment

The 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 함수를 활용했습니다.
그리고 mintWithTokenURI 함수를 호출할 때 19개를 소유했으면 추가로 같은 메뉴 NFT 1개를 발행하지 않고 바로 19개 소각하고 마스터 NFT배지를 발행하면 되서 19개까지만 반복문을 돌았습니다. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants