building out the minting function:
a. NFT to pint to an address
b. keep track of the token ids
c. keep track of token owner addresses to token ids
d. keep track of how many tokens an owner address has
e. create an even that emits a transfer log
- contract address, where it is being minted to, the id
114. Mapping Database for The Minting NFT Function
먼저 c, d 번 기능을 위해 매핑 구조를 만들어야 한다.
- mapping in solidity creates a hash tableof key pair values
// Mapping from token_id to the owner
mapping(uint256 => address) private _tokenOwner;
// Mapping from owner to number of owned tokens
mapping(address => uint256) private _OwnedTokensCount;
- uint 는 alias 이다. 실제로 uint 가 의미하는 것은 uint256 인데 이것은 최대 256 bit까지 나타낼 수 있다는 것을 의미하고 둘중 어느 버전으로 사용해도 상관없다.
115. Exercise - Write The Minting NFT Function
Excercise:
- write a function called _mint that takes two arguments an address called to and an integer called tokenId.
- add internal visibility to the signature
- set the _tokenOwner of the tokenId to the address argument 'to'.
- increase the owner token count by 1 each time the function is called
BONUS
create two requirements
5. Require that the mint address isn't 0
6. Require that the token has not already been minted
116. Solution - Write The Minting NFT Function
function _exists(uint tokenId) internal view returns(bool) {
// setting the address of nft owner to check the mapping
// of the address from tokenOwner at the tokenId
address owner = _tokenOwner[tokenId];
// return truthiness that address is not zero
return owner != address(0);
}
function _mint(address to, uint tokenId) internal {
// requires that the address isn't zero
require(to != address(0), 'ERC721: minting to the zero address');
// requires that the token does not already exist
require(!_exists(tokenId), 'ERC721: token already minted');
// we are adding a new address with a tokenId for minting
_tokenOwner[tokenId] = to;
// keeping track of each address that is minting and adding one to the count
_OwnedTokensCount[to]++;
}
118. Transer Event for Minting NFTs
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId);
/////
emit Transfer(address(0), to, tokenId);
from = contract address 인데 아직 해당 부분을 짜지 않았으니 일단 default 값으로 address(0)을 전달한다.
119. Storing NFTs on the marketplace Smart Contract I
이제 Connector에 ERC721.sol을 연결해주어야 한다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import './ERC721Metadata.sol';
import './ERC721.sol';
contract ERC721Connector is ERC721Metadata, ERC721 {
constructor(string memory name, string memory symbol) ERC721Metadata(name, symbol) {
}
}
그리고 KryptoBirdz.sol 파일을 수정한다.
정신 빼놓고 듣다가 Connector를 수정했었다...ㅎ
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import './ERC721Connector.sol';
contract KryptoBird is ERC721Connector {
// array to store our nfts
string [] public kryptoBirdz;
mapping(string => bool) _kryptoBirdzExists;
function mint(string memory _kryptoBird) public {
require(!_kryptoBirdzExists[_kryptoBird], 'Error - kryptoBird already exists');
/* this is deprecated
uint _id = KryptoBirdz.push(_kryptoBird);
- .push no longer returns the length but a ref to the added element
*/
kryptoBirdz.push(_kryptoBird);
uint _id = kryptoBirdz.length -1;
_mint(msg.sender, _id);
_kryptoBirdzExists[_kryptoBird] = true;
}
constructor () ERC721Connector('KryptoBird', 'KBIRDZ'){
}
}
121. Mint Your Very First Coded NFT :)
이제 다시 컴파일하고, migrate 하고 truffle console 열어서 확인해보면
kryptoBird = await KryptoBird.deployed()
kryptoBird.mint('http..1') // 아무거나 쓰자
그러면 로그가 막 나오는데..
배포했을 때 KryptoBird의 contract address가 to 의 address와 같은 것을 확인할 수 있다. from은 msg.sender 즉 우리의 account 주소이다.
사실 지금 잘 이해가 안간다..
그리고 똑같은 string을 다시 mint하려고하면 우리가 require 에서 만들어놨던 error 가 실행되는 것도 확인할 수 있다.