Skip to content

Commit f88418d

Browse files
huanghaoxdalaocu
authored andcommitted
#TASK48: SFT模版注释
1 parent 81e66a4 commit f88418d

File tree

10 files changed

+1137
-0
lines changed

10 files changed

+1137
-0
lines changed

contracts/business_template/SFT/ERC3525.sol

Lines changed: 656 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.0;
4+
5+
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
6+
import "./IERC721.sol";
7+
8+
/**
9+
* @title ERC-3525 Semi-Fungible Token Standard
10+
* @dev See https://eips.ethereum.org/EIPS/eip-3525
11+
* Note: the ERC-165 identifier for this interface is 0xd5358140.
12+
*/
13+
interface IERC3525 is IERC165, IERC721 {
14+
/**
15+
* @dev MUST emit when value of a token is transferred to another token with the same slot,
16+
* including zero value transfers (_value == 0) as well as transfers when tokens are created
17+
* (`_fromTokenId` == 0) or destroyed (`_toTokenId` == 0).
18+
* @param _fromTokenId The token id to transfer value from
19+
* @param _toTokenId The token id to transfer value to
20+
* @param _value The transferred value
21+
*/
22+
event TransferValue(uint256 indexed _fromTokenId, uint256 indexed _toTokenId, uint256 _value);
23+
24+
/**
25+
* @dev MUST emits when the approval value of a token is set or changed.
26+
* @param _tokenId The token to approve
27+
* @param _operator The operator to approve for
28+
* @param _value The maximum value that `_operator` is allowed to manage
29+
*/
30+
event ApprovalValue(uint256 indexed _tokenId, address indexed _operator, uint256 _value);
31+
32+
/**
33+
* @dev MUST emit when the slot of a token is set or changed.
34+
* @param _tokenId The token of which slot is set or changed
35+
* @param _oldSlot The previous slot of the token
36+
* @param _newSlot The updated slot of the token
37+
*/
38+
event SlotChanged(uint256 indexed _tokenId, uint256 indexed _oldSlot, uint256 indexed _newSlot);
39+
40+
/**
41+
* @notice 获取令牌用于值的小数位数 - 例如 6、指用户
42+
* 代币价值的表示可以通过将其除以 1,000,000 来计算。
43+
* 考虑到与第三方钱包的兼容性,该功能定义为
44+
* `valueDecimals()` 而不是 `decimals()` 以避免与 ERC20 代币发生冲突。
45+
* @return 值的小数位数
46+
*/
47+
function valueDecimals() external view returns (uint8);
48+
49+
/**
50+
* @notice Get the value of a token.
51+
* @param _tokenId The token for which to query the balance
52+
* @return The value of `_tokenId`
53+
*/
54+
function balanceOf(uint256 _tokenId) external view returns (uint256);
55+
56+
/**
57+
* @notice 获取令牌的插槽。
58+
* @param _tokenId 令牌的标识符
59+
* @return 令牌的插槽
60+
*/
61+
function slotOf(uint256 _tokenId) external view returns (uint256);
62+
63+
64+
/**
65+
* @notice 允许操作员管理代币的价值,最高可达“_value”数量。
66+
* @dev 必须恢复,除非调用者是当前所有者、授权操作员或批准的
67+
* `_tokenId` 的地址。
68+
* 必须发出 ApprovalValue 事件。
69+
* @param _tokenId 要批准的令牌
70+
* @param _operator 待审核的运营商
71+
* @param _value 允许`_operator`管理的`_toTokenId`的最大值
72+
*/
73+
function approve(
74+
uint256 _tokenId,
75+
address _operator,
76+
uint256 _value
77+
) external payable;
78+
79+
/**
80+
* @notice Get the maximum value of a token that an operator is allowed to manage.
81+
* @param _tokenId The token for which to query the allowance
82+
* @param _operator The address of an operator
83+
* @return The current approval value of `_tokenId` that `_operator` is allowed to manage
84+
*/
85+
function allowance(uint256 _tokenId, address _operator) external view returns (uint256);
86+
87+
/**
88+
* @notice 将值从指定令牌转移到具有相同插槽的另一个指定令牌。
89+
* @dev Caller 必须是当前所有者、授权操作员或已被授权的操作员
90+
* 批准了整个 `_fromTokenId` 或其中的一部分。
91+
* 如果 _fromTokenId 或 _toTokenId 为零令牌 ID 或不存在,则必须还原。
92+
* 如果 `_fromTokenId` 和 `_toTokenId` 的插槽不匹配,则必须恢复。
93+
* 如果 _value 超过 _fromTokenId 的余额或其对
94+
* 操作员。
95+
* 必须发出 `TransferValue` 事件。
96+
* @param _fromTokenId 从中转移价值的代币
97+
* @param _toTokenId 将价值转移到的代币
98+
* @param _value 传递的值
99+
*/
100+
function transferFrom(
101+
uint256 _fromTokenId,
102+
uint256 _toTokenId,
103+
uint256 _value
104+
) external payable;
105+
106+
/**
107+
* @notice 将值从指定令牌转移到地址。 调用者应确认
108+
* `_to` 能够接收 ERC3525 代币。
109+
* @dev 此函数必须创建一个新的 ERC3525 令牌,该令牌具有相同的槽以供 _to 接收
110+
* 转移的价值。
111+
* 如果 _fromTokenId 为零令牌 ID 或不存在,则必须还原。
112+
* 如果 _to 是零地址,则必须恢复。
113+
* 如果 _value 超过 _fromTokenId 的余额或其对
114+
* 操作员。
115+
* 必须发出 `Transfer` 和 `TransferValue` 事件。
116+
* @param _fromTokenId 从中转移价值的代币
117+
* @param _to 将值传送到的地址
118+
* @param _value 传递的值
119+
* @return 为接收转移值的 _to 创建的新令牌的 ID
120+
*/
121+
function transferFrom(
122+
uint256 _fromTokenId,
123+
address _to,
124+
uint256 _value
125+
) external payable returns (uint256);
126+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.1;
4+
5+
/**
6+
* @title EIP-3525 token receiver interface
7+
* @dev Interface for a smart contract that wants to be informed by EIP-3525 contracts when
8+
* receiving values from ANY addresses or EIP-3525 tokens.
9+
* Note: the EIP-165 identifier for this interface is 0x009ce20b.
10+
*/
11+
interface IERC3525Receiver {
12+
/**
13+
* @notice Handle the receipt of an EIP-3525 token value.
14+
* @dev An EIP-3525 smart contract MUST check whether this function is implemented by the
15+
* recipient contract, if the recipient contract implements this function, the EIP-3525
16+
* contract MUST call this function after a value transfer (i.e. `transferFrom(uint256,
17+
* uint256,uint256,bytes)`).
18+
* MUST return 0x009ce20b (i.e. `bytes4(keccak256('onERC3525Received(address,uint256,uint256,
19+
* uint256,bytes)'))`) if the transfer is accepted.
20+
* MUST revert or return any value other than 0x009ce20b if the transfer is rejected.
21+
* @param _operator The address which triggered the transfer
22+
* @param _fromTokenId The token id to transfer value from
23+
* @param _toTokenId The token id to transfer value to
24+
* @param _value The transferred value
25+
* @param _data Additional data with no specified format
26+
* @return `bytes4(keccak256('onERC3525Received(address,uint256,uint256,uint256,bytes)'))`
27+
* unless the transfer is rejected.
28+
*/
29+
function onERC3525Received(address _operator, uint256 _fromTokenId, uint256 _toTokenId, uint256 _value, bytes calldata _data) external returns (bytes4);
30+
31+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.1;
4+
5+
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
6+
7+
/**
8+
* @title ERC-721 Non-Fungible Token Standard
9+
* @dev See https://eips.ethereum.org/EIPS/eip-721
10+
* Note: the ERC-165 identifier for this interface is 0x80ac58cd.
11+
*/
12+
interface IERC721 is IERC165 {
13+
/**
14+
* @dev This emits when ownership of any NFT changes by any mechanism.
15+
* This event emits when NFTs are created (`from` == 0) and destroyed
16+
* (`to` == 0). Exception: during contract creation, any number of NFTs
17+
* may be created and assigned without emitting Transfer. At the time of
18+
* any transfer, the approved address for that NFT (if any) is reset to none.
19+
*/
20+
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
21+
22+
/**
23+
* @dev This emits when the approved address for an NFT is changed or
24+
* reaffirmed. The zero address indicates there is no approved address.
25+
* When a Transfer event emits, this also indicates that the approved
26+
* address for that NFT (if any) is reset to none.
27+
*/
28+
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
29+
30+
/**
31+
* @dev This emits when an operator is enabled or disabled for an owner.
32+
* The operator can manage all NFTs of the owner.
33+
*/
34+
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
35+
36+
/**
37+
* @notice Count all NFTs assigned to an owner
38+
* @dev NFTs assigned to the zero address are considered invalid, and this
39+
* function throws for queries about the zero address.
40+
* @param _owner An address for whom to query the balance
41+
* @return The number of NFTs owned by `_owner`, possibly zero
42+
*/
43+
function balanceOf(address _owner) external view returns (uint256);
44+
45+
/**
46+
* @notice Find the owner of an NFT
47+
* @dev NFTs assigned to zero address are considered invalid, and queries
48+
* about them do throw.
49+
* @param _tokenId The identifier for an NFT
50+
* @return The address of the owner of the NFT
51+
*/
52+
function ownerOf(uint256 _tokenId) external view returns (address);
53+
54+
/**
55+
* @notice Transfers the ownership of an NFT from one address to another address
56+
* @dev Throws unless `msg.sender` is the current owner, an authorized
57+
* operator, or the approved address for this NFT. Throws if `_from` is
58+
* not the current owner. Throws if `_to` is the zero address. Throws if
59+
* `_tokenId` is not a valid NFT. When transfer is complete, this function
60+
* checks if `_to` is a smart contract (code size > 0). If so, it calls
61+
* `onERC721Received` on `_to` and throws if the return value is not
62+
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
63+
* @param _from The current owner of the NFT
64+
* @param _to The new owner
65+
* @param _tokenId The NFT to transfer
66+
* @param data Additional data with no specified format, sent in call to `_to`
67+
*/
68+
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable;
69+
70+
/**
71+
* @notice Transfers the ownership of an NFT from one address to another address
72+
* @dev This works identically to the other function with an extra data parameter,
73+
* except this function just sets data to "".
74+
* @param _from The current owner of the NFT
75+
* @param _to The new owner
76+
* @param _tokenId The NFT to transfer
77+
*/
78+
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
79+
80+
/**
81+
* @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
82+
* TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
83+
* THEY MAY BE PERMANENTLY LOST
84+
* @dev Throws unless `msg.sender` is the current owner, an authorized
85+
* operator, or the approved address for this NFT. Throws if `_from` is
86+
* not the current owner. Throws if `_to` is the zero address. Throws if
87+
* `_tokenId` is not a valid NFT.
88+
* @param _from The current owner of the NFT
89+
* @param _to The new owner
90+
* @param _tokenId The NFT to transfer
91+
*/
92+
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
93+
94+
/**
95+
* @notice Change or reaffirm the approved address for an NFT
96+
* @dev The zero address indicates there is no approved address.
97+
* Throws unless `msg.sender` is the current NFT owner, or an authorized
98+
* operator of the current owner.
99+
* @param _approved The new approved NFT controller
100+
* @param _tokenId The NFT to approve
101+
*/
102+
function approve(address _approved, uint256 _tokenId) external payable;
103+
104+
/**
105+
* @notice Enable or disable approval for a third party ("operator") to manage
106+
* all of `msg.sender`'s assets
107+
* @dev Emits the ApprovalForAll event. The contract MUST allow
108+
* multiple operators per owner.
109+
* @param _operator Address to add to the set of authorized operators
110+
* @param _approved True if the operator is approved, false to revoke approval
111+
*/
112+
function setApprovalForAll(address _operator, bool _approved) external;
113+
114+
/**
115+
* @notice Get the approved address for a single NFT
116+
* @dev Throws if `_tokenId` is not a valid NFT.
117+
* @param _tokenId The NFT to find the approved address for
118+
* @return The approved address for this NFT, or the zero address if there is none
119+
*/
120+
function getApproved(uint256 _tokenId) external view returns (address);
121+
122+
/**
123+
* @notice Query if an address is an authorized operator for another address
124+
* @param _owner The address that owns the NFTs
125+
* @param _operator The address that acts on behalf of the owner
126+
* @return True if `_operator` is an approved operator for `_owner`, false otherwise
127+
*/
128+
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
129+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.1;
4+
5+
/**
6+
* @title ERC721 token receiver interface
7+
* @dev Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.
8+
* Note: the ERC-165 identifier for this interface is 0x150b7a02.
9+
*/
10+
interface IERC721Receiver {
11+
/**
12+
* @notice Handle the receipt of an NFT
13+
* @dev The ERC721 smart contract calls this function on the recipient
14+
* after a `transfer`. This function MAY throw to revert and reject the
15+
* transfer. Return of other than the magic value MUST result in the
16+
* transaction being reverted.
17+
* Note: the contract address is always the message sender.
18+
* @param _operator The address which called `safeTransferFrom` function
19+
* @param _from The address which previously owned the token
20+
* @param _tokenId The NFT identifier which is being transferred
21+
* @param _data Additional data with no specified format
22+
* @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
23+
* unless throwing
24+
*/
25+
function onERC721Received(
26+
address _operator,
27+
address _from,
28+
uint256 _tokenId,
29+
bytes calldata _data
30+
) external returns(bytes4);
31+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.9;
3+
4+
import "@openzeppelin/contracts/utils/Strings.sol";
5+
import "../ERC3525.sol";
6+
7+
contract ERC3525GettingStarted is ERC3525 {
8+
using Strings for uint256;
9+
address public owner;
10+
11+
constructor(
12+
address owner_
13+
) ERC3525("ERC3525GettingStarted", "ERC3525GS", 18) {
14+
owner = owner_;
15+
}
16+
17+
function mint(address to_, uint256 slot_, uint256 amount_) external {
18+
require(
19+
msg.sender == owner,
20+
"ERC3525GettingStarted: only owner can mint"
21+
);
22+
_mint(to_, slot_, amount_);
23+
}
24+
function tokenURI(uint256 tokenId_) public view virtual override returns (string memory) {
25+
return string(
26+
abi.encodePacked(
27+
'<svg width="600" height="600" xmlns="http://www.w3.org/2000/svg">',
28+
' <g> <title>Layer 1</title>',
29+
' <rect id="svg_1" height="600" width="600" y="0" x="0" stroke="#000" fill="#000000"/>',
30+
' <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_2" y="340" x="200" stroke-width="0" stroke="#000" fill="#ffffff">TokenId: ',
31+
tokenId_.toString(),
32+
'</text>',
33+
' <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_3" y="410" x="200" stroke-width="0" stroke="#000" fill="#ffffff">Balance: ',
34+
balanceOf(tokenId_).toString(),
35+
'</text>',
36+
' <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_3" y="270" x="200" stroke-width="0" stroke="#000" fill="#ffffff">Slot: ',
37+
slotOf(tokenId_).toString(),
38+
'</text>',
39+
' <text xml:space="preserve" text-anchor="start" font-family="Noto Sans JP" font-size="24" id="svg_4" y="160" x="150" stroke-width="0" stroke="#000" fill="#ffffff">ERC3525 GETTING STARTED</text>',
40+
' </g> </svg>'
41+
)
42+
);
43+
}
44+
}

0 commit comments

Comments
 (0)