ERC-1155 공부하다 정리해야할 생각이 들어서 공식 문서인 아래 페이지들을 번역/정리한 글입니다.
– https://ethereum.org/ko/developers/docs/standards/tokens/erc-1155/
소개
여러 토큰 유형을 관리하는 컨트랙트를 위한 표준 인터페이스입니다. 배포된 단일 컨트랙트에는 FT(대체 가능한 토큰), NFT(대체 불가능한 토큰) 또는 기타 구성(예: 반 대체 가능한 토큰)의 모든 조합이 포함될 수 있습니다.
Multi Token의 표준이란 무엇인가요?
이 아이디어는 간단하며, FT와 NFT 유형을 얼마든지 표현하고 제어할 수 있는 스마트 컨트랙트 인터페이스를 만들려는 것입니다. 이러한 방식으로 ERC-1155 토큰은 ERC-20 및 ERC-721 토큰과 동일한 기능을 수행할 수 있으며, 심지어 두 가지 기능을 동시에 수행할 수도 있습니다. 이는 ERC-20과 ERC-721 표준의 기능을 개선하여 더 효율적으로 만들고 명백한 구현 오류를 수정합니다.
ERC-1155 토큰에 대한 자세한 설명은 EIP-1155 에 나와 있습니다.
전제 조건
이 페이지를 더 잘 이해하려면 먼저 토큰 표준, ERC-20 및 ERC-721 에 대해 읽어보시기 바랍니다.
ERC-1155 기능과 특징
- 일괄 전송: 한 번의 호출로 여러 자산을 전송할 수 있습니다.
- 일괄 잔액: 한 번의 호출로 여러 자산의 잔액을 가져옵니다.
- 일괄 승인: 모든 토큰을 하나의 주소로 승인합니다.
- Hook: 토큰 Hook을 받습니다.
- NFT 지원: 공급량이 딱 하나인 경우 NFT로 처리합니다.
- 안전 전송 규칙: 보안 전송을 위한 규칙 집합입니다.
일괄 전송
일괄 전송은 일반 ERC-20 전송과 매우 유사하게 작동합니다. 일반 ERC-20 transferFrom
함수를 살펴보겠습니다:
// ERC-20
function transferFrom(address from, address to, uint256 value) external returns (bool);
// ERC-1155
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external;
SolidityERC-1155의 유일한 차이점은 값을 배열로 전달하고 아이디 배열도 전달한다는 점입니다. 예를 들어 ids=[3, 6, 13]
과 values=[100, 200, 5]
가 주어지면 결과 전송은 다음과 같습니다.
- id가 3인 토큰 100개를
_from
에서_to
로 전송합니다. - id가 6인 토큰 200개를
_from
에서_to
로 전송합니다. - id가 13인 토큰 5개를
_from
에서_to
로 전송합니다.
ERC-1155에는 transferFrom
만 있고 transfer
는 없습니다. 일반 transfer
처럼 사용하려면 발신 주소를 함수를 호출하는 주소로 설정하면 됩니다.
잔액 일괄 조회
각 ERC-20 balanceOf
콜에도 일괄 지원 기능이 있는 파트너 기능이 있습니다. 다시 한 번 말씀드리자면, 이것은 ERC-20 버전입니다:
// ERC-20
function balanceOf(address owner) external view returns (uint256);
// ERC-1155
function balanceOfBatch(
address[] calldata _owners,
uint256[] calldata _ids
) external view returns (uint256[] memory);
Solidity잔액 호출의 경우 더 간단하게 한 번의 호출로 여러 잔액을 검색할 수 있습니다. 소유자 배열을 전달한 다음 토큰 ID 배열을 전달하면 됩니다.
예를 들어 _ids=[3, 6, 13]
, _owners=[0xbeef..., 0x1337..., 0x1111...]
이 주어지면 반환값은 다음과 같습니다.
[
balanceOf(0xbeef...),
balanceOf(0x1337...),
balanceOf(0x1111...)
]
Solidity일괄 승인
// ERC-1155
function setApprovalForAll(
address _operator,
bool _approved
) external;
function isApprovedForAll(
address _owner,
address _operator
) external view returns (bool);
Solidity승인은 ERC-20과 약간 다릅니다. 특정 금액을 승인하는 대신 setApprovalForAll
을 통해 운영자(_operator
)를 승인하거나 승인하지 않도록 설정합니다.
현재 상태를 읽는 것은 isApprovedForAll
을 통해 할 수 있습니다. 보시다시피, 이는 all-or-nothing 작업입니다. 승인할 토큰의 수나 토큰 종류(class)를 정의할 수는 없습니다.
이는 의도적으로 단순성을 염두에 두고 설계되었습니다. 하나의 주소에 대해서만 모든 것을 승인할 수 있습니다.
수신 Hook
function onERC1155BatchReceived(
address _operator,
address _from,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external returns(bytes4);
SolidityEIP-165 지원으로 인해 ERC-1155는 스마트 컨트랙트에 대한 수신 Hook만 지원합니다. Hook 함수는 다음과 같이 미리 정의된 bytes4
값을 반환해야 합니다:
bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
Solidity수신 컨트랙트가 이 값을 반환하면, 컨트랙트가 전송을 수락하고 ERC-1155 토큰을 처리하는 방법을 알고 있는 것으로 간주합니다. 이제 더 이상 컨트랙트에 토큰이 갇혀 있지 않아도 됩니다!
NFT 지원
공급량이 하나뿐인 경우 토큰은 기본적으로 NFT입니다. 그리고 ERC-721의 표준과 마찬가지로 메타데이터 URL을 정의할 수 있습니다. 이 URL은 클라이언트가 읽고 수정할 수 있습니다(여기를 참조하세요).
안전 전송 규칙
이전 설명에서 몇 가지 안전한 전송 규칙에 대해 이미 언급했습니다. 하지만 가장 중요한 규칙을 살펴보겠습니다:
- 발신자가
_from
주소에 토큰을 사용하도록 승인받았거나 발신자가_from
와 같아야 합니다. - 다음과 같은 경우 전송 호출은 되돌려야 합니다.
_to
주소가 0인 경우_ids
의 길이가_values
의 길이와 같지 않은 경우._ids
의 토큰 보유자의 잔액이 수신자에게 전송된_values
의 금액보다 낮은 경우.- 기타 오류가 발생하는 경우.
Note: Hook을 포함한 모든 배치 함수는 배치가 없는 버전으로도 존재합니다. 이는 하나의 자산만 전송하는 것이 여전히 가장 일반적으로 사용되는 방법이라는 점을 고려한 가스 효율성을 위한 것입니다. 안전한 전송 규칙 등 설명의 단순화를 위해 제외했습니다. 이름은 동일하며 ‘Batch’만 제거하면 됩니다.