Skip to content

Commit

Permalink
optimize nrc721
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonLi000 committed Jul 18, 2018
1 parent 47e29d0 commit 630ba1b
Showing 1 changed file with 137 additions and 75 deletions.
212 changes: 137 additions & 75 deletions NRC721.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ function name()

#### balanceOf

Returns the number of tokens owned by `_owner`.
Returns the number of tokens owned by `owner`.

``` js
// returns The number of NFTs owned by `_owner`, possibly zero
function balanceOf(_owner)
// returns The number of NFTs owned by `owner`, possibly zero
function balanceOf(owner)
```

#### ownerOf
Expand All @@ -38,20 +38,20 @@ Returns the address of the owner of the tokens.

``` js
// returns the address of the owner of the tokens
function ownerOf(_tokenId)
function ownerOf(tokenId)
```


#### transferFrom
Transfers the ownership of an token from one address to another address. The caller is responsible to confirm that `_to` is capable of receiving token or else they may be permanently lost.
Transfers the ownership of an token from one address to another address. The caller is responsible to confirm that `to` is capable of receiving token or else they may be permanently lost.

Transfers `_tokenId` tokenId from address `_from` to address `_to`, and MUST fire the `Transfer` event.
Transfers `tokenId` tokenId from address `from` to address `to`, and MUST fire the `Transfer` event.

The function SHOULD `throws` unless the transaction from is the current owner, an authorized operator, or the approved address for this token. `throws` if `_from` is not the current owner. `throws` if `_to` is the contract address. `throws` if `_tokenId` is not a valid token.
The function SHOULD `throws` unless the transaction from is the current owner, an authorized operator, or the approved address for this token. `throws` if `from` is not the current owner. `throws` if `to` is the contract address. `throws` if `tokenId` is not a valid token.

``` js
// if transfer fail, throw error
function transferFrom(_from, _to, _tokenId)
function transferFrom(from, to, tokenId)
```


Expand All @@ -62,18 +62,18 @@ Set or reaffirm the approved address for an token.
The function SHOULD `throws` unless transcation from is the current token owner, or an authorized operator of the current owner.

``` js
function approve(_to, _tokenId)
function approve(to, tokenId)
```

#### setApprovalForAll

Enable or disable approval for a third party (`operator`) to manage all of transaction from's assets.

`_operator` Address to add to the set of authorized operators.
`_approved` True if the operators is approved, false to revoke approval
`operator` Address to add to the set of authorized operators.
`approved` True if the operators is approved, false to revoke approval

``` js
function setApprovalForAll(_operator, _approved)
function setApprovalForAll(operator, approved)
```

#### getApproved
Expand All @@ -82,45 +82,45 @@ Get the approved address for a single token.

``` js
// return the approved address for this token, or "" if there is none
function getApproved(_tokenId)
function getApproved(tokenId)
```

#### isApprovedForAll

Query if an address is an authorized operator for another address.

``` js
// return true if `_operator` is an approved operator for `_owner`, false otherwise
function isApprovedForAll(_owner, _operator)
// return true if `operator` is an approved operator for `owner`, false otherwise
function isApprovedForAll(owner, operator)
```

### Events


#### transferEvent
#### _transferEvent

This emits when ownership of any token changes by any mechanism.

``` js
function transferEvent: function(status, from, to, value)
function _transferEvent: function(status, from, to, value)
```



#### approveEvent
#### _approveEvent

This emits when the approved address for an token is changed or reaffirmed.

When a Transfer event emits, this also indicates that the approved address for that token (if any) is reset to none

``` js
function approveEvent: function(status, from, spender, value)
function _approveEvent: function(status, from, spender, value)
```

## Implementation

