- Contract name:
- ArianeeCreditHistory
- Optimization enabled
- true
- Compiler version
- v0.5.6+commit.b259423e
- Verified at
- 2019-06-25 07:54:29.816424Z
Contract source code
// File: @0xcert/ethereum-utils-contracts/src/contracts/permission/ownable.sol pragma solidity 0.5.6; /** * @dev The contract has an owner address, and provides basic authorization control whitch * simplifies the implementation of user permissions. This contract is based on the source code at: * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol */ contract Ownable { /** * @dev Error constants. */ string constant NOT_OWNER = "018001"; string constant ZERO_ADDRESS = "018002"; /** * @dev Address of the owner. */ address public owner; /** * @dev An event which is triggered when the owner is changed. * @param previousOwner The address of the previous owner. * @param newOwner The address of the new owner. */ event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The constructor sets the original `owner` of the contract to the sender account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner, NOT_OWNER); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership( address _newOwner ) public onlyOwner { require(_newOwner != address(0), ZERO_ADDRESS); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } } // File: @0xcert/ethereum-utils-contracts/src/contracts/math/safe-math.sol pragma solidity 0.5.6; /** * @dev Math operations with safety checks that throw on error. This contract is based on the * source code at: * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol. */ library SafeMath { /** * @dev Error constants. */ string constant OVERFLOW = "008001"; string constant SUBTRAHEND_GREATER_THEN_MINUEND = "008002"; string constant DIVISION_BY_ZERO = "008003"; /** * @dev Multiplies two numbers, reverts on overflow. * @param _factor1 Factor number. * @param _factor2 Factor number. * @return The product of the two factors. */ function mul( uint256 _factor1, uint256 _factor2 ) internal pure returns (uint256 product) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (_factor1 == 0) { return 0; } product = _factor1 * _factor2; require(product / _factor1 == _factor2, OVERFLOW); } /** * @dev Integer division of two numbers, truncating the quotient, reverts on division by zero. * @param _dividend Dividend number. * @param _divisor Divisor number. * @return The quotient. */ function div( uint256 _dividend, uint256 _divisor ) internal pure returns (uint256 quotient) { // Solidity automatically asserts when dividing by 0, using all gas. require(_divisor > 0, DIVISION_BY_ZERO); quotient = _dividend / _divisor; // assert(_dividend == _divisor * quotient + _dividend % _divisor); // There is no case in which this doesn't hold. } /** * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). * @param _minuend Minuend number. * @param _subtrahend Subtrahend number. * @return Difference. */ function sub( uint256 _minuend, uint256 _subtrahend ) internal pure returns (uint256 difference) { require(_subtrahend <= _minuend, SUBTRAHEND_GREATER_THEN_MINUEND); difference = _minuend - _subtrahend; } /** * @dev Adds two numbers, reverts on overflow. * @param _addend1 Number. * @param _addend2 Number. * @return Sum. */ function add( uint256 _addend1, uint256 _addend2 ) internal pure returns (uint256 sum) { sum = _addend1 + _addend2; require(sum >= _addend1, OVERFLOW); } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), reverts when * dividing by zero. * @param _dividend Number. * @param _divisor Number. * @return Remainder. */ function mod( uint256 _dividend, uint256 _divisor ) internal pure returns (uint256 remainder) { require(_divisor != 0, DIVISION_BY_ZERO); remainder = _dividend % _divisor; } } // File: contracts/ArianeeCreditHistory.sol pragma solidity 0.5.6; contract ArianeeCreditHistory is Ownable { using SafeMath for uint256; /** * @dev Mapping from address to array of creditHistory by type of credit. */ mapping(address => mapping(uint256=>CreditBuy[])) internal creditHistory; /** * @dev Mapping from address to creditHistory index by type of the credit. */ mapping(address => mapping(uint256=>uint256)) internal historyIndex; /** * @dev Mapping from address to totalCredit by type of the credit. */ mapping(address => mapping(uint256=>uint256)) internal totalCredits; /** * @dev Address of the actual store address. */ address public arianeeStoreAddress; struct CreditBuy{ uint256 price; uint256 quantity; } /** * @dev This emits when a new address is set. */ event SetAddress(string _addressType, address _newAddress); modifier onlyStore(){ require(msg.sender == arianeeStoreAddress, 'not called by store'); _; } /** * @dev public function that change the store contract address. * @notice Can only be called by the contract owner. */ function setArianeeStoreAddress(address _newArianeeStoreAdress) onlyOwner() external { arianeeStoreAddress = _newArianeeStoreAdress; emit SetAddress("arianeeStore", _newArianeeStoreAdress); } /** * @dev public funciton that add a credit history when credit are bought. * @notice can only be called by the store. * @param _spender address of the buyer * @param _price current price of the credit. * @param _quantity of credit buyed. * @param _type of credit buyed. */ function addCreditHistory(address _spender, uint256 _price, uint256 _quantity, uint256 _type) external onlyStore() { CreditBuy memory _creditBuy = CreditBuy({ price: _price, quantity: _quantity }); creditHistory[_spender][_type].push(_creditBuy); totalCredits[_spender][_type] = SafeMath.add(totalCredits[_spender][_type], _quantity); } /** * @dev Public function that consume a given quantity of credit and return the price of the oldest non spent credit. * @notice Can only be called by the store. * @param _spender address of the buyer. * @param _type type of credit. * @return price of the credit. */ function consumeCredits(address _spender, uint256 _type, uint256 _quantity) external onlyStore() returns (uint256) { require(totalCredits[_spender][_type]>0, "No credit of that type"); uint256 _index = historyIndex[_spender][_type]; require(creditHistory[_spender][_type][_index].quantity >= _quantity); uint256 price = creditHistory[_spender][_type][_index].price; creditHistory[_spender][_type][_index].quantity = SafeMath.sub(creditHistory[_spender][_type][_index].quantity, _quantity); totalCredits[_spender][_type] = SafeMath.sub(totalCredits[_spender][_type], 1); if(creditHistory[_spender][_type][_index].quantity == 0){ historyIndex[_spender][_type] = SafeMath.add(historyIndex[_spender][_type], 1); } return price; } /** * @notice Give a specific credit history for a given spender, and type. * @param _spender for which we want the credit history. * @param _type of the credit for which we want the history. * @param _index of the credit for which we want the history. * @return Credit history. */ function userCreditHistory(address _spender, uint256 _type, uint256 _index) external view returns (uint256 _price, uint256 _quantity) { _price = creditHistory[_spender][_type][_index].price; _quantity = creditHistory[_spender][_type][_index].quantity; } /** * @notice Get the actual index for a spender and a credit type. * @param _spender for which we want the credit history. * @param _type of the credit for which we want the history. * @return Current index. */ function userIndex(address _spender, uint256 _type) external view returns(uint256 _historyIndex){ _historyIndex = historyIndex[_spender][_type]; } /** * @notice Give the total balance of credit for a spender. * @param _spender for which we want the credit history. * @param _type of the credit for which we want the history. * @return Balance of the spender. */ function balanceOf(address _spender, uint256 _type) external view returns(uint256 _totalCredits){ _totalCredits = totalCredits[_spender][_type]; } }
Contract ABI
[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_totalCredits"}],"name":"balanceOf","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_type"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_price"},{"type":"uint256","name":"_quantity"}],"name":"userCreditHistory","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_type"},{"type":"uint256","name":"_index"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_historyIndex"}],"name":"userIndex","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_type"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"addCreditHistory","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_price"},{"type":"uint256","name":"_quantity"},{"type":"uint256","name":"_type"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setArianeeStoreAddress","inputs":[{"type":"address","name":"_newArianeeStoreAdress"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"consumeCredits","inputs":[{"type":"address","name":"_spender"},{"type":"uint256","name":"_type"},{"type":"uint256","name":"_quantity"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"arianeeStoreAddress","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"_newOwner"}],"constant":false},{"type":"event","name":"SetAddress","inputs":[{"type":"string","name":"_addressType","indexed":false},{"type":"address","name":"_newAddress","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","indexed":true},{"type":"address","name":"newOwner","indexed":true}],"anonymous":false}]
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100855760e060020a6000350462fdd58e811461008a57806340ee34f9146100c85780634a9a7acc146101135780638da5cb5b1461013f57806397d72be014610163578063b23e52731461019d578063d60b1e19146101c3578063f153fcd3146101f5578063f2fde38b146101fd575b600080fd5b6100b6600480360360408110156100a057600080fd5b50600160a060020a038135169060200135610223565b60408051918252519081900360200190f35b6100fa600480360360608110156100de57600080fd5b50600160a060020a03813516906020810135906040013561024a565b6040805192835260208301919091528051918290030190f35b6100b66004803603604081101561012957600080fd5b50600160a060020a0381351690602001356102d8565b6101476102ff565b60408051600160a060020a039092168252519081900360200190f35b61019b6004803603608081101561017957600080fd5b50600160a060020a03813516906020810135906040810135906060013561030e565b005b61019b600480360360208110156101b357600080fd5b5035600160a060020a0316610412565b6100b6600480360360608110156101d957600080fd5b50600160a060020a038135169060208101359060400135610547565b61014761082f565b61019b6004803603602081101561021357600080fd5b5035600160a060020a031661083e565b600160a060020a039091166000908152600360209081526040808320938352929052205490565b600160a060020a0383166000908152600160209081526040808320858452909152812080548291908490811061027c57fe5b60009182526020808320600290920290910154600160a060020a03881683526001825260408084208885529092529120805491935090849081106102bc57fe5b9060005260206000209060020201600101549050935093915050565b600160a060020a039091166000908152600260209081526040808320938352929052205490565b600054600160a060020a031681565b600454600160a060020a03163314610369576040805160e560020a62461bcd0281526020600482015260136024820152606860020a726e6f742063616c6c65642062792073746f726502604482015290519081900360640190fd5b610371610a8b565b506040805180820182528481526020808201858152600160a060020a038816600081815260018085528682208883528552868220805480830182559083528583208751600290920201908155935193019290925581526003825283812085825290915291909120546103e39084610990565b600160a060020a0390951660009081526003602090815260408083209483529390529190912093909355505050565b600054604080518082019091526006815260d060020a6530313830303102602082015290600160a060020a031633146104cc5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610491578181015183820152602001610479565b50505050905090810190601f1680156104be5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060048054600160a060020a038316600160a060020a03199091168117909155604080516020810192909252808252600c8282015260a060020a6b617269616e656553746f7265026060830152517fb5fa77bd6bc3d862c73fa2474bfb96a0f76d38b622c54ff2a0188be82fb965119181900360800190a150565b600454600090600160a060020a031633146105a5576040805160e560020a62461bcd0281526020600482015260136024820152606860020a726e6f742063616c6c65642062792073746f726502604482015290519081900360640190fd5b600160a060020a0384166000908152600360209081526040808320868452909152902054610619576040805160e560020a62461bcd0281526020600482015260166024820152605060020a754e6f20637265646974206f662074686174207479706502604482015290519081900360640190fd5b600160a060020a038416600081815260026020908152604080832087845282528083205493835260018252808320878452909152902080548491908390811061065e57fe5b906000526020600020906002020160010154101561067b57600080fd5b600160a060020a038516600090815260016020908152604080832087845290915281208054839081106106aa57fe5b60009182526020808320600290920290910154600160a060020a03891683526001825260408084208985529092529120805491925061070591849081106106ed57fe5b90600052602060002090600202016001015485610a0d565b600160a060020a0387166000908152600160209081526040808320898452909152902080548490811061073457fe5b600091825260208083206001600290930201820193909355600160a060020a03891682526003835260408083208984529093529190205461077491610a0d565b600160a060020a03871660008181526003602090815260408083208a845282528083209490945591815260018252828120888252909152208054839081106107b857fe5b9060005260206000209060020201600101546000141561082657600160a060020a0386166000908152600260209081526040808320888452909152902054610801906001610990565b600160a060020a03871660009081526002602090815260408083208984529091529020555b95945050505050565b600454600160a060020a031681565b600054604080518082019091526006815260d060020a6530313830303102602082015290600160a060020a031633146108bb5760405160e560020a62461bcd028152602060048201818152835160248401528351909283926044909101919085019080838360008315610491578181015183820152602001610479565b50604080518082019091526006815260d160020a6518189c181819026020820152600160a060020a0382166109345760405160e560020a62461bcd028152602060048201818152835160248401528351909283926044909101919085019080838360008315610491578181015183820152602001610479565b5060008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360008054600160a060020a031916600160a060020a0392909216919091179055565b604080518082019091526006815260d060020a653030383030310260208201528282019083821015610a065760405160e560020a62461bcd028152602060048201818152835160248401528351909283926044909101919085019080838360008315610491578181015183820152602001610479565b5092915050565b60008282111560405180604001604052806006815260200160d160020a6518181c1818190281525090610a845760405160e560020a62461bcd028152602060048201818152835160248401528351909283926044909101919085019080838360008315610491578181015183820152602001610479565b5050900390565b60405180604001604052806000815260200160008152509056fea165627a7a72305820e35349489610d28f3c2d6ed48f2c8401a73267f8f7ee771f32a5e6306a26121c0029