// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
정말 별 거 없다. 마치 화폐처럼, 모든 개별 토큰이 동일한 가치다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC721 {
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
}
balanceOf() : 특정 주소가 소유한 NFT 개수 조회
ownerOf() : 특정 NFT의 소유자 조회
transferFrom() : NFT 전송
safeTransferFrom() : 안전한 NFT 전송 (컨트랙트 주소도 받을 수 있도록 보장)
approve() : 특정 NFT의 사용 권한 부여
setApprovalForAll() : 모든 NFT에 대한 사용 권한 부여
다 필요없고 이것만 보면 된다.
이걸로 토큰을 유니크하게 구분하는 것이다.
겉으로는 똑같이 보이는 토큰일지라도, 유니크한 tokenId를 토큰에 부여해
각 토큰이 다른 것이다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC1155 {
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
}
balanceOf() : 특정 ID의 토큰 개수 조회
balanceOfBatch() : 여러 개의 ID에 대해 토큰 개수 조회
safeTransferFrom() : 특정 ID의 토큰 전송
safeBatchTransferFrom() : 여러 개의 ID를 한 번에 전송 (가스 절약)
setApprovalForAll() : 모든 토큰에 대한 사용 권한 부여
자, 생각해보자. 20과 721을 구별하는 식별자는? ID를 두는 것이라고 했다.
그러면 한 컨트랙트에서, FT, NFT 두 종류의 토큰을 관리할 수 있게 하려면?
ID는 그대로 두고, 발행량을 조절해서 1개면 NFT, 1개 초과면 FT가 되는 것 아니겠는가?
어려울 것 없다. 걍 ID를 두는 것이다. 대신 NFT와 구별되어야 하니 FT도 id는 주되, 발행량을 많이 하면 되는 것이다.
또 하나의 1155의 특징은 Batch가 가능해 가스비를 절약하는 것이다.
safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data)
위를 보자. A가 B에게 토큰을 보내는데, 원래 같았으면 3종류라면 트랜잭션 3번 보내야 했다.
근데 ids를 통해 3종류와 토큰 개수를 한번에 적어서 보낼 수 있는 것이다.
balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory)
이것도 보자. 주소 A,B,C의 토큰 보유량을 조회하고 싶다면? 각각 3번 조회해야 된다.
이제는 accounts에 한번에 넣고, 어떤 토큰인지 ids를 배열로 둬서 한번에 조회가 가능한 것이다.
모든 기술은 기존의 기술을 부모삼아 발전하다.
1~3번까지 읽으면 기존의 기술에 리틀 터치를 해서 발전을 한 양상임을 알 수 있다.
즉, ERC-6960은 1155의 기술 + 알파 라는 것이다.
아래 그림을 보자.
이제 ERC-20 + ERC-721을 커버하면서, 동시에
한 토큰 안에 여러 개의 하위 토큰을 둘 수 있는 것이다.
위의 그림을 보자. 너무너무 쉽다.
기존에 토큰을 구분했던 ID를 mainID로 두고, 그 아래에 여러 개의 SubId를 둬서
위 그림처럼 부모-자식 관계의 토큰을 만들 수 있다.
머리로는 이해했는데, 이건 어떤 분야에서 써야 하는 건지 감이 안 올 수 있다.
우리는 24년 체인링크 해커톤에서 이를 주제로 했는데,
선박 금융에서, 한 회사마다 한 컨트랙트가 있다.
배를 만들 때 마다, 새로운 MainID를 부여해 토큰을 만들어서 투자를 받고 투자자들에게 나눠준다.
여기가 끝이라면, ERC-721이랑 똑같다. 지루하다.
그래서 한 MainID인 배 마다, 아래 여러 SubID를 가진 토큰들을 만든다.
멤버쉽, 티켓 등으로 활용할 수 있게.
ㅈㄴ 별거 없다. 막말로 나도 이더리움 컨트리뷰터할 만 하지 않나?
ERC-20은 토큰들이 동일하고,
ERC-721은 토큰마다 ID를 둬서 서로를 구별하고,
ERC-1155는 ERC-20과 ERC-721 두 종류의 토큰을 한 컨트랙트 안에서 생성가능하고,
이는 ID를 둬서 가능하다.
추가로 Batch 조회, 전송을 추가해 가스비도 절약할 수 있다!
ERC-6960은 하나의 MainID 하위에, 추가로 SubID 토큰들을 둬서 부모-자식 관계의 토큰을 관리할 수 있는 Dual Layer Token도 구현 가능하다.
와 너무 이지하다. 쏘이지~