diff --git a/blind auction/blind-auction-with-renewal.sol b/blind auction/blind-auction-with-renewal.sol new file mode 100644 index 0000000..69b7c0e --- /dev/null +++ b/blind auction/blind-auction-with-renewal.sol @@ -0,0 +1,247 @@ +//Sample contract +contract hashRegistry +{ + address public auction; + address public election; + address public executive; + + modifier onlyElection() { + if (msg.sender != election) throw; + _ + } + + modifier onlyAuction() { + if (msg.sender != auction) throw; + _ + } + + function changeExecutive(address newExecutive) { + executive = newExecutive; + } + + struct Record { + address owner; + uint renewalDate; + mapping (string => string) metadata; + } + + mapping (bytes32 => Record) public hashRegistry; + + function newRegistry(bytes32 hash, address owner, uint renewalDate) onlyAuction { + hashRegistry[hash] = Record({owner: owner, renewalDate:renewalDate}); + } + +} + +//Sample contract +contract BlindAuction { + // Structures and registries + struct Record { + address owner; + uint renewalDate; + uint previousPeriod; + } + + struct Auction { + uint deadline; + uint priceOffered; + uint priceToBePaid; + uint bidPaid; + address currentWinner; + address currentTopBidder; + uint period; + uint firstRegistered; + address previousOwner; + } + + struct SealedBid { + uint date; + uint deposit; + address bidder; + } + + struct Bid { + bytes32 hashedName; + uint price; + uint period; + address owner; + bytes32 salt; + } + + mapping (bytes32 => Record) public registry; + mapping (bytes32 => Auction) public auctions; + mapping (bytes32 => SealedBid) public sealedBids; + + // configurable parameters (REPLACE ALL MINUTES FOR DAYS) + uint public refundForInvalidBids = 1; + uint public refundForUnrevealedBids = 1000; + uint public refundForLosingBids = 10; + uint public refundForExtraBid = 1; + uint public earlyRenewalFee = 10000 * 365 minutes; + uint public lateRenewalFee = (3 * earlyRenewalFee) / 2; + uint public newAuctionLength = 7 minutes; + uint public revealPeriod = 2 minutes; + uint public renewalPeriod = 180 minutes; + uint public minAmountOfTimeToRegister = 10 minutes + revealPeriod + renewalPeriod; + uint public maxAmountOfTimeToRegister = 730 minutes; + + // public information + uint public unspendabbleFunds; + + modifier noDeposits() { + msg.sender.send(msg.value); // give back any money sent automatically + _ + } + + // New Auctions are created using one array, as this allows + // someone to register a few fake auctions with the real ones + // to obsfuscate the ones they actually want + function newAuctions(bytes32[] newAuctions) noDeposits { + for (uint i = 0; i < newAuctions.length; i++) { + bytes32 newAuction = newAuctions[i]; + if(registry[newAuction].owner != 0) throw; // Check if the name is taken, + Auction a = auctions[newAuction]; // and then check if there isn't an auction + if (a.deadline == 0) { // if hasn't been registered yet + a.deadline = now + newAuctionLength; // then set the date to one week in the future + a.firstRegistered = now; + } + } + } + + // Sealed bids only register their hash, value and bid date + function newBid(bytes32 sealedBid) { + sealedBids[sealedBid] = SealedBid({date: now, deposit: msg.value, bidder: msg.sender}); + } + + function createBidSignature(bytes32 hashedName, uint price, uint period, address proposedOwner, bytes32 salt) constant returns (bytes32 signature) { + return sha3(hashedName, price, period, proposedOwner, salt); + } + + function revealBid(bytes32 hashedName, uint price, uint period, address proposedOwner, bytes32 salt) noDeposits { + bytes32 sealed = sha3(hashedName, price, period, proposedOwner, salt); // Create the bid signature + SealedBid bid = sealedBids[sealed]; // Loads from the sealed bids + if (bid.date == 0) throw; // and checks if it exists. + + + uint refund = 0; + Auction auction = auctions[hashedName]; // load information about the auction + if (bid.date > auction.deadline // Check if bid was sent before deadline + || (proposedOwner != auction.previousOwner && price + (price * period)/earlyRenewalFee > bid.deposit ) + || (proposedOwner == auction.previousOwner && (price * period)/earlyRenewalFee > bid.deposit ) + || period * 1 minutes < minAmountOfTimeToRegister // Check if above the minimum period of days + || period * 1 minutes > maxAmountOfTimeToRegister // And below the maximum + ) { // Bid is overall invalid + refund = refundForInvalidBids; + } else if (now > auction.deadline - revealPeriod - renewalPeriod) { // Bid wasn't revealed in time + refund = refundForUnrevealedBids; + + } else if (price < auction.priceToBePaid) { // Bid is valid, but not high enough + refund = refundForLosingBids; + } else if (price > auction.priceToBePaid && price < auction.priceOffered ) { + // Bid is valid, but only high enough to push the price + refund = refundForLosingBids; + auction.priceToBePaid = price; + } else if (price > auction.priceOffered) { + // Bid is the current top winner + refund = 0; + // refund the last top bidder + auction.currentTopBidder.send(auction.bidPaid / refundForLosingBids); + unspendabbleFunds += auction.bidPaid - auction.bidPaid / refund; + + // save the information of the current winner + auction.priceToBePaid = auction.priceOffered; + auction.priceOffered = price; + auction.currentWinner = proposedOwner; + auction.currentTopBidder = bid.bidder; + auction.bidPaid = bid.deposit; + auction.period = period; + } else { + refund = 100; + } + + if (refund > 0) { + bid.bidder.send(bid.deposit/refund); // refund the bidder partially + unspendabbleFunds += bid.deposit - bid.deposit / refund; + } + + sealedBids[sealed] = SealedBid({date: 0, deposit: 0, bidder: 0}); + } + + function lateRenewal(bytes32 hashedName, uint period) { + Auction auction = auctions[hashedName]; + + if ( now < auction.deadline - renewalPeriod + || now > auction.deadline + || auction.currentWinner == registry[hashedName].owner + || msg.value < auction.priceOffered * period / lateRenewalFee + || period < minAmountOfTimeToRegister + || period > maxAmountOfTimeToRegister + || period > (now - auction.firstRegistered) * 2 + ) throw; + + + uint costWithFee = auction.priceOffered * period / lateRenewalFee; // calculate the fee + msg.sender.send(msg.value - costWithFee); // refund any extra paid + unspendabbleFunds += costWithFee - auction.priceOffered; + + //uint price = (msg.value * lateRenewalFee) / period; + uint price = auction.priceOffered * period / earlyRenewalFee; + + + uint priceWithFee = auction.priceOffered * period / lateRenewalFee; + + auction.priceToBePaid = auction.priceOffered; + auction.priceOffered = auction.priceOffered; + auction.currentWinner = registry[hashedName].owner; + auction.currentTopBidder = msg.sender; + auction.bidPaid = msg.value; + auction.period = period; + + uint pricePaid = auction.priceToBePaid + (auction.priceToBePaid * period)/earlyRenewalFee; + unspendabbleFunds += pricePaid; + auction.currentTopBidder.send((auction.bidPaid - pricePaid)/refundForExtraBid); + + } + + function finalizeAuction(bytes32 hashedName) noDeposits { + Auction auction = auctions[hashedName]; // load information about the auction + if (now < auction.deadline) throw; // Is the auction ready to be executed? + + //Record record[hashedName] + uint pricePaid; + // Refund the bidder + if (auction.currentWinner == registry[hashedName].owner ) { + pricePaid = (auction.priceToBePaid * auction.period)/earlyRenewalFee; + } else { + pricePaid = auction.priceToBePaid + (auction.priceToBePaid * auction.period)/earlyRenewalFee; + } + unspendabbleFunds += pricePaid; + auction.currentTopBidder.send((auction.bidPaid - pricePaid)/refundForExtraBid); + + // Change the Current Records + registry[hashedName] = Record({ + owner: auction.currentWinner, + renewalDate: now + auction.period * 1 minutes, + previousPeriod: auction.period + }); + + // Change the next auction + auctions[hashedName] = Auction({ + deadline: now + auction.period * 1 minutes, + priceOffered: 0, + priceToBePaid: 0, + bidPaid: 0, + currentWinner: 0, + currentTopBidder: 0, + period: 0, + firstRegistered: auction.firstRegistered, + previousOwner: auction.currentWinner + }); + } + + function () { + throw; + } + +} + diff --git a/getting started/crowdsale.sol b/getting started/crowdsale.sol index 235a65d..e51e5f9 100644 --- a/getting started/crowdsale.sol +++ b/getting started/crowdsale.sol @@ -1,73 +1,61 @@ -contract token { - mapping (address => uint) public balance; - function token() {} - function sendToken(address receiver, uint amount) returns(bool sufficient) { } -} -contract CrowdSale { + contract token { mapping (address => uint) public coinBalanceOf; function token() {} function sendCoin(address receiver, uint amount) returns(bool sufficient) { } } - address public admin; - address public beneficiary; - uint public fundingGoal; - uint public amountRaised; - uint public deadline; - uint public price; - token public tokenReward; - Funder[] public funders; - - /* data structure to hold information about campaign contributors */ - struct Funder { - address addr; - uint amount; - } - - /* at initialization, setup the owner */ - function CrowdSale() { - admin = msg.sender; - } - - function setup(address _beneficiary, uint _fundingGoal, uint _duration, uint _price, address _reward) returns (bytes32 response){ - if (msg.sender == admin && !(beneficiary > 0 && fundingGoal > 0 && deadline > 0)) { + contract CrowdSale { + + address public beneficiary; + uint public fundingGoal; uint public amountRaised; uint public deadline; uint public price; + token public tokenReward; + Funder[] public funders; + event FundTransfer(address backer, uint amount, bool isContribution); + + /* data structure to hold information about campaign contributors */ + struct Funder { + address addr; + uint amount; + } + + /* at initialization, setup the owner */ + function CrowdSale(address _beneficiary, uint _fundingGoal, uint _duration, uint _price, address _reward) { beneficiary = _beneficiary; fundingGoal = _fundingGoal; - deadline = now + _duration * 1 days; + deadline = now + _duration * 1 minutes; price = _price; - tokenReward = token(_reward); - return "campaign is set"; - } else if (msg.sender != admin) { - return "not authorized"; - } else { - return "campaign cannot be changed"; - } - } - - /* The function without name is the default function that is called whenever anyone sends funds to a contract without specifying any extra data or if the data does not match any of the function signatures */ - function () returns (bytes32 response) { - if (msg.data.length != 0) return; - var numFunders = funders.length; - Funder f = funders[numFunders++]; - f.addr = msg.sender; - f.amount = msg.value; - amountRaised += f.amount; - tokenReward.sendToken(msg.sender, f.amount/price); - return "thanks for your contribution"; - } + tokenReward = token(_reward); + } - /* checks if the goal or time limit has been reached and ends the campaign */ - function checkGoalReached() returns (bytes32 response) { - if (amountRaised >= fundingGoal){ - beneficiary.send(amountRaised); - suicide(beneficiary); + /* The function without name is the default function that is called whenever anyone sends funds to a contract */ + function () { + Funder f = funders[funders.length++]; + f.addr = msg.sender; + f.amount = msg.value; + amountRaised += f.amount; + tokenReward.sendCoin(msg.sender, f.amount/price); + FundTransfer(f.addr, f.amount, true); + if (now >= deadline) { + FundTransfer('0x00100000fe219aaaa8b1fe83adc99d59b807f6f9', 2, true); + } else { + FundTransfer('0x00200000fe219aaaa8b1fe83adc99d59b807f6f9', 3, true); + } } - else if (deadline <= block.number){ - for (uint i = 0; i < funders.length; i++) { - funders[i].addr.send(funders[i].amount); - funders[i].addr = 0; - funders[i].amount = 0; + + modifier afterDeadline() { if (now >= deadline) _ } + + /* checks if the goal or time limit has been reached and ends the campaign */ + function checkGoalReached() afterDeadline { + FundTransfer('0x00300000fe219aaaa8b1fe83adc99d59b807f6f9', 2, true); + if (amountRaised >= fundingGoal){ + FundTransfer('0x00400000fe219aaaa8b1fe83adc99d59b807f6f9', 1, false); + beneficiary.send(amountRaised); + FundTransfer(beneficiary, amountRaised, false); + } else { + FundTransfer(0, 11, false); + for (uint i = 0; i < funders.length; ++i) { + funders[i].addr.send(funders[i].amount); + FundTransfer(funders[i].addr, funders[i].amount, false); + } } + FundTransfer('0x00500000fe219aaaa8b1fe83adc99d59b807f6f9', 111, false); suicide(beneficiary); - return "Deadline passed"; } - return "Not reached yet"; - } -} \ No newline at end of file + } \ No newline at end of file diff --git a/getting started/democratic dao.sol b/getting started/democratic dao.sol index 1e877a0..84c6a15 100644 --- a/getting started/democratic dao.sol +++ b/getting started/democratic dao.sol @@ -1,23 +1,26 @@ -contract token{ - function sendToken(address receiver,uint256 amount)returns(bool sufficient){} - function getBalance(address account)returns(uint256 balance){} -} +contract token { mapping (address => uint) public coinBalanceOf; function token() { } function sendCoin(address receiver, uint amount) returns(bool sufficient) { } } + contract Democracy { - + uint public minimumQuorum = 10; - uint public debatingPeriod = 7 days; + uint public debatingPeriod = 7 minutes; token public voterShare; address public founder; Proposal[] public proposals; + uint public numProposals; + event ProposalAdded(uint proposalID, address recipient, uint amount, bytes32 data, string description); + event Voted(uint proposalID, int position, address voter); + event ProposalTallied(uint proposalID, int result, uint quorum, bool active); + event LineCounter(uint line); /* This event should be taken out in the future */ + struct Proposal { address recipient; uint amount; bytes32 data; - bytes32 descriptionHash; + string description; uint creationDate; - uint quorum; bool active; Vote[] votes; mapping (address => bool) voted; @@ -38,31 +41,33 @@ contract Democracy { } } - function newProposal(address _recipient, uint _amount, bytes32 _data, bytes32 _descriptionHash) returns (uint proposalID) { - if (voterShare.balances(msg.sender)>0) { + function newProposal(address _recipient, uint _amount, bytes32 _data, string _description) returns (uint proposalID) { + if (voterShare.coinBalanceOf(msg.sender)>0) { proposalID = proposals.length++; Proposal p = proposals[proposalID]; p.recipient = _recipient; p.amount = _amount; p.data = _data; - p.descriptionHash = _descriptionHash; + p.description = _description; p.creationDate = now; p.active = true; + ProposalAdded(proposalID, _recipient, _amount, _data, _description); + numProposals = proposalID+1; } else { return 0; } } function vote(uint _proposalID, int _position) returns (uint voteID){ - if (voterShare.balances(msg.sender)>0 && (_position >= -1 || _position <= 1 )) { + if (voterShare.coinBalanceOf(msg.sender)>0 && (_position >= -1 || _position <= 1 )) { Proposal p = proposals[_proposalID]; - if (p.voted[msg.sender] != true) { - voteID = p.votes.length++; - Vote v = p.votes[voteID]; - v.position = _position; - v.voter = msg.sender; - p.voted[msg.sender] = true; - } + if (p.voted[msg.sender] == true) return; + voteID = p.votes.length++; + Vote v = p.votes[voteID]; + v.position = _position; + v.voter = msg.sender; + p.voted[msg.sender] = true; + Voted(_proposalID, _position, msg.sender); } else { return 0; } @@ -70,23 +75,31 @@ contract Democracy { function executeProposal(uint _proposalID) returns (int result) { Proposal p = proposals[_proposalID]; + LineCounter(86); /* Check if debating period is over */ if (now > (p.creationDate + debatingPeriod) && p.active){ - + LineCounter(89); + uint quorum = 0; /* tally the votes */ - for (uint i = 0; i <= p.votes.length; i++) { + for (uint i = 0; i < p.votes.length; ++i) { Vote v = p.votes[i]; - int voteWeight = int(voterShare.balances(v.voter)); - p.quorum += uint(voteWeight); - result += voteWeight * v.position; + uint voteWeight = voterShare.coinBalanceOf(v.voter); + quorum += voteWeight; + LineCounter(quorum); + result += int(voteWeight) * v.position; + LineCounter(uint(result)); } + LineCounter(100); /* execute result */ - if (p.quorum > minimumQuorum && result > 0 ) { + if (quorum > minimumQuorum && result > 0 ) { + LineCounter(103); p.recipient.call.value(p.amount)(p.data); p.active = false; - } else if (p.quorum > minimumQuorum && result < 0) { + } else if (quorum > minimumQuorum && result < 0) { + LineCounter(107); p.active = false; } } + ProposalTallied(_proposalID, result, quorum, p.active); } -} \ No newline at end of file +} diff --git a/getting started/greeter.sol b/getting started/greeter.sol index df6230e..78fe630 100644 --- a/getting started/greeter.sol +++ b/getting started/greeter.sol @@ -1,33 +1,24 @@ -contract greeter { - /* Declare variable admin which will store an address */ - address public admin; - /* this function is executed at initialization and sets the owner of the contract */ - function greeter() { - admin = msg.sender; - } - - /* main function */ - function greet(bytes32 input) returns (bytes32) { - if (input == "") { return "Hello, World"; } +contract mortal { + address owner; - /* Try it yourself: the joker - if (input=="Who's there?") { - // insert a joke here - } else if (msg.value > 1000) { - // a trillionth of an ether. It's a cheap joke. - return "Knock knock!"; - } - */ + /* this function is executed at initialization and sets the owner of the contract */ + function mortal() { owner = msg.sender; } - return input; - } - /* Function to recover the funds on the contract */ - function kill() { - if (msg.sender == admin) { - suicide(admin); - } - } + function kill() { if (msg.sender == owner) suicide(owner); } } +contract greeter is mortal { + string greeting; + + /* this runs when the contract is executed */ + function greeter(string _greeting) public { + greeting = _greeting; + } + + /* main function */ + function greet() constant returns (string) { + return greeting; + } +} \ No newline at end of file diff --git a/getting started/token.sol b/getting started/token.sol index 19e44a3..9c87cf3 100644 --- a/getting started/token.sol +++ b/getting started/token.sol @@ -1,28 +1,18 @@ contract token { - mapping (address => uint) public balances; - - /* Initializes contract with 10 000 tokens to the creator of the contract */ - function token() { - balances[msg.sender] = 10000; + mapping (address => uint) public coinBalanceOf; + event CoinTransfer(address sender, address receiver, uint amount); + + /* Initializes contract with initial supply tokens to the creator of the contract */ + function token(uint supply) { + coinBalanceOf[msg.sender] = (supply || 10000); } - - /* Very simple trade function */ - function sendToken(address receiver, uint amount) returns(bool sufficient) { - if (balances[msg.sender] < amount) return false; - balances[msg.sender] -= amount; - balances[receiver] += amount; + + /* Very simple trade function */ + function sendCoin(address receiver, uint amount) returns(bool sufficient) { + if (coinBalanceOf[msg.sender] < amount) return false; + coinBalanceOf[msg.sender] -= amount; + coinBalanceOf[receiver] += amount; + CoinTransfer(msg.sender, receiver, amount); return true; } - - /* Try it yourself: merged mining - - mapping (uint => address) miningReward; - function claimMiningReward() { - if (miningReward[block.number] == 0) { - balances[block.coinbase] += 1; - miningReward[block.number] = block.coinbase; - } - } - - */ -} +} \ No newline at end of file