#### Example implementations are available at
- [NRC721BasicToken.js](https://github.com/nebulasio/go-nebulas/blob/master/nf/nvm/test/NRC721BasicToken.js)
- [NRC721BasicToken.js](https://github.com/nebulasio/go-nebulas/blob/develop/nf/nvm/test/NRC721BasicToken.js)

```js

Expand Down Expand Up @@ -178,6 +178,7 @@ var StandardToken = function () {
return o.toString();
}
},

});
};

Expand All @@ -190,136 +191,196 @@ StandardToken.prototype = {
return this._name;
},

balanceOf: function (_owner) {
var balance = this.ownedTokensCount.get(_owner);
// Returns the number of tokens owned by owner.
balanceOf: function (owner) {
var balance = this.ownedTokensCount.get(owner);
if (balance instanceof BigNumber) {
return balance.toString(10);
} else {
return "0";
}
},

ownerOf: function (_tokenId) {
return this.tokenOwner.get(_tokenId);
//Returns the address of the owner of the tokenID.
ownerOf: function (tokenID) {
return this.tokenOwner.get(tokenID);
},

approve: function (_to, _tokenId) {
/**
* Set or reaffirm the approved address for an token.
* The function SHOULD throws unless transcation from is the current token owner, or an authorized operator of the current owner.
*/
approve: function (to, tokenId) {
var from = Blockchain.transaction.from;

var owner = this.ownerOf(_tokenId);
if (_to == owner) {
var owner = this.ownerOf(tokenId);
if (to == owner) {
throw new Error("invalid address in approve.");
}
if (owner == from || this.isApprovedForAll(owner, from)) {
this.tokenApprovals.set(_tokenId, _to);
this.approveEvent(true, owner, _to, _tokenId);
this.tokenApprovals.set(tokenId, to);
this._approveEvent(true, owner, to, tokenId);
} else {
throw new Error("permission denied in approve.");
}
},

getApproved: function (_tokenId) {
return this.tokenApprovals.get(_tokenId);
// Returns the approved address for a single token.
getApproved: function (tokenId) {
return this.tokenApprovals.get(tokenId);
},

setApprovalForAll: function(_to, _approved) {
/**
* Enable or disable approval for a third party (operator) to manage all of transaction from's assets.
* operator Address to add to the set of authorized operators.
* @param approved True if the operators is approved, false to revoke approval
*/
setApprovalForAll: function(to, approved) {
var from = Blockchain.transaction.from;
if (from == _to) {
if (from == to) {
throw new Error("invalid address in setApprovalForAll.");
}
var operator = this.operatorApprovals.get(from) || new Operator();
operator.set(_to, _approved);
operator.set(to, approved);
this.operatorApprovals.set(from, operator);
},

isApprovedForAll: function(_owner, _operator) {
var operator = this.operatorApprovals.get(_owner);
/**
* @dev Tells whether an operator is approved by a given owner
* @param owner owner address which you want to query the approval of
* @param operator operator address which you want to query the approval of
* @return bool whether the given operator is approved by the given owner
*/
isApprovedForAll: function(owner, operator) {
var operator = this.operatorApprovals.get(owner);
if (operator != null) {
if (operator.get(_operator) === "true") {
if (operator.get(operator) === "true") {
return true;
} else {
return false;
}
}
},

isApprovedOrOwner: function(_spender, _tokenId) {
var owner = this.ownerOf(_tokenId);
return _spender == owner || this.getApproved(_tokenId) == _spender || this.isApprovedForAll(owner, _spender);

/**
* @dev Returns whether the given spender can transfer a given token ID
* @param spender address of the spender to query
* @param tokenId uint256 ID of the token to be transferred
* @return bool whether the msg.sender is approved for the given token ID,
* is an operator of the owner, or is the owner of the token
*/
_isApprovedOrOwner: function(spender, tokenId) {
var owner = this.ownerOf(tokenId);
return spender == owner || this.getApproved(tokenId) == spender || this.isApprovedForAll(owner, spender);
},

transferFrom: function (_from, _to, _tokenId) {
var from = Blockchain.transaction.from;
/**
* Transfers the ownership of an token from one address to another address.
* The caller is responsible to confirm that to is capable of receiving token or else they may be permanently lost.
* Transfers tokenId from address from to address to, and MUST fire the Transfer event.
* The function SHOULD throws unless the transaction from is the current owner, an authorized operator, or the approved address for this token.
* Throws if from is not the current owner.
* Throws if to is the contract address.
* Throws if tokenId is not a valid token.
*/
transferFrom: function (from, to, tokenId) {
var sender = Blockchain.transaction.from;
var contractAddress = Blockchain.transaction.to;
if (contractAddress == _to) {
if (contractAddress == to) {
throw new Error("Forbidden to transfer money to a smart contract address");
}
if (this.isApprovedOrOwner(from, _tokenId)) {
this.clearApproval(_from, _tokenId);
this.removeTokenFrom(_from, _tokenId);
this.addTokenTo(_to, _tokenId);
this.transferEvent(true, _from, _to, _tokenId);
if (this._isApprovedOrOwner(sender, tokenId)) {
this._clearApproval(from, tokenId);
this._removeTokenFrom(from, tokenId);
this._addTokenTo(to, tokenId);
this._transferEvent(true, from, to, tokenId);
} else {
throw new Error("permission denied in transferFrom.");
}

},


clearApproval: function (_owner, _tokenId) {
var owner = this.ownerOf(_tokenId);
if (_owner != owner) {
/**
* Internal function to clear current approval of a given token ID
* Throws if the given address is not indeed the owner of the token
* @param sender owner of the token
* @param tokenId uint256 ID of the token to be transferred
*/
_clearApproval: function (sender, tokenId) {
var owner = this.ownerOf(tokenId);
if (sender != owner) {
throw new Error("permission denied in clearApproval.");
}
this.tokenApprovals.del(_tokenId);
this.tokenApprovals.del(tokenId);
},

removeTokenFrom: function(_from, _tokenId) {
if (_from != this.ownerOf(_tokenId)) {
/**
* Internal function to remove a token ID from the list of a given address
* @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
*/
_removeTokenFrom: function(from, tokenId) {
if (from != this.ownerOf(tokenId)) {
throw new Error("permission denied in removeTokenFrom.");
}
var tokenCount = this.ownedTokensCount.get(_from);
var tokenCount = this.ownedTokensCount.get(from);
if (tokenCount.lt(1)) {
throw new Error("Insufficient account balance in removeTokenFrom.");
}
this.ownedTokensCount.set(_from, tokenCount.minus(1));
this.ownedTokensCount.set(from, tokenCount.sub(1));
},

addTokenTo: function(_to, _tokenId) {
this.tokenOwner.set(_tokenId, _to);
var tokenCount = this.ownedTokensCount.get(_to) || new BigNumber(0);
this.ownedTokensCount.set(_to, tokenCount.plus(1));
/**
* Internal function to add a token ID to the list of a given address
* @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
*/
_addTokenTo: function(to, tokenId) {
this.tokenOwner.set(tokenId, to);
var tokenCount = this.ownedTokensCount.get(to) || new BigNumber(0);
this.ownedTokensCount.set(to, tokenCount.add(1));
},

mint: function(_to, _tokenId) {
this.addTokenTo(_to, _tokenId);
this.transferEvent(true, "", _to, _tokenId);
/**
* Internal function to mint a new 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
*/
_mint: function(to, tokenId) {
this._addTokenTo(to, tokenId);
this._transferEvent(true, "", to, tokenId);
},

burn: function(_owner, _tokenId) {
this.clearApproval(_owner, _tokenId);
this.removeTokenFrom(_owner, _tokenId);
this.transferEvent(true, _owner, "", _tokenId);
/**
* Internal function to burn a specific token
* @param tokenId uint256 ID of the token being burned by the msg.sender
*/
_burn: function(owner, tokenId) {
this._clearApproval(owner, tokenId);
this._removeTokenFrom(owner, tokenId);
this._transferEvent(true, owner, "", tokenId);
},

transferEvent: function (status, _from, _to, _tokenId) {
_transferEvent: function (status, from, to, tokenId) {
Event.Trigger(this.name(), {
Status: status,
Transfer: {
from: _from,
to: _to,
tokenId: _tokenId
from: from,
to: to,
tokenId: tokenId
}
});
},

approveEvent: function (status, _owner, _spender, _tokenId) {
_approveEvent: function (status, owner, spender, tokenId) {
Event.Trigger(this.name(), {
Status: status,
Approve: {
owner: _owner,
spender: _spender,
tokenId: _tokenId
owner: owner,
spender: spender,
tokenId: tokenId
}
});
}
Expand All @@ -329,4 +390,5 @@ StandardToken.prototype = {
module.exports = StandardToken;



```

0 comments on commit 630ba1b

Please sign in to comment.