dev/Solidity

LV.1 crypto zombies - 5 ERC721 & Crypto-Collectibles

_April 2021. 11. 28. 22:17

tokens, the ERC721 standard, and crypto-collectible assets에대해 다룬다

 

(1)Tokens

A token on Ethereum is basically just a smart contract that follows some common rules — namely it implements 

a standard set of functions that all other token contracts share, 

such as transferFrom(address _from, address _to, uint256 _tokenId) and balanceOf(address _owner).

 

그래서 erc20 토큰 찍어내는것은 쉬운편이다. 스마트 컨트랙을 따르면 되기때문

 

So basically a token is just a contract that keeps track of who owns how much of that token, 

and some functions so those users can transfer their tokens to other addresses.

All ERC20 tokens share the same set of functions with the same names, they can all be interacted with in the same ways.

 

근데 기존 코인과 달리 코인을 쪼갤수없이 하나의 아이템을 올리고싶다면?

또 각각의 아이템을 다르게 만들고싶다면?=NFT

이게바로 ERC721토큰이다. 

ERC721 tokens are not interchangeable since each one is assumed to be unique, and are not divisible

You can only trade them in whole units, and each one has a unique ID. 

그래서 nft도 트잭을 찍어보면 토큰갯수로 찍힌다.

1jdc토큰 = 1nft


(2)ERC721 Standard, Multiple Inheritance

 

contract ERC721 {
  event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
  event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);

  function balanceOf(address _owner) external view returns (uint256);
  function ownerOf(uint256 _tokenId) external view returns (address);
  function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
  function approve(address _approved, uint256 _tokenId) external payable;
}

이만큼 기능을 구현해주면 erc721이라 할수있음

내부는 개발자가 알아서 개발을 해줘야함

 

balanceOf :returns how many tokens that address owns. 주소주인이 가진 nft갯수

ownerOf : takes a token ID (in our case, a Zombie ID), and returns the address of the person who owns it 

             nft 주소로 주인 주소 찾기

transferFrom: 

approve: 

이두개는 세트인데

the token's owner first calls approve with the address he wants to transfer to, and the _tokenID . 

The contract then stores who is approved to take a token, usually in a mapping (uint256 => address). 

Then, when the owner or the approved address calls transferFrom, 

the contract checks if that msg.sender is the owner or is approved by the owner to take the token, 

and if so it transfers the token to him.

실제 transfer은 ERC721.sol의  emit Transfer(_from, _to, _tokenId); 통해 이루어짐

 

approve의 경우 2단계임

  1. You, the owner, call approve and give it the _approved address of the new owner, and the _tokenId you want him to take.
  2. The new owner calls transferFrom with the _tokenId. Next, the contract checks to make sure the new owner has been already approved, and then transfers him the token.

이것도 다 체크하고 실제 어프루브는 ERC721.sol의 emit Approval(msg.sender, _approved, _tokenId);

 


(3) Preventing Overflows and Underflows

안한거

such as some extra checks to make sure users don't accidentally transfer their zombies to address 0 (which is called "burning" a token — basically it's sent to an address that no one has the private key of, essentially making it unrecoverable).

토큰소각은 찐소각이아니라 없는주소/못쓰는주소로 보내는거였군..

 

컨트랙 보안강화

uint8 는 십진수 0~255까지저장할수 있다.

uint8 number = 255;
number++;

근데 이래버리면 다시 0으로 돌아간다. 이게 overflow

underflow는 음수 지정하면 나는 에러.

 

이런걸 검증하는 라이브러리가 SafeMath

import "./safemath.sol";

contract ZombieOwnership is ZombieAttack, ERC721 {

  using SafeMath for uint256;

이런식으로 넣으면 커버됨

 

 

이제 ++ -- 대신 .add .sub이런식으로 쓰면 라이브러리 사용가능

 


(4)주석 

The standard in the Solidity community is to use a format called natspec, which looks like this:

/// @title A contract for basic math operations
/// @author H4XF13LD MORRIS 💯💯😎💯💯
/// @notice For now, this contract just adds a multiply function
contract Math {
  /// @notice Multiplies 2 numbers together
  /// @param x the first uint.
  /// @param y the second uint.
  /// @return z the product of (x * y)
  /// @dev This function does not currently check for overflows
  function multiply(uint x, uint y) returns (uint z) {
    // This is just a normal comment, and won't get picked up by natspec
    z = x * y;
  }
}

@notice explains to a user what the contract / function does. @dev is for explaining extra details to developers.

all tags are optional. But at the very least, leave a @dev note explaining what each function does.