SBT는 어떻게 만들까?

molly·2023년 1월 16일
1

스마트컨트랙트

목록 보기
3/4
post-thumbnail

본 글은 SBT가 무엇인지에 대한 설명은 제외하고 구현에 포커스를 맞췄다.

SBT는 2022년초를 보면 EIP1238을 중심으로 토큰을 특정 주소 혹은 ID에 묶기, 사고 팔 수 있도록 허가하되 다른 요소를 추가하기 등의 내용들을 이야기 하였지만 다양한 문제점과 한계가 지적되면서 표준이 되지 못하고 다양한 EIP들이 제안되어왔지만 표준으로 등록되지 못하다가 EIP 5192가 22년 8월? 쯤에SBT 관련 최초 표준(Final)으로 등록되었다.

EIP5192

EIP5192에서는 “토큰의 전송 가능 여부”를 체크할 수 있는 인터페이스를 제안하였다

Event: Locked 이벤트와 Unlocked 이벤트

Function: Locked함수, Locked 여부를 체크

loked가 true일 경우 전송 관련된 모든 기능은 무시해야 한다.

IERC5192 인터페이스

// SPDX-License-Identifier: CC0-1.0
pragma solidity^0.8.0;

interface IERC5192 {
/// @notice Emitted when the locking status is changed to locked.
/// @dev If a token is minted and the status is locked, this event should be emitted.
/// @param tokenId The identifier for a token.
event Locked(uint256 tokenId);

/// @notice Emitted when the locking status is changed to unlocked.
/// @dev If a token is minted and the status is unlocked, this event should be emitted.
/// @param tokenId The identifier for a token.
event Unlocked(uint256 tokenId);

/// @notice Returns the locking status of an Soulbound Token
/// @dev SBTs assigned to zero address are considered invalid, and queries
/// about them do throw.
/// @param tokenId The identifier for an SBT.
function locked(uint256 tokenId)external view returns (bool);
}

위의 표준을 바탕으로 크게 두 가지 부분을 ERC721을 기준으로 수정하였다.
위는 추상화된 인터페이스이기에 이걸 사용하는 개발자가 직접 기능을 추가해야 한다.

첫 번째는 mint 함수를 만들어 토큰이 민팅된 후에 토큰의 락을 true로 바꾸어 전송할 수 없는 상태로 만들었다.

 function mint(address _to) public onlyOwner returns (uint256){
        _safeMint(_to, newTokenId); // NFT 발행
        lockToken(newTokenId); //SBT
        emit Locked(newTokenId); //SBT
        return (newTokenId);
    }

두 번째는 _beforeTokenTransfer함수를 erc721에서 상속받아 오버라이딩하여 토큰의 락상태가 true라면 revert를 발생시켜 전송이 불가하게 하였다,

function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId, /* firstTokenId */ //SBT
        uint256 batchSize
    ) internal virtual {
        require(_islock[tokenId]==false,"token is lock"); //SBT
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

즉, 기존에 있던 NFT 컨트랙트에 5192표준을 잘 적용시켜서 SBT로 만들어 낼 수 가 있다.

이후 추가할 옵션으로는

동일 계정당 (동일 프로젝트) 한 개의 SBT만 소유 가능

SBT를 소각한 사용자는 7일 동안 다시 받을 수 없는 페널티

등을 생각해 볼 수 있을 것 같다.

물론 위와 같은 방법으로는 완벽한 SBT가 될 수는 없다. 프로젝트의 방향성에 맞게 필요한 살들을 더 입혀 목적에 맞는 SBT를 만드는 것이 중요하다.

profile
BlockChain R&D

0개의 댓글