diff --git a/ERCTokenImplementation.sol b/ERCTokenImplementation.sol index fff4718..6b450c3 100644 --- a/ERCTokenImplementation.sol +++ b/ERCTokenImplementation.sol @@ -17,9 +17,11 @@ contract ERC pragma solidity ^0.4.17; contract Token is ERC { - uint totalTickets; + uint totalTokens; mapping(address => uint256[]) inventory; - uint16 ticketIndex = 0; //to track mapping in tickets + // Owner of account approves the transfer of specific indices by another account + mapping(address => mapping (address => uint256[])) allowed; + uint16 tokenIndex = 0; uint expiryTimeStamp; address owner; // the address that calls selfdestruct() and takes fees address admin; @@ -27,10 +29,11 @@ contract Token is ERC uint numOfTransfers = 0; string public name; string public symbol; - uint8 public constant decimals = 0; //no decimals as tickets cannot be split + uint8 public constant decimals = 0; //no decimals as tokens cannot be split event Transfer(address indexed _from, address indexed _to, uint256[] tokenIndices); event TransferFrom(address indexed _from, address indexed _to, uint _value); + event Approval(address indexed owner, address indexed _approved, uint indexed tokenCount); modifier adminOnly() { @@ -48,8 +51,8 @@ contract Token is ERC string eventSymbol, address adminAddr) public { - totalTickets = numberOfTokens.length; - //assign some tickets to event admin + totalTokens = numberOfTokens.length; + //assign some tokens to event admin expiryTimeStamp = expiry; owner = msg.sender; admin = adminAddr; @@ -82,11 +85,11 @@ contract Token is ERC address seller = ecrecover(message, v, r, s); for(uint i = 0; i < tokenIndices.length; i++) - { // transfer each individual tickets in the ask order + { // transfer each individual tokenss in the ask order uint index = uint(tokenIndices[i]); - require((inventory[seller][index] > 0)); // 0 means ticket sold. + require((inventory[seller][index] > 0)); // 0 means token sold. inventory[msg.sender].push(inventory[seller][index]); - inventory[seller][index] = 0; // 0 means ticket sold. + inventory[seller][index] = 0; // 0 means token sold. } seller.transfer(msg.value); } @@ -177,20 +180,46 @@ contract Token is ERC } } - function transferFrom(address _from, address _to, uint256[] tokenIndices) - adminOnly public + function transferFrom(address _from, address _to, uint256[] tokenIndices) public { bool isadmin = msg.sender == admin; for(uint i = 0; i < tokenIndices.length; i++) { require(inventory[_from][i] != 0 || isadmin); + require(allowed[_from][msg.sender][i] == tokenIndices[i] || isadmin); //pushes each element with ordering uint index = uint(tokenIndices[i]); inventory[_to].push(inventory[msg.sender][index]); inventory[_from][index] = 0; + delete allowed[_from][msg.sender][i]; } } + // Function can be used by external smart contract to ensure it is allowed to move NFTs + function checkAllowed(address owner, address proxy) public view returns (uint16[]) + { + return allowed[owner][proxy]; + } + + // This function approves specific NTFs to be available for use in an external contract + // See transferFromContract() above. + function approve(address _approved, uint256[] tokenIndices) public + { + // allow caller to cancel approval - each approval call resets previous approval + // putting 0 indices resets approval + delete allowed[msg.sender][_approved]; + + for(uint i = 0; i < tokenIndices.length; i++) + { + uint index = uint(tokenIndices[i]); + //check token ownership, abort function and revert changes if any problems + if(inventory[msg.sender][index] == 0) revert("No token at index"); + } + //Confirmed that msg.sender owns these tokens; can now allow external contract to move them + allowed[msg.sender][_approved] = tokenIndices; + emit Approval(msg.sender, _approved, tokenIndices.length); + } + function endContract() public { if(msg.sender == owner)