今日、ERC-721で簡単な図書館システムを作りました。Ropstenのテストネット上でこのスマートコントラクトを作りました。
ERC-20 vs. ERC-721トークン基準
ERC-20トークン基準は暗号柄を作るに使っているだけ。ERC-20トークン基準とは異なり、ERC-721トークン基準は様々資産を管理できます。例えば、CryptoKittiesはERC-721トークン基準で資産を管理しています。
コード
pragma solidity ^0.4.25;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/access/roles/MinterRole.sol";
contract LibraryNFT is ERC721Full, MinterRole {
struct Book {
uint256 id;
string title;
string author;
}
Book[] private bookCollection;
address private _contractCreator;
mapping(address => uint8) private _borrowedCount;
constructor() ERC721Full("LibraryNFT", "LIB") public {
_contractCreator = msg.sender;
}
function moveBook(address _from, address _to, uint256 _tokenId) private {
require(_to != address(0));
super._clearApproval(_from, _tokenId);
super._removeTokenFrom(_from, _tokenId);
super._addTokenTo(_to, _tokenId);
emit Transfer(_from, _to, _tokenId);
}
function addBook(string _title, string _author) public onlyMinter returns (bool) {
super._mint(_contractCreator, bookCollection.length+1);
bookCollection.push(Book(bookCollection.length+1, _title, _author));
return true;
}
function borrowBook(uint256 _bookId) public {
require(_borrowedCount[msg.sender] < 5);
require(super.ownerOf(_bookId) == _contractCreator);
moveBook(super.ownerOf(_bookId), msg.sender, _bookId);
_borrowedCount[msg.sender]++;
}
function returnBook(uint256 _bookId) public {
moveBook(msg.sender, _contractCreator, _bookId);
_borrowedCount[msg.sender]--;
}
function getBookTitle(uint256 _bookId) public view returns (string) {
return bookCollection[_bookId-1].title;
}
function getBookAuthor(uint256 _bookId) public view returns (string) {
return bookCollection[_bookId-1].author;
}
}
このコードは単純な図書館システム。本を付け加えれて借りれて返せるにできます。
スタート
pragma solidity ^0.4.25;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/access/roles/MinterRole.sol";
最初の行にSolidityのバージョンを入れます。次、we import OpenZeppelin's ERC-721 Token implementation, and MinterRole to determine who is able to mint new tokens. In this case, this is equivalent to adding new books.
Constructor関数
contract LibraryNFT is ERC721Full, MinterRole {
struct Book {
uint256 id;
string title;
string author;
}
Book[] private bookCollection;
address private _contractCreator;
mapping(address => uint8) private _borrowedCount;
constructor() ERC721Full("LibraryNFT", "LIB") public {
_contractCreator = msg.sender;
}
...
}
このスマートコントラクトはOpenZeppelinのERC-720 Token Implementationに相続しています。
Constructor関数に様々な価値を定義しています。例えば、トークンの名前や記号です。I am also set as the contractCreator, where all books will be stored if not borrowed by anyone.
基本的な関数
pragma solidity ^0.4.25;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/access/roles/MinterRole.sol";
contract LibraryNFT is ERC721Full, MinterRole {
...
function moveBook(address _from, address _to, uint256 _tokenId) private {
require(_to != address(0));
super._clearApproval(_from, _tokenId);
super._removeTokenFrom(_from, _tokenId);
super._addTokenTo(_to, _tokenId);
emit Transfer(_from, _to, _tokenId);
}
function addBook(string _title, string _author) public onlyMinter returns (bool) {
super._mint(_contractCreator, bookCollection.length+1);
bookCollection.push(Book(bookCollection.length+1, _title, _author));
return true;
}
function borrowBook(uint256 _bookId) public {
require(_borrowedCount[msg.sender] < 5);
require(super.ownerOf(_bookId) == _contractCreator);
moveBook(super.ownerOf(_bookId), msg.sender, _bookId);
_borrowedCount[msg.sender]++;
}
function returnBook(uint256 _bookId) public {
moveBook(msg.sender, _contractCreator, _bookId);
_borrowedCount[msg.sender]--;
}
}
Here are the required functions for the 図書館システム. First, I made my own implementation of transferTo, because I had to disregard the owner of the book. Then, we have functions to enable the adding, borrowing, and returning of books. A user is limited to borrowing only up to 5 books.
補足
contract LibraryNFT is ERC721Full, MinterRole {
...
function getBookTitle(uint256 _bookId) public view returns (string) {
return bookCollection[_bookId-1].title;
}
function getBookAuthor(uint256 _bookId) public view returns (string) {
return bookCollection[_bookId-1].author;
}
}
この補足の関数は「本の作家はだれですか?」と「本のタイトルは何ですか?」という質問に答えるものです。
Contract Address (0x21d069a5c270fa892897a2b9ad4be6d24f989ebe)にこのスマートコントラクトを見れます。
もっと読む: