-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathNFT-Brutus.sol
682 lines (508 loc) · 21.9 KB
/
NFT-Brutus.sol
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
pragma solidity ^0.5.15;
// SPDX-License-Identifier: Apache-2.0
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
contract Context {
constructor () internal { }
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
library Roles {
struct Role {
mapping (address => bool) bearer;
}
function add(Role storage role, address account) internal {
require(!has(role, account), "Roles: account already has role");
role.bearer[account] = true;
}
function remove(Role storage role, address account) internal {
require(has(role, account), "Roles: account does not have role");
role.bearer[account] = false;
}
function has(Role storage role, address account) internal view returns (bool) {
require(account != address(0), "Roles: account is the zero address");
return role.bearer[account];
}
}
library Address {
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-call-value
(bool success, ) = recipient.call.value(amount)("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
library Counters {
using SafeMath for uint256;
struct Counter {
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
counter._value += 1;
}
function decrement(Counter storage counter) internal {
counter._value = counter._value.sub(1);
}
}
contract MinterRole is Context {
using Roles for Roles.Role;
event MinterAdded(address indexed account);
event MinterRemoved(address indexed account);
Roles.Role private _minters;
constructor () internal {
_addMinter(_msgSender());
}
modifier onlyMinter() {
require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role");
_;
}
function isMinter(address account) public view returns (bool) {
return _minters.has(account);
}
function addMinter(address account) public onlyMinter {
_addMinter(account);
}
function renounceMinter() public {
_removeMinter(_msgSender());
}
function _addMinter(address account) internal {
_minters.add(account);
emit MinterAdded(account);
}
function _removeMinter(address account) internal {
_minters.remove(account);
emit MinterRemoved(account);
}
}
interface ITRC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
contract ITRC721 is ITRC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) public view returns (uint256 balance);
function ownerOf(uint256 tokenId) public view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) public;
function transferFrom(address from, address to, uint256 tokenId) public;
function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId) public view returns (address operator);
function setApprovalForAll(address operator, bool _approved) public;
function isApprovedForAll(address owner, address operator) public view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}
contract ITRC721Metadata is ITRC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
contract ITRC721Receiver {
function onTRC721Received(address operator, address from, uint256 tokenId, bytes memory data)
public returns (bytes4);
}
contract TRC165 is ITRC165 {
bytes4 private constant _INTERFACE_ID_TRC165 = 0x01ffc9a7;
mapping(bytes4 => bool) private _supportedInterfaces;
constructor () internal {
_registerInterface(_INTERFACE_ID_TRC165);
}
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
return _supportedInterfaces[interfaceId];
}
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "TRC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}
contract TRC721 is Context, TRC165, ITRC721 {
using SafeMath for uint256;
using Address for address;
using Counters for Counters.Counter;
// Equals to `bytes4(keccak256("onTRC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `ITRC721Receiver(0).onTRC721Received.selector`
//
// NOTE: TRC721 uses 0x150b7a02, TRC721 uses 0x5175f878.
bytes4 private constant _TRC721_RECEIVED = 0x5175f878;
// Mapping from token ID to owner
mapping (uint256 => address) private _tokenOwner;
// Mapping from token ID to approved address
mapping (uint256 => address) private _tokenApprovals;
// Mapping from owner to number of owned token
mapping (address => Counters.Counter) private _ownedTokensCount;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) private _operatorApprovals;
/*
* bytes4(keccak256('balanceOf(address)')) == 0x70a08231
* bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
* bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
* bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
*
* => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
* 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
*/
bytes4 private constant _INTERFACE_ID_TRC721 = 0x80ac58cd;
constructor () public {
// register the supported interfaces to conform to TRC721 via TRC165
_registerInterface(_INTERFACE_ID_TRC721);
}
function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0), "TRC721: balance query for the zero address");
return _ownedTokensCount[owner].current();
}
function ownerOf(uint256 tokenId) public view returns (address) {
address owner = _tokenOwner[tokenId];
require(owner != address(0), "TRC721: owner query for nonexistent token");
return owner;
}
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(to != owner, "TRC721: approval to current owner");
require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"TRC721: approve caller is not owner nor approved for all"
);
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
function getApproved(uint256 tokenId) public view returns (address) {
require(_exists(tokenId), "TRC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address to, bool approved) public {
require(to != _msgSender(), "TRC721: approve to caller");
_operatorApprovals[_msgSender()][to] = approved;
emit ApprovalForAll(_msgSender(), to, approved);
}
function isApprovedForAll(address owner, address operator) public view returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "TRC721: transfer caller is not owner nor approved");
_transferFrom(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
require(_isApprovedOrOwner(_msgSender(), tokenId), "TRC721: transfer caller is not owner nor approved");
_safeTransferFrom(from, to, tokenId, _data);
}
function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {
_transferFrom(from, to, tokenId);
require(_checkOnTRC721Received(from, to, tokenId, _data), "TRC721: transfer to non TRC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view returns (bool) {
address owner = _tokenOwner[tokenId];
return owner != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
require(_exists(tokenId), "TRC721: operator query for nonexistent token");
address owner = ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal {
_safeMint(to, tokenId, "");
}
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {
_mint(to, tokenId);
require(_checkOnTRC721Received(address(0), to, tokenId, _data), "TRC721: transfer to non TRC721Receiver implementer");
}
function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "TRC721: mint to the zero address");
require(!_exists(tokenId), "TRC721: token already minted");
_tokenOwner[tokenId] = to;
_ownedTokensCount[to].increment();
emit Transfer(address(0), to, tokenId);
}
function _burn(address owner, uint256 tokenId) internal {
require(ownerOf(tokenId) == owner, "TRC721: burn of token that is not own");
_clearApproval(tokenId);
_ownedTokensCount[owner].decrement();
_tokenOwner[tokenId] = address(0);
emit Transfer(owner, address(0), tokenId);
}
function _burn(uint256 tokenId) internal {
_burn(ownerOf(tokenId), tokenId);
}
function _transferFrom(address from, address to, uint256 tokenId) internal {
require(ownerOf(tokenId) == from, "TRC721: transfer of token that is not own");
require(to != address(0), "TRC721: transfer to the zero address");
_clearApproval(tokenId);
_ownedTokensCount[from].decrement();
_ownedTokensCount[to].increment();
_tokenOwner[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function isContract(address _addr) private view returns (bool){
uint32 size;
assembly {
size := extcodesize(_addr)
}
return (size > 0);
}
function _checkOnTRC721Received(address from, address to, uint256 tokenId, bytes memory _data)
internal returns (bool)
{
if (!isContract(to)) {
return true;
}
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = to.call(abi.encodeWithSelector(
ITRC721Receiver(to).onTRC721Received.selector,
_msgSender(),
from,
tokenId,
_data
));
if (!success) {
if (returndata.length > 0) {
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert("TRC721: transfer to non TRC721Receiver implementer");
}
} else {
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _TRC721_RECEIVED);
}
}
function _clearApproval(uint256 tokenId) private {
if (_tokenApprovals[tokenId] != address(0)) {
_tokenApprovals[tokenId] = address(0);
}
}
}
contract TRC721Metadata is Context, TRC165, TRC721, ITRC721Metadata {
// Token name
string private _name;
// Token symbol
string private _symbol;
// Base URI
string private _baseURI;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/*
* bytes4(keccak256('name()')) == 0x06fdde03
* bytes4(keccak256('symbol()')) == 0x95d89b41
* bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
*
* => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
*/
bytes4 private constant _INTERFACE_ID_TRC721_METADATA = 0x5b5e139f;
constructor (string memory name, string memory symbol, string memory baseURI) public {
_name = name;
_symbol = symbol;
_baseURI = baseURI;
_registerInterface(_INTERFACE_ID_TRC721_METADATA);
}
function name() external view returns (string memory) {
return _name;
}
function symbol() external view returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) external view returns (string memory) {
require(_exists(tokenId), "TRC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
// Even if there is a base URI, it is only appended to non-empty token-specific URIs
if (bytes(_tokenURI).length == 0) {
return "";
} else {
// abi.encodePacked is being used to concatenate strings
return string(abi.encodePacked(_baseURI, _tokenURI));
}
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
require(_exists(tokenId), "TRC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
function _setBaseURI(string memory baseURI) internal {
_baseURI = baseURI;
}
function baseURI() external view returns (string memory) {
return _baseURI;
}
function _burn(address owner, uint256 tokenId) internal {
super._burn(owner, tokenId);
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}
contract TRC721MetadataMintable is TRC721, TRC721Metadata, MinterRole {
function updateBaseURI(string memory baseURI) public onlyMinter returns(bool){
_setBaseURI(baseURI);
return true;
}
function mintWithTokenURI(address to, uint256 tokenId, string memory tokenURI) public onlyMinter returns (bool) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenURI);
return true;
}
function updateTokenURI(uint256 tokenId, string memory tokenURI) public onlyMinter returns (bool) {
_setTokenURI(tokenId, tokenURI);
return true;
}
}
contract TRC721Mintable is TRC721, MinterRole {
function mint(address to, uint256 tokenId) public onlyMinter returns (bool) {
_mint(to, tokenId);
return true;
}
function safeMint(address to, uint256 tokenId) public onlyMinter returns (bool) {
_safeMint(to, tokenId);
return true;
}
function safeMint(address to, uint256 tokenId, bytes memory _data) public onlyMinter returns (bool) {
_safeMint(to, tokenId, _data);
return true;
}
}
contract ITRC721Enumerable is ITRC721 {
function totalSupply() public view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);
function tokenByIndex(uint256 index) public view returns (uint256);
}
contract TRC721Enumerable is Context, TRC165, TRC721, ITRC721Enumerable {
// Mapping from owner to list of owned token IDs
mapping(address => uint256[]) private _ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] private _allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
/*
* bytes4(keccak256('totalSupply()')) == 0x18160ddd
* bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
* bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
*
* => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
*/
bytes4 private constant _INTERFACE_ID_TRC721_ENUMERABLE = 0x780e9d63;
/**
* @dev Constructor function.
*/
constructor () public {
// register the supported interface to conform to TRC721Enumerable via TRC165
_registerInterface(_INTERFACE_ID_TRC721_ENUMERABLE);
}
function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
require(index < balanceOf(owner), "TRC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
function totalSupply() public view returns (uint256) {
return _allTokens.length;
}
function tokenByIndex(uint256 index) public view returns (uint256) {
require(index < totalSupply(), "TRC721Enumerable: global index out of bounds");
return _allTokens[index];
}
function _transferFrom(address from, address to, uint256 tokenId) internal {
super._transferFrom(from, to, tokenId);
_removeTokenFromOwnerEnumeration(from, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
}
function _mint(address to, uint256 tokenId) internal {
super._mint(to, tokenId);
_addTokenToOwnerEnumeration(to, tokenId);
_addTokenToAllTokensEnumeration(tokenId);
}
function _burn(address owner, uint256 tokenId) internal {
super._burn(owner, tokenId);
_removeTokenFromOwnerEnumeration(owner, tokenId);
// Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
_ownedTokensIndex[tokenId] = 0;
_removeTokenFromAllTokensEnumeration(tokenId);
}
function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
return _ownedTokens[owner];
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
_ownedTokensIndex[tokenId] = _ownedTokens[to].length;
_ownedTokens[to].push(tokenId);
}
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
uint256 tokenIndex = _ownedTokensIndex[tokenId];
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
}
_ownedTokens[from].length--;
}
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
uint256 lastTokenIndex = _allTokens.length.sub(1);
uint256 tokenIndex = _allTokensIndex[tokenId];
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
_allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
_allTokens.length--;
_allTokensIndex[tokenId] = 0;
}
}
contract TRC721Token is TRC721, TRC721Enumerable, TRC721MetadataMintable {
constructor() public TRC721Metadata("Brutus Gallery", "BRGY", "https://mintearte.tk/") {
}
}