Skip to content

Instantly share code, notes, and snippets.

@wadro
Last active June 23, 2021 06:23
Show Gist options
  • Save wadro/390ee44e607ea4d4119383cd7d42d924 to your computer and use it in GitHub Desktop.
Save wadro/390ee44e607ea4d4119383cd7d42d924 to your computer and use it in GitHub Desktop.
멋쟁이사자처럼 Klaytn NFT Class 2주차 과제
/*
### 과제 제출 리스트
- [1주차(https://gist.github.com/wadro/26fee8648d9c2aae9431bb2ee8805835)](https://gist.github.com/wadro/26fee8648d9c2aae9431bb2ee8805835)
- [2주차(https://gist.github.com/wadro/390ee44e607ea4d4119383cd7d42d924)](https://gist.github.com/wadro/390ee44e607ea4d4119383cd7d42d924)
- [3주차(https://gist.github.com/wadro/e48b7665df98a81759e929742bb62cdb)](https://gist.github.com/wadro/e48b7665df98a81759e929742bb62cdb)
- [해커톤(https://gist.github.com/wadro/6fac56024ba4e2ebda34ec354ce0dbf6)](https://gist.github.com/wadro/6fac56024ba4e2ebda34ec354ce0dbf6)
---
*/
// 배포한 주소(account):
// BAOBAB_CONTRACT_ADDRESS : 0xC837e882Cb30aabF294534344b9ED77f6F456E19
// CYPRESS_CONTRACT_ADDRESS : 0xa559b3575fa5538c9f1b5bE43B19C0E00fA1419a
// 수정된 부분:
// 1. 컨트랙트 이름
// - NFTSimple -> MyTrademark [line 19]
// - NFTMarket -> TrademarkMarket [line 181]
// 2. 추가한 함수
// - logTrademark: [line 63]
// - tokenId 로 구분
// - logs 매핑(tokenId => 사용기록[배열]) 과 timestamps 매핑 (tokenId => 시간[배열]) ( 현재시간은 now 로 호출 )
/**
* 오후 12:16 2021-06-23 변경사항
* 1. tokenUri -> tokenInfo struct 로 변경
* - tokenUri 관련 함수 전부 변경
*
*/
// Klaytn IDE uses solidity 0.4.24, 0.5.6 versions.
pragma solidity >=0.4.24 <=0.5.6;
contract MyTrademark {
string public name = "LogTrademark";
string public symbol = "KL";
struct tokenInfo {
string title;
string tokenUri;
string description;
uint256 category;
uint256 sector;
}
mapping(uint256 => address) public tokenOwner;
mapping(uint256 => tokenInfo) public tokenInfoMap;
mapping(uint256 => uint256[]) private _timestamps;
mapping(uint256 => string[]) private _logs;
uint256[] private _enrolledTokens;
mapping(address => uint256[]) private _ownedTokens;
bytes4 private constant _KIP17_RECEIVED = 0x6745782b;
function registerMarkInfo(
address to, uint256 tokenId, string memory title,
string memory tokenUri, string memory description,
uint256 category, uint256 sector
) public returns (bool) {
require(to == msg.sender, "from != msg.sender");
require(
tokenOwner[tokenId] == 0x0000000000000000000000000000000000000000,
"enrolled ID!"
);
tokenOwner[tokenId] = to;
tokenInfo storage newToken = tokenInfoMap[tokenId];
newToken.title = title;
newToken.tokenUri = tokenUri;
newToken.description = description;
newToken.category = category;
newToken.sector = sector;
_enrolledTokens.push(tokenId);
// add token to the list
_ownedTokens[to].push(tokenId);
uint256 _tempNow = now;
_timestamps[tokenId].push(_tempNow); // 0: uint256: 1621905998
_logs[tokenId].push("Trace your first use log!");
return true;
}
function getMarkInfo(
uint256 tokenId
) public view returns (string memory, string memory, string memory,uint256,uint256){
tokenInfo storage s = tokenInfoMap[tokenId];
return (s.title,s.tokenUri,s.description,s.category,s.sector);
}
function setMarkInfo(
address from, uint256 tokenId, string memory title,
string memory tokenUri, string memory description,
uint256 category, uint256 sector
) public returns (bool) {
require(from == msg.sender, "from != msg.sender");
require(
from == tokenOwner[tokenId],
"you are not the owner of the token"
);
tokenInfo storage s = tokenInfoMap[tokenId];
s.title = title;
s.tokenUri = tokenUri;
s.description = description;
s.category = category;
s.sector = sector;
return true;
}
function logTrademark(
address from,
uint256 tokenId,
string memory logData
) public {
bytes memory _tempLog = bytes(_logs[tokenId][0]); // Uses memory
require(from == msg.sender, "from != msg.sender");
require(
from == tokenOwner[tokenId],
"you are not the owner of the token"
);
require(
// _tempLog.length == 25,
_tempLog.length != 0,
// firstlog != 0,
"first log error!"
);
_logs[tokenId].push(logData);
_timestamps[tokenId].push(now);
}
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 {
uint256 lastTokenIndex = _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][lastTokenIndex];
_ownedTokens[from][lastTokenIndex] = tokenId;
break;
}
}
_ownedTokens[from].length--;
}
function ownedTokens(address owner) public view returns (uint256[] memory) {
return _ownedTokens[owner];
}
function enrolledTokens() public view returns (uint256[] memory) {
return _enrolledTokens;
}
function getLogTimes(uint256 tokenId) public view returns (uint256[] memory) {
return _timestamps[tokenId];
}
function getLog(uint256 tokenId, uint256 index) public view returns (string memory) {
return _logs[tokenId][index];
}
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 TrademarkDeal {
mapping(uint256 => address[]) public seller;
function buyNFT(uint256 tokenId, address NFT)
public
payable
returns (bool)
{
uint256 _lastSellerIndex = seller[tokenId].length - 1;
address payable receiver = address(uint160(seller[tokenId][_lastSellerIndex]));
// Send 0.01 klay to Seller
receiver.transfer(10**16);
// Send NFT if properly send klay
MyTrademark(NFT).safeTransferFrom(
address(this),
msg.sender,
tokenId,
"0x00"
);
return true;
}
// 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].push(from);
// return signature which means this contract implemented interface for ERC721
return
bytes4(keccak256("onKIP17Received(address,address,uint256,bytes)"));
}
}
@wadro
Copy link
Author

wadro commented May 26, 2021

@anxiubin

안녕하세요 고민해서 코드를 작성하신 점이 눈에 띄네요:)
저는 그냥 연습용으로만 올려놨는데.. ㅎㅎ

73번째줄

이 부분은 왜 주석처리 하셨는지 알 수 있을까요?
logTrademark 함수를 실행하기 전에 최초 1회 로그가 등록되어있는지 확인이 필요할 것 같다고 생각이 들어요.

require(!logs[tokenId][0], "You should mint Token first");        

문구와 함께 이렇게 넣어주는 건 어떨까요?

저 부분이 아마 에러가 나서 주석처리 했던 걸로 기억해요.
다음 수업을 듣고 다시 수정해보려구요.
조언해주신 코드로 해보겠습니다. 😄

@juliana-kim
Copy link

반복적으로 사용되는 require문(예를들어 "you are not the owner of the token)과 같은 경우는 modifier로 별도 구현해도 좋을거 같습니다.

@wadro
Copy link
Author

wadro commented Jun 23, 2021

반복적으로 사용되는 require문(예를들어 "you are not the owner of the token)과 같은 경우는 modifier로 별도 구현해도 좋을거 같습니다.

코멘트 감사합니다! 수정해보겠습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment