본문 바로가기
D.evelop/BlockChian \ NFT

[NFT] 2주차(4) Smart Contract↔Wallet / Solidity - 블록체인 마켓 앱 만들기 with 그라운드X

by Danne 2022. 9. 30.

✅ Contract 연동하기

  • smart contract끼리 서로 호출 할 수 있다.
NFT 스마트 컨트렉트 Market 스마트 컨트랙트
Address Address
Balance: 0
Code: NFT
Balance: 0
Code: Market
Mint
safeTransferFrom
Buy
Sell


👉 두 스마트 컨트랙트를 연결할 때 필요한 것

  • 스마트 컨트렉트의 주소
  • 각 컨트랙트에 어떤 기능이 있는지 (인터페이스)를 알아야함

 

pragma solidity >=0.4.24 <=0.5.6;

contract NFTSimple {
    string public name = 'KlayLion';
    string public symbol = "DD";
    
    mapping (uint256 => address) public tokenOwner;
    mapping (uint256 => string) public tokenURIs;

    // 소유한 토큰 리스트
    mapping (address => uint256[]) private _ownedTokens;
    
    // mint(tokenId, uri, owner)
    // transferForm(form, to, tokenId) -> owner가 바뀌는 것(from -> to)

    //발행
    function mintWithTokenURI(address to, uint256 tokenId, string memory tokenURI) public returns (bool) {
        // to에게 tokenId(일련번호)를 발행하겠다.
        // 적힐 글자는 tokenURI
        tokenOwner[tokenId] = to;
        tokenURIs[tokenId] = tokenURI;

        // add token to the list
        _ownedTokens[to].push(tokenId);

        return true;
    }

    // 전송 
    function safeTransferFrom(address from, address to, uint256 tokenId) public {   
        require(from == msg.sender, "form != msg.sender"); // 보낸 사람이 from하고 같을 때
        require(from == tokenOwner[tokenId], "your are not the owner of the token"); // 보낸 사람이 토큰의 소유주일 때
        // 해당 토큰만 지우고
        _removeTokenFromList(from, tokenId);
        // 전송 받는 곳에 해당토큰 추가
        _ownedTokens[to].push(tokenId);
        // 해당 토큰을 전송
        tokenOwner[tokenId] = to; // 이것만 있으면 아무나 토큰을 전송할 수 있다.
    }

    // 기존 토큰 소유주의 토큰 삭제
    function _removeTokenFromList(address from, uint256 tokenId) private { 
        uint256 lastTokenIndex = _ownedTokens[from].length - 1;

        for(uint256 i=0 ; i<_ownedTokens[from].length; i++){
            // Swap last token with deleting token.
            if(tokenId == _ownedTokens[from][i]){
                _ownedTokens[from][i] = _ownedTokens[from][lastTokenIndex];
                _ownedTokens[from][lastTokenIndex] = tokenId;
                break;
            }
        }
        _ownedTokens[from].length--;
        
    }

    // 소유중인 토큰
    function ownerToken(address owner) public view returns (uint256[] memory){
        return _ownedTokens[owner];
    }
    

    function setTokenUri(uint256 id, string memory uri) public{
        tokenURIs[id] = uri;
    }
}

// 스마트 컨트랙트도 토큰을 소유할 수 있음
contract NFTMarket {
    function buyNFT(uint256 tokenId, address NFTAddress, address to) public returns (bool){
        // NFTAddress에서 NFTsimple을 가진 함수를 호출 할 수 있음
        NFTSimple(NFTAddress).safeTransferFrom(address(this), to, tokenId);
        // address(this) 나 스스로의 주소
        return true;
    }
}

 

✅ 2개의 스마트 컨트랙트 배포

  • NFTMarekt
  • NFTSimple

스마트 컨트랙트로 각각의 주소를 가진다.


✅ 개인 지갑에서 smart contarct(NFTMarket)로 토큰 전송

개인 지갑 NFTMarket

  • 0x403E...개인 지갑에 10이라는 id의 토큰을 배포

 

  • safeTransferFrom 를 통해 NFTMarket 컨트랙트 주소(0x6604...)에 10(token)을 전달

 

  • 10(token)의 소유주가 NFTMarket 컨트랙트(0x6604...)로 바뀐 것을 확일 할 수 있다.




✅ Smart contact에서 개인 지갑으로 토큰 전송


buyNFT함수로 스마트 컨트랙트(NFTMarket)가 가진 토큰을 개인 지갑으로 옮겨보자.

NFTMarket → 개인 지갑

  • 11이라는 토큰을 NFTMarket 컨트랙트(0x6604...)가 가지고 있다.
  • 해당 토큰(11)을 개인 지갑(0x403E...)로 전송.


NFTMarket컨트랙트 내부에 있는 buyNFT함수NFTSimple 컨트랙트의 safeTransferFrom함수를 사용하는 것이다.

contract NFTMarket {
    function buyNFT(uint256 tokenId, address NFTAddress, address to) public returns (bool){
        // NFTAddress에서 NFTsimple을 가진 함수를 호출 할 수 있음
        NFTSimple(NFTAddress).safeTransferFrom(address(this), to, tokenId);
        return true;
    }
}

 

  • 해당 토큰(11)의 owner가 개인 지갑(0x403E...)으로 변한 것을 확인 할 수 있다.

 

반응형

댓글