Skip to content

Instantly share code, notes, and snippets.

@goodjoon
Created March 27, 2016 13:18
Show Gist options
  • Select an option

  • Save goodjoon/4b76dc040bc2ab2d77ef to your computer and use it in GitHub Desktop.

Select an option

Save goodjoon/4b76dc040bc2ab2d77ef to your computer and use it in GitHub Desktop.
contract BlindAuction {
struct Bid {
bytes32 blindedBid;
uint deposit;
}
address public beneficiary;
uint public auctionStart;
uint public biddingEnd;
uint public revealEnd;
bool public ended;
mapping(address => Bid[]) public bids;
address public highestBidder;
uint public highestBid;
event AuctionEnded(address winner, uint highestBid);
// modifier 는 함수로의 input 을 validation 하는 편리한 방법임
// onlyBefore : `bid` 에 아래와 같이 적용 됨
// 신규 함수의 body 는 modifier 의 _ 가 예전 함수의 body 로 대체되어짐
modifier onlyBefore(uint _time) { if (now >= _time) throw; _ }
modifier onlyAfter(uint _time) { if (now <= _time) throw; _ }
function BlindAuction(uint _biddingTime,
uint _revealTime, address _beneficiary) {
beneficiary = _beneficiary;
auctionStart = now;
biddingEnd = now + _biddingTime;
revealEnd = biddingEnd + _revealTime;
}
// blinded bid 를 _blindedBid = sha3(value, fake, secret) 으로 한다
// 보내진 ether 는 revealing phase 에서 제대로 reveal 되었을 때
// 에만 refund 된다.
function bid(bytes32 _blindedBid)
onlyBefore(biddingEnd) {
bids[msg.sender].push(Bid(
{
blindedBid: _blindedBid,
deposit: msg.value
}));
}
// blinded bids 를 reveal 한다. 모든 적합한 blinded 무효한 bids 와
// 최고 높은 가격을 뺀 나머지 bids 에 대해서 refund 를 한다.
function reveal(uint[] _values, bool[] _fake, bytes32[] _secret)
onlyAfter(biddingEnd)
onlyBefore(revealEnd) {
uint length = bids[msg.sender].length;
if(_values.length != length || _fake.length != length ||
_secret.length != length) throw;
uint refund;
for (uint i = 0 ; i < length ; i++) {
var bid = bids[msg.sender][i];
var (value, fake, secret) = (_values[i], _fake[i], _secret[i]);
if (bid.blindedBid != sha3(value, fake, secret))
continue;
refund += bid.deposit;
if (!fake && bid.deposit >= value)
if (placeBid(msg.sender, value))
refund -= value;
bid.blindedBid = 0;
}
msg.sender.send(refund);
}
// internal function 은 contract 내부에서만 불릴 수 있다.
// 또는 상속받은 contract 에서만 불릴 수 있다.
function placeBid(address bidder, uint value) internal
returns (bool success) {
if (value <= highestBid)
return false;
if (highestBidder != 0)
highestBidder.send(highestBid);
highestBid = value;
highestBidder = bidder;
return true;
}
function auctionEnd()
onlyAfter(revealEnd) {
if (ended) throw;
AuctionEnded(highestBidder, highestBid);
beneficiary.send(this.balance);
ended = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment