Skip to content

Instantly share code, notes, and snippets.

@jangyoungdo
Last active May 31, 2021 06:46
Show Gist options
  • Save jangyoungdo/8c35cf4f456fd29e7775d5a0127f1c41 to your computer and use it in GitHub Desktop.
Save jangyoungdo/8c35cf4f456fd29e7775d5a0127f1c41 to your computer and use it in GitHub Desktop.
코드
pragma solidity >=0.4.24 <=0.5.6;
contract Enrollment_Music_NFT{
//NFT != token
struct Music {
string _MusicName;
string _informationOfMusic;
string _mp3_file;
bytes32 _NFT_ID;
}
bytes32 _NFT_ID;
Music [] MusicList;
mapping (address => bytes32[]) myNFT_list;
mapping (address => mapping(string => Music[])) My_music_is; //가수의 이름과 address를 키값으로 함으로서 중복을 최대한 막으려 했음
mapping (bytes32 => address) NFTowner;
string public token_name;
mapping (bytes32 => address) tokenOwner;
mapping (address => bytes32[]) ownedTokens;
mapping (string => bytes32) MusicToken;
//onKIP17received bytes value
bytes4 private constant _KIP17_RECEIVED = 0x6745782b; //교육에서 만들어준 기본 거래 코드에서 가져옴
//=> 참고코드에서는 토큰을 발행하고 토큰을 거래하는 부분만을 다뤘기 때문에 이거 하나로 했는데
//나는 거래가 두가지 양상을 보이므로 이를 어떻게 적용해야할 지 모르겠다
//창작자 본인의 주소를 넣어 본인임을 인증하고 최종 키값인 Music[]에 정보를 담는다
function pushMusic( address from,
string memory _MusicName,
string memory _informationOfMusic,
string memory _mp3_file//string memory _mp3_file =>임시적으로 표현, 어떻게 구현할 지 연구중
) public returns(bool) {
require(msg.sender==from);
//이미 있는 곡이름으로는 등록이 불가능함
require(checkMusic(_MusicName),"you already enrolled music");
_NFT_ID = keccak256(abi.encodePacked(from,_MusicName)); //입력한 정보들로 고유 _NFT_ID 생성
myNFT_list[from].push(_NFT_ID); //_NFT_ID 저장
NFTowner[_NFT_ID] = from;
My_music_is[from][_MusicName].push(Music(_MusicName,_informationOfMusic,_mp3_file,_NFT_ID));
return true;
}
function checkMusic(string memory _MusicName) internal view returns(bool) {
for(uint i =0; i < MusicList.length; i++ ) {
if(keccak256(abi.encodePacked(MusicList[i]._MusicName))==keccak256(abi.encodePacked(_MusicName))) {
return false;
}
}
return true;
}
//한곡에 발행할 수 있는 토큰의 종류는 하나이다.
//원하는 수량만큼
//발행할지 말지는 본인 선택
//하지만 하나의 종류의 토큰을 발행했을 시 그 정보는 변경이 불가능 하다
function getauthority(address from, string memory _MusicName, bytes32 _NFT_ID, string memory _token_name, uint _token_amount) public returns(bool) {
require( NFTowner[_NFT_ID] == msg.sender, "you can't use this service"); //pushMusic이 실행되어야만 실행될 수 있다는 require문을 쓰고 싶었는...
require( MusicToken[_MusicName] == 0, "you already made token"); //아직 토큰 발행이 되지 않음을 의미하고자 했다
for(uint i = 0; i < _token_amount ; i++) {
bytes32 tokenID = keccak256(abi.encodePacked(_MusicName,_token_name, i));
tokenOwner[tokenID] = from;
ownedTokens[from].push(tokenID);
}
return true;
}
function checkOwnedNFT(address from) public returns(bytes32[] memory) {
return myNFT_list[from];
} // address 주인이 소유한 NFT확인
function checkOwnedTokens(address from) public returns(bytes32[] memory) {
return ownedTokens[from];
} // address 주인이 소유한 코인확인
function safeTransferFrom(address from, address to, bytes32 tokenID, bytes memory _data) public { //to는 마켓 주소
require(ownedTokens[from].length > 0, "No token");
require(from == msg.sender, "from != msg.sender");
require(from == tokenOwner[tokenID], "you are not the owner of the token");
tokenOwner[tokenID] = to;
_removeTokenFromList(from, tokenID);
ownedTokens[to].push(tokenID);
tokenOwner[tokenID] = to;
require(
_checkOnKIP17Received(from, to, tokenID, _data), "KIP17: transfer to non KIP17Receiver implmenter"
);
}
function _checkOnKIP17Received(address from, address to, bytes32 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 true;
}
function isContract(address account) internal view returns(bool) {
uint256 size;
assembly{ size := extcodesize(account)}
return size > 0;
}
function _removeTokenFromList(address from, bytes32 tokenID) private {
uint256 lastTokenIndex = ownedTokens[from].length - 1;
for(uint256 i = 0; i< ownedTokens[from].length; i++) {
if(tokenID == ownedTokens[from][i]) {
ownedTokens[from][i] = ownedTokens[from][lastTokenIndex];
ownedTokens[from][lastTokenIndex] = ownedTokens[from][i];
break;
}
}
ownedTokens[from].length--;
}
}
contract Market {
mapping(bytes32 => address) public TokenSeller;
mapping(bytes32 => address) public NFTSeller;
//나한테 보낸 토큰 아이디 => 누가 보냈냐
function buyNFT(bytes32 _NFT_ID, address ContractAddress) public payable returns(bool) {
//구매한 사람한테 0.01KLAY를 전송
address payable receiver = address(uint256(NFTSeller[_NFT_ID]));
//send 0.01 KLAY to receiver
//10**18 PEB = 1KLAY
receiver.transfer(10**16); //예시
Enrollment_Music_NFT(ContractAddress).safeTransferFrom(address(this), msg.sender, _NFT_ID, "0x00");
return true;
}
function buytoken(bytes32 tokenID, address ContractAddress) public payable returns(bool) {
address payable receiver = address(uint256(TokenSeller[tokenID]));
receiver.transfer(10**16);
Enrollment_Music_NFT(ContractAddress).safeTransferFrom(address(this), msg.sender, tokenID, "0x00");
return true;
}
//market이 토큰을 받았을 때 (판매대에 올라갔을 때), 판매자가 누구인지 기록해야 됨
function onKIP17received_NFT(address operator, address from, bytes32 _NFT_ID, bytes memory data) public returns(bytes4) {
NFTSeller[_NFT_ID] = from;
return bytes4(keccak256("onKIP17received1(address,address,bytes32,bytes)"));
}
function onKIP17received_Token(address operator, address from, bytes32 tokenID, bytes memory data) public returns(bytes4) {
TokenSeller[tokenID] = from;
return bytes4(keccak256("onKIP17Received2(address,address,bytes32,bytes)"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment