Back to HomeToken Name DADA Collectible Symbol Ɖ Decimals 0 Deployer 0x60775d...3b7a71 Deployment Block 4,339,477 Deployment Date Oct 5, 2017, 03:56 PM Code Size 9.6 KB Gas at Deploy 2,814,332
Deployed October 5, 2017 (9 years ago)Block 4,339,477
This contract is not yet documented
Know something about this contract? Switch to the History tab and suggest an edit to help preserve Ethereum history.
Spurious Dragon EraVerified Source
Token Information
Key Facts
Transactions by Year
2017216
2018839
201915
20203
20211,388
20221,071
2023190
202487
202521
Deployment Transaction: 0x94c903d2f89a0546...7779a3cd94209a93
Source Verified
Etherscan verified
Spurious Dragon Era
Continued DoS protection. State trie clearing.
Block span: 2,675,000 — 4,369,999
November 22, 2016 — October 16, 2017
Bytecode Overview
Opcodes9,858
Unique Opcodes238
Jump Instructions472
Storage Operations393
Verified Source Available
Source verified on Etherscan.
Show source code (Solidity)
pragma solidity ^0.4.13;
/**
* This contract handles the actions for every collectible on DADA...
*/
contract DadaCollectible {
// DADA's account
address owner;
// starts turned off to prepare the drawings before going public
bool isExecutionAllowed = false;
// ERC20 token standard attributes
string public name;
string public symbol;
uint8 public decimals;
uint256 public totalSupply;
struct Offer {
bool isForSale;
uint drawingId;
uint printIndex;
address seller;
uint minValue; // in ether
address onlySellTo; // specify to sell only to a specific person
uint lastSellValue;
}
struct Bid {
bool hasBid;
uint drawingId;
uint printIndex;
address bidder;
uint value;
}
struct Collectible{
uint drawingId;
string checkSum; // digest of the drawing, created using SHA2
uint totalSupply;
uint nextPrintIndexToAssign;
bool allPrintsAssigned;
uint initialPrice;
uint initialPrintIndex;
string collectionName;
uint authorUId; // drawing creator id
string scarcity; // denotes how scarce is the drawing
}
// key: printIndex
// the value is the user who owns that specific print
mapping (uint => address) public DrawingPrintToAddress;
// A record of collectibles that are offered for sale at a specific minimum value,
// and perhaps to a specific person, the key to access and offer is the printIndex.
// since every single offer inside the Collectible struct will be tied to the main
// drawingId that identifies that collectible.
mapping (uint => Offer) public OfferedForSale;
// A record of the highest collectible bid, the key to access a bid is the printIndex
mapping (uint => Bid) public Bids;
// "Hash" list of the different Collectibles available in the market place
mapping (uint => Collectible) public drawingIdToCollectibles;
mapping (address => uint) public pendingWithdrawals;
mapping (address => uint256) public balances;
// returns the balance of a particular account
function balanceOf(address _owner) constant returns (uint256 balance) {
return balances[_owner];
}
// Events
event Assigned(address indexed to, uint256 collectibleIndex, uint256 printIndex);
event Transfer(address indexed from, address indexed to, uint256 value);
event CollectibleTransfer(address indexed from, address indexed to, uint256 collectibleIndex, uint256 printIndex);
event CollectibleOffered(uint indexed collectibleIndex, uint indexed printIndex, uint minValue, address indexed toAddress, uint lastSellValue);
event CollectibleBidEntered(uint indexed collectibleIndex, uint indexed printIndex, uint value, address indexed fromAddress);
event CollectibleBidWithdrawn(uint indexed collectibleIndex, uint indexed printIndex, uint value, address indexed fromAddress);
event CollectibleBought(uint indexed collectibleIndex, uint printIndex, uint value, address indexed fromAddress, address indexed toAddress);
event CollectibleNoLongerForSale(uint indexed collectibleIndex, uint indexed printIndex);
// The constructor is executed only when the contract is created in the blockchain.
function DadaCollectible () {
// assigns the address of the account creating the contract as the
// "owner" of the contract. Since the contract doesn't have
// a "set" function for the owner attribute this value will be immutable.
owner = msg.sender;
// Update total supply
totalSupply = 16600;
// Give to DADA all initial drawings
balances[owner] = totalSupply;
// Set the name for display purposes
name = "DADA Collectible";
// Set the symbol for display purposes
symbol = "Ɖ";
// Amount of decimals for display purposes
decimals = 0;
}
// main business logic functions
// buyer's functions
function buyCollectible(uint drawingId, uint printIndex) payable {
require(isExecutionAllowed);
// requires the drawing id to actually exist
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
Offer storage offer = OfferedForSale[printIndex];
require(offer.drawingId != 0);
require(offer.isForSale); // drawing actually for sale
require(offer.onlySellTo == 0x0 || offer.onlySellTo == msg.sender); // drawing can be sold to this user
require(msg.value >= offer.minValue); // Didn't send enough ETH
require(offer.seller == DrawingPrintToAddress[printIndex]); // Seller still owner of the drawing
require(DrawingPrintToAddress[printIndex] != msg.sender);
address seller = offer.seller;
address buyer = msg.sender;
DrawingPrintToAddress[printIndex] = buyer; // "gives" the print to the buyer
// decrease by one the amount of prints the seller has of this particullar drawing
balances[seller]--;
// increase by one the amount of prints the buyer has of this particullar drawing
balances[buyer]++;
// launch the Transfered event
Transfer(seller, buyer, 1);
// transfer ETH to the seller
// profit delta must be equal or greater than 1e-16 to be able to divide it
// between the involved entities (art creator -> 30%, seller -> 60% and dada -> 10%)
// profit percentages can't be lower than 1e-18 which is the lowest unit in ETH
// equivalent to 1 wei.
// if(offer.lastSellValue < msg.value && (msg.value - offer.lastSellValue) >= uint(0.0000000000000001) ){ commented because we're assuming values are expressed in "weis", adjusting in relation to that
if(offer.lastSellValue < msg.value && (msg.value - offer.lastSellValue) >= 100 ){ // assuming 100 (weis) wich is equivalent to 1e-16
uint profit = msg.value - offer.lastSellValue;
// seller gets base value plus 60% of the profit
pendingWithdrawals[seller] += offer.lastSellValue + (profit*60/100);
// dada gets 10% of the profit
// pendingWithdrawals[owner] += (profit*10/100);
// dada receives 30% of the profit to give to the artist
// pendingWithdrawals[owner] += (profit*30/100);
// going manual for artist and dada percentages (30 + 10)
pendingWithdrawals[owner] += (profit*40/100);
}else{
// if the seller doesn't make a profit of the sell he gets the 100% of the traded
// value.
pendingWithdrawals[seller] += msg.value;
}
makeCollectibleUnavailableToSale(buyer, drawingId, printIndex, msg.value);
// launch the CollectibleBought event
CollectibleBought(drawingId, printIndex, msg.value, seller, buyer);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid storage bid = Bids[printIndex];
if (bid.bidder == buyer) {
// Kill bid and refund value
pendingWithdrawals[buyer] += bid.value;
Bids[printIndex] = Bid(false, collectible.drawingId, printIndex, 0x0, 0);
}
}
function alt_buyCollectible(uint drawingId, uint printIndex) payable {
require(isExecutionAllowed);
// requires the drawing id to actually exist
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
Offer storage offer = OfferedForSale[printIndex];
require(offer.drawingId == 0);
require(msg.value >= collectible.initialPrice); // Didn't send enough ETH
require(DrawingPrintToAddress[printIndex] == 0x0); // should be equal to a "null" address (0x0) since it shouldn't have an owner yet
address seller = owner;
address buyer = msg.sender;
DrawingPrintToAddress[printIndex] = buyer; // "gives" the print to the buyer
// decrease by one the amount of prints the seller has of this particullar drawing
// commented while we decide what to do with balances for DADA
balances[seller]--;
// increase by one the amount of prints the buyer has of this particullar drawing
balances[buyer]++;
// launch the Transfered event
Transfer(seller, buyer, 1);
// transfer ETH to the seller
// profit delta must be equal or greater than 1e-16 to be able to divide it
// between the involved entities (art creator -> 30%, seller -> 60% and dada -> 10%)
// profit percentages can't be lower than 1e-18 which is the lowest unit in ETH
// equivalent to 1 wei.
pendingWithdrawals[owner] += msg.value;
OfferedForSale[printIndex] = Offer(false, collectible.drawingId, printIndex, buyer, msg.value, 0x0, msg.value);
// launch the CollectibleBought event
CollectibleBought(drawingId, printIndex, msg.value, seller, buyer);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid storage bid = Bids[printIndex];
if (bid.bidder == buyer) {
// Kill bid and refund value
pendingWithdrawals[buyer] += bid.value;
Bids[printIndex] = Bid(false, collectible.drawingId, printIndex, 0x0, 0);
}
}
function enterBidForCollectible(uint drawingId, uint printIndex) payable {
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require(DrawingPrintToAddress[printIndex] != 0x0); // Print is owned by somebody
require(DrawingPrintToAddress[printIndex] != msg.sender); // Print is not owned by bidder
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
require(msg.value > 0); // Bid must be greater than 0
// get the current bid for that print if any
Bid storage existing = Bids[printIndex];
// Must outbid previous bid by at least 5%. Apparently is not possible to
// multiply by 1.05, that's why we do it manually.
require(msg.value >= existing.value+(existing.value*5/100));
if (existing.value > 0) {
// Refund the failing bid from the previous bidder
pendingWithdrawals[existing.bidder] += existing.value;
}
// add the new bid
Bids[printIndex] = Bid(true, collectible.drawingId, printIndex, msg.sender, msg.value);
CollectibleBidEntered(collectible.drawingId, printIndex, msg.value, msg.sender);
}
// used by a user who wants to cancell a bid placed by her/him
function withdrawBidForCollectible(uint drawingId, uint printIndex) {
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
require(DrawingPrintToAddress[printIndex] != 0x0); // Print is owned by somebody
require(DrawingPrintToAddress[printIndex] != msg.sender); // Print is not owned by bidder
Bid storage bid = Bids[printIndex];
require(bid.bidder == msg.sender);
CollectibleBidWithdrawn(drawingId, printIndex, bid.value, msg.sender);
uint amount = bid.value;
Bids[printIndex] = Bid(false, collectible.drawingId, printIndex, 0x0, 0);
// Refund the bid money
msg.sender.transfer(amount);
}
// seller's functions
function offerCollectibleForSale(uint drawingId, uint printIndex, uint minSalePriceInWei) {
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require(DrawingPrintToAddress[printIndex] == msg.sender);
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
uint lastSellValue = OfferedForSale[printIndex].lastSellValue;
OfferedForSale[printIndex] = Offer(true, collectible.drawingId, printIndex, msg.sender, minSalePriceInWei, 0x0, lastSellValue);
CollectibleOffered(drawingId, printIndex, minSalePriceInWei, 0x0, lastSellValue);
}
function withdrawOfferForCollectible(uint drawingId, uint printIndex){
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require(DrawingPrintToAddress[printIndex] == msg.sender);
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
uint lastSellValue = OfferedForSale[printIndex].lastSellValue;
OfferedForSale[printIndex] = Offer(false, collectible.drawingId, printIndex, msg.sender, 0, 0x0, lastSellValue);
// launch the CollectibleNoLongerForSale event
CollectibleNoLongerForSale(collectible.drawingId, printIndex);
}
function offerCollectibleForSaleToAddress(uint drawingId, uint printIndex, uint minSalePriceInWei, address toAddress) {
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require(DrawingPrintToAddress[printIndex] == msg.sender);
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
uint lastSellValue = OfferedForSale[printIndex].lastSellValue;
OfferedForSale[printIndex] = Offer(true, collectible.drawingId, printIndex, msg.sender, minSalePriceInWei, toAddress, lastSellValue);
CollectibleOffered(drawingId, printIndex, minSalePriceInWei, toAddress, lastSellValue);
}
function acceptBidForCollectible(uint drawingId, uint minPrice, uint printIndex) {
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
require(DrawingPrintToAddress[printIndex] == msg.sender);
address seller = msg.sender;
Bid storage bid = Bids[printIndex];
require(bid.value > 0); // Will be zero if there is no actual bid
require(bid.value >= minPrice); // Prevent a condition where a bid is withdrawn and replaced with a lower bid but seller doesn't know
DrawingPrintToAddress[printIndex] = bid.bidder;
balances[seller]--;
balances[bid.bidder]++;
Transfer(seller, bid.bidder, 1);
uint amount = bid.value;
Offer storage offer = OfferedForSale[printIndex];
// transfer ETH to the seller
// profit delta must be equal or greater than 1e-16 to be able to divide it
// between the involved entities (art creator -> 30%, seller -> 60% and dada -> 10%)
// profit percentages can't be lower than 1e-18 which is the lowest unit in ETH
// equivalent to 1 wei.
// if(offer.lastSellValue > msg.value && (msg.value - offer.lastSellValue) >= uint(0.0000000000000001) ){ commented because we're assuming values are expressed in "weis", adjusting in relation to that
if(offer.lastSellValue < amount && (amount - offer.lastSellValue) >= 100 ){ // assuming 100 (weis) wich is equivalent to 1e-16
uint profit = amount - offer.lastSellValue;
// seller gets base value plus 60% of the profit
pendingWithdrawals[seller] += offer.lastSellValue + (profit*60/100);
// dada gets 10% of the profit
// pendingWithdrawals[owner] += (profit*10/100);
// dada receives 30% of the profit to give to the artist
// pendingWithdrawals[owner] += (profit*30/100);
pendingWithdrawals[owner] += (profit*40/100);
}else{
// if the seller doesn't make a profit of the sell he gets the 100% of the traded
// value.
pendingWithdrawals[seller] += amount;
}
// does the same as the function makeCollectibleUnavailableToSale
OfferedForSale[printIndex] = Offer(false, collectible.drawingId, printIndex, bid.bidder, 0, 0x0, amount);
CollectibleBought(collectible.drawingId, printIndex, bid.value, seller, bid.bidder);
Bids[printIndex] = Bid(false, collectible.drawingId, printIndex, 0x0, 0);
}
// used by a user who wants to cashout his money
function withdraw() {
require(isExecutionAllowed);
uint amount = pendingWithdrawals[msg.sender];
// Remember to zero the pending refund before
// sending to prevent re-entrancy attacks
pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
// Transfer ownership of a punk to another user without requiring payment
function transfer(address to, uint drawingId, uint printIndex) returns (bool success){
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
// checks that the user making the transfer is the actual owner of the print
require(DrawingPrintToAddress[printIndex] == msg.sender);
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
makeCollectibleUnavailableToSale(to, drawingId, printIndex, OfferedForSale[printIndex].lastSellValue);
// sets the new owner of the print
DrawingPrintToAddress[printIndex] = to;
balances[msg.sender]--;
balances[to]++;
Transfer(msg.sender, to, 1);
CollectibleTransfer(msg.sender, to, drawingId, printIndex);
// Check for the case where there is a bid from the new owner and refund it.
// Any other bid can stay in place.
Bid storage bid = Bids[printIndex];
if (bid.bidder == to) {
// Kill bid and refund value
pendingWithdrawals[to] += bid.value;
Bids[printIndex] = Bid(false, drawingId, printIndex, 0x0, 0);
}
return true;
}
// utility functions
function makeCollectibleUnavailableToSale(address to, uint drawingId, uint printIndex, uint lastSellValue) {
require(isExecutionAllowed);
require(drawingIdToCollectibles[drawingId].drawingId != 0);
Collectible storage collectible = drawingIdToCollectibles[drawingId];
require(DrawingPrintToAddress[printIndex] == msg.sender);
require((printIndex < (collectible.totalSupply+collectible.initialPrintIndex)) && (printIndex >= collectible.initialPrintIndex));
OfferedForSale[printIndex] = Offer(false, collectible.drawingId, printIndex, to, 0, 0x0, lastSellValue);
// launch the CollectibleNoLongerForSale event
CollectibleNoLongerForSale(collectible.drawingId, printIndex);
}
function newCollectible(uint drawingId, string checkSum, uint256 _totalSupply, uint initialPrice, uint initialPrintIndex, string collectionName, uint authorUId, string scarcity){
// requires the sender to be the same address that compiled the contract,
// this is ensured by storing the sender address
// require(owner == msg.sender);
require(owner == msg.sender);
// requires the drawing to not exist already in the scope of the contract
require(drawingIdToCollectibles[drawingId].drawingId == 0);
drawingIdToCollectibles[drawingId] = Collectible(drawingId, checkSum, _totalSupply, initialPrintIndex, false, initialPrice, initialPrintIndex, collectionName, authorUId, scarcity);
}
function flipSwitchTo(bool state){
// require(owner == msg.sender);
require(owner == msg.sender);
isExecutionAllowed = state;
}
function mintNewDrawings(uint amount){
require(owner == msg.sender);
totalSupply = totalSupply + amount;
balances[owner] = balances[owner] + amount;
Transfer(0, owner, amount);
}
}