토큰 : 몇몇 공통 규약을 따르는 스마트 컨트랙트
contract ERC721 {
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
function balanceOf(address _owner) public view returns (uint256 _balance);
function ownerOf(uint256 _tokenId) public view returns (address _owner);
function transfer(address _to, uint256 _tokenId) public;
function approve(address _to, uint256 _tokenId) public;
function takeOwnership(uint256 _tokenId) public;
}
contract SatoshiNakamoto is NickSzabo, HalFinney {
// 오 이런, 이 세계의 비밀이 밝혀졌군!
}
function balanceOf(address _owner) public view returns (uint256 _balance);
address를 받아서 그 해당 값이 토큰을 얼마나 가지고 있는지 반환.
크립토 좀비에서는 좀비를 의미하고, 어떤 유저가 얼마나 많은 좀비를 소유하고 있는지를 의미한다.
토큰 ID(크립토 좀비에서는 좀비ID)를 받고, 이 ID를 소유하고 있는 사람의 address를 반환.
function ownerOf(uint256 _tokenId) public view returns (address _owner);
기존에 우리의 코드에서 사용하던 modifier의 이름이 토큰 표준 함수의 이름과 같아서 바꿔줘야 함.
ERC721 토큰 표준을 사용하고 있다는 것은 다른 컨트랙트들도 우리의 컨트랙트가 정확한 이름으로 정의된 함수를 가지고 있고 그렇게 작동할 것을 기대한다는 것.
이를 통해서 다른 컨트랙트는 우리의 내부 구현 로직을 모르더라도 토큰 표준 함수들을 통해서 우리와도 통신할 수 있다.
ERC721를 전송하는 방법에는 2가지 방식이 있다.
- transfer
토큰의 소유자가 전송상대의 address 와 전송하고자 하는 _tokenId 와 함께 transfer 함수를 호출한다.function transfer(address _to, uint256 _tokenId) public;
- approve
위의 정보를 가지고 approve 함수를 호출하고나서 컨트랙트에 누가 해당 토큰을 가질 수 있도록 허가를 받았는지 저장. (2 단계로 구성)function approve(address _to, uint256 _tokenId) public; function takeOwnership(uint256 _tokenId) public;
approve 방식의 경우에 2번의 함수 호출이 발생하기 때문에 함수 호출 사이에 누가 무엇에 대해 승인이 허가났는지 저장할 데이터 구조가 필요하다.
takeOwnership 함수에서는 msg.sender가 토큰을 가질 수 있도록 승인되었는지 확인하고, 확인이 되면 _transfer 호출
솔리디티에서 특별한 종류의 컨트랙트
기본(native) 데이터 타입에 함수를 붙일 때 유용하게 사용됨.
오버플로우와 언더플로우 같은 문제를 막아주는 라이브러리.
require과 비슷하게 조건을 만족시키지 않으면 에러를 발생시킴.
차이점: require 함수는 실패하면 남은 가스를 되돌려 줌.