文件 1 的 1:StudServiceV3.sol
pragma solidity ^0.4.24;
interface ICore {
function tokenSold(uint256 _tokenId) external;
function lastHorseSex() external view returns (bytes32);
function exists(uint256 _tokenId) external view returns (bool);
function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function approve(address _approved, uint256 _tokenId) external payable;
function getApproved(uint256 _tokenId) external view returns (address);
function setApprovalForAll(address _to, bool _approved) external;
function getHorseSex(uint256 _horse) external view returns (bytes32);
function getTimestamp(uint256 _horse) external view returns (uint256);
function getBaseValue(uint256 _horse) external view returns (uint256);
function getBloodline(uint256 _horse) external view returns (bytes32);
function setBaseValue(uint256 _horseId, uint256 _baseValue) external;
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function isTokenApproved(address _spender, uint256 _tokenId) external view returns (bool);
function mintToken(address _owner, string _hash, uint256 _batchNumber) external payable returns (uint256);
function mintCustomHorse(address _owner, string _hash, uint256 _genotype, bytes32 _gender) external returns (uint256);
function createOffspring(address _owner, string _hash, uint256 _male, uint256 _female) external payable returns (uint256);
function getHorseData( uint256 _horse ) external view returns (string, bytes32, uint256, uint256, uint256, uint256, bytes32, bytes32);
}
pragma solidity ^0.4.24;
interface IBreedTypes {
function populateMatrix() external;
function getBreedType(uint256 _id) external view returns(bytes32);
function generateBreedType(uint256 _id, uint256 _father, uint256 _mother) external;
function setBreedingAddress(address _breeding) external;
}
pragma solidity >= 0.4.22 < 0.5;
contract OraclizeI {
address public cbAddress;
function query(uint _timestamp, string _datasource, string _arg) external payable returns (bytes32 _id);
function query_withGasLimit(uint _timestamp, string _datasource, string _arg, uint _gaslimit) external payable returns (bytes32 _id);
function query2(uint _timestamp, string _datasource, string _arg1, string _arg2) public payable returns (bytes32 _id);
function query2_withGasLimit(uint _timestamp, string _datasource, string _arg1, string _arg2, uint _gaslimit) external payable returns (bytes32 _id);
function queryN(uint _timestamp, string _datasource, bytes _argN) public payable returns (bytes32 _id);
function queryN_withGasLimit(uint _timestamp, string _datasource, bytes _argN, uint _gaslimit) external payable returns (bytes32 _id);
function getPrice(string _datasource) public returns (uint _dsprice);
function getPrice(string _datasource, uint gaslimit) public returns (uint _dsprice);
function setProofType(byte _proofType) external;
function setCustomGasPrice(uint _gasPrice) external;
function randomDS_getSessionPubKeyHash() external constant returns(bytes32);
}
contract OraclizeAddrResolverI {
function getAddress() public returns (address _addr);
}
library Buffer {
struct buffer {
bytes buf;
uint capacity;
}
function init(buffer memory buf, uint _capacity) internal pure {
uint capacity = _capacity;
if(capacity % 32 != 0) capacity += 32 - (capacity % 32);
buf.capacity = capacity;
assembly {
let ptr := mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
mstore(0x40, add(ptr, capacity))
}
}
function resize(buffer memory buf, uint capacity) private pure {
bytes memory oldbuf = buf.buf;
init(buf, capacity);
append(buf, oldbuf);
}
function max(uint a, uint b) private pure returns(uint) {
if(a > b) {
return a;
}
return b;
}
function append(buffer memory buf, bytes data) internal pure returns(buffer memory) {
if(data.length + buf.buf.length > buf.capacity) {
resize(buf, max(buf.capacity, data.length) * 2);
}
uint dest;
uint src;
uint len = data.length;
assembly {
let bufptr := mload(buf)
let buflen := mload(bufptr)
dest := add(add(bufptr, buflen), 32)
mstore(bufptr, add(buflen, mload(data)))
src := add(data, 32)
}
for(; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
uint mask = 256 ** (32 - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
return buf;
}
function append(buffer memory buf, uint8 data) internal pure {
if(buf.buf.length + 1 > buf.capacity) {
resize(buf, buf.capacity * 2);
}
assembly {
let bufptr := mload(buf)
let buflen := mload(bufptr)
let dest := add(add(bufptr, buflen), 32)
mstore8(dest, data)
mstore(bufptr, add(buflen, 1))
}
}
function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {
if(len + buf.buf.length > buf.capacity) {
resize(buf, max(buf.capacity, len) * 2);
}
uint mask = 256 ** len - 1;
assembly {
let bufptr := mload(buf)
let buflen := mload(bufptr)
let dest := add(add(bufptr, buflen), len)
mstore(dest, or(and(mload(dest), not(mask)), data))
mstore(bufptr, add(buflen, len))
}
return buf;
}
}
library CBOR {
using Buffer for Buffer.buffer;
uint8 private constant MAJOR_TYPE_INT = 0;
uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1;
uint8 private constant MAJOR_TYPE_BYTES = 2;
uint8 private constant MAJOR_TYPE_STRING = 3;
uint8 private constant MAJOR_TYPE_ARRAY = 4;
uint8 private constant MAJOR_TYPE_MAP = 5;
uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7;
function encodeType(Buffer.buffer memory buf, uint8 major, uint value) private pure {
if(value <= 23) {
buf.append(uint8((major << 5) | value));
} else if(value <= 0xFF) {
buf.append(uint8((major << 5) | 24));
buf.appendInt(value, 1);
} else if(value <= 0xFFFF) {
buf.append(uint8((major << 5) | 25));
buf.appendInt(value, 2);
} else if(value <= 0xFFFFFFFF) {
buf.append(uint8((major << 5) | 26));
buf.appendInt(value, 4);
} else if(value <= 0xFFFFFFFFFFFFFFFF) {
buf.append(uint8((major << 5) | 27));
buf.appendInt(value, 8);
}
}
function encodeIndefiniteLengthType(Buffer.buffer memory buf, uint8 major) private pure {
buf.append(uint8((major << 5) | 31));
}
function encodeUInt(Buffer.buffer memory buf, uint value) internal pure {
encodeType(buf, MAJOR_TYPE_INT, value);
}
function encodeInt(Buffer.buffer memory buf, int value) internal pure {
if(value >= 0) {
encodeType(buf, MAJOR_TYPE_INT, uint(value));
} else {
encodeType(buf, MAJOR_TYPE_NEGATIVE_INT, uint(-1 - value));
}
}
function encodeBytes(Buffer.buffer memory buf, bytes value) internal pure {
encodeType(buf, MAJOR_TYPE_BYTES, value.length);
buf.append(value);
}
function encodeString(Buffer.buffer memory buf, string value) internal pure {
encodeType(buf, MAJOR_TYPE_STRING, bytes(value).length);
buf.append(bytes(value));
}
function startArray(Buffer.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY);
}
function startMap(Buffer.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_MAP);
}
function endSequence(Buffer.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE);
}
}
contract usingOraclize {
uint constant day = 60*60*24;
uint constant week = 60*60*24*7;
uint constant month = 60*60*24*30;
byte constant proofType_NONE = 0x00;
byte constant proofType_TLSNotary = 0x10;
byte constant proofType_Ledger = 0x30;
byte constant proofType_Android = 0x40;
byte constant proofType_Native = 0xF0;
byte constant proofStorage_IPFS = 0x01;
uint8 constant networkID_auto = 0;
uint8 constant networkID_mainnet = 1;
uint8 constant networkID_testnet = 2;
uint8 constant networkID_morden = 2;
uint8 constant networkID_consensys = 161;
OraclizeAddrResolverI OAR;
OraclizeI oraclize;
modifier oraclizeAPI {
if((address(OAR)==0)||(getCodeSize(address(OAR))==0))
oraclize_setNetwork(networkID_auto);
if(address(oraclize) != OAR.getAddress())
oraclize = OraclizeI(OAR.getAddress());
_;
}
modifier coupon(string code){
oraclize = OraclizeI(OAR.getAddress());
_;
}
function oraclize_setNetwork(uint8 networkID) internal returns(bool){
return oraclize_setNetwork();
networkID;
}
function oraclize_setNetwork() internal returns(bool){
if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){
OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed);
oraclize_setNetworkName("eth_mainnet");
return true;
}
if (getCodeSize(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1)>0){
OAR = OraclizeAddrResolverI(0xc03A2615D5efaf5F49F60B7BB6583eaec212fdf1);
oraclize_setNetworkName("eth_ropsten3");
return true;
}
if (getCodeSize(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e)>0){
OAR = OraclizeAddrResolverI(0xB7A07BcF2Ba2f2703b24C0691b5278999C59AC7e);
oraclize_setNetworkName("eth_kovan");
return true;
}
if (getCodeSize(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48)>0){
OAR = OraclizeAddrResolverI(0x146500cfd35B22E4A392Fe0aDc06De1a1368Ed48);
oraclize_setNetworkName("eth_rinkeby");
return true;
}
if (getCodeSize(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475)>0){
OAR = OraclizeAddrResolverI(0x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);
return true;
}
if (getCodeSize(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF)>0){
OAR = OraclizeAddrResolverI(0x20e12A1F859B3FeaE5Fb2A0A32C18F5a65555bBF);
return true;
}
if (getCodeSize(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA)>0){
OAR = OraclizeAddrResolverI(0x51efaF4c8B3C9AfBD5aB9F4bbC82784Ab6ef8fAA);
return true;
}
return false;
}
function __callback(bytes32 myid, string result) public {
__callback(myid, result, new bytes(0));
}
function __callback(bytes32 myid, string result, bytes proof) public {
return;
myid; result; proof;
oraclize = OraclizeI(0);
}
function oraclize_getPrice(string datasource) oraclizeAPI internal returns (uint){
return oraclize.getPrice(datasource);
}
function oraclize_getPrice(string datasource, uint gaslimit) oraclizeAPI internal returns (uint){
return oraclize.getPrice(datasource, gaslimit);
}
function oraclize_query(string datasource, string arg) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
return oraclize.query.value(price)(0, datasource, arg);
}
function oraclize_query(uint timestamp, string datasource, string arg) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
return oraclize.query.value(price)(timestamp, datasource, arg);
}
function oraclize_query(uint timestamp, string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
return oraclize.query_withGasLimit.value(price)(timestamp, datasource, arg, gaslimit);
}
function oraclize_query(string datasource, string arg, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
return oraclize.query_withGasLimit.value(price)(0, datasource, arg, gaslimit);
}
function oraclize_query(string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
return oraclize.query2.value(price)(0, datasource, arg1, arg2);
}
function oraclize_query(uint timestamp, string datasource, string arg1, string arg2) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
return oraclize.query2.value(price)(timestamp, datasource, arg1, arg2);
}
function oraclize_query(uint timestamp, string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
return oraclize.query2_withGasLimit.value(price)(timestamp, datasource, arg1, arg2, gaslimit);
}
function oraclize_query(string datasource, string arg1, string arg2, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
return oraclize.query2_withGasLimit.value(price)(0, datasource, arg1, arg2, gaslimit);
}
function oraclize_query(string datasource, string[] argN) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
bytes memory args = stra2cbor(argN);
return oraclize.queryN.value(price)(0, datasource, args);
}
function oraclize_query(uint timestamp, string datasource, string[] argN) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
bytes memory args = stra2cbor(argN);
return oraclize.queryN.value(price)(timestamp, datasource, args);
}
function oraclize_query(uint timestamp, string datasource, string[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
bytes memory args = stra2cbor(argN);
return oraclize.queryN_withGasLimit.value(price)(timestamp, datasource, args, gaslimit);
}
function oraclize_query(string datasource, string[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
bytes memory args = stra2cbor(argN);
return oraclize.queryN_withGasLimit.value(price)(0, datasource, args, gaslimit);
}
function oraclize_query(string datasource, string[1] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](1);
dynargs[0] = args[0];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[1] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](1);
dynargs[0] = args[0];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](1);
dynargs[0] = args[0];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](1);
dynargs[0] = args[0];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[2] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[2] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[3] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[3] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[4] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[4] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[5] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[5] args) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, string[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, string[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
string[] memory dynargs = new string[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[] argN) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
bytes memory args = ba2cbor(argN);
return oraclize.queryN.value(price)(0, datasource, args);
}
function oraclize_query(uint timestamp, string datasource, bytes[] argN) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource);
if (price > 1 ether + tx.gasprice*200000) return 0;
bytes memory args = ba2cbor(argN);
return oraclize.queryN.value(price)(timestamp, datasource, args);
}
function oraclize_query(uint timestamp, string datasource, bytes[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
bytes memory args = ba2cbor(argN);
return oraclize.queryN_withGasLimit.value(price)(timestamp, datasource, args, gaslimit);
}
function oraclize_query(string datasource, bytes[] argN, uint gaslimit) oraclizeAPI internal returns (bytes32 id){
uint price = oraclize.getPrice(datasource, gaslimit);
if (price > 1 ether + tx.gasprice*gaslimit) return 0;
bytes memory args = ba2cbor(argN);
return oraclize.queryN_withGasLimit.value(price)(0, datasource, args, gaslimit);
}
function oraclize_query(string datasource, bytes[1] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[1] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[1] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](1);
dynargs[0] = args[0];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[2] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[2] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[2] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](2);
dynargs[0] = args[0];
dynargs[1] = args[1];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[3] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[3] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[3] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](3);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[4] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[4] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[4] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](4);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[5] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[5] args) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(timestamp, datasource, dynargs);
}
function oraclize_query(uint timestamp, string datasource, bytes[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(timestamp, datasource, dynargs, gaslimit);
}
function oraclize_query(string datasource, bytes[5] args, uint gaslimit) oraclizeAPI internal returns (bytes32 id) {
bytes[] memory dynargs = new bytes[](5);
dynargs[0] = args[0];
dynargs[1] = args[1];
dynargs[2] = args[2];
dynargs[3] = args[3];
dynargs[4] = args[4];
return oraclize_query(datasource, dynargs, gaslimit);
}
function oraclize_cbAddress() oraclizeAPI internal returns (address){
return oraclize.cbAddress();
}
function oraclize_setProof(byte proofP) oraclizeAPI internal {
return oraclize.setProofType(proofP);
}
function oraclize_setCustomGasPrice(uint gasPrice) oraclizeAPI internal {
return oraclize.setCustomGasPrice(gasPrice);
}
function oraclize_randomDS_getSessionPubKeyHash() oraclizeAPI internal returns (bytes32){
return oraclize.randomDS_getSessionPubKeyHash();
}
function getCodeSize(address _addr) view internal returns(uint _size) {
assembly {
_size := extcodesize(_addr)
}
}
function parseAddr(string _a) internal pure returns (address){
bytes memory tmp = bytes(_a);
uint160 iaddr = 0;
uint160 b1;
uint160 b2;
for (uint i=2; i<2+2*20; i+=2){
iaddr *= 256;
b1 = uint160(tmp[i]);
b2 = uint160(tmp[i+1]);
if ((b1 >= 97)&&(b1 <= 102)) b1 -= 87;
else if ((b1 >= 65)&&(b1 <= 70)) b1 -= 55;
else if ((b1 >= 48)&&(b1 <= 57)) b1 -= 48;
if ((b2 >= 97)&&(b2 <= 102)) b2 -= 87;
else if ((b2 >= 65)&&(b2 <= 70)) b2 -= 55;
else if ((b2 >= 48)&&(b2 <= 57)) b2 -= 48;
iaddr += (b1*16+b2);
}
return address(iaddr);
}
function strCompare(string _a, string _b) internal pure returns (int) {
bytes memory a = bytes(_a);
bytes memory b = bytes(_b);
uint minLength = a.length;
if (b.length < minLength) minLength = b.length;
for (uint i = 0; i < minLength; i ++)
if (a[i] < b[i])
return -1;
else if (a[i] > b[i])
return 1;
if (a.length < b.length)
return -1;
else if (a.length > b.length)
return 1;
else
return 0;
}
function indexOf(string _haystack, string _needle) internal pure returns (int) {
bytes memory h = bytes(_haystack);
bytes memory n = bytes(_needle);
if(h.length < 1 || n.length < 1 || (n.length > h.length))
return -1;
else if(h.length > (2**128 -1))
return -1;
else
{
uint subindex = 0;
for (uint i = 0; i < h.length; i ++)
{
if (h[i] == n[0])
{
subindex = 1;
while(subindex < n.length && (i + subindex) < h.length && h[i + subindex] == n[subindex])
{
subindex++;
}
if(subindex == n.length)
return int(i);
}
}
return -1;
}
}
function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string) {
bytes memory _ba = bytes(_a);
bytes memory _bb = bytes(_b);
bytes memory _bc = bytes(_c);
bytes memory _bd = bytes(_d);
bytes memory _be = bytes(_e);
string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
bytes memory babcde = bytes(abcde);
uint k = 0;
for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
return string(babcde);
}
function strConcat(string _a, string _b, string _c, string _d) internal pure returns (string) {
return strConcat(_a, _b, _c, _d, "");
}
function strConcat(string _a, string _b, string _c) internal pure returns (string) {
return strConcat(_a, _b, _c, "", "");
}
function strConcat(string _a, string _b) internal pure returns (string) {
return strConcat(_a, _b, "", "", "");
}
function parseInt(string _a) internal pure returns (uint) {
return parseInt(_a, 0);
}
function parseInt(string _a, uint _b) internal pure returns (uint) {
bytes memory bresult = bytes(_a);
uint mint = 0;
bool decimals = false;
for (uint i=0; i<bresult.length; i++){
if ((bresult[i] >= 48)&&(bresult[i] <= 57)){
if (decimals){
if (_b == 0) break;
else _b--;
}
mint *= 10;
mint += uint(bresult[i]) - 48;
} else if (bresult[i] == 46) decimals = true;
}
if (_b > 0) mint *= 10**_b;
return mint;
}
function uint2str(uint i) internal pure returns (string){
if (i == 0) return "0";
uint j = i;
uint len;
while (j != 0){
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;
while (i != 0){
bstr[k--] = byte(48 + i % 10);
i /= 10;
}
return string(bstr);
}
using CBOR for Buffer.buffer;
function stra2cbor(string[] arr) internal pure returns (bytes) {
safeMemoryCleaner();
Buffer.buffer memory buf;
Buffer.init(buf, 1024);
buf.startArray();
for (uint i = 0; i < arr.length; i++) {
buf.encodeString(arr[i]);
}
buf.endSequence();
return buf.buf;
}
function ba2cbor(bytes[] arr) internal pure returns (bytes) {
safeMemoryCleaner();
Buffer.buffer memory buf;
Buffer.init(buf, 1024);
buf.startArray();
for (uint i = 0; i < arr.length; i++) {
buf.encodeBytes(arr[i]);
}
buf.endSequence();
return buf.buf;
}
string oraclize_network_name;
function oraclize_setNetworkName(string _network_name) internal {
oraclize_network_name = _network_name;
}
function oraclize_getNetworkName() internal view returns (string) {
return oraclize_network_name;
}
function oraclize_newRandomDSQuery(uint _delay, uint _nbytes, uint _customGasLimit) internal returns (bytes32){
require((_nbytes > 0) && (_nbytes <= 32));
_delay *= 10;
bytes memory nbytes = new bytes(1);
nbytes[0] = byte(_nbytes);
bytes memory unonce = new bytes(32);
bytes memory sessionKeyHash = new bytes(32);
bytes32 sessionKeyHash_bytes32 = oraclize_randomDS_getSessionPubKeyHash();
assembly {
mstore(unonce, 0x20)
mstore(add(unonce, 0x20), xor(blockhash(sub(number, 1)), xor(coinbase, timestamp)))
mstore(sessionKeyHash, 0x20)
mstore(add(sessionKeyHash, 0x20), sessionKeyHash_bytes32)
}
bytes memory delay = new bytes(32);
assembly {
mstore(add(delay, 0x20), _delay)
}
bytes memory delay_bytes8 = new bytes(8);
copyBytes(delay, 24, 8, delay_bytes8, 0);
bytes[4] memory args = [unonce, nbytes, sessionKeyHash, delay];
bytes32 queryId = oraclize_query("random", args, _customGasLimit);
bytes memory delay_bytes8_left = new bytes(8);
assembly {
let x := mload(add(delay_bytes8, 0x20))
mstore8(add(delay_bytes8_left, 0x27), div(x, 0x100000000000000000000000000000000000000000000000000000000000000))
mstore8(add(delay_bytes8_left, 0x26), div(x, 0x1000000000000000000000000000000000000000000000000000000000000))
mstore8(add(delay_bytes8_left, 0x25), div(x, 0x10000000000000000000000000000000000000000000000000000000000))
mstore8(add(delay_bytes8_left, 0x24), div(x, 0x100000000000000000000000000000000000000000000000000000000))
mstore8(add(delay_bytes8_left, 0x23), div(x, 0x1000000000000000000000000000000000000000000000000000000))
mstore8(add(delay_bytes8_left, 0x22), div(x, 0x10000000000000000000000000000000000000000000000000000))
mstore8(add(delay_bytes8_left, 0x21), div(x, 0x100000000000000000000000000000000000000000000000000))
mstore8(add(delay_bytes8_left, 0x20), div(x, 0x1000000000000000000000000000000000000000000000000))
}
oraclize_randomDS_setCommitment(queryId, keccak256(abi.encodePacked(delay_bytes8_left, args[1], sha256(args[0]), args[2])));
return queryId;
}
function oraclize_randomDS_setCommitment(bytes32 queryId, bytes32 commitment) internal {
oraclize_randomDS_args[queryId] = commitment;
}
mapping(bytes32=>bytes32) oraclize_randomDS_args;
mapping(bytes32=>bool) oraclize_randomDS_sessionKeysHashVerified;
function verifySig(bytes32 tosignh, bytes dersig, bytes pubkey) internal returns (bool){
bool sigok;
address signer;
bytes32 sigr;
bytes32 sigs;
bytes memory sigr_ = new bytes(32);
uint offset = 4+(uint(dersig[3]) - 0x20);
sigr_ = copyBytes(dersig, offset, 32, sigr_, 0);
bytes memory sigs_ = new bytes(32);
offset += 32 + 2;
sigs_ = copyBytes(dersig, offset+(uint(dersig[offset-1]) - 0x20), 32, sigs_, 0);
assembly {
sigr := mload(add(sigr_, 32))
sigs := mload(add(sigs_, 32))
}
(sigok, signer) = safer_ecrecover(tosignh, 27, sigr, sigs);
if (address(keccak256(pubkey)) == signer) return true;
else {
(sigok, signer) = safer_ecrecover(tosignh, 28, sigr, sigs);
return (address(keccak256(pubkey)) == signer);
}
}
function oraclize_randomDS_proofVerify__sessionKeyValidity(bytes proof, uint sig2offset) internal returns (bool) {
bool sigok;
bytes memory sig2 = new bytes(uint(proof[sig2offset+1])+2);
copyBytes(proof, sig2offset, sig2.length, sig2, 0);
bytes memory appkey1_pubkey = new bytes(64);
copyBytes(proof, 3+1, 64, appkey1_pubkey, 0);
bytes memory tosign2 = new bytes(1+65+32);
tosign2[0] = byte(1);
copyBytes(proof, sig2offset-65, 65, tosign2, 1);
bytes memory CODEHASH = hex"fd94fa71bc0ba10d39d464d0d8f465efeef0a2764e3887fcc9df41ded20f505c";
copyBytes(CODEHASH, 0, 32, tosign2, 1+65);
sigok = verifySig(sha256(tosign2), sig2, appkey1_pubkey);
if (sigok == false) return false;
bytes memory LEDGERKEY = hex"7fb956469c5c9b89840d55b43537e66a98dd4811ea0a27224272c2e5622911e8537a2f8e86a46baec82864e98dd01e9ccc2f8bc5dfc9cbe5a91a290498dd96e4";
bytes memory tosign3 = new bytes(1+65);
tosign3[0] = 0xFE;
copyBytes(proof, 3, 65, tosign3, 1);
bytes memory sig3 = new bytes(uint(proof[3+65+1])+2);
copyBytes(proof, 3+65, sig3.length, sig3, 0);
sigok = verifySig(sha256(tosign3), sig3, LEDGERKEY);
return sigok;
}
modifier oraclize_randomDS_proofVerify(bytes32 _queryId, string _result, bytes _proof) {
require((_proof[0] == "L") && (_proof[1] == "P") && (_proof[2] == 1));
bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName());
require(proofVerified);
_;
}
function oraclize_randomDS_proofVerify__returnCode(bytes32 _queryId, string _result, bytes _proof) internal returns (uint8){
if ((_proof[0] != "L")||(_proof[1] != "P")||(_proof[2] != 1)) return 1;
bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName());
if (proofVerified == false) return 2;
return 0;
}
function matchBytes32Prefix(bytes32 content, bytes prefix, uint n_random_bytes) internal pure returns (bool){
bool match_ = true;
require(prefix.length == n_random_bytes);
for (uint256 i=0; i< n_random_bytes; i++) {
if (content[i] != prefix[i]) match_ = false;
}
return match_;
}
function oraclize_randomDS_proofVerify__main(bytes proof, bytes32 queryId, bytes result, string context_name) internal returns (bool){
uint ledgerProofLength = 3+65+(uint(proof[3+65+1])+2)+32;
bytes memory keyhash = new bytes(32);
copyBytes(proof, ledgerProofLength, 32, keyhash, 0);
if (!(keccak256(keyhash) == keccak256(abi.encodePacked(sha256(abi.encodePacked(context_name, queryId)))))) return false;
bytes memory sig1 = new bytes(uint(proof[ledgerProofLength+(32+8+1+32)+1])+2);
copyBytes(proof, ledgerProofLength+(32+8+1+32), sig1.length, sig1, 0);
if (!matchBytes32Prefix(sha256(sig1), result, uint(proof[ledgerProofLength+32+8]))) return false;
bytes memory commitmentSlice1 = new bytes(8+1+32);
copyBytes(proof, ledgerProofLength+32, 8+1+32, commitmentSlice1, 0);
bytes memory sessionPubkey = new bytes(64);
uint sig2offset = ledgerProofLength+32+(8+1+32)+sig1.length+65;
copyBytes(proof, sig2offset-64, 64, sessionPubkey, 0);
bytes32 sessionPubkeyHash = sha256(sessionPubkey);
if (oraclize_randomDS_args[queryId] == keccak256(abi.encodePacked(commitmentSlice1, sessionPubkeyHash))){
delete oraclize_randomDS_args[queryId];
} else return false;
bytes memory tosign1 = new bytes(32+8+1+32);
copyBytes(proof, ledgerProofLength, 32+8+1+32, tosign1, 0);
if (!verifySig(sha256(tosign1), sig1, sessionPubkey)) return false;
if (oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash] == false){
oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash] = oraclize_randomDS_proofVerify__sessionKeyValidity(proof, sig2offset);
}
return oraclize_randomDS_sessionKeysHashVerified[sessionPubkeyHash];
}
function copyBytes(bytes from, uint fromOffset, uint length, bytes to, uint toOffset) internal pure returns (bytes) {
uint minLength = length + toOffset;
require(to.length >= minLength);
uint i = 32 + fromOffset;
uint j = 32 + toOffset;
while (i < (32 + fromOffset + length)) {
assembly {
let tmp := mload(add(from, i))
mstore(add(to, j), tmp)
}
i += 32;
j += 32;
}
return to;
}
function safer_ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal returns (bool, address) {
bool ret;
address addr;
assembly {
let size := mload(0x40)
mstore(size, hash)
mstore(add(size, 32), v)
mstore(add(size, 64), r)
mstore(add(size, 96), s)
ret := call(3000, 1, 0, size, 128, size, 32)
addr := mload(size)
}
return (ret, addr);
}
function ecrecovery(bytes32 hash, bytes sig) internal returns (bool, address) {
bytes32 r;
bytes32 s;
uint8 v;
if (sig.length != 65)
return (false, 0);
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
}
if (v < 27)
v += 27;
if (v != 27 && v != 28)
return (false, 0);
return safer_ecrecover(hash, v, r, s);
}
function safeMemoryCleaner() internal pure {
assembly {
let fmem := mload(0x40)
codecopy(fmem, codesize, sub(msize, fmem))
}
}
}
pragma solidity ^0.4.24;
library Roles {
struct Role {
mapping (address => bool) bearer;
}
function add(Role storage role, address account) internal {
require(account != address(0), "add: invalid account address");
require(!has(role, account), "add: account is already added");
role.bearer[account] = true;
}
function remove(Role storage role, address account) internal {
require(account != address(0), "remove: invalid account address");
require(has(role, account), "add: account is not defined");
role.bearer[account] = false;
}
function has(Role storage role, address account) internal view returns (bool) {
require(account != address(0), "has: invalid account address");
return role.bearer[account];
}
}
pragma solidity ^0.4.24;
contract StudServiceAdmin {
using Roles for Roles.Role;
event StudServiceAdminAdded(address indexed account);
event StudServiceAdminRemoved(address indexed account);
Roles.Role private _StudServiceAdmins;
constructor () internal {
_addStudServiceAdmin(msg.sender);
}
modifier onlyStudServiceAdmin() {
require(isStudServiceAdmin(msg.sender));
_;
}
function isStudServiceAdmin(address account) public view returns (bool) {
return _StudServiceAdmins.has(account);
}
function addStudServiceAdmin(address account) public onlyStudServiceAdmin {
_addStudServiceAdmin(account);
}
function renounceStudServiceAdmin() public onlyStudServiceAdmin {
_removeStudServiceAdmin(msg.sender);
}
function _addStudServiceAdmin(address account) internal {
_StudServiceAdmins.add(account);
emit StudServiceAdminAdded(account);
}
function _removeStudServiceAdmin(address account) internal {
_StudServiceAdmins.remove(account);
emit StudServiceAdminRemoved(account);
}
}
pragma solidity ^0.4.24;
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0);
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
pragma solidity ^0.4.24;
contract StudServiceV3 is StudServiceAdmin, usingOraclize {
using SafeMath for uint256;
uint256 private _baseFee;
uint256[] private _horsesInStud;
string private _oraclizeUrl;
ICore private _core;
IBreedTypes private _breedTypes;
struct StudInfo {
bool inStud;
uint256 matingPrice;
uint256 duration;
uint256 studCreatedAt;
}
mapping(uint256 => bool) private _timeframes;
mapping(uint256 => StudInfo) private _studs;
mapping(uint256 => uint256) private _horseIndex;
mapping(uint256 => bool) private _currentlyInStud;
mapping(bytes32 => uint256) private _bloodlineWeights;
mapping(bytes32 => uint256) private _breedTypeWeights;
event HorseInStud(
uint256 horseId,
uint256 matingPrice,
uint256 duration,
uint256 timestamp
);
event HorseDisabledFromStud(uint256 horseId, uint256 timestamp);
event HorseRemovedFromStud(uint256 horseId, uint256 timestamp);
modifier onlyHorseOwner(uint256 horseId) {
require(msg.sender == _core.ownerOf(horseId), "SS notOwnerOfHorse");
_;
}
constructor (ICore core, IBreedTypes breedTypes) public {
_core = core;
_breedTypes = breedTypes;
_bloodlineWeights[bytes32("N")] = 180;
_bloodlineWeights[bytes32("S")] = 120;
_bloodlineWeights[bytes32("F")] = 40;
_bloodlineWeights[bytes32("B")] = 15;
_breedTypeWeights[bytes32("genesis")] = 180;
_breedTypeWeights[bytes32("legendary")] = 150;
_breedTypeWeights[bytes32("exclusive")] = 120;
_breedTypeWeights[bytes32("elite")] = 90;
_breedTypeWeights[bytes32("cross")] = 80;
_breedTypeWeights[bytes32("pacer")] = 60;
_timeframes[86400] = true;
_timeframes[259200] = true;
_timeframes[604800] = true;
_baseFee = 0.05 ether;
_oraclizeUrl = "json(https://api.zed.run/api/v1/remove_horse_stud).horse_id";
}
function() external payable {
}
function putInStud(uint256 horseId, uint256 matingPrice, uint256 duration)
external
payable
onlyHorseOwner(horseId)
{
require(
msg.value >= oraclize_getPrice("URL"),
"SS oraclizePriceNotMet"
);
_putInstud(horseId, matingPrice, duration);
emit HorseInStud(horseId, matingPrice, duration, block.timestamp);
}
function removeFromStud(uint256 horseId) external onlyHorseOwner(horseId) {
require(isHorseInStud(horseId), "SS horseIsNotInStud");
_deleteHorseFromStud(horseId);
emit HorseDisabledFromStud(horseId, block.timestamp);
}
function __callback(bytes32 _id, string _result) public {
require(msg.sender == oraclize_cbAddress(), "SS notOraclize");
uint256 horseId = parseInt(_result);
_disableHorseFromStud(horseId);
emit HorseRemovedFromStud(horseId, block.timestamp);
}
function adminPutInStud(
uint256 horseId,
uint256 matingPrice,
uint256 duration
) external payable onlyStudServiceAdmin {
require(
msg.value >= oraclize_getPrice("URL"),
"SS oraclizePriceNotMet"
);
_putInstud(horseId, matingPrice, duration);
emit HorseInStud(horseId, matingPrice, duration, block.timestamp);
}
function adminRemoveHorseFromstud(uint256 horseId)
external
onlyStudServiceAdmin
{
_disableHorseFromStud(horseId);
emit HorseRemovedFromStud(horseId, block.timestamp);
}
function makeAvailableForStud(uint256 horseId)
external
onlyStudServiceAdmin
{
_currentlyInStud[horseId] = false;
}
function setBreedTypesAddress(IBreedTypes breedTypes)
external
onlyStudServiceAdmin
{
require(
address(breedTypes) != address(0),
"setBreedTypesAddress: invalid breedtypes contract address"
);
_breedTypes = breedTypes;
}
function setCoreAddress(ICore core) external onlyStudServiceAdmin {
require(
address(core) != address(0),
"setCoreAddress: invalid core contract address"
);
_core = core;
}
function setBreedTypeWeight(bytes32 breedType, uint256 weight)
external
onlyStudServiceAdmin
{
_breedTypeWeights[breedType] = weight;
}
function setBloodlineWeight(bytes32 bloodType, uint256 weight)
external
onlyStudServiceAdmin
{
_bloodlineWeights[bloodType] = weight;
}
function setBaseFee(uint256 baseFee) external onlyStudServiceAdmin {
_baseFee = baseFee;
}
function setOraclizeUrl(string newUrl) external onlyStudServiceAdmin {
_oraclizeUrl = newUrl;
}
function addTimeFrame(uint256 secondsFrame) external onlyStudServiceAdmin {
require(secondsFrame > 0, "addTimeFrame: invalid seconds frame");
require(
!_timeframes[secondsFrame],
"addTimeFrame: seconds frame already active"
);
_timeframes[secondsFrame] = true;
}
function removeTimeFrame(uint256 secondsFrame)
external
onlyStudServiceAdmin
{
require(
_timeframes[secondsFrame],
"removeTimeFrame: seconds frame is not found"
);
_timeframes[secondsFrame] = false;
}
function getMinimumBreedPrice(uint256 horseId)
public
view
returns (uint256)
{
bytes32 breedType;
bytes32 breedTypeFromContract = _breedTypes.getBreedType(horseId);
if (breedTypeFromContract == bytes32(0)) {
breedType = bytes32("genesis");
} else {
breedType = breedTypeFromContract;
}
bytes32 bloodline = _core.getBloodline(horseId);
uint256 bloodlineWeight = _bloodlineWeights[bloodline]
.mul(0.80 ether)
.div(100);
uint256 breedWeight = _breedTypeWeights[breedType].mul(0.20 ether).div(
100
);
return bloodlineWeight.add(breedWeight).mul(_baseFee).div(1 ether);
}
function isTimeframeExist(uint256 duration) external view returns (bool) {
return _timeframes[duration];
}
function getStudInfo(uint256 horseId)
external
view
returns (bool, uint256, uint256, uint256)
{
StudInfo memory stud = _studs[horseId];
return (
stud.inStud,
stud.matingPrice,
stud.duration,
stud.studCreatedAt
);
}
function getHorseIndex(uint256 horseId) external view returns (uint256) {
return _horseIndex[horseId];
}
function getBreedTypeWeight(bytes32 breedType)
external
view
returns (uint256)
{
return _breedTypeWeights[breedType];
}
function getBloodLineWeight(bytes32 bloodLine)
external
view
returns (uint256)
{
return _bloodlineWeights[bloodLine];
}
function getQueryPrice() external view returns (uint256) {
return oraclize_getPrice("URL");
}
function getHorsesInStud() external view returns (uint256[]) {
return _horsesInStud;
}
function getMatingPrice(uint256 horseId) external view returns (uint256) {
return _studs[horseId].matingPrice;
}
function getStudTime(uint256 horseId) external view returns (uint256) {
return _studs[horseId].duration;
}
function getOraclizeUrl() external view returns (string) {
return _oraclizeUrl;
}
function getBaseFee() external view returns (uint256) {
return _baseFee;
}
function getCore() external view returns (address) {
return address(_core);
}
function getBreedTypes() external view returns (address) {
return address(_breedTypes);
}
function isHorseInStud(uint256 horseId) public view returns (bool) {
return _studs[horseId].inStud;
}
function isCurentlyInStud(uint256 horseId) external view returns (bool) {
return _currentlyInStud[horseId];
}
function _putInstud(uint256 horseId, uint256 matingPrice, uint256 duration)
private
{
require(_core.exists(horseId), "SS horseDoesNotExist");
require(
bytes32("M") == _core.getHorseSex(horseId),
"SS horseIsNotMale"
);
require(!_currentlyInStud[horseId], "SS horseIsInStud");
uint256 _minimumBreedPrice = getMinimumBreedPrice(horseId);
require(
matingPrice >= _minimumBreedPrice,
"SS matingPriceLowerThanMinimumBreedPrice"
);
uint256 _duration = 86400;
if (_timeframes[duration] || isStudServiceAdmin(msg.sender)) {
_duration = duration;
}
_studs[horseId] = StudInfo(
true,
matingPrice,
_duration,
block.timestamp
);
_horseIndex[horseId] = _horsesInStud.push(horseId) - 1;
_sendOraclizeQuery(_duration, horseId);
_currentlyInStud[horseId] = true;
}
function _sendOraclizeQuery(uint256 duration, uint256 horseId) private {
string memory payload = strConcat("{\"stud_info\":", uint2str(horseId), "}");
oraclize_query(duration, "URL", _oraclizeUrl, payload);
}
function _disableHorseFromStud(uint256 horseId) private {
if (isHorseInStud(horseId)) {
_deleteHorseFromStud(horseId);
}
if (_currentlyInStud[horseId]) {
_currentlyInStud[horseId] = false;
}
}
function _deleteHorseFromStud(uint256 horseId) private {
uint256 index = _horseIndex[horseId];
uint256 lastHorseIndex = _horsesInStud.length - 1;
uint256 lastHorse = _horsesInStud[lastHorseIndex];
_horsesInStud[index] = lastHorse;
_horseIndex[lastHorse] = index;
delete _horsesInStud[lastHorseIndex];
delete _studs[horseId];
_horsesInStud.length--;
}
}