❗️ 스마트 컨트랙트 개발을 찍어먹기 했습니다. 다루는 키워드에 대한 자세한 설명은 생략 하고 only 과정만 담았습니다.
트러플 설치 (기본적으로 node.js 설치가 되어있어야 함)
sudo npm install -g truffle
스마트 컨트랙트 개발을 위한 디렉토리 안에서 명령어 입력
truffle init
├── contracts
├── migrations
├── test
└── truffle-config.js
오픈제플린 (open zeppelin) 설치
```bash
npm install @openzeppelin/contracts
```
- 설치하게 되면 많은 양의 파일들이 생성된다. 추후 스마트 컨트랙트 구현에 이용됨.
contracts
디렉토리에 DigitalPicture.sol
파일 만들기
truffle create contract DigitalPicture
├── contracts
│ └── DigitalPicture.sol
DigitalPicture.sol 코드 작성
// contracts/DigitalPicture.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 DigitalPicture is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() ERC721("DigitalPicture", "NDP") {}
// public 으로 해야만 web3.js 에서 이용할 수 있다.
// address : 지갑 주소 정보
// NFT 를 발행 할때마다 increment 되면서 순차적으로 키 생성
function publishItem(address creator, string memory tokenURI) public returns (uint256){
_tokenIds.increment(); // 1
uint256 newTokenId = _tokenIds.current();
// 해당 지갑 주소를 가지고 있는 사람한테 NFT 토큰 한개를 전달해주는 함수
_mint(creator, newTokenId);
// tokenURI : 창작자의 그림이 저장되어있는 특정 위치
_setTokenURI(newTokenId, tokenURI);
return newTokenId;
}
}
컴파일하기
truffle compile
build/contracts
에 파일들이 생성된다.├── build
│ └── contracts
│ ├── Address.json
│ ├── Context.json
│ ├── Counters.json
│ ├── DigitalPicture.json
│ ├── ERC165.json
│ ├── ERC721.json
│ ├── ERC721URIStorage.json
│ ├── IERC165.json
│ ├── IERC4906.json
│ ├── IERC721.json
│ ├── IERC721Metadata.json
│ ├── IERC721Receiver.json
│ ├── Math.json
│ ├── SignedMath.json
│ └── Strings.json
migration 파일 생성하기
// migrations/1_contract_migrations.js
const DigitalPicture = artifacts.require("DigitalPicture");
module.exports = function (deployer) {
deployer.deploy(DigitalPicture);
};
테스트 해보자
QUICKSTART로 진행
// test/DigitalPicture.test.js
const DigitalPicture = artifacts.require("DigitalPicture");
contract("DigitalPicture", async function (accounts) {
const [owner] = accounts;
// 각각 테스트 케이스를 실행하기 전 무조건 실행되는 코드
beforeEach(async function () {
this.token = await DigitalPicture.new();
});
it("publish item", async function () {
const tokenId = await this.token.publishItem(owner, "http://dev.sample.com/a/b/abc.jpg");
console.log(tokenId);
});
});
// development 주석 해재후
...
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
...
테스트 명령어로 테스트
truffle test ./test/DigitalPicture.test.js