Created
February 18, 2022 13:44
-
-
Save dwook/5c3c357dd25259c3a5a3afe82430d32f to your computer and use it in GitHub Desktop.
LoveChain 스마트컨트랙트
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 experimental ABIEncoderV2; | |
pragma solidity >=0.4.24 <=0.5.6; | |
contract LoveChain { | |
string public name = "LoveChain"; | |
string public symbol = "LC"; | |
address private deployer; // 배포자 주소 | |
address private NSeoulTowerMarketAddress; // 남산마켓 주소 | |
constructor() public { | |
deployer = msg.sender; | |
} | |
mapping (uint256 => address) public tokenOwner; | |
mapping (uint256 => uint256) public lastTransactionPrice; | |
mapping (uint256 => string) private _tokenURIs; | |
mapping (address => uint256[]) private _ownerTokens; | |
mapping (uint256 => string[]) private _tokenCoupleName; | |
bytes4 private constant _KIP17_RECEIVED = 0x6745782b; | |
uint256 private constant MINT_PRICE = 50; // 민팅 가격; | |
modifier onlyDeployer () { | |
require(msg.sender == deployer, "you are not deployer"); | |
_; | |
} | |
function setNSeoulMarketAddress(address marketAddress) public onlyDeployer { // 남산마켓 주소를 저장하기 위한 함수 | |
NSeoulTowerMarketAddress = marketAddress; | |
} | |
function mintWithTokenURI(address to, uint256 tokenId, string memory URI) public onlyDeployer returns (bool) { | |
tokenOwner[tokenId] = address(to); | |
if(to == NSeoulTowerMarketAddress) { // 마켓으로 민팅한다면 가격 정보를 전달 | |
NSeoulTowerMarket(to).setMintedToken(tokenId, MINT_PRICE); | |
} | |
_tokenURIs[tokenId] = URI; | |
_ownerTokens[address(to)].push(tokenId); | |
return true; | |
} | |
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { | |
// _data에는 가격 정보를 담아준다. | |
// ex) 0x0000000000000000000000000000000000000000000000000000000000000001 = 1 | |
require(from == msg.sender, "from != msg.sender"); | |
require(from == tokenOwner[tokenId], "you are not the owner of the token"); | |
_removeTokenFromList(from, tokenId); | |
_ownerTokens[to].push(tokenId); | |
_clearCoupleName(tokenId); | |
tokenOwner[tokenId] = to; | |
if (from == NSeoulTowerMarketAddress) { // 마켓에 전송되는 경우(= 거래가 발생) 최근 거래 가격을 업데이트 | |
_updateLastTransactionPrice(tokenId, _data); | |
} | |
require( | |
_checkOnKIP17Received(from, to, tokenId, _data), "KIP17: transfer to non KIPReceiver implementer" | |
); | |
} | |
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) { | |
uint256 size; | |
assembly { size := extcodesize(account)} | |
return size > 0; | |
} | |
function _removeTokenFromList(address from, uint256 tokenId) private { | |
for (uint256 i = 0; i < _ownerTokens[from].length; i++) { | |
if (tokenId == _ownerTokens[from][i]) { | |
_ownerTokens[from][i] = _ownerTokens[from][_ownerTokens[from].length - 1]; | |
break; | |
} | |
} | |
_ownerTokens[from].length--; | |
} | |
function writeCoupleName(uint256 tokenId, string memory name1, string memory name2) public { // 커플 이름 등록 | |
require(tokenOwner[tokenId] == msg.sender, "tokenOwner != sender"); | |
_tokenCoupleName[tokenId].push(name1); | |
_tokenCoupleName[tokenId].push(name2); | |
} | |
function _clearCoupleName(uint256 tokenId) private { // 커플 이름 삭제 | |
delete _tokenCoupleName[tokenId]; | |
} | |
function ownedTokens(address owner) public view returns (uint256[] memory) { | |
return _ownerTokens[owner]; | |
} | |
function coupleNamesOf(uint256 tokenId) public view returns (string[] memory) { // 커플 이름 조회 | |
return _tokenCoupleName[tokenId]; | |
} | |
function _bytestoUint256(bytes memory _bytes) internal pure returns (uint256 value) { // 타입캐스팅 | |
assembly { | |
value := mload(add(_bytes, 0x20)) | |
} | |
} | |
function _updateLastTransactionPrice(uint256 tokenId, bytes memory priceData) internal { // 최신 거래 가격 업데이트 | |
lastTransactionPrice[tokenId] = _bytestoUint256(priceData); | |
} | |
function mintManyTokens(address to, uint256 num, uint256 startId) public onlyDeployer { | |
// 테스트용 임시 민팅 | |
for (uint256 i = 0; i < num; i++) { | |
mintWithTokenURI(to, startId+i, "test"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment