Skip to content

Instantly share code, notes, and snippets.

@dwook
Created February 18, 2022 13:44
Show Gist options
  • Save dwook/5c3c357dd25259c3a5a3afe82430d32f to your computer and use it in GitHub Desktop.
Save dwook/5c3c357dd25259c3a5a3afe82430d32f to your computer and use it in GitHub Desktop.
LoveChain 스마트컨트랙트
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