-
-
Save ika9810/d73dd3ea8c081050acfef80d6447818e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity >=0.4.24 <=0.5.6; | |
pragma experimental ABIEncoderV2; | |
contract IKIP17Receiver { | |
function onKIP17Received( | |
address operator, | |
address from, | |
uint256 tokenId, | |
bytes memory data | |
) public returns (bytes4); | |
} | |
contract NFTContract { | |
string public name = "Ai NFTA"; | |
string public symbol = "AN"; | |
mapping(uint256 => address) public tokenOwner; | |
mapping(uint256 => string) public tokenURIs; | |
// 소유한 토큰 리스트 | |
mapping(address => uint256[]) private _ownedTokens; | |
bytes4 private constant _KIP17_RECEIVED = 0x6745782b; | |
// mint(tokenId, uri, owner) | |
// transferFrom(from, 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, | |
bytes memory _data | |
) public { | |
require(from == msg.sender, "from != msg.sender"); | |
require( | |
from == tokenOwner[tokenId], | |
"you are not the owner of the token" | |
); | |
// | |
_removeTokenFromList(from, tokenId); | |
_ownedTokens[to].push(tokenId); | |
// | |
tokenOwner[tokenId] = to; | |
// | |
require( | |
_checkOnKIP17Received(from, to, tokenId, _data), | |
"KIP17: transfer to non KIP17Receiver implementer" | |
); | |
} | |
function _removeTokenFromList(address from, uint256 tokenId) private { | |
// [10, 15, 19, 20] -> 19번을 삭제 하고 싶어요 | |
// [20, 15, 20, 19] | |
// [10, 15, 20] | |
uint256 lastTokenIdex = _ownedTokens[from].length - 1; | |
for (uint256 i = 0; i < _ownedTokens[from].length; i++) { | |
if (tokenId == _ownedTokens[from][i]) { | |
// Swap last token with deleting token; | |
_ownedTokens[from][i] = _ownedTokens[from][lastTokenIdex]; | |
_ownedTokens[from][lastTokenIdex] = tokenId; | |
break; | |
} | |
} | |
// | |
_ownedTokens[from].length--; | |
} | |
function ownedTokens(address owner) public view returns (uint256[] memory) { | |
return _ownedTokens[owner]; | |
} | |
function ownedTokenUrl(uint256 tokenId) public view returns (string memory) { | |
string storage temp = tokenURIs[tokenId]; | |
return temp; | |
} | |
function balanceOf(address owner) public view returns (uint256) { | |
require( | |
owner != address(0), | |
"KIP17: balance query for the zero address" | |
); | |
return _ownedTokens[owner].length; | |
} | |
function setTokenUri(uint256 id, string memory uri) public { | |
tokenURIs[id] = uri; | |
} | |
function _checkOnKIP17Received( | |
address from, | |
address to, | |
uint256 tokenId, | |
bytes memory _data | |
) internal returns (bool) { | |
bool success; | |
bytes memory returndata; | |
if (!isContract(to)) { | |
return true; | |
} | |
(success, returndata) = to.call( | |
abi.encodeWithSelector( | |
_KIP17_RECEIVED, | |
msg.sender, | |
from, | |
tokenId, | |
_data | |
) | |
); | |
if ( | |
returndata.length != 0 && | |
abi.decode(returndata, (bytes4)) == _KIP17_RECEIVED | |
) { | |
return true; | |
} | |
return false; | |
} | |
function isContract(address account) internal view returns (bool) { | |
// This method relies in extcodesize, which returns 0 for contracts in | |
// construction, since the code is only stored at the end of the | |
// constructor execution. | |
uint256 size; | |
// solhint-disable-next-line no-inline-assembly | |
assembly { | |
size := extcodesize(account) | |
} | |
return size > 0; | |
} | |
} | |
contract ArtistMarketContract { | |
mapping(uint256 => address) public seller; | |
/** | |
buyNFT | |
@dev 작가는 | |
safeTransferFrom 함수를 통해 마켓에 소유권을 이전함 | |
displayNFT 함수를 통해 전시 요청을 함 | |
startArtNFTSelling 함수를 실행하여 판매 허가를 해야 함 | |
@notice 마켓이 일시적으로 소유한 NFT를 구매자가 구매 함 (판매 허가 조건 추가 예정) | |
*/ | |
function buyNFT(uint256 tokenId, address NFT) | |
public | |
payable | |
returns (bool) | |
{ | |
address payable receiver = address(uint160(seller[tokenId])); | |
// Send 0.01 klay to Seller | |
receiver.transfer(10**16); | |
// Send NFT if properly send klay | |
NFTContract(NFT).safeTransferFrom( | |
address(this), | |
msg.sender, | |
tokenId, | |
"0x00" | |
); | |
return true; | |
} | |
/** | |
displayNFT | |
@dev displayNFT를 통해 전시회에 전시 요청을 할 수 있음, ArtistMarketContract는 허가를 받은 작품만 getArtNFTs 함수를 통해 전시회 사이트에 전시함 | |
*/ | |
function displayNFT(uint256 tokenId, address NFT) public { | |
} | |
/** | |
getArtNFTs | |
@dev getArtNFTs를 통해 허가를 받은 작품만 getArtNFTs 함수를 통해 전시회 사이트에 전시함 | |
*/ | |
function getArtNFTs(uint256 tokenId, address NFT) public{ | |
} | |
/** | |
startArtNFTAuction | |
@dev startArtNFTAuction를 통해 작가가 본의 작품의 경매를 시작함 | |
*/ | |
function startArtNFTAuction(uint256 tokenId, address NFT) public{ | |
} | |
/** | |
bidArtNFTAuction | |
@dev bidArtNFTAuction를 작품 구매자는 경매에 구매할 금액을 제안함 | |
*/ | |
function bidArtNFTAuction(uint256 tokenId, address NFT) public{ | |
} | |
/** | |
bidArtNFTAuction | |
@dev 작품 구매자는 현재 작품의 경매 가격을 확인할 수 있음 | |
*/ | |
function getArtNFTAuctionPrice(uint256 tokenId, address NFT) public{ | |
} | |
// Called when SafeTransferFrom called from NFT Contract | |
function onKIP17Received( | |
address operator, | |
address from, | |
uint256 tokenId, | |
bytes memory data | |
) public returns (bytes4) { | |
// Set token seller, who was a token owner | |
seller[tokenId] = from; | |
// return signature which means this contract implemented interface for ERC721 | |
return | |
bytes4(keccak256("onKIP17Received(address,address,uint256,bytes)")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment