LoginSignup
2
0

More than 5 years have passed since last update.

ERC-721で簡単な図書館システムを作っていること

Last updated at Posted at 2018-10-18

今日、ERC-721で簡単な図書館システムを作りました。Ropstenのテストネット上でこのスマートコントラクトを作りました。

ERC-20 vs. ERC-721トークン基準

ERC-20トークン基準は暗号柄を作るに使っているだけ。ERC-20トークン基準とは異なり、ERC-721トークン基準は様々資産を管理できます。例えば、CryptoKittiesはERC-721トークン基準で資産を管理しています。

コード

libraryContractNFT.sol
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; 
    }
}

このコードは単純な図書館システム。本を付け加えれて借りれて返​せ​るにできます。

スタート

libraryContractNFT.sol
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関数

libraryContractNFT.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;
    }
    ...
}

このスマートコントラクトはOpenZeppelinのERC-720 Token Implementationに相続しています。

Constructor関数に様々な価値を定義しています。例えば、トークンの名前や記号です。I am also set as the contractCreator, where all books will be stored if not borrowed by anyone.

基本的な関数

libraryContractNFT.sol
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.

補足

libraryContractNFT.sol
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)にこのスマートコントラクトを見れます。

もっと読む:

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0