
Functions must be annotated as `stateful` in order to - Update the contract state (using `put`) - Call `Chain.spend` or other primitive functions that cost tokens - Call an Oracle or AENS function that requires a signature - Make a remote call with a non-zero value - Construct a lambda calling a stateful function It does not need to be stateful to - Read the contract state - Call another contract with value=0, even when the remote function is stateful
44 lines
1.4 KiB
Plaintext
44 lines
1.4 KiB
Plaintext
//
|
|
// Dutch auction example
|
|
//
|
|
contract DutchAuction =
|
|
|
|
record state = { start_amount : int,
|
|
start_height : int,
|
|
dec : int,
|
|
beneficiary : address,
|
|
sold : bool }
|
|
|
|
// Add to work around current lack of predefined functions
|
|
private stateful function spend(to, amount) =
|
|
let total = Contract.balance
|
|
Chain.spend(to, amount)
|
|
total - amount
|
|
|
|
private function require(b : bool, err : string) =
|
|
if(!b) abort(err)
|
|
|
|
// TTL set by user on posting contract, typically (start - end ) div dec
|
|
public function init(beneficiary, start, decrease) : state =
|
|
require(start > 0 && decrease > 0, "bad args")
|
|
{ start_amount = start,
|
|
start_height = Chain.block_height,
|
|
beneficiary = beneficiary,
|
|
dec = decrease,
|
|
sold = false }
|
|
|
|
// -- API
|
|
|
|
// We are the buyer... interesting case to buy for someone else and keep 10%
|
|
public stateful function bid() =
|
|
require( !(state.sold), "sold")
|
|
let cost =
|
|
state.start_amount - (Chain.block_height - state.start_height) * state.dec
|
|
require( Contract.balance >= cost, "no money")
|
|
|
|
// transaction(SpendTx({recipient = state.beneficiary,
|
|
// amount = cost })) // or self.balance ** burn money **
|
|
spend(state.beneficiary, cost)
|
|
spend(Call.caller, Contract.balance)
|
|
put(state{sold = true})
|