forked from CryptoGifts/cryptosanta
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBasicNFT.sol
More file actions
129 lines (96 loc) · 3.49 KB
/
BasicNFT.sol
File metadata and controls
129 lines (96 loc) · 3.49 KB
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
pragma solidity ^0.4.15;
import './NFT.sol';
contract BasicNFT is NFT, NFTEvents {
uint public totalTokens;
// Array of owned tokens for a user
mapping(address => uint[]) public ownedTokens;
mapping(address => uint) _virtualLength;
mapping(uint => uint) _tokenIndexInOwnerArray;
// Mapping from token ID to owner
mapping(uint => address) public tokenOwner;
// Allowed transfers for a token (only one at a time)
mapping(uint => address) public allowedTransfer;
// Metadata associated with each token
mapping(uint => string) public _tokenMetadata;
function totalSupply() public constant returns (uint) {
return totalTokens;
}
function balanceOf(address owner) public constant returns (uint) {
return _virtualLength[owner];
}
function tokenOfOwnerByIndex(address owner, uint index) public constant returns (uint) {
require(index >= 0 && index < balanceOf(owner));
return ownedTokens[owner][index];
}
function ownerOf(uint tokenId) public constant returns (address) {
return tokenOwner[tokenId];
}
function transfer(address to, uint tokenId) public {
require(tokenOwner[tokenId] == msg.sender || allowedTransfer[tokenId] == msg.sender);
return _transfer(tokenOwner[tokenId], to, tokenId);
}
function takeOwnership(uint tokenId) public {
require(allowedTransfer[tokenId] == msg.sender);
return _transfer(tokenOwner[tokenId], msg.sender, tokenId);
}
function transferFrom(address from, address to, uint tokenId) public {
require(allowedTransfer[tokenId] == msg.sender);
return _transfer(from, to, tokenId);
}
function approve(address beneficiary, uint tokenId) public {
require(msg.sender == tokenOwner[tokenId]);
if (allowedTransfer[tokenId] != 0) {
allowedTransfer[tokenId] = 0;
}
allowedTransfer[tokenId] = beneficiary;
Approval(tokenOwner[tokenId], beneficiary, tokenId);
}
function tokenMetadata(uint tokenId) constant public returns (string) {
return _tokenMetadata[tokenId];
}
function metadata(uint tokenId) constant public returns (string) {
return _tokenMetadata[tokenId];
}
function updateTokenMetadata(uint tokenId, string _metadata) public {
require(msg.sender == tokenOwner[tokenId]);
_tokenMetadata[tokenId] = _metadata;
MetadataUpdated(tokenId, msg.sender, _metadata);
}
function getAllTokens(address owner) public constant returns (uint[]) {
uint size = _virtualLength[owner];
uint[] memory result = new uint[](size);
for (uint i = 0; i < size; i++) {
result[i] = ownedTokens[owner][i];
}
return result;
}
function _transfer(address from, address to, uint tokenId) internal {
_clearApproval(tokenId);
_removeTokenFrom(from, tokenId);
_addTokenTo(to, tokenId);
Transferred(tokenId, from, to);
}
function _clearApproval(uint tokenId) internal {
allowedTransfer[tokenId] = 0;
Approval(tokenOwner[tokenId], 0, tokenId);
}
function _removeTokenFrom(address from, uint tokenId) internal {
require(_virtualLength[from] > 0);
uint length = _virtualLength[from];
uint index = _tokenIndexInOwnerArray[tokenId];
uint swapToken = ownedTokens[from][length - 1];
ownedTokens[from][index] = swapToken;
_tokenIndexInOwnerArray[swapToken] = index;
_virtualLength[from]--;
}
function _addTokenTo(address owner, uint tokenId) internal {
if (ownedTokens[owner].length == _virtualLength[owner]) {
ownedTokens[owner].push(tokenId);
} else {
ownedTokens[owner][_virtualLength[owner]] = tokenId;
}
tokenOwner[tokenId] = owner;
_tokenIndexInOwnerArray[tokenId] = _virtualLength[owner];
_virtualLength[owner]++;
}
}