pragma solidity ^0.5.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor() internal {}
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
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;
}
}
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount)
external
returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender)
external
view
returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
interface IERC1155 {
// Events
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferSingle(
address indexed _operator,
address indexed _from,
address indexed _to,
uint256 _id,
uint256 _amount
);
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferBatch(
address indexed _operator,
address indexed _from,
address indexed _to,
uint256[] _ids,
uint256[] _amounts
);
/**
* @dev MUST emit when an approval is updated
*/
event ApprovalForAll(
address indexed _owner,
address indexed _operator,
bool _approved
);
/**
* @dev MUST emit when the URI is updated for a token ID
* URIs are defined in RFC 3986
* The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema"
*/
event URI(string _amount, uint256 indexed _id);
/**
* @notice Transfers amount of an _id from the _from address to the _to address specified
* @dev MUST emit TransferSingle event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if balance of sender for token `_id` is lower than the `_amount` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(
address _from,
address _to,
uint256 _id,
uint256 _amount,
bytes calldata _data
) external;
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @dev MUST emit TransferBatch event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if length of `_ids` is not the same as length of `_amounts`
* MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _amounts,
bytes calldata _data
) external;
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/
function balanceOf(address _owner, uint256 _id)
external
view
returns (uint256);
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids)
external
view
returns (uint256[] memory);
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @dev MUST emit the ApprovalForAll event on success
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved) external;
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return True if the operator is approved, false if not
*/
function isApprovedForAll(address _owner, address _operator)
external
view
returns (bool isOperator);
}
interface IERC1155Metadata {
/***********************************|
| Metadata Public Function s |
|__________________________________*/
/**
* @notice A distinct Uniform Resource Identifier (URI) for a given token.
* @dev URIs are defined in RFC 3986.
* URIs are assumed to be deterministically generated based on token ID
* Token IDs are assumed to be represented in their hex format in URIs
* @return URI string
*/
function uri(uint256 _id) external view returns (string memory);
}
library Strings {
// via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol
function strConcat(
string memory _a,
string memory _b,
string memory _c,
string memory _d,
string memory _e
) internal pure returns (string memory) {
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);
uint256 k = 0;
for (uint256 i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
for (uint256 i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
for (uint256 i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
for (uint256 i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
for (uint256 i = 0; i < _be.length; i++) babcde[k++] = _be[i];
return string(babcde);
}
function strConcat(
string memory _a,
string memory _b,
string memory _c,
string memory _d
) internal pure returns (string memory) {
return strConcat(_a, _b, _c, _d, "");
}
function strConcat(
string memory _a,
string memory _b,
string memory _c
) internal pure returns (string memory) {
return strConcat(_a, _b, _c, "", "");
}
function strConcat(string memory _a, string memory _b)
internal
pure
returns (string memory)
{
return strConcat(_a, _b, "", "", "");
}
function uint2str(uint256 _i)
internal
pure
returns (string memory _uintAsString)
{
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len - 1;
while (_i != 0) {
bstr[k--] = bytes1(uint8(48 + (_i % 10)));
_i /= 10;
}
return string(bstr);
}
}
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath#mul: OVERFLOW");
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath#div: DIVISION_BY_ZERO");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath#sub: UNDERFLOW");
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath#add: OVERFLOW");
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO");
return a % b;
}
}
/**
* Copyright 2018 ZeroEx Intl.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Utility library of inline functions on addresses
*/
library Address {
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract,
* as the code is not actually created until after the constructor finishes.
* @param account address of the account to check
* @return whether the target address is a contract
*/
function isContract(address account) internal view returns (bool) {
bytes32 codehash;
bytes32 accountHash
= 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// XXX Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address.
// See https://ethereum.stackexchange.com/a/14016/36603
// for more details about how this works.
// TODO Check this again before the Serenity release, because all addresses will be
// contracts then.
assembly {
codehash := extcodehash(account)
}
return (codehash != 0x0 && codehash != accountHash);
}
}
contract BCCGDistributor is Ownable {
using Strings for string;
using SafeMath for uint256;
using Address for address;
uint256 public _currentCardId = 0;
address private _salesperson;
uint256 private _limitPerWallet;
bool public _saleStarted = false;
struct Card {
uint256 cardId;
address contractAddress;
uint256 tokenId;
uint256 totalAmount;
uint256 currentAmount;
address paymentToken;
uint256 basePrice;
uint256 limitForFree;
bool isFinished;
bool isPrivate;
mapping(address => bool) whitelist;
}
struct History {
address contractAddress;
mapping(uint256 => mapping(address => uint256)) purchasedHistories;
}
// Events
event CreateCard(
address indexed _from,
uint256 _cardId,
address indexed _contractAddress,
uint256 _tokenId,
uint256 _totalAmount,
address _paymentToken,
uint256 _basePrice
);
event PurchaseCard(address indexed _from, uint256 _cardId, uint256 _amount);
event CardChanged(uint256 _cardId);
event WhiteListAdded(uint256 _cardId, address indexed addr);
event WhiteListRemoved(uint256 _cardId, address indexed addr);
event BatchWhiteListAdded(uint256 _cardId, address[] addr);
event BatchWhiteListRemoved(uint256 _cardId, address[] addr);
mapping(uint256 => Card) internal _cards;
mapping(uint256 => uint256) internal _earning;
mapping(address => History) internal _history;
constructor() public {
_salesperson = msg.sender;
_limitPerWallet = 1;
}
function setLimitPerWallet(uint256 limit)
public
onlyOwner
returns (bool)
{
_limitPerWallet = limit;
return true;
}
function setSalesPerson(address newSalesPerson)
public
onlyOwner
returns (bool)
{
_salesperson = newSalesPerson;
return true;
}
function getEarning(uint256 _cardId) public view returns (uint256) {
return _earning[_cardId];
}
function startSale() public onlyOwner returns (bool) {
_saleStarted = true;
return true;
}
function stopSale() public onlyOwner returns (bool) {
_saleStarted = false;
return false;
}
function createCard(
address _contractAddress,
uint256 _tokenId,
uint256 _totalAmount,
address _paymentToken,
uint256 _basePrice,
uint256 _limitForFree,
bool _isPrivate
) public onlyOwner returns (uint256) {
IERC1155 _contract = IERC1155(_contractAddress);
require(
_contract.balanceOf(msg.sender, _tokenId) >= _totalAmount,
"Initial supply cannot be more than available supply"
);
require(
_contract.isApprovedForAll(msg.sender, address(this)) == true,
"Contract must be whitelisted by owner"
);
uint256 _id = _getNextCardID();
_incrementCardId();
Card memory _newCard;
_newCard.cardId = _id;
_newCard.contractAddress = _contractAddress;
_newCard.tokenId = _tokenId;
_newCard.totalAmount = _totalAmount;
_newCard.currentAmount = _totalAmount;
_newCard.paymentToken = _paymentToken;
_newCard.basePrice = _basePrice;
_newCard.limitForFree = _limitForFree;
_newCard.isFinished = false;
_newCard.isPrivate = _isPrivate;
_cards[_id] = _newCard;
_earning[_id] = 0;
emit CreateCard(
msg.sender,
_id,
_contractAddress,
_tokenId,
_totalAmount,
_paymentToken,
_basePrice
);
return _id;
}
function purchaseNFT(uint256 _cardId, uint256 _amount)
public
returns (bool)
{
require(_saleStarted == true, "Sale stopped");
Card storage _currentCard = _cards[_cardId];
require(_currentCard.isFinished == false, "Card is finished");
require(_currentCard.isPrivate == false || _currentCard.whitelist[msg.sender] == true, "Not allowed to buy");
IERC1155 _contract = IERC1155(_currentCard.contractAddress);
require(
_currentCard.currentAmount >= _amount,
"Order exceeds the max number of available NFTs"
);
History storage _currentHistory = _history[_currentCard.contractAddress];
uint256 _currentBoughtAmount = _currentHistory.purchasedHistories[_currentCard.tokenId][msg.sender];
require(
_currentBoughtAmount < _limitPerWallet,
"Order exceeds the max limit of NFTs per wallet"
);
uint256 availableAmount = _limitPerWallet.sub(_currentBoughtAmount);
if (availableAmount > _amount) {
availableAmount = _amount;
}
if (_currentCard.basePrice != 0) {
IERC20 _paymentContract = IERC20(_currentCard.paymentToken);
uint256 _price = _currentCard.basePrice.mul(availableAmount);
require(
_paymentContract.balanceOf(msg.sender) >= _price,
"Do not have enough funds"
);
require(
_paymentContract.allowance(msg.sender, address(this)) >= _price,
"Must be approved for purchase"
);
_paymentContract.transferFrom(msg.sender, _salesperson, _price);
_earning[_cardId] = _earning[_cardId].add(_price);
} else {
IERC20 _paymentContract = IERC20(_currentCard.paymentToken);
uint256 accountBalance = msg.sender.balance;
require(
_paymentContract.balanceOf(msg.sender).add(accountBalance) >=
_currentCard.limitForFree,
"Do not have enough funds"
);
}
_contract.safeTransferFrom(
owner(),
msg.sender,
_currentCard.tokenId,
availableAmount,
""
);
_currentCard.currentAmount = _currentCard.currentAmount.sub(availableAmount);
_currentHistory.purchasedHistories[_currentCard.tokenId][msg.sender] = _currentBoughtAmount.add(availableAmount);
emit PurchaseCard(msg.sender, _cardId, availableAmount);
return true;
}
function _getNextCardID() private view returns (uint256) {
return _currentCardId.add(1);
}
function _incrementCardId() private {
_currentCardId++;
}
function cancelCard(uint256 _cardId) public onlyOwner returns (bool) {
_cards[_cardId].isFinished = true;
emit CardChanged(_cardId);
return true;
}
function setCardPaymentToken(uint256 _cardId, address _newTokenAddress)
public
onlyOwner
returns (bool)
{
_cards[_cardId].paymentToken = _newTokenAddress;
emit CardChanged(_cardId);
return true;
}
function setCardPrice(
uint256 _cardId,
uint256 _newPrice,
uint256 _newLimit
) public onlyOwner returns (bool) {
_cards[_cardId].basePrice = _newPrice;
_cards[_cardId].limitForFree = _newLimit;
emit CardChanged(_cardId);
return true;
}
function setCardVisibility(
uint256 _cardId,
bool _isPrivate
) public onlyOwner returns (bool) {
_cards[_cardId].isPrivate = _isPrivate;
emit CardChanged(_cardId);
return true;
}
function addWhiteListAddress(
uint256 _cardId,
address addr
) public onlyOwner returns (bool) {
_cards[_cardId].whitelist[addr] = true;
emit WhiteListAdded(_cardId, addr);
return true;
}
function batchAddWhiteListAddress(
uint256 _cardId,
address[] memory addr
) public onlyOwner returns (bool) {
Card storage currentCard = _cards[_cardId];
for (uint256 i = 0; i < addr.length; i ++) {
currentCard.whitelist[addr[i]] = true;
}
emit BatchWhiteListAdded(_cardId, addr);
return true;
}
function removeWhiteListAddress(
uint256 _cardId,
address addr
) public onlyOwner returns (bool) {
_cards[_cardId].whitelist[addr] = false;
emit WhiteListRemoved(_cardId, addr);
return true;
}
function batchRemoveWhiteListAddress(
uint256 _cardId,
address[] memory addr
) public onlyOwner returns (bool) {
Card storage currentCard = _cards[_cardId];
for (uint256 i = 0; i < addr.length; i ++) {
currentCard.whitelist[addr[i]] = false;
}
emit BatchWhiteListRemoved(_cardId, addr);
return true;
}
function isCardPrivate(uint256 _cardId) public view returns (bool) {
return _cards[_cardId].isPrivate;
}
function isAllowedCard(uint256 _cardId) public view returns (bool) {
return _cards[_cardId].whitelist[msg.sender];
}
function isCardCompleted(uint256 _cardId) public view returns (bool) {
return _cards[_cardId].isFinished;
}
function isCardFree(uint256 _cardId) public view returns (bool) {
if (_cards[_cardId].basePrice == 0) return true;
return false;
}
function getCardPaymentToken(uint256 _cardId)
public view returns (address)
{
return _cards[_cardId].paymentToken;
}
function getCardRequirement(uint256 _cardId) public view returns (uint256) {
return _cards[_cardId].limitForFree;
}
function getCardContract(uint256 _cardId) public view returns (address) {
return _cards[_cardId].contractAddress;
}
function getCardTokenId(uint256 _cardId) public view returns (uint256) {
return _cards[_cardId].tokenId;
}
function getCardTotalAmount(uint256 _cardId) public view returns (uint256) {
return _cards[_cardId].totalAmount;
}
function getCardCurrentAmount(uint256 _cardId)
public
view
returns (uint256)
{
return _cards[_cardId].currentAmount;
}
function getCardBasePrice(uint256 _cardId) public view returns (uint256) {
return _cards[_cardId].basePrice;
}
function getCardURL(uint256 _cardId) public view returns (string memory) {
return
IERC1155Metadata(_cards[_cardId].contractAddress).uri(
_cards[_cardId].tokenId
);
}
}
{
"compilationTarget": {
"BCCGDistributor.sol": "BCCGDistributor"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardPaymentToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"addr","type":"address[]"}],"name":"batchRemoveWhiteListAddress","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardBasePrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"_isPrivate","type":"bool"}],"name":"setCardVisibility","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardURL","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_currentCardId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"isCardCompleted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardTokenId","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"isCardFree","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"cancelCard","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"_newTokenAddress","type":"address"}],"name":"setCardPaymentToken","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"limit","type":"uint256"}],"name":"setLimitPerWallet","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"addr","type":"address"}],"name":"addWhiteListAddress","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardRequirement","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_saleStarted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"_amount","type":"uint256"}],"name":"purchaseNFT","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newSalesPerson","type":"address"}],"name":"setSalesPerson","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"isCardPrivate","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"startSale","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"_newPrice","type":"uint256"},{"name":"_newLimit","type":"uint256"}],"name":"setCardPrice","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardTotalAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getCardCurrentAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_contractAddress","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_totalAmount","type":"uint256"},{"name":"_paymentToken","type":"address"},{"name":"_basePrice","type":"uint256"},{"name":"_limitForFree","type":"uint256"},{"name":"_isPrivate","type":"bool"}],"name":"createCard","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"getEarning","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"addr","type":"address[]"}],"name":"batchAddWhiteListAddress","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"stopSale","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_cardId","type":"uint256"},{"name":"addr","type":"address"}],"name":"removeWhiteListAddress","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_cardId","type":"uint256"}],"name":"isAllowedCard","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":false,"name":"_cardId","type":"uint256"},{"indexed":true,"name":"_contractAddress","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"},{"indexed":false,"name":"_totalAmount","type":"uint256"},{"indexed":false,"name":"_paymentToken","type":"address"},{"indexed":false,"name":"_basePrice","type":"uint256"}],"name":"CreateCard","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":false,"name":"_cardId","type":"uint256"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"PurchaseCard","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_cardId","type":"uint256"}],"name":"CardChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_cardId","type":"uint256"},{"indexed":true,"name":"addr","type":"address"}],"name":"WhiteListAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_cardId","type":"uint256"},{"indexed":true,"name":"addr","type":"address"}],"name":"WhiteListRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_cardId","type":"uint256"},{"indexed":false,"name":"addr","type":"address[]"}],"name":"BatchWhiteListAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_cardId","type":"uint256"},{"indexed":false,"name":"addr","type":"address[]"}],"name":"BatchWhiteListRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]