Lazy Minting

heitz·2022년 4월 17일
1

dapp 개발 - nft

목록 보기
4/4

💡 Lazy minting이란?

판매자가 민팅한 nft가 market에서 팔리지 않는다면, 판매자 입장에선 minting price만 지불한셈이다. 이런 상황을 피하기 위해 lazy minting이 도입되었다. 이름에서 알 수 있듯이, 민팅 과정을 미루는 것이다.
이는 nft가 실제로 구매 될 때 nft를 판매자에게 민팅하고 판매자가 구매자에게 nft를 transfer하는 방식이다. 즉, 구매가 이뤄지기 전 까지 market에 올라가있는 nft는 사실 nft가 아니라 단순 이미지일 뿐이다.
lazy minting을 사용하면 minting price를 구매자가 지불하게 된다.
참고 - https://nftschool.dev/tutorial/lazy-minting/#how-it-works

💡 절차

  1. creator (판매자)
  • 판매자는 마켓에 아이템을 listing 하는 시점에서 signer로서 EIP712을 통해 signature을 생성
    → signer._signTypedData(domain, types, voucher) 실행시 metamask가 열리면서 서명하게 되고, 그 결과를 저장한 것이 signature임
    → 이 signature은 판매자가 해당 아이템을 NFT로 생성하는 것을 허락함을 증명함
  • signature은 0xd849585d6e93ac0089cb21f2d7001a57a4361ce7e4f26794222e336ad4713dcc6549aac8f3~~~~~~~b48e1d8039c85142aae5c62ce0ab64fd471c
    이런식으로 생겼고 타입은 bytes이다. 이는 나중에 구매자가 마켓에 리스팅 된 아이템을 구매(구매하면 아이템이 nft로 민팅됨)할 때 호출하는 redeem 함수에 전달되는 voucher안에 포함되어 전달된다.
  • 구매가 redeem되기위해선 아이템정보(id, price, uri 등)와 signature가 필요하므로 아이템을 listing하는 시점에서 생성된 아이템정보와 signature가 어딘가에 저장되어야 한다. (ex. database)
  1. buyer (구매자)
  • 구매를 하면 contract의 redeem 함수가 실행되고, 구매자의 address는 redeemer로서 redeem 함수에 전달된다.
  • 먼저 nft를 민팅해야하므로 _mint 함수에 _verify 함수로부터 얻은 signer address(buyer address)를 전달하여 nft를 민팅한다.
  • 그 다음 buyer, 즉 redeemer에게 민팅한 nft를 transfer한다.
function redeem(address redeemer, NFTVoucher calldata voucher) public payable returns (uint256) {
    // make sure signature is valid and get the address of the signer
    address signer = _verify(voucher);

    // make sure that the redeemer is paying enough to cover the buyer's cost
    require(msg.value >= voucher.minPrice, "Insufficient funds to redeem");

    // first assign the token to the signer, to establish provenance on-chain
    _mint(signer, voucher.tokenId);
    _setTokenURI(voucher.tokenId, voucher.uri);
    
    // transfer the token to the redeemer
    _transfer(signer, redeemer, voucher.tokenId);

    return voucher.tokenId;
  }
  • _verify 함수에서는 _hash 함수에서 signature 정보를 제외한 voucher 정보를 가지고 TypedData를 생성한 다음 digest 변수에 저장한다. 그 다음, ECDSA 알고리즘(타원곡선 디지털서명 알고리즘)을 통해 digest와 signature 정보로 부터 signer address를 복구한다. (ECDSA의 recover 함수를 사용한다.)
function _verify(NFTVoucher calldata voucher) internal view returns (address) {
    bytes32 digest = _hash(voucher);
    return ECDSA.recover(digest, voucher.signature);
  }
function _hash(NFTVoucher calldata voucher) internal view returns (bytes32) {
    return _hashTypedDataV4(keccak256(abi.encode(
      keccak256("NFTVoucher(uint256 tokenId,uint256 minPrice,string uri)"),
      voucher.tokenId,
      voucher.minPrice,
      keccak256(bytes(voucher.uri))
    )));
  }

결론

lazy minting을 사용하면 판매자 입장에선 minting price로 인한 진입장벽으로부터 자유로워지기 때문에 market에 다양한 nft가 등록될 수 있다. 하지만 minting되기 전까지 minting을 위한 정보(image, signature 등)가 어딘가에 저장되어있어야하기 때문에 탈중앙이라는 가치엔 다소 위배된다.

profile
For Fun

0개의 댓글