Gods Unchained Cards
About
Stats
Public Functions
52
Event Types
10
Code Size
79,916 bytes
Events (10) keyboard_arrow_up
Constants (8) keyboard_arrow_up
State Variables (34) keyboard_arrow_up
Functions
getProperty keyboard_arrow_up
getTokenKey keyboard_arrow_up
Source Code
function getTokenKey(uint256 _tokenId, bytes32 _key)
public
pure
returns (bytes32)
{
// one prefix to prevent collisions
return keccak256(abi.encodePacked(uint256(1), _tokenId, _key));
}
getClassKey keyboard_arrow_up
getClassProperty keyboard_arrow_up
balanceOf keyboard_arrow_up
ownerOf keyboard_arrow_up
Source Code
function ownerOf(uint256 tokenId) public view returns (address) {
uint48 uID = ownerIDs[tokenId];
if (uID == 0) {
uint256 start = getBatchStart(tokenId);
Batch memory b = batches[start];
require(start + b.size > tokenId, "BT: token does not exist");
uID = b.userID;
require(uID != 0, "BT: bad batch owner");
}
return userIDToAddress[uID];
}
safeTransferFrom keyboard_arrow_up
Requirements help
Source Code
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public {
safeTransferFrom(from, to, tokenId, "");
}
transferFrom keyboard_arrow_up
Requirements help
Source Code
function transferFrom(
address from,
address to,
uint256 tokenId
) public {
//solhint-disable-next-line max-line-length
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_transferFrom(from, to, tokenId);
}
approve keyboard_arrow_up
Requirements help
Source Code
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(to != owner, "BT: approval to current owner");
require(
msg.sender == owner || isApprovedForAll(owner, msg.sender),
"BT: approve caller is not owner nor approved for all"
);
approvedIDs[tokenId] = _getUserID(to);
emit Approval(owner, to, tokenId);
}
getApproved keyboard_arrow_up
Requirements help
null
Source Code
function getApproved(uint256 tokenId) public view returns (address) {
require(_exists(tokenId), "BT: approved query for nonexistent token");
return userIDToAddress[approvedIDs[tokenId]];
}
setApprovalForAll keyboard_arrow_up
Requirements help
Source Code
function setApprovalForAll(address to, bool approved) public {
require(to != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][to] = approved;
emit ApprovalForAll(_msgSender(), to, approved);
}
isApprovedForAll keyboard_arrow_up
safeTransferFrom keyboard_arrow_up
Requirements help
Source Code
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public {
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_safeTransferFrom(from, to, tokenId, _data);
}
name keyboard_arrow_up
symbol keyboard_arrow_up
tokenURI keyboard_arrow_up
Source Code
function tokenURI(uint256 tokenId) external view returns (string memory) {
return
string(
abi.encodePacked(
baseURI,
String.fromAddress(address(this)),
"/",
String.fromUint(tokenId)
)
);
}
supportsInterface keyboard_arrow_up
getBatchStart keyboard_arrow_up
getBatch keyboard_arrow_up
totalSupply keyboard_arrow_up
transferBatch keyboard_arrow_up
Source Code
function transferBatch(
address from,
address to,
uint256 start,
uint256 end
) public {
for (uint256 i = start; i < end; i++) {
transferFrom(from, to, i);
}
}
transferAllFrom keyboard_arrow_up
Source Code
function transferAllFrom(
address from,
address to,
uint256[] memory tokenIDs
) public {
for (uint256 i = 0; i < tokenIDs.length; i++) {
transferFrom(from, to, tokenIDs[i]);
}
}
safeTransferBatch keyboard_arrow_up
Source Code
function safeTransferBatch(
address from,
address to,
uint256 start,
uint256 end
) public {
for (uint256 i = start; i < end; i++) {
safeTransferFrom(from, to, i);
}
}
safeTransferAllFrom keyboard_arrow_up
Source Code
function safeTransferAllFrom(
address from,
address to,
uint256[] memory tokenIDs
) public {
for (uint256 i = 0; i < tokenIDs.length; i++) {
safeTransferFrom(from, to, tokenIDs[i]);
}
}
owner keyboard_arrow_up
isOwner keyboard_arrow_up
renounceOwnership keyboard_arrow_up
transferOwnership keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Source Code
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
getDetails keyboard_arrow_up
Source Code
function getDetails(uint256 tokenId)
public
view
returns (uint16 proto, uint8 quality)
{
return
isOld(tokenId)
? old.getDetails(tokenId)
: (cardProtos[tokenId], cardQualities[tokenId]);
}
mintCard keyboard_arrow_up
Source Code
function mintCard(
address _to,
uint16 _proto,
uint8 _quality
) public returns (uint256 id) {
require(!migrating, "must not be migrating");
super.mintCard(_to, _proto, _quality);
}
mintCards keyboard_arrow_up
Requirements help
Source Code
function mintCards(
address _to,
uint16[] memory _protos,
uint8[] memory _qualities
) public returns (uint256 id) {
require(!migrating, "must not be migrating");
super.mintCards(_to, _protos, _qualities);
}
addFactory keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
Source Code
function addFactory(address _factory, uint256 _season) public onlyOwner {
require(seasons.length >= _season, "Core: season must exist");
require(_season > 0, "Core: season must not be 0");
require(
!factoryApproved[_factory][_season],
"Core: this factory is already approved"
);
require(!seasonTradable[_season], "Core: season must not be tradable");
factoryApproved[_factory][_season] = true;
}
approveForMythic keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
Source Code
function approveForMythic(address _factory, uint16 _mythic) public onlyOwner {
require(_mythic >= MYTHIC_THRESHOLD, "not a mythic");
require(
!mythicApproved[_mythic][_factory],
"Core: this factory is already approved for this mythic"
);
mythicApproved[_mythic][_factory] = true;
}
makeMythicTradable keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
Source Code
function makeMythicTradable(uint16 _mythic) public onlyOwner {
require(_mythic >= MYTHIC_THRESHOLD, "Core: not a mythic");
require(!mythicTradable[_mythic], "Core: must not be tradable already");
mythicTradable[_mythic] = true;
}
unlockTrading keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
Source Code
function unlockTrading(uint256 _season) public onlyOwner {
require(
_season > 0 && _season <= seasons.length,
"Core: must be a current season"
);
require(!seasonTradable[_season], "Core: season must not be tradable");
seasonTradable[_season] = true;
}
burn keyboard_arrow_up
burnAll keyboard_arrow_up
isTradable keyboard_arrow_up
Source Code
function isTradable(uint256 _tokenId) public view returns (bool) {
uint16 proto = getProto(_tokenId);
if (proto >= MYTHIC_THRESHOLD) {
return mythicTradable[proto];
}
return seasonTradable[protoToSeason[proto]];
}
startSeason keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
One or more of the following:
-
low
must be greater than
undefined.high
- OR
the number of values in seasons
must be equal to
0
Source Code
function startSeason(
string memory name,
uint16 low,
uint16 high
) public onlyOwner returns (uint256) {
require(low > 0, "Core: must not be zero proto");
require(high > low, "Core: must be a valid range");
require(
seasons.length == 0 || low > seasons[seasons.length - 1].high,
"Core: seasons cannot overlap"
);
require(MYTHIC_THRESHOLD > high, "Core: cannot go into mythic territory");
// seasons start at 1
uint16 id = uint16(seasons.push(Season({high: high, low: low})));
uint256 cp;
assembly {
cp := protoToSeason_slot
}
StorageWrite.repeatUint16(cp, low, (high - low) + 1, id);
emit SeasonStarted(id, name, low, high);
return id;
}
updateProtos keyboard_arrow_up
Parameters help
Modifiers help
onlyOwner checks for the following:
null
Source Code
function updateProtos(
uint16[] memory _ids,
uint8[] memory _gods,
uint8[] memory _cardTypes,
uint8[] memory _rarities,
uint8[] memory _manas,
uint8[] memory _attacks,
uint8[] memory _healths,
uint8[] memory _tribes
) public onlyOwner {
for (uint256 i = 0; i < _ids.length; i++) {
uint16 id = _ids[i];
require(id > 0, "Core: proto must not be zero");
Proto memory proto = protos[id];
require(!proto.locked, "Core: proto is locked");
protos[id] = Proto({
locked: false,
exists: true,
god: _gods[i],
cardType: _cardTypes[i],
rarity: _rarities[i],
mana: _manas[i],
attack: _attacks[i],
health: _healths[i],
tribe: _tribes[i]
});
emit ProtoUpdated(id);
}
}
lockProtos keyboard_arrow_up
Modifiers help
onlyOwner checks for the following:
null
Requirements help
Source Code
function lockProtos(uint16[] memory _ids) public onlyOwner {
require(_ids.length > 0, "must lock some");
for (uint256 i = 0; i < _ids.length; i++) {
uint16 id = _ids[i];
require(id > 0, "proto must not be zero");
Proto storage proto = protos[id];
require(!proto.locked, "proto is locked");
require(proto.exists, "proto must exist");
proto.locked = true;
emit ProtoUpdated(id);
}
}
setQuality keyboard_arrow_up
Source Code
function setQuality(uint256 _tokenId, uint8 _quality) public {
uint16 proto = cardProtos[_tokenId];
// wont' be able to change mythic season
uint256 season = protoToSeason[proto];
require(
factoryApproved[msg.sender][season],
"Core: factory can't change quality of this season"
);
cardQualities[_tokenId] = _quality;
emit QualityChanged(_tokenId, _quality, msg.sender);
}
setPropertyManager keyboard_arrow_up
setProperty keyboard_arrow_up
Requirements help
Source Code
function setProperty(
uint256 _id,
bytes32 _key,
bytes32 _value
) public {
require(msg.sender == propertyManager, "Core: must be property manager");
_setProperty(_id, _key, _value);
}
setClassProperty keyboard_arrow_up
Requirements help
Source Code
function setClassProperty(bytes32 _key, bytes32 _value) public {
require(msg.sender == propertyManager, "Core: must be property manager");
_setClassProperty(_key, _value);
}
setBaseURI keyboard_arrow_up
setMigrating keyboard_arrow_up
copyUntil keyboard_arrow_up
copyNextBatch keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function copyNextBatch() public {
require(migrating, "must be migrating");
uint256 start = nextBatch;
(uint48 userID, uint16 size) = old.batches(start);
require(size > 0 && userID > 0, "incorrect batch or limit reached");
if (old.cardProtos(start) != 0) {
address to = old.userIDToAddress(userID);
uint48 uID = _getUserID(to);
batches[start] = Batch({userID: uID, size: size});
uint256 end = start.add(size);
for (uint256 i = start; i < end; i++) {
emit Transfer(address(0), to, i);
}
_balances[to] = _balances[to].add(size);
tokenCount = tokenCount.add(size);
}
nextBatch = nextBatch.add(batchSize);
}
isOld keyboard_arrow_up
getProto keyboard_arrow_up
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal BatchWrapper._transferFrom keyboard_arrow_up
Requirements help
Source Code
function _transferFrom(
address from,
address to,
uint256 tokenId
) internal {
require(isTradable(tokenId), "BW: not yet tradable");
super._transferFrom(from, to, tokenId);
}
internal BatchWrapper._validateProtos keyboard_arrow_up
Source Code
function _validateProtos(uint16[] memory _protos) internal {
uint16 maxProto = 0;
uint16 minProto = MAX_UINT16;
for (uint256 i = 0; i < _protos.length; i++) {
uint16 proto = _protos[i];
if (proto >= MYTHIC_THRESHOLD) {
_checkCanCreateMythic(proto);
} else {
require(proto != 0, "proto is zero");
if (proto > maxProto) {
maxProto = proto;
}
if (minProto > proto) {
minProto = proto;
}
}
}
if (maxProto != 0) {
uint256 season = protoToSeason[maxProto];
// cards must be from the same season
require(season != 0, "Core: must have season set");
require(
season == protoToSeason[minProto],
"Core: can only create cards from the same season"
);
require(
factoryApproved[msg.sender][season],
"Core: must be approved factory for this season"
);
}
}
internal NewCards._transferFrom keyboard_arrow_up
Requirements help
Source Code
function _transferFrom(
address from,
address to,
uint256 tokenId
) internal {
require(isTradable(tokenId), "Core: not yet tradable");
super._transferFrom(from, to, tokenId);
}
internal NewCards._validateAndSaveDetails keyboard_arrow_up
Source Code
function _validateAndSaveDetails(
uint256 start,
uint16[] memory _protos,
uint8[] memory _qualities
) internal {
_validateProtos(_protos);
uint256 cp;
assembly {
cp := cardProtos_slot
}
StorageWrite.uint16s(cp, start, _protos);
uint256 cq;
assembly {
cq := cardQualities_slot
}
StorageWrite.uint8s(cq, start, _qualities);
}
internal NewCards._validateProto keyboard_arrow_up
Source Code
function _validateProto(uint16 proto) internal {
if (proto >= MYTHIC_THRESHOLD) {
_checkCanCreateMythic(proto);
} else {
uint256 season = protoToSeason[proto];
require(season != 0, "Core: must have season set");
require(
factoryApproved[msg.sender][season],
"Core: must be approved factory for this season"
);
}
}
internal NewCards._validateProtos keyboard_arrow_up
Source Code
function _validateProtos(uint16[] memory _protos) internal {
uint16 maxProto = 0;
uint16 minProto = MAX_UINT16;
for (uint256 i = 0; i < _protos.length; i++) {
uint16 proto = _protos[i];
if (proto >= MYTHIC_THRESHOLD) {
_checkCanCreateMythic(proto);
} else {
if (proto > maxProto) {
maxProto = proto;
}
if (minProto > proto) {
minProto = proto;
}
}
}
if (maxProto != 0) {
uint256 season = protoToSeason[maxProto];
// cards must be from the same season
require(season != 0, "Core: must have season set");
require(
season == protoToSeason[minProto],
"Core: can only create cards from the same season"
);
require(
factoryApproved[msg.sender][season],
"Core: must be approved factory for this season"
);
}
}
internal NewCards._checkCanCreateMythic keyboard_arrow_up
Requirements help
Source Code
function _checkCanCreateMythic(uint16 proto) internal {
require(
mythicApproved[proto][msg.sender],
"Core: not approved to create this mythic"
);
require(!mythicCreated[proto], "Core: mythic has already been created");
mythicCreated[proto] = true;
}
internal Ownable.constructor keyboard_arrow_up
internal Ownable._transferOwnership keyboard_arrow_up
Source Code
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
internal BatchToken._getUserID keyboard_arrow_up
Source Code
function _getUserID(address to) internal returns (uint48) {
if (to == address(0)) {
return 0;
}
uint48 uID = addressToUserID[to];
if (uID == 0) {
require(userCount + 1 > userCount, "BT: must not overflow");
uID = userCount++;
userIDToAddress[uID] = to;
addressToUserID[to] = uID;
}
return uID;
}
internal BatchToken._batchMint keyboard_arrow_up
Requirements help
Source Code
function _batchMint(address to, uint16 size) internal returns (uint256) {
require(to != address(0), "BT: must not be null");
require(size > 0 && size <= batchSize, "BT: size must be within limits");
uint256 start = nextBatch;
uint48 uID = _getUserID(to);
batches[start] = Batch({userID: uID, size: size});
uint256 end = start.add(size);
for (uint256 i = start; i < end; i++) {
emit Transfer(address(0), to, i);
}
nextBatch = nextBatch.add(batchSize);
_balances[to] = _balances[to].add(size);
tokenCount = tokenCount.add(size);
return start;
}
internal BatchToken._transferFrom keyboard_arrow_up
Requirements help
Source Code
function _transferFrom(
address from,
address to,
uint256 tokenId
) internal {
require(ownerOf(tokenId) == from, "BT: transfer of token that is not own");
require(to != address(0), "BT: transfer to the zero address");
require(
_isApprovedOrOwner(msg.sender, tokenId),
"BT: caller is not owner nor approved"
);
_cancelApproval(tokenId);
_balances[from] = _balances[from].sub(1);
_balances[to] = _balances[to].add(1);
ownerIDs[tokenId] = _getUserID(to);
emit Transfer(from, to, tokenId);
}
internal BatchToken._burn keyboard_arrow_up
Requirements help
null
Source Code
function _burn(uint256 tokenId) internal {
require(
_isApprovedOrOwner(msg.sender, tokenId),
"BT: caller is not owner nor approved"
);
_cancelApproval(tokenId);
address owner = ownerOf(tokenId);
_balances[owner] = _balances[owner].sub(1);
ownerIDs[tokenId] = 0;
tokenCount = tokenCount.sub(1);
emit Transfer(owner, address(0), tokenId);
}
internal BatchToken._cancelApproval keyboard_arrow_up
internal BatchToken._exists keyboard_arrow_up
internal ERC721Metadata._setTokenURI keyboard_arrow_up
Requirements help
null
Source Code
function _setTokenURI(uint256 tokenId, string memory uri) internal {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = uri;
}
internal ERC721Metadata._burn keyboard_arrow_up
Source Code
function _burn(address owner, uint256 tokenId) internal {
super._burn(owner, tokenId);
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
internal ERC165.constructor keyboard_arrow_up
internal ERC165._registerInterface keyboard_arrow_up
Requirements help
Source Code
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
internal ERC721._safeTransferFrom keyboard_arrow_up
Requirements help
Source Code
function _safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal {
_transferFrom(from, to, tokenId);
require(
_checkOnERC721Received(from, to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
internal ERC721._exists keyboard_arrow_up
internal ERC721._isApprovedOrOwner keyboard_arrow_up
Requirements help
null
Source Code
function _isApprovedOrOwner(address spender, uint256 tokenId)
internal
view
returns (bool)
{
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ownerOf(tokenId);
return (spender == owner ||
getApproved(tokenId) == spender ||
isApprovedForAll(owner, spender));
}
internal ERC721._safeMint keyboard_arrow_up
Requirements help
Source Code
function _safeMint(address to, uint256 tokenId) internal {
_safeMint(to, tokenId, "");
}
internal ERC721._safeMint keyboard_arrow_up
Requirements help
Source Code
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
internal ERC721._mint keyboard_arrow_up
Requirements help
Source Code
function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_tokenOwner[tokenId] = to;
_ownedTokensCount[to].increment();
emit Transfer(address(0), to, tokenId);
}
internal ERC721._burn keyboard_arrow_up
Source Code
function _burn(address owner, uint256 tokenId) internal {
require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");
_clearApproval(tokenId);
_ownedTokensCount[owner].decrement();
_tokenOwner[tokenId] = address(0);
emit Transfer(owner, address(0), tokenId);
}
internal ERC721._burn keyboard_arrow_up
Requirements help
Source Code
function _burn(uint256 tokenId) internal {
_burn(ownerOf(tokenId), tokenId);
}
internal ERC721._transferFrom keyboard_arrow_up
Requirements help
Source Code
function _transferFrom(
address from,
address to,
uint256 tokenId
) internal {
require(
ownerOf(tokenId) == from,
"ERC721: transfer of token that is not own"
);
require(to != address(0), "ERC721: transfer to the zero address");
_clearApproval(tokenId);
_ownedTokensCount[from].decrement();
_ownedTokensCount[to].increment();
_tokenOwner[tokenId] = to;
emit Transfer(from, to, tokenId);
}
internal ERC721._checkOnERC721Received keyboard_arrow_up
Source Code
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal returns (bool) {
if (!to.isContract()) {
return true;
}
bytes4 retval = IERC721Receiver(to).onERC721Received(
_msgSender(),
from,
tokenId,
_data
);
return (retval == _ERC721_RECEIVED);
}
internal ERC721._clearApproval keyboard_arrow_up
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
internal ERC165.constructor keyboard_arrow_up
internal ERC165._registerInterface keyboard_arrow_up
Requirements help
Source Code
function _registerInterface(bytes4 interfaceId) internal {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
internal InscribableToken._setProperty keyboard_arrow_up
Source Code
function _setProperty(
uint256 _id,
bytes32 _key,
bytes32 _value
) internal {
properties[getTokenKey(_id, _key)] = _value;
emit TokenPropertySet(_id, _key, _value);
}