-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathAuctionNFT.java
138 lines (121 loc) · 4.55 KB
/
AuctionNFT.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package bt.sample;
import bt.*;
import bt.compiler.CompilerVersion;
import bt.compiler.TargetCompilerVersion;
import bt.ui.EmulatorWindow;
/**
* Auction smart contract with a beneficiary and with 1% fee for creator.
*
* An Auction smart contract that will allow people to send funds which will be
* refunded back to them (minus the activation fee) if someone else sends more.
*
* This smart contract is initially closed and the beneficiary (the current owner)
* is the creator. Then one can call the {@link #open(Address, long, long)} method.
*
* After the auction times-out any new transaction received will trigger the auction
* closing logic. When closing, the current beneficiary receive the highest bid amount
* and the highest bidder becomes the new beneficiary. This new beneficiary can
* choose to open the auction again with a new timeout and new minimum bid value.
*
* Inspired by http://ciyam.org/at/at_auction.html
*
* @author jjos
*/
@TargetCompilerVersion(CompilerVersion.v0_0_0)
public class AuctionNFT extends Contract {
public static final long MIN_BALANCE = ONE_BURST * 4;
public static final long ACTIVATION_FEE = ONE_BURST * 30;
boolean isOpen;
Address beneficiary;
long highestBid;
Address highestBidder;
Timestamp timeout;
long newBid, fee;
/**
* Constructor, when in blockchain the constructor is called when the first TX
* reaches the contract.
*/
public AuctionNFT() {
beneficiary = getCreator();
}
/**
* Private function for checking if the timeout expired.
*
* @return true if this contract expired
*/
private boolean expired() {
if (!isOpen)
return true;
if (getBlockTimestamp().ge(timeout)) {
isOpen = false;
if (highestBidder != null) {
// we have a bidder
fee = highestBid / 100; // 1% fee
sendAmount(fee, getCreator());
// send the balance to the current beneficiary, minus the current TX
// amount (that will be refunded and a min balance to ensure the
// contract can run a few more lines of code)
sendAmount(getCurrentBalance() - getCurrentTxAmount() - MIN_BALANCE, beneficiary);
// set the new beneficiary
beneficiary = highestBidder;
}
}
return !isOpen;
}
/**
* Opens the auction giving a beneficiary, a timeout and a minimum price.
*
* @param timeout the number of minutes this auction will time out
* @param minBid the new minimum bid
* @param beneficiary the beneficiary of this auction, or null to keep the current one
*/
public void open(long timeout, long minBid, Address beneficiary) {
if (!isOpen && getCurrentTxSender() == this.beneficiary) {
// only the current beneficiary can re-open the auction
if(beneficiary!=null)
this.beneficiary = beneficiary;
this.timeout = getBlockTimestamp().addMinutes(timeout);
highestBid = minBid;
highestBidder = null;
isOpen = true;
}
}
/**
* Bids will be handled by this function, which is called when transactions are received.
*/
public void txReceived() {
if (expired()) {
// Send back this transaction funds
refund();
return;
}
newBid = getCurrentTxAmount() + ACTIVATION_FEE;
if (newBid > highestBid) {
// we have a new higher bid, return the previous one
if (highestBidder != null) {
sendAmount(highestBid - ACTIVATION_FEE, highestBidder);
}
highestBidder = getCurrentTxSender();
highestBid = newBid;
} else {
// Bid too low, just send back
refund();
}
}
/**
* Refunds the last received transaction
*/
private void refund() {
sendAmount(getCurrentTxAmount(), getCurrentTxSender());
}
public static void main(String[] args) throws Exception {
// some initialization code to make things easier to debug
Emulator emu = Emulator.getInstance();
Address creator = Emulator.getInstance().getAddress("BENEFICIARY");
emu.airDrop(creator, 1000 * Contract.ONE_BURST);
Address auction = Emulator.getInstance().getAddress("AUCTION");
emu.createConctract(creator, auction, AuctionNFT.class, Contract.ONE_BURST);
emu.forgeBlock();
new EmulatorWindow(AuctionNFT.class);
}
}