Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
openzeppelin-contracts-upgradeable
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
俞永鹏
openzeppelin-contracts-upgradeable
Commits
23afc74b
Commit
23afc74b
authored
Jan 17, 2018
by
Facundo Spagnuolo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Address feedback comments for ERC721
parent
af337047
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
39 additions
and
34 deletions
+39
-34
ERC721TokenMock.sol
contracts/mocks/ERC721TokenMock.sol
+4
-4
ERC721Token.sol
contracts/token/ERC721Token.sol
+21
-16
ERC721Token.test.js
test/token/ERC721Token.test.js
+14
-14
No files found.
contracts/mocks/ERC721TokenMock.sol
View file @
23afc74b
...
@@ -9,11 +9,11 @@ import "../token/ERC721Token.sol";
...
@@ -9,11 +9,11 @@ import "../token/ERC721Token.sol";
contract ERC721TokenMock is ERC721Token {
contract ERC721TokenMock is ERC721Token {
function ERC721TokenMock() ERC721Token() public { }
function ERC721TokenMock() ERC721Token() public { }
function
publicM
int(address _to, uint256 _tokenId) public {
function
m
int(address _to, uint256 _tokenId) public {
super.mint(_to, _tokenId);
super.
_
mint(_to, _tokenId);
}
}
function
publicB
urn(uint256 _tokenId) public {
function
b
urn(uint256 _tokenId) public {
super.burn(_tokenId);
super.
_
burn(_tokenId);
}
}
}
}
contracts/token/ERC721Token.sol
View file @
23afc74b
...
@@ -108,7 +108,7 @@ contract ERC721Token is ERC721 {
...
@@ -108,7 +108,7 @@ contract ERC721Token is ERC721 {
* @param _tokenId uint256 ID of the token being claimed by the msg.sender
* @param _tokenId uint256 ID of the token being claimed by the msg.sender
*/
*/
function takeOwnership(uint256 _tokenId) public {
function takeOwnership(uint256 _tokenId) public {
require(isApprovedFor(_tokenId));
require(isApprovedFor(
msg.sender,
_tokenId));
clearApprovalAndTransfer(ownerOf(_tokenId), msg.sender, _tokenId);
clearApprovalAndTransfer(ownerOf(_tokenId), msg.sender, _tokenId);
}
}
...
@@ -117,7 +117,7 @@ contract ERC721Token is ERC721 {
...
@@ -117,7 +117,7 @@ contract ERC721Token is ERC721 {
* @param _to The address that will own the minted token
* @param _to The address that will own the minted token
* @param _tokenId uint256 ID of the token to be minted by the msg.sender
* @param _tokenId uint256 ID of the token to be minted by the msg.sender
*/
*/
function mint(address _to, uint256 _tokenId) internal {
function
_
mint(address _to, uint256 _tokenId) internal {
require(_to != address(0));
require(_to != address(0));
addToken(_to, _tokenId);
addToken(_to, _tokenId);
Transfer(0x0, _to, _tokenId);
Transfer(0x0, _to, _tokenId);
...
@@ -127,7 +127,7 @@ contract ERC721Token is ERC721 {
...
@@ -127,7 +127,7 @@ contract ERC721Token is ERC721 {
* @dev Burns a specific token
* @dev Burns a specific token
* @param _tokenId uint256 ID of the token being burned by the msg.sender
* @param _tokenId uint256 ID of the token being burned by the msg.sender
*/
*/
function burn(uint256 _tokenId) onlyOwnerOf(_tokenId) internal {
function
_
burn(uint256 _tokenId) onlyOwnerOf(_tokenId) internal {
if (approvedFor(_tokenId) != 0) {
if (approvedFor(_tokenId) != 0) {
clearApproval(msg.sender, _tokenId);
clearApproval(msg.sender, _tokenId);
}
}
...
@@ -136,6 +136,17 @@ contract ERC721Token is ERC721 {
...
@@ -136,6 +136,17 @@ contract ERC721Token is ERC721 {
}
}
/**
/**
* @dev Tells whether the msg.sender is approved for the given token ID or not
* This function is not private so it can be extended in further implementations like the operatable ERC721
* @param _owner address of the owner to query the approval of
* @param _tokenId uint256 ID of the token to query the approval of
* @return bool whether the msg.sender is approved for the given token ID or not
*/
function isApprovedFor(address _owner, uint256 _tokenId) internal view returns (bool) {
return approvedFor(_tokenId) == _owner;
}
/**
* @dev Internal function to clear current approval and transfer the ownership of a given token ID
* @dev Internal function to clear current approval and transfer the ownership of a given token ID
* @param _from address which you want to send tokens from
* @param _from address which you want to send tokens from
* @param _to address which you want to transfer the token to
* @param _to address which you want to transfer the token to
...
@@ -156,7 +167,7 @@ contract ERC721Token is ERC721 {
...
@@ -156,7 +167,7 @@ contract ERC721Token is ERC721 {
* @dev Internal function to clear current approval of a given token ID
* @dev Internal function to clear current approval of a given token ID
* @param _tokenId uint256 ID of the token to be transferred
* @param _tokenId uint256 ID of the token to be transferred
*/
*/
function clearApproval(address _owner, uint256 _tokenId)
internal
{
function clearApproval(address _owner, uint256 _tokenId)
private
{
require(ownerOf(_tokenId) == _owner);
require(ownerOf(_tokenId) == _owner);
tokenApprovals[_tokenId] = 0;
tokenApprovals[_tokenId] = 0;
Approval(_owner, 0, _tokenId);
Approval(_owner, 0, _tokenId);
...
@@ -167,7 +178,7 @@ contract ERC721Token is ERC721 {
...
@@ -167,7 +178,7 @@ contract ERC721Token is ERC721 {
* @param _to address representing the new owner of the given token ID
* @param _to address representing the new owner of the given token ID
* @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
* @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
*/
*/
function addToken(address _to, uint256 _tokenId)
internal
{
function addToken(address _to, uint256 _tokenId)
private
{
require(tokenOwner[_tokenId] == address(0));
require(tokenOwner[_tokenId] == address(0));
tokenOwner[_tokenId] = _to;
tokenOwner[_tokenId] = _to;
uint256 length = balanceOf(_to);
uint256 length = balanceOf(_to);
...
@@ -181,8 +192,7 @@ contract ERC721Token is ERC721 {
...
@@ -181,8 +192,7 @@ contract ERC721Token is ERC721 {
* @param _from address representing the previous owner of the given token ID
* @param _from address representing the previous owner of the given token ID
* @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
* @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
*/
*/
function removeToken(address _from, uint256 _tokenId) internal {
function removeToken(address _from, uint256 _tokenId) private {
require(balanceOf(_from) > 0);
require(ownerOf(_tokenId) == _from);
require(ownerOf(_tokenId) == _from);
uint256 tokenIndex = ownedTokensIndex[_tokenId];
uint256 tokenIndex = ownedTokensIndex[_tokenId];
...
@@ -192,18 +202,13 @@ contract ERC721Token is ERC721 {
...
@@ -192,18 +202,13 @@ contract ERC721Token is ERC721 {
tokenOwner[_tokenId] = 0;
tokenOwner[_tokenId] = 0;
ownedTokens[_from][tokenIndex] = lastToken;
ownedTokens[_from][tokenIndex] = lastToken;
ownedTokens[_from][lastTokenIndex] = 0;
ownedTokens[_from][lastTokenIndex] = 0;
// Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
// be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
// the lastToken to the first position, and then dropping the element placed in the last position of the list
ownedTokens[_from].length--;
ownedTokens[_from].length--;
ownedTokensIndex[_tokenId] = 0;
ownedTokensIndex[_tokenId] = 0;
ownedTokensIndex[lastToken] = tokenIndex;
ownedTokensIndex[lastToken] = tokenIndex;
totalTokens = totalTokens.sub(1);
totalTokens = totalTokens.sub(1);
}
}
/**
* @dev Tells whether the msg.sender is approved for the given token ID or not
* @param _tokenId uint256 ID of the token to query the approval of
* @return bool whether the msg.sender is approved for the given token ID or not
*/
function isApprovedFor(uint256 _tokenId) internal view returns (bool) {
return approvedFor(_tokenId) == msg.sender;
}
}
}
test/token/ERC721Token.test.js
View file @
23afc74b
...
@@ -17,8 +17,8 @@ contract('ERC721Token', accounts => {
...
@@ -17,8 +17,8 @@ contract('ERC721Token', accounts => {
beforeEach
(
async
function
()
{
beforeEach
(
async
function
()
{
token
=
await
ERC721Token
.
new
({
from
:
_creator
});
token
=
await
ERC721Token
.
new
({
from
:
_creator
});
await
token
.
publicM
int
(
_creator
,
_firstTokenId
,
{
from
:
_creator
});
await
token
.
m
int
(
_creator
,
_firstTokenId
,
{
from
:
_creator
});
await
token
.
publicM
int
(
_creator
,
_secondTokenId
,
{
from
:
_creator
});
await
token
.
m
int
(
_creator
,
_secondTokenId
,
{
from
:
_creator
});
});
});
describe
(
'totalSupply'
,
function
()
{
describe
(
'totalSupply'
,
function
()
{
...
@@ -73,7 +73,7 @@ contract('ERC721Token', accounts => {
...
@@ -73,7 +73,7 @@ contract('ERC721Token', accounts => {
it
(
'mints the given token ID to the given address'
,
async
function
()
{
it
(
'mints the given token ID to the given address'
,
async
function
()
{
const
previousBalance
=
await
token
.
balanceOf
(
to
);
const
previousBalance
=
await
token
.
balanceOf
(
to
);
await
token
.
publicM
int
(
to
,
tokenId
);
await
token
.
m
int
(
to
,
tokenId
);
const
owner
=
await
token
.
ownerOf
(
tokenId
);
const
owner
=
await
token
.
ownerOf
(
tokenId
);
owner
.
should
.
be
.
equal
(
to
);
owner
.
should
.
be
.
equal
(
to
);
...
@@ -83,7 +83,7 @@ contract('ERC721Token', accounts => {
...
@@ -83,7 +83,7 @@ contract('ERC721Token', accounts => {
});
});
it
(
'adds that token to the token list of the owner'
,
async
function
()
{
it
(
'adds that token to the token list of the owner'
,
async
function
()
{
await
token
.
publicM
int
(
to
,
tokenId
);
await
token
.
m
int
(
to
,
tokenId
);
const
tokens
=
await
token
.
tokensOf
(
to
);
const
tokens
=
await
token
.
tokensOf
(
to
);
tokens
.
length
.
should
.
be
.
equal
(
1
);
tokens
.
length
.
should
.
be
.
equal
(
1
);
...
@@ -91,7 +91,7 @@ contract('ERC721Token', accounts => {
...
@@ -91,7 +91,7 @@ contract('ERC721Token', accounts => {
});
});
it
(
'emits a transfer event'
,
async
function
()
{
it
(
'emits a transfer event'
,
async
function
()
{
const
{
logs
}
=
await
token
.
publicM
int
(
to
,
tokenId
);
const
{
logs
}
=
await
token
.
m
int
(
to
,
tokenId
);
logs
.
length
.
should
.
be
.
equal
(
1
);
logs
.
length
.
should
.
be
.
equal
(
1
);
logs
[
0
].
event
.
should
.
be
.
eq
(
'Transfer'
);
logs
[
0
].
event
.
should
.
be
.
eq
(
'Transfer'
);
...
@@ -105,7 +105,7 @@ contract('ERC721Token', accounts => {
...
@@ -105,7 +105,7 @@ contract('ERC721Token', accounts => {
const
to
=
ZERO_ADDRESS
;
const
to
=
ZERO_ADDRESS
;
it
(
'reverts'
,
async
function
()
{
it
(
'reverts'
,
async
function
()
{
await
assertRevert
(
token
.
publicM
int
(
to
,
tokenId
));
await
assertRevert
(
token
.
m
int
(
to
,
tokenId
));
});
});
});
});
});
});
...
@@ -114,7 +114,7 @@ contract('ERC721Token', accounts => {
...
@@ -114,7 +114,7 @@ contract('ERC721Token', accounts => {
const
tokenId
=
_firstTokenId
;
const
tokenId
=
_firstTokenId
;
it
(
'reverts'
,
async
function
()
{
it
(
'reverts'
,
async
function
()
{
await
assertRevert
(
token
.
publicM
int
(
accounts
[
1
],
tokenId
));
await
assertRevert
(
token
.
m
int
(
accounts
[
1
],
tokenId
));
});
});
});
});
});
});
...
@@ -129,7 +129,7 @@ contract('ERC721Token', accounts => {
...
@@ -129,7 +129,7 @@ contract('ERC721Token', accounts => {
it
(
'burns the given token ID and adjusts the balance of the owner'
,
async
function
()
{
it
(
'burns the given token ID and adjusts the balance of the owner'
,
async
function
()
{
const
previousBalance
=
await
token
.
balanceOf
(
sender
);
const
previousBalance
=
await
token
.
balanceOf
(
sender
);
await
token
.
publicB
urn
(
tokenId
,
{
from
:
sender
});
await
token
.
b
urn
(
tokenId
,
{
from
:
sender
});
await
assertRevert
(
token
.
ownerOf
(
tokenId
));
await
assertRevert
(
token
.
ownerOf
(
tokenId
));
const
balance
=
await
token
.
balanceOf
(
sender
);
const
balance
=
await
token
.
balanceOf
(
sender
);
...
@@ -137,7 +137,7 @@ contract('ERC721Token', accounts => {
...
@@ -137,7 +137,7 @@ contract('ERC721Token', accounts => {
});
});
it
(
'removes that token from the token list of the owner'
,
async
function
()
{
it
(
'removes that token from the token list of the owner'
,
async
function
()
{
await
token
.
publicB
urn
(
tokenId
,
{
from
:
sender
});
await
token
.
b
urn
(
tokenId
,
{
from
:
sender
});
const
tokens
=
await
token
.
tokensOf
(
sender
);
const
tokens
=
await
token
.
tokensOf
(
sender
);
tokens
.
length
.
should
.
be
.
equal
(
1
);
tokens
.
length
.
should
.
be
.
equal
(
1
);
...
@@ -145,7 +145,7 @@ contract('ERC721Token', accounts => {
...
@@ -145,7 +145,7 @@ contract('ERC721Token', accounts => {
});
});
it
(
'emits a burn event'
,
async
function
()
{
it
(
'emits a burn event'
,
async
function
()
{
const
{
logs
}
=
await
token
.
publicB
urn
(
tokenId
,
{
from
:
sender
});
const
{
logs
}
=
await
token
.
b
urn
(
tokenId
,
{
from
:
sender
});
logs
.
length
.
should
.
be
.
equal
(
1
);
logs
.
length
.
should
.
be
.
equal
(
1
);
logs
[
0
].
event
.
should
.
be
.
eq
(
'Transfer'
);
logs
[
0
].
event
.
should
.
be
.
eq
(
'Transfer'
);
...
@@ -160,13 +160,13 @@ contract('ERC721Token', accounts => {
...
@@ -160,13 +160,13 @@ contract('ERC721Token', accounts => {
});
});
it
(
'clears the approval'
,
async
function
()
{
it
(
'clears the approval'
,
async
function
()
{
await
token
.
publicB
urn
(
tokenId
,
{
from
:
sender
});
await
token
.
b
urn
(
tokenId
,
{
from
:
sender
});
const
approvedAccount
=
await
token
.
approvedFor
(
tokenId
);
const
approvedAccount
=
await
token
.
approvedFor
(
tokenId
);
approvedAccount
.
should
.
be
.
equal
(
ZERO_ADDRESS
);
approvedAccount
.
should
.
be
.
equal
(
ZERO_ADDRESS
);
});
});
it
(
'emits an approval event'
,
async
function
()
{
it
(
'emits an approval event'
,
async
function
()
{
const
{
logs
}
=
await
token
.
publicB
urn
(
tokenId
,
{
from
:
sender
});
const
{
logs
}
=
await
token
.
b
urn
(
tokenId
,
{
from
:
sender
});
logs
.
length
.
should
.
be
.
equal
(
2
);
logs
.
length
.
should
.
be
.
equal
(
2
);
...
@@ -182,7 +182,7 @@ contract('ERC721Token', accounts => {
...
@@ -182,7 +182,7 @@ contract('ERC721Token', accounts => {
const
sender
=
accounts
[
1
];
const
sender
=
accounts
[
1
];
it
(
'reverts'
,
async
function
()
{
it
(
'reverts'
,
async
function
()
{
await
assertRevert
(
token
.
publicB
urn
(
tokenId
,
{
from
:
sender
}));
await
assertRevert
(
token
.
b
urn
(
tokenId
,
{
from
:
sender
}));
});
});
});
});
});
});
...
@@ -191,7 +191,7 @@ contract('ERC721Token', accounts => {
...
@@ -191,7 +191,7 @@ contract('ERC721Token', accounts => {
const
tokenID
=
_unknownTokenId
;
const
tokenID
=
_unknownTokenId
;
it
(
'reverts'
,
async
function
()
{
it
(
'reverts'
,
async
function
()
{
await
assertRevert
(
token
.
publicB
urn
(
tokenID
,
{
from
:
_creator
}));
await
assertRevert
(
token
.
b
urn
(
tokenID
,
{
from
:
_creator
}));
});
});
});
});
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment