본문 바로가기
프로그래밍/solidity

[220527] nft 발행/판매 취소 기능 만들기

by 한코코 2022. 5. 19.

nft 발행기능, 판매기능은 어찌저찌 만들었다.

가격 수정 기능이 있으면 좋겠지만, 검색하다보니 힌번 발행한 nft는 가격 수정이 불가능하다고한다.

 

그렇다면 필요한 기능은 다음 두가지.

1) 판매 취소를 한 후, 적당한 때에 다시 그 가격으로 판매 등록을 한다. -> 판매취소기능

2) nft를 삭제한 후, 새 nft를 발행해서 원하는 가격으로 등록한다. -> 삭제기능

 

 

 

 

 

삭제방법 1.   selfdestruct

zeppelin에서 제공하는 기능

코드가 블록체인에서 지워지는 유일한 방법은 주소의 컨트랙트에가 selfdestruct연산을 사용했을때이며,

블록체인에서 계약을 삭제할 수 있는 기능이 selfdestruct라고 한다.

잠만, 그 계약 자체가 nft 컨트랙트 1개의 계약인거지...?

상호간을 연결하고있는 스마트컨트랙트 그 자체 계약이 아닌거지...?

왜 검색할수록 스마트 컨트렉트 그 자체를 말하는거 같지?

( https://ethereum-blockchain-developer.com/022-pausing-destroying-smart-contracts/04-destroy-smart-contracts/ )

 

selfdestruct계약에 저장된 나머지 모든 Ether를 지정된 주소로 보낸다.

하지만 제거된 컨트랙트에 Ether를 전송하면, 해당 Ether는 영구적으로 손실된다.

악의적인 의도로 해킹으로 사용할 수 있으니 예방할 수 있는 코드를 작성하라고 한다.

( https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#potentially-unsafe-operations )

( https://hackernoon.com/how-to-hack-smart-contracts-self-destruct-and-solidity )

불안정성을 지닌 selfdestruct 말고 delegatecall이나 callcode를 실행해 대신 할 수 있다고 한다.

( callcode : v0.5.0 이후 삭제되었음.)

 

 

 

 

 

삭제방법 2.   _burn 함수 사용

zeppelin에서 제공하는 기능

 * @dev Burns a NFT.
   * @notice This is a private function which should be called from user-implemented external burn
   * function. Its purpose is to show and properly initialize data structures when using this
   * implementation. Also, note that this burn implementation allows the minter to re-mint a burned
   * NFT.
   * @param _tokenId ID of the NFT to be burned.
   */
  function _burn(
    uint256 _tokenId
  )
    internal
    validNFToken(_tokenId)
  {
    address tokenOwner = idToOwner[_tokenId];
    _clearApproval(_tokenId);
    _removeNFToken(tokenOwner, _tokenId);
    emit Transfer(tokenOwner, address(0), _tokenId);
  }

 

 

삭제방법 3.   배열에서 삭제하는 방식으로 구현

이건 burn 함수를 사용하지 않고 토큰을 삭제하는 방법 같아보임.

다음 코드를 포함한 다른 sol 파일을 import한 파일을 import한 파일임.

mapping(address => uint256) balances;
/**
 * @title Burnable Token
 * @dev Token that can be irreversibly burned (destroyed).
 */
contract BurnableToken is StandardToken {
    event Burn(address indexed burner, uint256 value);
    /**
     * @dev Burns a specific amount of tokens.
     * @param _value The amount of token to be burned.
     */
    function burn(uint256 _value) public {
        require(_value > 0);
        require(_value <= balances[msg.sender]);
        // no need to require value <= totalSupply, since that would imply the
        // sender's balance is greater than the totalSupply, which *should* be an assertion failure

        address burner = msg.sender;
        balances[burner] = balances[burner].sub(_value);
        totalSupply = totalSupply.sub(_value);
        Burn(burner, _value);
    }
}

 

 

 

 

 

토큰 판매 취소 기능

function removeTokenOnSale(uint256 memory tokenIds) public {
    require(tokenIds.length > 0 , "tokenIds is empty");
    for(uint i = 0; i < tokenIds.length; i++){
        uint tokenId = tokenIds[i];
        address tokenSeller = nftAddress.ownerOf(tokenId);
        require(msg.sender == tokenSeller, "caller is not token seller");
        tokenPrice[tokenId] = 0;
    }
}

 

 

 

어... 잠만 여기까지 오니까 그냥 솔리디티 처음부터 배우는게 낫겠는데 아니 이게 뭐여....

되는거냐 이거...

댓글