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 25, 2021

@BbChip0103

훌륭한 코멘트 감사합니다.
앞으로도 복습하는 의미로 조금씩 다듬어 가보려고 합니다.

미국에서 쓰이고 있는 보조등록부 라는 개념을 가져온 것으로
말씀하신것처럼 사용한 내역을 증명 할수 있도록 공용장부를 만드는 느낌이죠.
사용자의 참여도를 올리고, 증명에만 거의 포커스를 맞출수 있도록 기존 특허 출원 절차보다 간소화시키려고 생각중입니다.

아이디어에 대한 코멘트부터 코드에 대한 코멘트까지 정성어린 조언에 감사드리고 좋게 봐주셔서 다행입니다.
흔히들 무관심보단 악플이 낫다고 하죠 ㅎㅎ 얼마든지 태클을 걸어도 괜찮습니다.
아이디어의 입장에서는 더 성장할수 있고, 사회 전체적으로 이익이 된다면 결국 긍정적인 영향이 저에게도 돌아오니까요.
(그렇다고 사회를 위해 희생한다는 말은 아니고 어디까지나 밸런스를 맞춘다는 가정입니다.)

예전에는 이런 활동을 할때 남들에게 비판받고 공격받는 것이 두려울때가 있었지만, 때로는 정말 악담에 진정성이 담길때가 있죠.
그리고 이 코멘트에는 꼭 답장 안하셔도 됩니다. 가끔 헛소리를 합니다.

@anxiubin
Copy link

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

73번째줄

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

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

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

@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