Kip17을 이용한 솔리디티 에러

한참 공부 중인 사람 입니다. ㅠ
시작 부터 막히네요 ㅠ;

pragma solidity ^0.5.0;

import '@klaytn/contracts/token/KIP17/KIP17Token.sol';

contract PalbokToken is KIP17Token {

    constructor(string memory name, string memory symbol) KIP17Token(name, symbol) public {}

    struct PalbokTokenInfo {
        string author;
        string createDate;
    }

    mapping (uint256 => PalbokTokenInfo) palbokTokenInfos;

    // 토큰에 tokenURI 외 간단한 정보 저장
    function setPalbokTokenEtcInfo(
        uint256 tokenId,
        string memory author,
        string memory createDate
    ) public {
        palbokTokenInfos[tokenId] = PalbokTokenInfo(author, createDate);
    }

    // 토큰 정보 보기
    function getPBT(uint256 tokenId) public view returns (string memory, string memory, string memory) {
        string memory _author = palbokTokenInfos[tokenId].author;
        string memory _createDate = palbokTokenInfos[tokenId].createDate;
        string memory _tokenUri = tokenURI(tokenId);
        return (_author, _createDate, _tokenUri);
    }
}

KIP17Token.sol을 상속 받고 있습니다.
그리고 "tokenURI(_tokenId)"를 사용 하려고하는데
tokenURI 를 찾지를 못하네요…
DeclarationError: Undeclared identifier. 에러가 나는데 무엇을 잘못 할 걸 까요? ㅠㅠ;

안녕하세요

KIP17Token.sol => KIP17Full.sol => KIP17Metadata.soltokenURI함수를 가지고 있지만 접근 제어자가 external로 설정 되어있어 내부에서 실행이 불가능한것입니다.

접근 제어자 종류는 다음과 같습니다.

  • public : 어디든지 호출 가능합니다.
  • external : 컨트랙트 내부에서 호출이 불가능 합니다. 외부에서 실행시킬 수 있습니다.
  • private : 컨트랙트 안에서 호출 할 수 있습니다.
  • internal : 컨트랙트와 derived 컨트랙트만 호출 할 수 있습니다.

아주 간단한 해결 방법은 KIP17Metadata.sol 파일에 tokenURI함수를 다음과 같이 바꿔주시면됩니다.

//...

function tokenURI(uint256 tokenId) public view returns (string memory) {
  require(_exists(tokenId), "KIP17Metadata: URI query for nonexistent token");
  return _tokenURIs[tokenId];
}

//...

이더리움 스마트 컨트랙트 개발 주의사항. 스마트 컨트랙트를 블록체인에 배포하기 전에는, 많은 검증과 테스트를… | by Eun Woo Nam | RayonProtocol | Medium



다음 예제를 확인하시고 개발에 참고하시면 될 것 같습니다.
tokenURI부분은 포함되지 않았습니다.

source

pragma solidity 0.5.6;

import "@klaytn/contracts/token/KIP17/KIP17Token.sol";

contract Example is KIP17Token {
  constructor() KIP17Token("Example", "EXAM") public {

  }

  struct Post {
    address author;
    string content;
    uint256 createdAt;
  }

  mapping(uint256 => Post) posts;

  function upsertPost(uint256 tokenId, string memory content) public {
    // 토큰이 존재해야함
    require(_exists(tokenId), "KIP17: approved query for nonexistent token");

    // 해당 토큰 소유자여야함
    require(ownerOf(tokenId) == msg.sender, "Permission denied");

    Post memory post;
    post.author = msg.sender;
    post.content = content;
    post.createdAt = block.timestamp;

    posts[tokenId] = post;
  }

  function getPostByTokenId(uint256 tokenId) public view returns (address, string memory, uint256) {
    // 토큰이 존재해야함
    require(_exists(tokenId), "KIP17: approved query for nonexistent token");

    Post memory post = posts[tokenId];
    return (post.author, post.content, post.createdAt);
  }
}

dependencies

"@klaytn/contracts": "^0.9.0"

2 Likes

아!! 감사합니다

  • public : 어디든지 호출 가능합니다.
  • external : 컨트랙트 내부에서 호출이 불가능 합니다. 외부에서 실행시킬 수 있습니다.
  • private : 컨트랙트 안에서 호출 할 수 있습니다.
  • internal : 컨트랙트와 derived 컨트랙트만 호출 할 수 있습니다.

이것을 잘 확인하고 사용해야 겠네요…
제가 안되는 것을 가지고 계속 시도하고 있었군요 :frowning:

node_module 안에있는 “@klaytn/contracts” 소스를 public으로 수정하기엔 그렇고… 사용가능 한 곳에서 잘 불러 쓰도록 설계 해야겠네요~

감사합니다~ ^^

1 Like