1. 시작하기 앞서
ERC1155 스마트 컨트랙트는 단순하게 말하면 이전 편에서 했었던 ERC20과 ERC721을 결합한 형태라 볼 수 있다.
이전 편을 못 보신 분은 아래 링크를 통해 보실 수 있습니다.
EIP-165를 지원하고 ERC20이나 ERC721과는 다르게 한 번의 트랜잭션으로 여러 자산을 전송하거나 일괄 승인이 가능하다. 또한 ERC1155에서 자산을 mint할때 공급량을 1로 하면 NFT로 처리가 된다.
https://ethereum.org/ko/developers/docs/standards/tokens/erc-1155
2. ERC1155 예시
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract TestERC1155 is ERC1155 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() ERC1155("https://game.example/api/item/1.json") {
_mint(msg.sender, GOLD, 10**18, ""); // 재화
_mint(msg.sender, THORS_HAMMER, 1, ""); // NFT 아이템
}
function createNFT(address player, string memory tokenURI)
public
returns (uint256)
{
uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);
_setTokenURI(newItemId, tokenURI);
_tokenIds.increment();
return newItemId;
}
}
예시로 짜보았다. 스마트 컨트랙트 초기 생성자에서 골드라는 재화와 토르의 망치라는 NFT를 생성하고 스마트 컨트랙트 발급자에게 부여한다. 그리고 NFT를 만들 수 있는 기능을 넣어두었다. URI는 ERC721과 같이 MetadataURI인데 해당 형태는 이전 포스팅 ERC721편을 보면 나와 있다.
이처럼 ERC20의 재화와 ERC721의 NFT를 발급할 수 있어 ERC1155를 ERC20과 ERC721을 결합한 형태라고들 한다. 하지만 더 중요한 것은 하나의 트랜잭션으로 일괄 전송과 일괄 승인이 가능한 것인데 ERC1155의 해당 함수를 보자.
// 일괄 전송
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
...
}
// 일괄 잔액 확인
function balanceOfBatch(
address[] memory accounts,
uint256[] memory ids
) public view virtual override returns (uint256[] memory) {
...
}
// 일괄 승인
function setApprovalForAll(address operator, bool approved) public virtual override {
...
}
위의 safeBatchTransferFrom함수에서 ids와 amounts가 array형태인 것을 볼 수 있다.
예를 들어, ids = [3,6,9]이고 amounts = [100,200,300]이라면 3번에게 100토큰을 6번에게 200토큰을 주게 된다.
기존에는 한 트랙잭션에서 한 주소에게 밖에 보내지 못했다면 ERC1155에서는 한 번에 일괄적으로 보낼 수 있어 수수료 절감 효과가 있다고 볼 수 있다.
3. ERC1155토큰을 다른 컨트랙트로 보낼 시 주의할 점
다른 스마트 컨트랙트에서 ERC1155에서 보낸 토큰을 받으려면 해당 컨트랙트가 ERC1155Holder라는 컨트랙트를 상속해야한다.
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
contract MyContract is ERC1155Holder {
}
여기서 ERC1155Holder의 onERC1155Received와 onERC1155BatchReceived 함수를 구현하여 좀 더 복잡한 시나리오를 구현할 수 있다.
이 외 ERC1155의 사전 설정으로 ERC1155PresetMinterPauser를 상속하여 mint에 대한 엑세스 제어 및 일시 중지 기능에 대한 엑세스를 제어할 수 있다.
4. 다음편에서는
다음편에서는 기존 배포 방식과는 달리 Upgradeable Proxy로 배포를 진행해 보겠다.
Upgradeable Proxy는 기능 추가, 버그 등을 수정할 수 있도록하는 플러그인이다. 물론 제약 사항도 있으니 다음 편에 알아보자.
다음 편 보러 가기:
답글 남기기