티스토리 뷰

반응형

오픈씨의 수수료 분배 코드를 참고해서 코드를 작성해보았다.

ERC-1155 기반의 수수료를 관리자에게 떼어주고, 수수료를 제외한 나머지 금액과 NFT를 구매자에게 transfer하는 contract를 만들어보자.

예외처리 부분을 모두 제외한 오직 수수료 분배 부분만 작성되어 있으니, 예외처리 로직은 입맛에 맞게 추가하길 바란다.


 

  • 사용 IDE : Remix IDE 0.24.0 ver
  • Compile version : 0.8.6+commit.11564f7e
  • Solidity version : 0.8.0 이상

코드설명

//수수료율
uint private _feePercent = 25;// 수수료 : 2.5 %

솔리디티에서 소수점을 나타낼 수 있는 타입은 없기에 수수료를 uint 타입으로 설정
오픈씨와 같은 2.5 퍼센트로 수수료율을 고정하였다.

 

//상하 반전 기본 숫자(소수점 표현이 안 되는 uint 타입을 나눠서 소수점 표현할때 필요)
uint private constant INVERSE_BASIS_POINT = 1000;

수수료율 소수점을 나타낼 변수
수수료율 소수점 자리를 늘리고 싶으면 위 변수에 0을 하나씩 추가하면 된다.

 

 

address payable admin = payable(_administrator);

//구매자가 보내야하는 금액
//관리자에게 수수료 전송
uint requiredAmount = SafeMath.div(SafeMath.mul(_feePercent, msg.value),INVERSE_BASIS_POINT);

//보내야하는 금액(수수료)보다 주문금액이 더 커야함
require(msg.value >= requiredAmount, "The fee amount is different.");

admin.transfer(requiredAmount);

수수료는 거래소 관리자에게 자동으로 입금되도록 작성하였다.
(사용자가 보내는 이더 수량 * 작성한 수수료 율) / 1000
공식으로 관리자에게 입금할 금액을 계산한다.

 


그 이후는 쉽다. 수수료 금액을 계산 했으면
원래 보내는 금액에서 계산된 수수료 금액을 차감한 액수를 판매자에게 입금하고
이후 NFT를 transfer하는 코드를 추가하면 된다.

 


전체코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
 
import "@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
 
 
contract GameItems is ERC1155PresetMinterPauser {
 
    //수수료율
    uint private _feePercent = 25;// 수수료 : 2.5 %
 
    //상하 반전 기본 숫자(소수점 표현이 안 되는 uint 타입을 나눠서 소수점 표현할때 필요)
    uint private constant INVERSE_BASIS_POINT = 1000;
 
    // Token name
    string private _name;
 
    // Token symbol
    string private _symbol;
 
    //관리자 주소
    address private _administrator;
 
 
    constructor(string memory name_, string memory symbol_, address administrator_) ERC1155PresetMinterPauser(
        "https://image-repositories.test/metadata/{id}.json") {
         _name = name_;
        _symbol = symbol_;
        _administrator = administrator_;
    }
 
 
    function name() public view virtual  returns (string memory) {
        return _name;
    }
 
    function symbol() public view virtual  returns (string memory) {
        return _symbol;
    }
 
    function administrator() public view virtual  returns (address) {
        return _administrator;
    }
 
 
 
    // 이벤트 정의
    event TransferEvent(address sender, uint value, uint256 itemId);
 
 
    /*
    @param owner : nft 소유자
    @param tokenId : nft 토큰 ID
    */
    function testTransfer(
        address owner,  
        uint tokenId
        ) public payable {
 
        require(msg.value > 0 && balanceOf(owner, tokenId) > 0"The price must be greater than 0 ETH");
        require(_administrator != address(0), "There are no administrators !");
 
        
 
        address payable admin = payable(_administrator);
        //구매자가 보내야하는 금액
        //관리자에게 수수료 전송
        uint requiredAmount = SafeMath.div(SafeMath.mul(_feePercent, msg.value),INVERSE_BASIS_POINT);
        //보내야하는 금액(수수료)보다 주문금액이 더 커야함
        require(msg.value >= requiredAmount, "The fee amount is different.");
        admin.transfer(requiredAmount);
 
 
 
        //address seller = ownerOf(tokenId);
        address payable sellerwallet = payable(owner);
        //판매자가 받을 금액
        uint receiveAmount = SafeMath.sub(msg.value,requiredAmount);
        require(msg.value >= receiveAmount, "The purchase price is different.");
        //판매자에게 수수료 뗀 금액 전송
        sellerwallet.transfer(receiveAmount);
 
 
 
        // 구매자에게 NFT 옮기기
        _safeTransferFrom(owner, msg.sender, tokenId, 1 , "");
 
        emit TransferEvent(msg.sender, msg.value, tokenId);
 
    } 
 
}
cs

 


전체 코드는 Remix에서 컴파일 및 배포 테스트 가능하다.
testTransfer를 테스트할때는 value에 nft 가격을 입력한 후 테스트 하길 바란다.

 


아래는 의도대로 잘 전송된 모습

반응형
댓글
공지사항