Rock, Paper, Scissors
Status: ReadyType: Multi-party
#lang glow
let winner = (handA : Nat, handB : Nat) : Nat => {
(handA + (4 - handB)) % 3
};
@interaction([A, B])
let rockPaperScissors = (wagerAmount) => {
@A let handA = input(Nat, "First player, pick your hand: 0 (Rock), 1 (Paper), 2 (Scissors)");
@A require! (handA < 3);
@A let salt = randomUInt256();
@verifiably!(A) let commitment = digest(salt, handA);
publish! A -> commitment;
deposit! A -> wagerAmount;
@B let handB = input(Nat, "Second player, pick your hand: 0 (Rock), 1 (Paper), 2 (Scissors)");
publish! B -> handB;
deposit! B -> wagerAmount;
require! (handB < 3);
publish! A -> salt, handA;
require! (handA < 3);
verify! commitment;
// outcome: 0 (B_Wins), 1 (Draw), 2 (A_Wins)
let outcome = winner(handA, handB);
switch (outcome) {
| 0 => withdraw! B <- 2*wagerAmount
| 1 => withdraw! A <- wagerAmount;
| 2 => withdraw! A <- 2*wagerAmount
withdraw! B <- wagerAmount
};
outcome
};
Buy Signature
Status: ReadyType: Multi-party
#lang glow
@interaction([Buyer, Seller])
let buySig = (digest : Digest, price : Nat) => {
deposit! Buyer -> price;
@publicly!(Seller) let signature = sign(digest);
// The line above is equivalent to the three below:
//// @verifiably!(Seller) let signature = sign(digest);
//// publish! Seller -> signature;
//// verify! signature; // This line is itself the same as the one below:
////// require! isValidSignature(Seller, signature, digest);
withdraw! Seller <- price;
};
Asset Swap
Status: In developmentType: Multi-party
#lang glow
@interaction({participants: [A, B], assets: [T, U]})
let swap = (t: Nat, u: Nat) => {
deposit! A -> { T: t };
deposit! B -> { U: u };
withdraw! B <- { T: t };
withdraw! A <- { U: u };
};
// Usage example:
/*
@interaction({participants: [alice, bob], assets: [ETH, DAI]}) swap(10, 2084)
*/
Crowdfunding
Status: In developmentType: Social
#lang glow
data Action = Pledge(TokenAmount) | Close | Reclaim(TokenAmount);
let platformCommission amount = quotient(amount, 100);
@interaction
let crowdfunding = (target: TokenAmount,
expirationTime : Timestamp) => {
require! expirationTime > currentTime();
let rec crowdfund = (ledger : Table(TokenAmount <- Participant),
totalPledged: TokenAmount) => {
assert! totalPledged == totalAmount(ledger);
choice {
| ForAllParticipant (NewPledger) {
@NewPledger amount =
input(["Enter next pledge"], TokenAmount);
publish! NewPledger -> Pledge(amount);
deposit! NewPledger -> amount;
require! currentTime() < expirationTime;
crowdfund(Table.add(ledger, NewPledger, amount),
totalPledged + amount);
| publish! Organizer -> Success;
require! currentTime() >= expirationTime;
require! totalPledged >= target;
let commission = platformCommission(totalPledged);
withdraw! Platform <- commission;
withdraw! Organizer <- totalPledged - commission;
| ForAllParticipant(Pledger)
publish! Pledger -> Reclaim(amount);
require! currentTime() >= expirationTime;
require! totalPledged < target;
require! Table.get(ledger, Pledger) == amount;
withdraw! Pledger <- amount;
crowdfund(Table.remove(ledger, Pledger),
totalPledged - amount);
}
crowdfund({}, 0);
}
Auction
Status: In developmentType: Social
#lang glow
data Action = Bid(TokenAmount) | BuyItNow | Close;
@interaction([Seller])
let simpleAuction = (goods : Assets, expirationTime : Timestamp, buyItNowPrice: TokenAmount) => {
require! Assets.is_positive(goods);
require! expirationTime > currentTime();
deposit! Seller -> goods; // escrow for the goods (TODO: also allow auction of services with an escrow)
@interaction([Seller, CurrentBidder])
let rec auction = (currentBid) => {
assert! @deposited == goods + currentBid;
choice {
| ForAllParticipant (NewBidder) {
@NewBidder bid = Bid(input(["Enter next bid"], TokenAmout));
publish! NewBidder -> bid ; deposit! NewBidder -> bid;
@NewBidder assume! @value(goods) > @value(bid);
require! currentTime() < expirationTime;
require! bid > currentBid;
//optional: require! bid < buyItNowPrice;
withdraw! CurrentBidder <- currentBid;
@interaction([Seller, NewBidder]) auction(bid);
| ForAllParticipant (NewBidder) {
publish! NewBidder -> BuyItNow ; deposit! NewBidder -> buyItNowPrice;
//optional: require! currentTime() < expirationTime;
withdraw! NewBidder <- goods;
withdraw! CurrentBidder <- currentBid;
withdraw! Seller <- buyItNowPrice;
| { publish! _ -> Close; } => // only Seller and currentBidder are interested in it.
require! currentTime() >= expirationTime;
withdraw! Seller <- currentBid;
withdraw! CurrentBidder <- goods;
};
@interaction([Seller, Seller]) auction(0);
}