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

[220516] nft 판매등록하기 / 오픈제플린, 솔리디티

by 한코코 2022. 5. 16.

SaleAnimalToken.sol

// SPDX-License-Identifier: MIT -> 라이센스
pragma solidity ^0.8.0; // 컴파일러 명시

import "MintAnimalToken.sol";

contract SaleAnimalToken {
    // mintAnimal을 디플로이하면 나오는 주소값을 저장함
    MintAnimalToken public mintAnimalTokenAddress;

    constructor (address _mintAnimalTokenAddress) {
        mintAnimalTokenAddress = MintAnimalToken(_mintAnimalTokenAddress);
    }

    // 가격을 관리하는 매핑
    mapping(uint256 => uint256) public animalTokenPrices;
    // 프론트엔드에서 어떤게 판매중인지 검색할때 쓸 배열
    uint256[] public onSaleAnimalTokenArray;

    // 판매등록하는 함수 (무엇을 팔지, 얼마에 팔지)
    // public -> 모든 범위
    function setForSaleAnimalToken(uint256 _animalTokenId,uint256 _price) public {
        // 토큰 주인의 정보
        address animalTokenOwner
        	= mintAnimalTokenAddress.ownerOf(_animalTokenId);

        // 주인이 맞는지 확인
        require(animalTokenOwner == msg.sender,
        	"Caller is not animal token owner.");
        
        // 0보다 작은 값은 존재하지 않음
        require(_price > 0, "Price is zero or lower.");
        
        // 값이 0원이거나 아니거나. 0이 아니면 판매등록이 되었다는 뜻
        require(animalTokenPrices[_animalTokenId] == 0,
        	"This animal token is already on sale.");
        
        // this = setForSaleAnimalToken 이걸 가르킴
        // animalTokenOwner(주인)이 address(this)(판매권한)을 넘겼니?
        require(mintAnimalTokenAddress.isApprovedForAll(
        	animalTokenOwner, address(this)),
            "Animal token owner did not approve token."
        );

        animalTokenPrices[_animalTokenId] = _price;
        onSaleAnimalTokenArray.push(_animalTokenId); // 판매중이면 배열에 추가함
    }
}

 

 

CONTRACT를 MintAnimalToken으로 선택 > Deploy 클릭 > 생성된 주소값 복사

 

 

CONTRACT를 SaleAnimalToken으로 선택 > DEPLOY에 복사한 값 붙여넣기 > transact 클릭 > 새로운 개체 생성됨

이 곳에 넣은 주소값은 SaleAnimalToken.js에 있는 address _mintAnimalTokenAddress에 들어간다.

 

 

MintAnimalToken > 민팅 > animalTypes에 1 입력, call 클릭

SaleAnimalToken > setForSaleAnimalToken > 1 입력, 가격 입력 > transact

 

 

에러가 생긴다. 왜인지 알아보자

require(animalTokenOwner == msg.sender, "Caller is not animal token owner.");
require(_price > 0, "Price is zero or lower.");
require(animalTokenPrices[_animalTokenId] == 0, "This animal token is already on sale.");
require(mintAnimalTokenAddress.isApprovedForAll(
	animalTokenOwner, address(this)),
    "Animal token owner did not approve token." // 에러코드 일치
);

작성했던 코드 중에서 네번째 require의 오류코드가 출력되어있는 것을 볼 수 있다.

그렇다면 세번째까지는 조건을 충족했다는 소리가 되므로, 네번째 코드만 오류를 살펴보면 된다.

 

 

에러의 원인 역추적하기

MintAnimalToken > ACCOUNT 에서 주소 복사

SaleAnimalToken > setForSaleAnimalToken 주소 복사

 

 

MintAnimalToken > isApprovedForAll에 복사한 주소를 각각 넣고 call을 클릭

0 : bool: false 값이 나온다. false값을 true 값으로 만들어줘야한다.

 

 

MintAnimalToken > setApprovedForAll에 isApprovedForAll의 operator 주소를 붙여놓고, approved에는 true값을 넣는다.

transact를 클릭했을때 에러없이 실행이 된다면, 다시한번 isApprovedForAll의 call 버튼을 클릭한다.

bool값이 true로 바뀌어서 뜨면 변환이 완료되었다.

 

 

본래 목적이었던 setForSaleAnimalToken>transact를 클릭하면 문제없이 실행된다.

즉, tokenId가 1번의 가격이 10으로 정해진것이다.

 

animalTokenPrices에 tokenId 1번을 넣으면 가격이 얼마로 책정되어있는지 보여준다.

onSaleAnimalTokenArray(판매리스트)에 인덱스번호 0번을 넣으면 tokenId가 1번이 들어가있는 것을 볼 수 있다.

댓글