이거 따라할 때 생겼던 에러와 해결내용
https://medium.com/pinata/how-to-build-erc-721-nfts-with-ipfs-e76a21d8f914
1. ERC721
오픈제플린 최신버전은 ERC721URIStorage 가 ERC721를 대체한다. 이름 바꿔줘야함.
못가져옴 사용이 안되어서 에러 뜸
,DeclarationError: Undeclared identifier.
--> project:/contracts/UniqueAsset.sol:29:3:
|
29 | _setTokenURI(newItemId, metadata);
//기존
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
//ERC721.sol가 없고 이제 ERC721URIStorage.sol이거 씀
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
근데 나는 여전히 계속 빨간줄 뜨더라고 그래서
../node_modules/
로 경로 찾아주니까 빨간줄 사라짐
2. DeclarationError
사실 무엇보다
변수들을 못찾았는데
DeclarationError: Undeclared identifier. Did you mean "hash"?
--> project:/contracts/UniqueAsset.sol:24:11:
|
24 | require(hashes[hash] != 1);
| ^^^^^^
,DeclarationError: Undeclared identifier. Did you mean "hash"?
--> project:/contracts/UniqueAsset.sol:25:3:
|
25 | hashes[hash] = 1;
| ^^^^^^
그이유는!!!!
괄호를 잘못 묶었더라고..ㅋㅋㅋㅋ...
contract 안에 함수 있는건데
contract랑 함수를 따로 해서 contract에 담아둔 애들이름 못 쓰는 거였다
결과 컴파일 잘된다!
3. 경고 Visibility for constructor is ignored.
경고 뜨는 건
Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable,
making it "abstract" is sufficient.
(경고: 생성자의 가시성은 무시됩니다. 계약을 배포할 수 없도록 하려면 "추상"으로 만드는 것으로 충분합니다.)
--> project:/contracts/UniqueAsset.sol:16:4:
|
16 | constructor() public ERC721("UniqueAsset", "UNA") {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
생성자에 더이상 가시성(public/ external)이 필요하지 않다고 한다.
왜냐면 생성자는 처음에 배포됐을 때만 읽히니까 다음에 또 불려질 일이 없다.
public을 지웠더니 경고가 사라졌다.
추가적으로는
솔리디티 버전을 코드랑 잘 맞춰줘야하는 것. 필요할 때 f1눌러서 버전수정했다.
따라한 내용 정리
필요한 것
- vscode(nodejs, 솔리디티확장자)
- IPFS 설치
- Ganache — 이더리움의 로컬 블록체인 — 설치
- 트러플 설치
- NodeJS 설치
- 피나타 API 키
스마트 계약 작성
(오픈제플린에서 가져와서 쓸거임)
새프로젝트 폴더 만듦
mkdir mySpecialAsset
디랙토리 초기화
npm init -y
Truffle을 활용해 스마트 계약 프로젝트 초기화
truffle init
Open Zeppelin 계약에 액세스할거라서 설치
npm install @openzeppelin/contracts
contracts 폴더 구조 안에 파일 생성! (솔리디티 버전 맞춰서 하기)
UniqueAsset.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "../node_modules/@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "../node_modules/@openzeppelin/contracts/utils/Counters.sol";
contract UniqueAsset is ERC721URIStorage{
//Counters to help us increment the identifiers for the tokens we mint.
// 카운터 라이브러리(갯수세는역할함)를 쓴다. 이 유형으로
using Counters for Counters.Counter;
//변수만듦to keep track of all of the tokens we’ve issued.
Counters.Counter private _tokenIds;
//mapping for the IPFS hashes associated with tokens.
mapping(string => uint8) hashes;
constructor() ERC721("UniqueAsset", "UNA") {}
// 특정IPFS해시에 아직 mint안되어있으면 mint하는 함수
// a method to our contract that will allow us to mint an NFT for a specific IPFS hash if not token has been minted yet for that hash
//nft수령인//NFT를 생성할 콘텐츠와 관련된 IPFS 해시 //자산에 대한 JSON 메타데이터에 대한 링크를 참조해야 한다
function awardItem(address recipient, string memory hash, string memory metadata) public returns (uint256)
{
require(hashes[hash] != 1);
hashes[hash] = 1;
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, metadata);
return newItemId;
}
}
폴더구조 migrations 들어가서
2_deploy_contract.js
파일 생성
var UniqueAsset = artifacts.require("UniqueAsset");
module.exports = function (deployer) {
deployer.deploy(UniqueAsset);
};
다 하면 컴파일
truffle compile
만약 오류가 발생하면 Ganache가 실행 중인 포트를 수동으로 설정 (아니면 나처럼 버전, 모듈경로 등의 문제일수도 있음 위에 참조)
truffle-config.js
(가나슈 퀵스타 누르면 뜨는 창에있는거랑 동일하게)
truffle migrate
이걸로
NFT 스마트 계약을 배포
이제 스마트 계약을 처리했으므로 기본 자산을 IPFS로 가져와 관련 NFT를 발행할 때 사용할 수 있는지 확인
IPFS에 자산 추가
우리는 Pinata를 사용하여 자산을 IPFS에 추가하고 고정된 상태로 유지하도록 할 것입니다.
https://app.pinata.cloud/pinmanager
uploadFile.js
업로드할 파일 준비
작업을
npm i axios form-data
쉽게 하려면 두 가지 종속성이 필요하다
이 스크립트에
const pinataApiKey = "YOURAPIKEY";
const pinataSecretApiKey = "YOURSECRETKEY";
const axios = require("axios");
const fs = require("fs");
const FormData = require("form-data");
const pinFileToIPFS = async () => {
const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`;=
let data = new FormData();
data.append("file", fs.createReadStream("./pathtoyourfile.png"));
const res = await axios.post(url, data, {
maxContentLength: "Infinity",
headers: {
"Content-Type": `multipart/form-data; boundary=${data._boundary}`
pinata_api_key: pinataApiKey,
pinata_secret_api_key: pinataSecretApiKey,
},
});
console.log(res.data);
};
pinFileToIPFS();
코드 넣기
Pinata에서 로그인하고 새 키 만들면 뜨는
키"YOURAPIKEY"와 비밀키"YOURSECRETKEY"를 넣기
node uploadFile.js
성공적으로 됐으면 이렇게 뜸
해당 해시는 자산의 검증 가능한 표현이고 IPFS 네트워크의 자산을 의미한다. 누군가가 자산을 변조하고 변경한 경우 해시가 달라진다. 이 해시는 우리의 스마트 계약을 통해 NFT를 발행할 때 사용해야 하는 것이다. 공개 게이트웨이를 제공하는 모든 IPFS 호스트는 이제 콘텐츠를 표시할 수 있다.. 라고 위 링크 글에 있다.
이게 Pinata에 자산을 업로드 하는 거라는데 pinata 내 계정에는 뭔가 달라진게 안보인다.
게이트웨이를 통해서 봐야돼서 그런건가 흠...
이상
뒤에 json 파일 만드는 것 이전까지 해봤다.
https://stackoverflow.com/questions/68608281/file-import-callback-not-supported-on-truffle-migrate
'블록체인 > 솔리디티' 카테고리의 다른 글
truffle migrate이슈 (truffle명령어) [Error: *** Deployment Failed ***] (0) | 2022.02.28 |
---|---|
ParserError: Expected primary expression 오류 (0) | 2022.02.28 |
call 로우레벨 함수, Delegate call개념 (0) | 2022.02.28 |
payable (생성자에 넣기, 특정계정 권한주기, 함수수정modifier) (0) | 2022.02.27 |
이더리움 송금 스마트컨트랙트 코드(이더잔액: 주소.balance, msg.value:송금액,msg.sender:보내는자) (0) | 2022.02.26 |