Feature Tip: Add private address tag to any address under My Name Tag !
Contract Overview
More Info
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
View more zero value Internal Transactions in Advanced View mode
Contract Name:
ChainMonstersCore
Compiler Version
v0.4.18+commit.9cf6e910
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2018-02-17
*/
pragma solidity ^0.4.18;
/// @title Interface for contracts conforming to ERC-721: Deed Standard
/// @author William Entriken (https://phor.net), et. al.
/// @dev Specification at https://github.com/ethereum/eips/XXXFinalUrlXXX
interface ERC721 {
// COMPLIANCE WITH ERC-165 (DRAFT) /////////////////////////////////////////
/// @dev ERC-165 (draft) interface signature for itself
// bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7
// bytes4(keccak256('supportsInterface(bytes4)'));
/// @dev ERC-165 (draft) interface signature for ERC721
// bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xda671b9b
// bytes4(keccak256('ownerOf(uint256)')) ^
// bytes4(keccak256('countOfDeeds()')) ^
// bytes4(keccak256('countOfDeedsByOwner(address)')) ^
// bytes4(keccak256('deedOfOwnerByIndex(address,uint256)')) ^
// bytes4(keccak256('approve(address,uint256)')) ^
// bytes4(keccak256('takeOwnership(uint256)'));
/// @notice Query a contract to see if it supports a certain interface
/// @dev Returns `true` the interface is supported and `false` otherwise,
/// returns `true` for INTERFACE_SIGNATURE_ERC165 and
/// INTERFACE_SIGNATURE_ERC721, see ERC-165 for other interface signatures.
function supportsInterface(bytes4 _interfaceID) external pure returns (bool);
// PUBLIC QUERY FUNCTIONS //////////////////////////////////////////////////
/// @notice Find the owner of a deed
/// @param _deedId The identifier for a deed we are inspecting
/// @dev Deeds assigned to zero address are considered invalid, and
/// queries about them do throw.
/// @return The non-zero address of the owner of deed `_deedId`, or `throw`
/// if deed `_deedId` is not tracked by this contract
function ownerOf(uint256 _deedId) external view returns (address _owner);
/// @notice Count deeds tracked by this contract
/// @return A count of valid deeds tracked by this contract, where each one of
/// them has an assigned and queryable owner not equal to the zero address
function countOfDeeds() external view returns (uint256 _count);
/// @notice Count all deeds assigned to an owner
/// @dev Throws if `_owner` is the zero address, representing invalid deeds.
/// @param _owner An address where we are interested in deeds owned by them
/// @return The number of deeds owned by `_owner`, possibly zero
function countOfDeedsByOwner(address _owner) external view returns (uint256 _count);
/// @notice Enumerate deeds assigned to an owner
/// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if
/// `_owner` is the zero address, representing invalid deeds.
/// @param _owner An address where we are interested in deeds owned by them
/// @param _index A counter less than `countOfDeedsByOwner(_owner)`
/// @return The identifier for the `_index`th deed assigned to `_owner`,
/// (sort order not specified)
function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId);
// TRANSFER MECHANISM //////////////////////////////////////////////////////
/// @dev This event emits when ownership of any deed changes by any
/// mechanism. This event emits when deeds are created (`from` == 0) and
/// destroyed (`to` == 0). Exception: during contract creation, any
/// transfers may occur without emitting `Transfer`. At the time of any transfer,
/// the "approved taker" is implicitly reset to the zero address.
event Transfer(address indexed from, address indexed to, uint256 indexed deedId);
/// @dev The Approve event emits to log the "approved taker" for a deed -- whether
/// set for the first time, reaffirmed by setting the same value, or setting to
/// a new value. The "approved taker" is the zero address if nobody can take the
/// deed now or it is an address if that address can call `takeOwnership` to attempt
/// taking the deed. Any change to the "approved taker" for a deed SHALL cause
/// Approve to emit. However, an exception, the Approve event will not emit when
/// Transfer emits, this is because Transfer implicitly denotes the "approved taker"
/// is reset to the zero address.
event Approval(address indexed owner, address indexed approved, uint256 indexed deedId);
/// @notice Set the "approved taker" for your deed, or revoke approval by
/// setting the zero address. You may `approve` any number of times while
/// the deed is assigned to you, only the most recent approval matters. Emits
/// an Approval event.
/// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` ==
/// `msg.sender` or if `_deedId` is not a valid deed.
/// @param _deedId The deed for which you are granting approval
function approve(address _to, uint256 _deedId) external payable;
/// @notice Become owner of a deed for which you are currently approved
/// @dev Throws if `msg.sender` is not approved to become the owner of
/// `deedId` or if `msg.sender` currently owns `_deedId` or if `_deedId is not a
/// valid deed.
/// @param _deedId The deed that is being transferred
function takeOwnership(uint256 _deedId) external payable;
}
contract Ownable {
address public owner;
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == 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 {
if (newOwner != address(0)) {
owner = newOwner;
}
}
}
contract MonsterAccessControl {
event ContractUpgrade(address newContract);
// The addresses of the accounts (or contracts) that can execute actions within each roles.
address public adminAddress;
/// @dev Access modifier for CEO-only functionality
modifier onlyAdmin() {
require(msg.sender == adminAddress);
_;
}
}
// This contract stores all data on the blockchain
// only our other contracts can interact with this
// the data here will be valid for all eternity even if other contracts get updated
// this way we can make sure that our Monsters have a hard-coded value attached to them
// that no one including us can change(!)
contract MonstersData {
address coreContract;
struct Monster {
// timestamp of block when this monster was spawned/created
uint64 birthTime;
// generation number
// gen0 is the very first generation - the later monster spawn the less likely they are to have
// special attributes and stats
uint16 generation;
uint16 mID; // this id (from 1 to 151) is responsible for everything visually like showing the real deal!
bool tradeable;
// breeding
bool female;
// is this monster exceptionally rare?
bool shiny;
}
// lv1 base stats
struct MonsterBaseStats {
uint16 hp;
uint16 attack;
uint16 defense;
uint16 spAttack;
uint16 spDefense;
uint16 speed;
}
struct Trainer {
// timestamp of block when this player/trainer was created
uint64 birthTime;
// add username
string username;
// current area in the "world"
uint16 currArea;
address owner;
}
// take timestamp of block this game was created on the blockchain
uint64 creationBlock = uint64(now);
}
contract MonstersBase is MonsterAccessControl, MonstersData {
/// @dev Transfer event as defined in current draft of ERC721. Emitted every time a monster
/// ownership is assigned, including births.
event Transfer(address from, address to, uint256 tokenId);
bool lockedMonsterCreator = false;
MonsterAuction public monsterAuction;
MonsterCreatorInterface public monsterCreator;
function setMonsterCreatorAddress(address _address) external onlyAdmin {
// only set this once so we (the devs) can't cheat!
require(!lockedMonsterCreator);
MonsterCreatorInterface candidateContract = MonsterCreatorInterface(_address);
monsterCreator = candidateContract;
lockedMonsterCreator = true;
}
// An approximation of currently how many seconds are in between blocks.
uint256 public secondsPerBlock = 15;
// array containing all monsters in existence
Monster[] monsters;
uint8[] areas;
uint8 areaIndex = 0;
mapping(address => Trainer) public addressToTrainer;
/// @dev A mapping from monster IDs to the address that owns them. All monster have
/// some valid owner address, even gen0 monster are created with a non-zero owner.
mapping (uint256 => address) public monsterIndexToOwner;
// @dev A mapping from owner address to count of tokens that address owns.
// Used internally inside balanceOf() to resolve ownership count.
mapping (address => uint256) ownershipTokenCount;
mapping (uint256 => address) public monsterIndexToApproved;
mapping (uint256 => string) public monsterIdToNickname;
mapping (uint256 => bool) public monsterIdToTradeable;
mapping (uint256 => uint256) public monsterIdToGeneration;
mapping (uint256 => uint8[7]) public monsterIdToIVs;
// adds new area to world
function _createArea() internal {
areaIndex++;
areas.push(areaIndex);
}
function _createMonster(uint256 _generation, address _owner, uint256 _mID, bool _tradeable,
bool _female, bool _shiny) internal returns (uint)
{
Monster memory _monster = Monster({
generation: uint16(_generation),
birthTime: uint64(now),
mID: uint16(_mID),
tradeable: _tradeable,
female: _female,
shiny: _shiny
});
uint256 newMonsterId = monsters.push(_monster) - 1;
require(newMonsterId == uint256(uint32(newMonsterId)));
monsterIdToNickname[newMonsterId] = "";
_transfer(0, _owner, newMonsterId);
return newMonsterId;
}
function _createTrainer(string _username, uint16 _starterId, address _owner) internal returns (uint mon) {
Trainer memory _trainer = Trainer({
birthTime: uint64(now),
username: string(_username),
// sets to first area!,
currArea: uint16(1),
owner: address(_owner)
});
addressToTrainer[_owner] = _trainer;
bool gender = monsterCreator.getMonsterGender();
// starters cannot be traded and are not shiny
if (_starterId == 1) {
mon = _createMonster(0, _owner, 1, false, gender, false);
} else if (_starterId == 2) {
mon = _createMonster(0, _owner, 4, false, gender, false);
} else if (_starterId == 3) {
mon = _createMonster(0, _owner, 7, false, gender, false);
}
}
function _moveToArea(uint16 _newArea, address player) internal {
addressToTrainer[player].currArea = _newArea;
}
// assigns ownership of monster to address
function _transfer(address _from, address _to, uint256 _tokenId) internal {
ownershipTokenCount[_to]++;
monsterIndexToOwner[_tokenId] = _to;
if (_from != address(0)) {
ownershipTokenCount[_from]--;
// clear any previously approved ownership exchange
delete monsterIndexToApproved[_tokenId];
}
// Emit Transfer event
Transfer(_from, _to, _tokenId);
}
// Only admin can fix how many seconds per blocks are currently observed.
function setSecondsPerBlock(uint256 secs) external onlyAdmin {
//require(secs < cooldowns[0]);
secondsPerBlock = secs;
}
}
contract MonsterOwnership is MonstersBase, ERC721 {
function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
return monsterIndexToOwner[_tokenId] == _claimant;
}
function _isTradeable(uint256 _tokenId) public view returns (bool) {
return monsterIdToTradeable[_tokenId];
}
/// @dev Checks if a given address currently has transferApproval for a particular monster.
/// @param _claimant the address we are confirming monster is approved for.
/// @param _tokenId monster id, only valid when > 0
function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) {
return monsterIndexToApproved[_tokenId] == _claimant;
}
function balanceOf(address _owner) public view returns (uint256 count) {
return ownershipTokenCount[_owner];
}
function transfer(address _to, uint256 _tokenId) public payable {
transferFrom(msg.sender, _to, _tokenId);
}
function transferFrom(address _from, address _to, uint256 _tokenId) public payable {
require(monsterIdToTradeable[_tokenId]);
// Safety check to prevent against an unexpected 0x0 default.
require(_to != address(0));
// Disallow transfers to this contract to prevent accidental misuse.
// The contract should never own any monsters (except very briefly
// after a gen0 monster is created and before it goes on auction).
require(_to != address(this));
// Check for approval and valid ownership
require(_owns(_from, _tokenId));
// checks if _to was aproved
require(_from == msg.sender || msg.sender == address(monsterAuction) || _approvedFor(_to, _tokenId));
// Reassign ownership (also clears pending approvals and emits Transfer event).
_transfer(_from, _to, _tokenId);
}
function totalSupply() public view returns (uint) {
return monsters.length;
}
function tokensOfOwner(address _owner) public view returns (uint256[] ownerTokens) {
uint256 tokenCount = balanceOf(_owner);
if (tokenCount > 0) {
uint256[] memory result = new uint256[](tokenCount);
uint256 totalMonsters = totalSupply();
uint256 resultIndex = 0;
uint256 monsterId;
for (monsterId = 0; monsterId <= totalMonsters; monsterId++) {
if (monsterIndexToOwner[monsterId] == _owner) {
result[resultIndex] = monsterId;
resultIndex++;
}
}
return result;
}
return new uint256[](0);
}
bytes4 internal constant INTERFACE_SIGNATURE_ERC165 =
bytes4(keccak256("supportsInterface(bytes4)"));
bytes4 internal constant INTERFACE_SIGNATURE_ERC721 =
bytes4(keccak256("ownerOf(uint256)")) ^
bytes4(keccak256("countOfDeeds()")) ^
bytes4(keccak256("countOfDeedsByOwner(address)")) ^
bytes4(keccak256("deedOfOwnerByIndex(address,uint256)")) ^
bytes4(keccak256("approve(address,uint256)")) ^
bytes4(keccak256("takeOwnership(uint256)"));
function supportsInterface(bytes4 _interfaceID) external pure returns (bool) {
return _interfaceID == INTERFACE_SIGNATURE_ERC165 || _interfaceID == INTERFACE_SIGNATURE_ERC721;
}
function ownerOf(uint256 _deedId) external view returns (address _owner) {
var owner = monsterIndexToOwner[_deedId];
require(owner != address(0));
return owner;
}
function _approve(uint256 _tokenId, address _approved) internal {
monsterIndexToApproved[_tokenId] = _approved;
}
function countOfDeeds() external view returns (uint256 _count) {
return totalSupply();
}
function countOfDeedsByOwner(address _owner) external view returns (uint256 _count) {
var arr = tokensOfOwner(_owner);
return arr.length;
}
function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId) {
return tokensOfOwner(_owner)[_index];
}
function approve(address _to, uint256 _tokenId) external payable {
// Only an owner can grant transfer approval.
require(_owns(msg.sender, _tokenId));
// Register the approval (replacing any previous approval).
monsterIndexToApproved[_tokenId] = _to;
// Emit approval event.
Approval(msg.sender, _to, _tokenId);
}
function takeOwnership(uint256 _deedId) external payable {
transferFrom(this.ownerOf(_deedId), msg.sender, _deedId);
}
}
contract MonsterAuctionBase {
// Reference to contract tracking NFT ownership
MonsterOwnership public nonFungibleContract;
ChainMonstersCore public core;
struct Auction {
// current owner
address seller;
// price in wei
uint256 price;
// time when auction started
uint64 startedAt;
uint256 id;
}
// Cut owner takes on each auction, measured in basis points (1/100 of a percent).
// Values 0-10,000 map to 0%-100%
uint256 public ownerCut;
// Map from token ID to their corresponding auction.
mapping(uint256 => Auction) tokenIdToAuction;
mapping(uint256 => address) public auctionIdToSeller;
mapping (address => uint256) public ownershipAuctionCount;
event AuctionCreated(uint256 tokenId, uint256 price, uint256 uID, address seller);
event AuctionSuccessful(uint256 tokenId, uint256 price, address newOwner, uint256 uID);
event AuctionCancelled(uint256 tokenId, uint256 uID);
function _transfer(address _receiver, uint256 _tokenId) internal {
// it will throw if transfer fails
nonFungibleContract.transfer(_receiver, _tokenId);
}
function _addAuction(uint256 _tokenId, Auction _auction) internal {
tokenIdToAuction[_tokenId] = _auction;
AuctionCreated(
uint256(_tokenId),
uint256(_auction.price),
uint256(_auction.id),
address(_auction.seller)
);
}
function _cancelAuction(uint256 _tokenId, address _seller) internal {
Auction storage _auction = tokenIdToAuction[_tokenId];
uint256 uID = _auction.id;
_removeAuction(_tokenId);
ownershipAuctionCount[_seller]--;
_transfer(_seller, _tokenId);
AuctionCancelled(_tokenId, uID);
}
function _buy(uint256 _tokenId, uint256 _bidAmount) internal returns (uint256) {
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
uint256 price = auction.price;
require(_bidAmount >= price);
address seller = auction.seller;
uint256 uID = auction.id;
// Auction Bid looks fine! so remove
_removeAuction(_tokenId);
ownershipAuctionCount[seller]--;
if (price > 0) {
uint256 auctioneerCut = _computeCut(price);
uint256 sellerProceeds = price - auctioneerCut;
// NOTE: Doing a transfer() in the middle of a complex
// method like this is generally discouraged because of
// reentrancy attacks and DoS attacks if the seller is
// a contract with an invalid fallback function. We explicitly
// guard against reentrancy attacks by removing the auction
// before calling transfer(), and the only thing the seller
// can DoS is the sale of their own asset! (And if it's an
// accident, they can call cancelAuction(). )
if (seller != address(core)) {
seller.transfer(sellerProceeds);
}
}
// Calculate any excess funds included with the bid. If the excess
// is anything worth worrying about, transfer it back to bidder.
// NOTE: We checked above that the bid amount is greater than or
// equal to the price so this cannot underflow.
uint256 bidExcess = _bidAmount - price;
// Return the funds. Similar to the previous transfer, this is
// not susceptible to a re-entry attack because the auction is
// removed before any transfers occur.
msg.sender.transfer(bidExcess);
// Tell the world!
AuctionSuccessful(_tokenId, price, msg.sender, uID);
return price;
}
function _removeAuction(uint256 _tokenId) internal {
delete tokenIdToAuction[_tokenId];
}
function _isOnAuction(Auction storage _auction) internal view returns (bool) {
return (_auction.startedAt > 0);
}
function _computeCut(uint256 _price) internal view returns (uint256) {
// NOTE: We don't use SafeMath (or similar) in this function because
// all of our entry functions carefully cap the maximum values for
// currency (at 128-bits), and ownerCut <= 10000 (see the require()
// statement in the ClockAuction constructor). The result of this
// function is always guaranteed to be <= _price.
return _price * ownerCut / 10000;
}
}
contract MonsterAuction is MonsterAuctionBase, Ownable {
bool public isMonsterAuction = true;
uint256 public auctionIndex = 0;
function MonsterAuction(address _nftAddress, uint256 _cut) public {
require(_cut <= 10000);
ownerCut = _cut;
var candidateContract = MonsterOwnership(_nftAddress);
nonFungibleContract = candidateContract;
ChainMonstersCore candidateCoreContract = ChainMonstersCore(_nftAddress);
core = candidateCoreContract;
}
// only possible to decrease ownerCut!
function setOwnerCut(uint256 _cut) external onlyOwner {
require(_cut <= ownerCut);
ownerCut = _cut;
}
function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
return (nonFungibleContract.ownerOf(_tokenId) == _claimant);
}
function _escrow(address _owner, uint256 _tokenId) internal {
// it will throw if transfer fails
nonFungibleContract.transferFrom(_owner, this, _tokenId);
}
function withdrawBalance() external onlyOwner {
uint256 balance = this.balance;
owner.transfer(balance);
}
function tokensInAuctionsOfOwner(address _owner) external view returns(uint256[] auctionTokens) {
uint256 numAuctions = ownershipAuctionCount[_owner];
uint256[] memory result = new uint256[](numAuctions);
uint256 totalAuctions = core.totalSupply();
uint256 resultIndex = 0;
uint256 auctionId;
for (auctionId = 0; auctionId <= totalAuctions; auctionId++) {
Auction storage auction = tokenIdToAuction[auctionId];
if (auction.seller == _owner) {
result[resultIndex] = auctionId;
resultIndex++;
}
}
return result;
}
function createAuction(uint256 _tokenId, uint256 _price, address _seller) external {
require(_seller != address(0));
require(_price == uint256(_price));
require(core._isTradeable(_tokenId));
require(_owns(msg.sender, _tokenId));
_escrow(msg.sender, _tokenId);
Auction memory auction = Auction(
_seller,
uint256(_price),
uint64(now),
uint256(auctionIndex)
);
auctionIdToSeller[auctionIndex] = _seller;
ownershipAuctionCount[_seller]++;
auctionIndex++;
_addAuction(_tokenId, auction);
}
function buy(uint256 _tokenId) external payable {
//delete auctionIdToSeller[_tokenId];
// buy will throw if the bid or funds transfer fails
_buy (_tokenId, msg.value);
_transfer(msg.sender, _tokenId);
}
function cancelAuction(uint256 _tokenId) external {
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
address seller = auction.seller;
require(msg.sender == seller);
_cancelAuction(_tokenId, seller);
}
function getAuction(uint256 _tokenId) external view returns (address seller, uint256 price, uint256 startedAt) {
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
return (
auction.seller,
auction.price,
auction.startedAt
);
}
function getPrice(uint256 _tokenId) external view returns (uint256) {
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
return auction.price;
}
}
contract ChainMonstersAuction is MonsterOwnership {
bool lockedMonsterAuction = false;
function setMonsterAuctionAddress(address _address) external onlyAdmin {
require(!lockedMonsterAuction);
MonsterAuction candidateContract = MonsterAuction(_address);
require(candidateContract.isMonsterAuction());
monsterAuction = candidateContract;
lockedMonsterAuction = true;
}
uint256 public constant PROMO_CREATION_LIMIT = 5000;
uint256 public constant GEN0_CREATION_LIMIT = 5000;
// Counts the number of monster the contract owner has created.
uint256 public promoCreatedCount;
uint256 public gen0CreatedCount;
// its stats are completely dependent on the spawn alghorithm
function createPromoMonster(uint256 _mId, address _owner) external onlyAdmin {
// during generation we have to keep in mind that we have only 10,000 tokens available
// which have to be divided by 151 monsters, some rarer than others
// see WhitePaper for gen0/promo monster plan
// sanity check that this monster ID is actually in game yet
require(monsterCreator.baseStats(_mId, 1) > 0);
require(promoCreatedCount < PROMO_CREATION_LIMIT);
promoCreatedCount++;
uint8[7] memory ivs = uint8[7](monsterCreator.getGen0IVs());
bool gender = monsterCreator.getMonsterGender();
bool shiny = false;
if (ivs[6] == 1) {
shiny = true;
}
uint256 monsterId = _createMonster(0, _owner, _mId, true, gender, shiny);
monsterIdToTradeable[monsterId] = true;
monsterIdToIVs[monsterId] = ivs;
}
function createGen0Auction(uint256 _mId, uint256 price) external onlyAdmin {
// sanity check that this monster ID is actually in game yet
require(monsterCreator.baseStats(_mId, 1) > 0);
require(gen0CreatedCount < GEN0_CREATION_LIMIT);
uint8[7] memory ivs = uint8[7](monsterCreator.getGen0IVs());
bool gender = monsterCreator.getMonsterGender();
bool shiny = false;
if (ivs[6] == 1) {
shiny = true;
}
uint256 monsterId = _createMonster(0, this, _mId, true, gender, shiny);
monsterIdToTradeable[monsterId] = true;
_approve(monsterId, monsterAuction);
monsterIdToIVs[monsterId] = ivs;
monsterAuction.createAuction(monsterId, price, address(this));
gen0CreatedCount++;
}
}
// used during launch for world championship
// can and will be upgraded during development with new battle system!
// this is just to give players something to do and test their monsters
// also demonstrates how we can build up more mechanics on top of our locked core contract!
contract MonsterChampionship is Ownable {
bool public isMonsterChampionship = true;
ChainMonstersCore core;
// list of top ten
address[10] topTen;
// holds the address current "world" champion
address public currChampion;
mapping (address => uint256) public addressToPowerlevel;
mapping (uint256 => address) public rankToAddress;
// try to beat every other player in the top10 with your strongest monster!
// effectively looping through all top10 players, beating them one by one
// and if strong enough placing your in the top10 as well
function contestChampion(uint256 _tokenId) external {
uint maxIndex = 9;
// fail tx if player is already champion!
// in theory players could increase their powerlevel by contesting themselves but
// this check stops that from happening so other players have the chance to
// become the temporary champion!
if (currChampion == msg.sender) {
revert();
}
require(core.isTrainer(msg.sender));
require(core.monsterIndexToOwner(_tokenId) == msg.sender);
uint myPowerlevel = 10; // todo add calculation method to this contract!
// checks if this transaction is useless
// since we can't fight against ourself!
// also stops reentrancy attacks
require(myPowerlevel > addressToPowerlevel[msg.sender]);
uint myRank = 0;
for (uint i = 0; i <= maxIndex; i++) {
if (myPowerlevel > addressToPowerlevel[topTen[i]]) {
// you have beaten this one so increase temporary rank
myRank = i;
if (myRank == maxIndex) {
currChampion = msg.sender;
}
}
}
addressToPowerlevel[msg.sender] = myPowerlevel;
address[10] storage newTopTen = topTen;
if (currChampion == msg.sender) {
for (uint j = 0; j < maxIndex; j++) {
// remove ourselves from this list in case
if (newTopTen[j] == msg.sender) {
newTopTen[j] = 0x0;
break;
}
}
}
for (uint x = 0; x <= myRank; x++) {
if (x == myRank) {
newTopTen[x] = msg.sender;
} else {
if (x < maxIndex)
newTopTen[x] = topTen[x+1];
}
}
topTen = newTopTen;
}
function getTopPlayers() external view returns (address[10] players) {
players = topTen;
}
function MonsterChampionship(address coreContract) public {
core = ChainMonstersCore(coreContract);
}
function withdrawBalance() external onlyOwner {
uint256 balance = this.balance;
owner.transfer(balance);
}
}
// where the not-so-much "hidden" magic happens
contract MonsterCreatorInterface is Ownable {
uint8 public lockedMonsterStatsCount = 0;
uint nonce = 0;
function rand(uint16 min, uint16 max) public returns (uint16) {
nonce++;
uint16 result = (uint16(keccak256(block.blockhash(block.number-1), nonce))%max);
if (result < min) {
result = result+min;
}
return result;
}
mapping(uint256 => uint8[8]) public baseStats;
function addBaseStats(uint256 _mId, uint8[8] data) external onlyOwner {
// lock" the stats down forever
// since hp is never going to be 0 this is a valid check
// so we have to be extra careful when adding new baseStats!
require(data[0] > 0);
require(baseStats[_mId][0] == 0);
baseStats[_mId] = data;
}
function _addBaseStats(uint256 _mId, uint8[8] data) internal {
baseStats[_mId] = data;
lockedMonsterStatsCount++;
}
function MonsterCreatorInterface() public {
// these monsters are already down and "locked" down stats/design wise
_addBaseStats(1, [45, 49, 49, 65, 65, 45, 12, 4]);
_addBaseStats(2, [60, 62, 63, 80, 80, 60, 12, 4]);
_addBaseStats(3, [80, 82, 83, 100, 100, 80, 12, 4]);
_addBaseStats(4, [39, 52, 43, 60, 50, 65, 10, 6]);
_addBaseStats(5, [58, 64, 58, 80, 65, 80, 10, 6]);
_addBaseStats(6, [78, 84, 78, 109, 85, 100, 10, 6]);
_addBaseStats(7, [44, 48, 65, 50, 64, 43, 11, 14]);
_addBaseStats(8, [59, 63, 80, 65, 80, 58, 11, 14]);
_addBaseStats(9, [79, 83, 100, 85, 105, 78, 11, 14]);
_addBaseStats(10, [40, 35, 30, 20, 20, 50, 7, 4]);
_addBaseStats(149, [55, 50, 45, 135, 95, 120, 8, 14]);
_addBaseStats(150, [91, 134, 95, 100, 100, 80, 2, 5]);
_addBaseStats(151, [100, 100, 100, 100, 100, 100, 5, 19]);
}
// this serves as a lookup for new monsters to be generated since all monsters
// of the same id share the base stats
// also makes it possible to only store the monsterId on core and change this one
// during evolution process to save gas and additional transactions
function getMonsterStats( uint256 _mID) external constant returns(uint8[8] stats) {
stats[0] = baseStats[_mID][0];
stats[1] = baseStats[_mID][1];
stats[2] = baseStats[_mID][2];
stats[3] = baseStats[_mID][3];
stats[4] = baseStats[_mID][4];
stats[5] = baseStats[_mID][5];
stats[6] = baseStats[_mID][6];
stats[7] = baseStats[_mID][7];
}
function getMonsterGender () external returns(bool female) {
uint16 femaleChance = rand(0, 100);
if (femaleChance >= 50) {
female = true;
}
}
// generates randomized IVs for a new monster
function getMonsterIVs() external returns(uint8[7] ivs) {
bool shiny = false;
uint16 chance = rand(1, 8192);
if (chance == 42) {
shiny = true;
}
// IVs range between 0 and 31
// stat range modified for shiny monsters!
if (shiny) {
ivs[0] = uint8(rand(10, 31));
ivs[1] = uint8(rand(10, 31));
ivs[2] = uint8(rand(10, 31));
ivs[3] = uint8(rand(10, 31));
ivs[4] = uint8(rand(10, 31));
ivs[5] = uint8(rand(10, 31));
ivs[6] = 1;
} else {
ivs[0] = uint8(rand(0, 31));
ivs[1] = uint8(rand(0, 31));
ivs[2] = uint8(rand(0, 31));
ivs[3] = uint8(rand(0, 31));
ivs[4] = uint8(rand(0, 31));
ivs[5] = uint8(rand(0, 31));
ivs[6] = 0;
}
}
// gen0 monsters profit from shiny boost while shiny gen0s have potentially even higher IVs!
// further increasing the rarity by also doubling the shiny chance!
function getGen0IVs() external returns (uint8[7] ivs) {
bool shiny = false;
uint16 chance = rand(1, 4096);
if (chance == 42) {
shiny = true;
}
if (shiny) {
ivs[0] = uint8(rand(15, 31));
ivs[1] = uint8(rand(15, 31));
ivs[2] = uint8(rand(15, 31));
ivs[3] = uint8(rand(15, 31));
ivs[4] = uint8(rand(15, 31));
ivs[5] = uint8(rand(15, 31));
ivs[6] = 1;
} else {
ivs[0] = uint8(rand(10, 31));
ivs[1] = uint8(rand(10, 31));
ivs[2] = uint8(rand(10, 31));
ivs[3] = uint8(rand(10, 31));
ivs[4] = uint8(rand(10, 31));
ivs[5] = uint8(rand(10, 31));
ivs[6] = 0;
}
}
function withdrawBalance() external onlyOwner {
uint256 balance = this.balance;
owner.transfer(balance);
}
}
contract GameLogicContract {
bool public isGameLogicContract = true;
function GameLogicContract() public {
}
}
contract OmegaContract {
bool public isOmegaContract = true;
function OmegaContract() public {
}
}
contract ChainMonstersCore is ChainMonstersAuction, Ownable {
// using a bool to enable us to prepare the game
bool hasLaunched = false;
// this address will hold future gamelogic in place
address gameContract;
// this contract
address omegaContract;
function ChainMonstersCore() public {
adminAddress = msg.sender;
_createArea(); // area 1
_createArea(); // area 2
}
// we don't know the exact interfaces yet so use the lockedMonsterStats value to determine if the game is "ready"
// see WhitePaper for explaination for our upgrade and development roadmap
function setGameLogicContract(address _candidateContract) external onlyOwner {
require(monsterCreator.lockedMonsterStatsCount() == 151);
require(GameLogicContract(_candidateContract).isGameLogicContract());
gameContract = _candidateContract;
}
function setOmegaContract(address _candidateContract) external onlyOwner {
require(OmegaContract(_candidateContract).isOmegaContract());
omegaContract = _candidateContract;
}
// omega contract takes care of all neccessary checks so assume that this is correct(!)
function evolveMonster(uint256 _tokenId, uint16 _toMonsterId) external {
require(msg.sender == omegaContract);
// retrieve current monster struct
Monster storage mon = monsters[_tokenId];
// evolving only changes monster ID since this is responsible for base Stats
// an evolved monster keeps its gender, generation, IVs and EVs
mon.mID = _toMonsterId;
}
// only callable by gameContract after the full game is launched
// since all additional monsters after the promo/gen0 ones need to use this coreContract
// contract as well we have to prepare this core for our future updates where
// players can freely roam the world and hunt ChainMonsters thus generating more
function spawnMonster(uint256 _mId, address _owner) external {
require(msg.sender == gameContract);
uint8[7] memory ivs = uint8[7](monsterCreator.getMonsterIVs());
bool gender = monsterCreator.getMonsterGender();
bool shiny = false;
if (ivs[6] == 1) {
shiny = true;
}
// important to note that the IV generators do not use Gen0 methods and are Generation 1
// this means there won't be more than the 10,000 Gen0 monsters sold during the development through the marketplace
uint256 monsterId = _createMonster(1, _owner, _mId, false, gender, shiny);
monsterIdToTradeable[monsterId] = true;
monsterIdToIVs[monsterId] = ivs;
}
// used to add playable content to the game
// monsters will only spawn in certain areas so some are locked on release
// due to the game being in active development on "launch"
// each monster has a maximum number of 3 areas where it can appear
function createArea() public onlyAdmin {
_createArea();
}
function createTrainer(string _username, uint16 _starterId) public {
require(hasLaunched);
// only one trainer/account per ethereum address
require(addressToTrainer[msg.sender].owner == 0);
// valid input check
require(_starterId == 1 || _starterId == 2 || _starterId == 3);
uint256 mon = _createTrainer(_username, _starterId, msg.sender);
// due to stack limitations we have to assign the IVs here:
monsterIdToIVs[mon] = monsterCreator.getMonsterIVs();
}
function changeUsername(string _name) public {
require(addressToTrainer[msg.sender].owner == msg.sender);
addressToTrainer[msg.sender].username = _name;
}
function changeMonsterNickname(uint256 _tokenId, string _name) public {
// users won't be able to rename a monster that is part of an auction
require(_owns(msg.sender, _tokenId));
// some string checks...?
monsterIdToNickname[_tokenId] = _name;
}
function moveToArea(uint16 _newArea) public {
require(addressToTrainer[msg.sender].currArea > 0);
// never allow anyone to move to area 0 or below since this is used
// to determine if a trainer profile exists in another method!
require(_newArea > 0);
// make sure that this area exists yet!
require(areas.length >= _newArea);
// when player is not stuck doing something else he can move freely!
_moveToArea(_newArea, msg.sender);
}
// to be changed to retrieve current stats!
function getMonster(uint256 _id) external view returns (
uint256 birthTime, uint256 generation, uint8[8] stats,
uint256 mID, bool tradeable, uint256 uID)
{
Monster storage mon = monsters[_id];
birthTime = uint256(mon.birthTime);
generation = mon.generation; // hardcoding due to stack too deep error
mID = uint256(mon.mID);
tradeable = bool(mon.tradeable);
// these values are retrieved from monsterCreator
stats = uint8[8](monsterCreator.getMonsterStats(uint256(mon.mID)));
// hack to overcome solidity's stack limitation in monster struct....
uID = _id;
}
function isTrainer(address _check) external view returns (bool isTrainer) {
Trainer storage trainer = addressToTrainer[_check];
return (trainer.currArea > 0);
}
function withdrawBalance() external onlyOwner {
uint256 balance = this.balance;
owner.transfer(balance);
}
// after we have setup everything we can unlock the game
// for public
function launchGame() external onlyOwner {
hasLaunched = true;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"promoCreatedCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"createArea","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_newArea","type":"uint16"}],"name":"moveToArea","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"launchGame","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_name","type":"string"}],"name":"changeMonsterNickname","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"_isTradeable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"monsterIdToNickname","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_check","type":"address"}],"name":"isTrainer","outputs":[{"name":"isTrainer","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"deedOfOwnerByIndex","outputs":[{"name":"_deedId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"secs","type":"uint256"}],"name":"setSecondsPerBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getMonster","outputs":[{"name":"birthTime","type":"uint256"},{"name":"generation","type":"uint256"},{"name":"stats","type":"uint8[8]"},{"name":"mID","type":"uint256"},{"name":"tradeable","type":"bool"},{"name":"uID","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_deedId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"_owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"GEN0_CREATION_LIMIT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"count","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_toMonsterId","type":"uint16"}],"name":"evolveMonster","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"changeUsername","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"secondsPerBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"monsterIndexToApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"name":"monsterIdToIVs","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"ownerTokens","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_mId","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createPromoMonster","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"countOfDeedsByOwner","outputs":[{"name":"_count","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"monsterIdToTradeable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_candidateContract","type":"address"}],"name":"setGameLogicContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_username","type":"string"},{"name":"_starterId","type":"uint16"}],"name":"createTrainer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transfer","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"monsterIndexToOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"monsterCreator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_deedId","type":"uint256"}],"name":"takeOwnership","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"monsterAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_candidateContract","type":"address"}],"name":"setOmegaContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setMonsterAuctionAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"countOfDeeds","outputs":[{"name":"_count","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PROMO_CREATION_LIMIT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setMonsterCreatorAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"addressToTrainer","outputs":[{"name":"birthTime","type":"uint64"},{"name":"username","type":"string"},{"name":"currArea","type":"uint16"},{"name":"owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_mId","type":"uint256"},{"name":"_owner","type":"address"}],"name":"spawnMonster","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"monsterIdToGeneration","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gen0CreatedCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"adminAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_mId","type":"uint256"},{"name":"price","type":"uint256"}],"name":"createGen0Auction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"deedId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"deedId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newContract","type":"address"}],"name":"ContractUpgrade","type":"event"}]Contract Creation Code
60606040526001805460a060020a60e060020a031916740100000000000000000000000000000000000000004267ffffffffffffffff16021760e060020a60ff0219169055600f6004556007805460ff199081169091556010805490911690556013805460a060020a60ff021916905534156200007b57600080fd5b60138054600160a060020a033316600160a060020a03199182168117909255600080549091169091179055620000be64010000000062001e3c620000dc82021704565b620000d664010000000062001e3c620000dc82021704565b6200019d565b6007805460ff198116600160ff92831681019092161790915560068054909181016200010983826200013d565b5060009182526020918290206007548383049091018054939092066101000a60ff9182168102910219909216919091179055565b8154818355818115116200017457601f016020900481601f0160209004836000526020600020918201910162000174919062000179565b505050565b6200019a91905b8082111562000196576000815560010162000180565b5090565b90565b61262b80620001ad6000396000f30060606040526004361061022c5763ffffffff60e060020a60003504166301ffc9a7811461023157806305e455461461027d578063095ea7b3146102a257806316754c55146102bb57806318160ddd146102ce57806323b872dd146102e157806325c70a44146102fe578063295f6ce7146103185780633aac76611461032b5780634c8bae93146103815780634d0470551461039757806350beca781461042457806353270910146104435780635663896e146104655780635fd8c7101461047b57806362fb6fe11461048e5780636352211e14610505578063680eba271461053757806370a082311461054a57806375872a5a1461056957806377c846af146105865780637a7d4937146105d75780637d55aeea146105ea57806380eb1cbc146106005780638462151c1461062f5780638b56aff8146106a15780638da5cb5b146106c357806392efd277146106d6578063975dfff9146106f557806397fce1bb1461070b5780639b1323921461072a578063a9059cbb14610781578063ad4b558c14610798578063addb51ff146107ae578063b2e6ceeb146107c1578063b43c19a6146107cc578063bba45738146107df578063bfbbd489146107fe578063c34588ba1461081d578063defb958414610537578063e66c66d914610830578063e7127e291461084f578063e95015b914610922578063eb6c4bc814610944578063f1ca94101461095a578063f2fde38b1461096d578063fc6f94681461098c578063fd01249c1461099f575b600080fd5b341561023c57600080fd5b6102697fffffffff00000000000000000000000000000000000000000000000000000000600435166109b8565b604051901515815260200160405180910390f35b341561028857600080fd5b610290610b75565b60405190815260200160405180910390f35b6102b9600160a060020a0360043516602435610b7b565b005b34156102c657600080fd5b6102b9610bf3565b34156102d957600080fd5b610290610c18565b6102b9600160a060020a0360043581169060243516604435610c1f565b341561030957600080fd5b6102b961ffff60043516610ce0565b341561032357600080fd5b6102b9610d3c565b341561033657600080fd5b6102b9600480359060446024803590810190830135806020601f82018190048102016040519081016040528181529291906020840183838082843750949650610d8e95505050505050565b341561038c57600080fd5b610269600435610dc2565b34156103a257600080fd5b6103ad600435610dd7565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156103e95780820151838201526020016103d1565b50505050905090810190601f1680156104165780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561042f57600080fd5b610269600160a060020a0360043516610e87565b341561044e57600080fd5b610290600160a060020a0360043516602435610eaa565b341561047057600080fd5b6102b9600435610ed1565b341561048657600080fd5b6102b9610ef1565b341561049957600080fd5b6104a4600435610f48565b60405186815260208101869052604081018561010080838360005b838110156104d75780820151838201526020016104bf565b5050505090500184815260200183151515158152602001828152602001965050505050505060405180910390f35b341561051057600080fd5b61051b60043561103f565b604051600160a060020a03909116815260200160405180910390f35b341561054257600080fd5b610290611063565b341561055557600080fd5b610290600160a060020a0360043516611069565b341561057457600080fd5b6102b960043561ffff60243516611084565b341561059157600080fd5b6102b960046024813581810190830135806020601f820181900481020160405190810160405281815292919060208401838380828437509496506110ec95505050505050565b34156105e257600080fd5b61029061114c565b34156105f557600080fd5b61051b600435611152565b341561060b57600080fd5b61061960043560243561116d565b60405160ff909116815260200160405180910390f35b341561063a57600080fd5b61064e600160a060020a03600435166111a3565b60405160208082528190810183818151815260200191508051906020019060200280838360005b8381101561068d578082015183820152602001610675565b505050509050019250505060405180910390f35b34156106ac57600080fd5b6102b9600435600160a060020a0360243516611286565b34156106ce57600080fd5b61051b611482565b34156106e157600080fd5b610290600160a060020a0360043516611491565b341561070057600080fd5b6102696004356114af565b341561071657600080fd5b6102b9600160a060020a03600435166114c4565b341561073557600080fd5b6102b960046024813581810190830135806020601f820181900481020160405190810160405281815292919060208401838380828437509496505050923561ffff1692506115e1915050565b6102b9600160a060020a03600435166024356116fe565b34156107a357600080fd5b61051b600435611709565b34156107b957600080fd5b61051b611724565b6102b9600435611733565b34156107d757600080fd5b61051b6117a7565b34156107ea57600080fd5b6102b9600160a060020a03600435166117b6565b341561080957600080fd5b6102b9600160a060020a036004351661185f565b341561082857600080fd5b610290611929565b341561083b57600080fd5b6102b9600160a060020a0360043516611938565b341561085a57600080fd5b61086e600160a060020a03600435166119bd565b60405167ffffffffffffffff8516815261ffff83166040820152600160a060020a03821660608201526080602082018181528554600260001961010060018416150201909116049183018290529060a0830190869080156109105780601f106108e557610100808354040283529160200191610910565b820191906000526020600020905b8154815290600101906020018083116108f357829003601f168201915b50509550505050505060405180910390f35b341561092d57600080fd5b6102b9600435600160a060020a03602435166119fb565b341561094f57600080fd5b610290600435611b20565b341561096557600080fd5b610290611b32565b341561097857600080fd5b6102b9600160a060020a0360043516611b38565b341561099757600080fd5b61051b611b82565b34156109aa57600080fd5b6102b9600435602435611b91565b60006040517f737570706f727473496e7465726661636528627974657334290000000000000081526019016040518091039020600160e060020a03191682600160e060020a0319161480610b6f57506040517f74616b654f776e6572736869702875696e743235362900000000000000000000815260160160405180910390206040517f617070726f766528616464726573732c75696e74323536290000000000000000815260180160405180910390206040517f646565644f664f776e65724279496e64657828616464726573732c75696e743281527f3536290000000000000000000000000000000000000000000000000000000000602082015260230160405180910390206040517f636f756e744f66446565647342794f776e6572286164647265737329000000008152601c0160405180910390206040517f636f756e744f66446565647328290000000000000000000000000000000000008152600e0160405180910390206040517f6f776e65724f662875696e743235362900000000000000000000000000000000815260100160405180910390201818181818600160e060020a03191682600160e060020a031916145b92915050565b60115481565b610b853382611e1c565b1515610b9057600080fd5b6000818152600b6020526040908190208054600160a060020a031916600160a060020a03858116918217909255839290913316907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925905160405180910390a45050565b60005433600160a060020a03908116911614610c0e57600080fd5b610c16611e3c565b565b6005545b90565b6000818152600d602052604090205460ff161515610c3c57600080fd5b600160a060020a0382161515610c5157600080fd5b30600160a060020a031682600160a060020a031614151515610c7257600080fd5b610c7c8382611e1c565b1515610c8757600080fd5b33600160a060020a031683600160a060020a03161480610cb5575060025433600160a060020a039081169116145b80610cc55750610cc58282611e9b565b1515610cd057600080fd5b610cdb838383611ebb565b505050565b600160a060020a03331660009081526008602052604081206002015461ffff1611610d0a57600080fd5b600061ffff821611610d1b57600080fd5b60065461ffff8216901015610d2f57600080fd5b610d398133611f91565b50565b60135433600160a060020a03908116911614610d5757600080fd5b6013805474ff0000000000000000000000000000000000000000191674010000000000000000000000000000000000000000179055565b610d983383611e1c565b1515610da357600080fd5b6000828152600c60205260409020818051610cdb92916020019061237d565b6000908152600d602052604090205460ff1690565b600c6020528060005260406000206000915090508054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e7f5780601f10610e5457610100808354040283529160200191610e7f565b820191906000526020600020905b815481529060010190602001808311610e6257829003601f168201915b505050505081565b600160a060020a031660009081526008602052604081206002015461ffff161190565b6000610eb5836111a3565b8281518110610ec057fe5b906020019060200201519392505050565b60005433600160a060020a03908116911614610eec57600080fd5b600455565b60135460009033600160a060020a03908116911614610f0f57600080fd5b50601354600160a060020a0330811631911681156108fc0282604051600060405180830381858888f193505050501515610d3957600080fd5b600080610f536123fb565b600080600080600588815481101515610f6857fe5b60009182526020822001805460035467ffffffffffffffff82169a5068010000000000000000820461ffff9081169a506a010000000000000000000083041697506c0100000000000000000000000090910460ff169550909250600160a060020a03169063c841df4f908690604051610100015260405160e060020a63ffffffff8416028152600481019190915260240161010060405180830381600087803b151561101357600080fd5b6102c65a03f1151561102457600080fd5b50505060405161010081016040529698959793959294505050565b600081815260096020526040812054600160a060020a0316801515610b6f57600080fd5b61138881565b600160a060020a03166000908152600a602052604090205490565b60155460009033600160a060020a039081169116146110a257600080fd5b60058054849081106110b057fe5b6000918252602090912001805461ffff9093166a0100000000000000000000026bffff0000000000000000000019909316929092179091555050565b600160a060020a033381166000818152600860205260409020600201546201000090049091161461111c57600080fd5b600160a060020a033316600090815260086020526040902060010181805161114892916020019061237d565b5050565b60045481565b600b60205260009081526040902054600160a060020a031681565b600f602052600082815260409020816007811061118657fe5b60209182820401919006915091509054906101000a900460ff1681565b6111ab612424565b60006111b5612424565b60008060006111c387611069565b9450600085111561125957846040518059106111dc5750595b908082528060200260200182016040525093506111f7610c18565b925060009150600090505b82811161125157600081815260096020526040902054600160a060020a0388811691161415611249578084838151811061123857fe5b602090810290910101526001909101905b600101611202565b83955061127c565b60006040518059106112685750595b908082528060200260200182016040525095505b5050505050919050565b61128e612436565b600080548190819033600160a060020a039081169116146112ae57600080fd5b600354600090600160a060020a03166391cee1fd886001846040516020015260405160e060020a63ffffffff851602815260048101929092526024820152604401602060405180830381600087803b151561130857600080fd5b6102c65a03f1151561131957600080fd5b5050506040518051905060ff1611151561133257600080fd5b601154611388901061134357600080fd5b601180546001019055600354600160a060020a031663342ba8de600060405160e001526040518163ffffffff1660e060020a02815260040160e060405180830381600087803b151561139457600080fd5b6102c65a03f115156113a557600080fd5b50505060405160e081016040908152600354919550600160a060020a0390911690636827b9db9060009051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561140257600080fd5b6102c65a03f1151561141357600080fd5b50505060405180519350600092505060c084015160ff166001141561143757600191505b6114476000868860018787611fc1565b6000818152600d60209081526040808320805460ff19166001179055600f909152902090915061147990856007612450565b50505050505050565b601354600160a060020a031681565b600061149b612424565b6114a4836111a3565b905080519392505050565b600d6020526000908152604090205460ff1681565b60135433600160a060020a039081169116146114df57600080fd5b600354600160a060020a0316637afa0c666000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561152757600080fd5b6102c65a03f1151561153857600080fd5b5050506040518051905060ff16609714151561155357600080fd5b80600160a060020a031663b9b7569b6000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561159957600080fd5b6102c65a03f115156115aa57600080fd5b5050506040518051905015156115bf57600080fd5b60148054600160a060020a031916600160a060020a0392909216919091179055565b60135460009074010000000000000000000000000000000000000000900460ff16151561160d57600080fd5b600160a060020a03338116600090815260086020526040902060020154620100009004161561163b57600080fd5b8161ffff166001148061165257508161ffff166002145b8061166157508161ffff166003145b151561166c57600080fd5b61167783833361219c565b600354909150600160a060020a031663a3848b1a600060405160e001526040518163ffffffff1660e060020a02815260040160e060405180830381600087803b15156116c257600080fd5b6102c65a03f115156116d357600080fd5b50505060405160e0810160409081526000838152600f602052206116f8916007612450565b50505050565b611148338383610c1f565b600960205260009081526040902054600160a060020a031681565b600354600160a060020a031681565b610d3930600160a060020a0316636352211e8360006040516020015260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561178557600080fd5b6102c65a03f1151561179657600080fd5b505050604051805190503383610c1f565b600254600160a060020a031681565b60135433600160a060020a039081169116146117d157600080fd5b80600160a060020a031663d8e4ab0d6000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561181757600080fd5b6102c65a03f1151561182857600080fd5b50505060405180519050151561183d57600080fd5b60158054600160a060020a031916600160a060020a0392909216919091179055565b6000805433600160a060020a0390811691161461187b57600080fd5b60105460ff161561188b57600080fd5b5080600160a060020a03811663bfab4f8b6000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156118d357600080fd5b6102c65a03f115156118e457600080fd5b5050506040518051905015156118f957600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055506010805460ff19166001179055565b6000611933610c18565b905090565b6000805433600160a060020a0390811691161461195457600080fd5b60015460e060020a900460ff161561196b57600080fd5b5060038054600160a060020a03909216600160a060020a0319909216919091179055600180547fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a179055565b60086020526000908152604090208054600282015467ffffffffffffffff909116916001019061ffff811690620100009004600160a060020a031684565b611a03612436565b6014546000908190819033600160a060020a03908116911614611a2557600080fd5b600354600160a060020a031663a3848b1a600060405160e001526040518163ffffffff1660e060020a02815260040160e060405180830381600087803b1515611a6d57600080fd5b6102c65a03f11515611a7e57600080fd5b50505060405160e081016040908152600354919550600160a060020a0390911690636827b9db9060009051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611adb57600080fd5b6102c65a03f11515611aec57600080fd5b50505060405180519350600092505060c084015160ff1660011415611b1057600191505b6114476001868860008787611fc1565b600e6020526000908152604090205481565b60125481565b60135433600160a060020a03908116911614611b5357600080fd5b600160a060020a03811615610d395760138054600160a060020a038316600160a060020a031990911617905550565b600054600160a060020a031681565b611b99612436565b600080548190819033600160a060020a03908116911614611bb957600080fd5b600354600090600160a060020a03166391cee1fd886001846040516020015260405160e060020a63ffffffff851602815260048101929092526024820152604401602060405180830381600087803b1515611c1357600080fd5b6102c65a03f11515611c2457600080fd5b5050506040518051905060ff16111515611c3d57600080fd5b6012546113889010611c4e57600080fd5b600354600160a060020a031663342ba8de600060405160e001526040518163ffffffff1660e060020a02815260040160e060405180830381600087803b1515611c9657600080fd5b6102c65a03f11515611ca757600080fd5b50505060405160e081016040908152600354919550600160a060020a0390911690636827b9db9060009051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515611d0457600080fd5b6102c65a03f11515611d1557600080fd5b50505060405180519350600092505060c084015160ff1660011415611d3957600191505b611d496000308860018787611fc1565b6000818152600d60205260409020805460ff19166001179055600254909150611d7c908290600160a060020a031661234f565b6000818152600f60205260409020611d9690856007612450565b50600254600160a060020a03166354279bdd82873060405160e060020a63ffffffff861602815260048101939093526024830191909152600160a060020a03166044820152606401600060405180830381600087803b1515611df757600080fd5b6102c65a03f11515611e0857600080fd5b505060128054600101905550505050505050565b600090815260096020526040902054600160a060020a0391821691161490565b6007805460ff198116600160ff9283168101909216179091556006805490918101611e6783826124df565b5060009182526020918290206007548383049091018054939092066101000a60ff9182168102910219909216919091179055565b6000908152600b6020526040902054600160a060020a0391821691161490565b600160a060020a038083166000818152600a6020908152604080832080546001019055858352600990915290208054600160a060020a0319169091179055831615611f3c57600160a060020a0383166000908152600a602090815260408083208054600019019055838352600b90915290208054600160a060020a03191690555b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef838383604051600160a060020a039384168152919092166020820152604080820192909252606001905180910390a1505050565b600160a060020a03166000908152600860205260409020600201805461ffff191661ffff92909216919091179055565b6000611fcb612513565b600060c0604051908101604052804267ffffffffffffffff1681526020018a61ffff1681526020018861ffff16815260200187151581526020018615158152602001851515815250915060016005805480600101828161202b9190612548565b600092835260209092208591018151815467ffffffffffffffff191667ffffffffffffffff919091161781556020820151815461ffff91909116680100000000000000000269ffff0000000000000000199091161781556040820151815461ffff919091166a0100000000000000000000026bffff0000000000000000000019909116178155606082015181549015156c01000000000000000000000000026cff00000000000000000000000019909116178155608082015181549015156d0100000000000000000000000000026dff000000000000000000000000001990911617815560a082015181549015156e010000000000000000000000000000026eff0000000000000000000000000000199091161790555003905063ffffffff8116811461215757600080fd5b602060405190810160409081526000808352838152600c6020522090805161218392916020019061237d565b5061219060008983611ebb565b98975050505050505050565b60006121a661256c565b60006080604051908101604090815267ffffffffffffffff421682526020808301899052600182840152600160a060020a03871660608401819052600090815260089091522090925082908151815467ffffffffffffffff191667ffffffffffffffff9190911617815560208201518160010190805161222a92916020019061237d565b50604082015160028201805461ffff191661ffff929092169190911790556060820151600291909101805475ffffffffffffffffffffffffffffffffffffffff0000191662010000600160a060020a0393841602179055600354169050636827b9db6000604051602001526040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156122c357600080fd5b6102c65a03f115156122d457600080fd5b5050506040518051915050600161ffff86161415612305576122fe60008560016000856000611fc1565b9250612346565b8461ffff1660021415612324576122fe60008560046000856000611fc1565b8461ffff16600314156123465761234360008560076000856000611fc1565b92505b50509392505050565b6000918252600b60205260409091208054600160a060020a031916600160a060020a03909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106123be57805160ff19168380011785556123eb565b828001600101855582156123eb579182015b828111156123eb5782518255916020019190600101906123d0565b506123f792915061259b565b5090565b6101006040519081016040526008815b60008152600019909101906020018161240b5790505090565b60206040519081016040526000815290565b60e06040519081016040526000815260066020820161240b565b6001830191839082156124d35791602002820160005b838211156124a457835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302612466565b80156124d15782816101000a81549060ff02191690556001016020816000010492830192600103026124a4565b505b506123f79291506125b5565b815481835581811511610cdb57601f016020900481601f01602090048360005260206000209182019101610cdb919061259b565b60c06040519081016040908152600080835260208301819052908201819052606082018190526080820181905260a082015290565b815481835581811511610cdb57600083815260209020610cdb9181019083016125d3565b60806040519081016040526000815260208101612587612424565b815260006020820181905260409091015290565b610c1c91905b808211156123f757600081556001016125a1565b610c1c91905b808211156123f757805460ff191681556001016125bb565b610c1c91905b808211156123f75780546effffffffffffffffffffffffffffff191681556001016125d95600a165627a7a723058207015b50dedfa77ad9ec1e87cc1335efaf532493b54f87dcfa84842ed7e2e4c550029
Swarm Source
bzzr://7015b50dedfa77ad9ec1e87cc1335efaf532493b54f87dcfa84842ed7e2e4c55
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.
Contract






