티스토리 뷰
반응형
오픈씨의 수수료 분배 코드를 참고해서 코드를 작성해보았다.
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 가격을 입력한 후 테스트 하길 바란다.
아래는 의도대로 잘 전송된 모습
반응형
'BlockChain > Solidity' 카테고리의 다른 글
[Solidity] 솔리디티 기본문법 Storage, Memory, Calldata (1) | 2023.05.04 |
---|---|
[Solidity] 솔리디티 기본문법 view와 pure (0) | 2023.05.02 |
[Solidity] 솔리디티 기본문법 override(오버라이드, 재정의)와 virtual (0) | 2023.04.28 |
[Solidity] 솔리디티 기본문법 msg.sender (0) | 2023.04.25 |
[Solidity] OpenZeppelin의 Ownable 컨트랙트(소유 가능한 컨트랙트) (0) | 2023.04.14 |
댓글
공지사항