Skip to content

Instantly share code, notes, and snippets.

@TheCyberWatchers
Created October 3, 2022 12:48
Show Gist options
  • Save TheCyberWatchers/d77ece397cb2083b722c1d47954f6fc7 to your computer and use it in GitHub Desktop.
Save TheCyberWatchers/d77ece397cb2083b722c1d47954f6fc7 to your computer and use it in GitHub Desktop.
//index.mjs
import { loadStdlib, ask } from "@reach-sh/stdlib";
import * as backend from './build/index.main.mjs';
const stdlib = loadStdlib();
const isAlice = await ask.ask(
`Are you Alice?`,
ask.yesno
);
const who = isAlice ? 'Alice' : 'Bob'
console.log(`Starting Rock, Paper, Scissors! as ${Who}`);
let acc = null;
const createAcc = await ask.ask(
`Would you like to create an account? (only possible on devnet)`,
ask.yesno
);
if(createAcc){
acc = await stdlib.newTestAccount(stdlib.parseCurrency(1000));
} else {
const secret = await ask.ask(
`What is your account secret?`,
(x => x)
);
acc = await stdlib.newAccountFromSecret(secret);
}
let ctc = null;
if(isAlice){
ctc = acc.contract(backend);
ctc.getInfo().then((info) => {
console.log(`The contract is deployed as = ${JSON.stringify(info)}`);});
} else {
const info = await ask.ask(
`Please paste the contract information:`,
JSON.parse
);
ctc = acc.contact(backend, info)
}
const fmt = (x) => stdlib.formatCurrency(x, 4);
const getBalance = async () => fmt(await stdlib.balanceOf(acc));
const before = await getBalance();
console.log(`Your balance is ${before}`)
const interact = { ...stdlib.hasRandom };
interact.informTimeout = () => {
console.log(`There was a timeout.`);
process.exit(1);
};
if (isAlice) {
const amt = await ask.ask(
`How much do you want to wager?`,
stdlib.parseCurrency
);
interact.wager = amt;
interact.deadline = { ETH: 100, ALGO: 100, CFX: 1000 }[stdlib.connector];
} else {
interact.acceptWager = async (amt) => {
const accepted = await ask.ask(
`Do you accept the wager of ${fmt(amt)}?`,
ask.yesno
);
if(!accepted){
process.exit(0);
}
};
}
const HAND = ['Rock', 'Paper', 'Scissors'];
const HANDS = {
'Rock': 0, 'R': 0, 'r': 0,
'Paper': 1, 'P': 1, 'p': 1,
"Scissors": 2, 'S': 2, 's': 2,
};
interact.getHand = async () => {
const hand = await ask.ask(`What hand will you play?`, (x) => {
const hand = HANDS[x];
if (hand === undefined){
throw Error(`Not a valid hand ${hand}`);
}
return hand;
});
console.log(`You played ${HAND[hand]}`);
return hand;
};
const OUTCOME = ['Bob wins', 'Draw', 'Alice wins'];
interact.seeOutcome = async (outcome) => {
console.log(`The outcome is: ${OUTCOME[outcome]}`);
};
const part = isAlice ? ctc.p.Alice : ctc.p.Bob;
await part(interact);
const after = await getBalance();
console.log(`Your balance is now ${after}`);
ask.done();
//index.rsh
'reach 0.1';
const [ isHand, ROCK, PAPER, SCISSORS ] = makeEnum(3);
const [ isOutcome, B_WINS, DRAW, A_WINS ] = makeEnum(3);
const winner = (handAlice, handBob) =>
((handAlice + (4 - handBob)) % 3);
assert(winner(ROCK, PAPER) == B_WINS);
assert(winner(PAPER, ROCK) == A_WINS);
assert(winner(ROCK, ROCK) == DRAW);
forall(UInt, handAlice =>
forall(UInt, handBob =>
assert(isOutcome(winner(handAlice, handBob)))));
forall(UInt, (hand) =>
assert(winner(hand, hand) == DRAW));
const Player = {
...hasRandom,
getHand: Fun([], UInt),
seeOutcome: Fun([UInt], Null),
informTimeout: Fun([], Null),
};
export const main = Reach.App(() => {
const Alice = Participant('Alice', {
...Player,
wager: UInt, // atomic units of currency
deadline: UInt, // time delta (blocks/rounds)
});
const Bob = Participant('Bob', {
...Player,
acceptWager: Fun([UInt], Null),
});
init();
const informTimeout = () => {
each([Alice, Bob], () => {
interact.informTimeout();
});
};
Alice.only(() => {
const wager = declassify(interact.wager);
const deadline = declassify(interact.deadline);
});
Alice.publish(wager, deadline)
.pay(wager);
commit();
Bob.only(() => {
interact.acceptWager(wager);
});
Bob.pay(wager)
.timeout(relativeTime(deadline), () => closeTo(Alice, informTimeout));
var outcome = DRAW;
invariant( balance() == 2 * wager && isOutcome(outcome) );
while ( outcome == DRAW ) {
commit();
Alice.only(() => {
const _handAlice = interact.getHand();
const [_commitAlice, _saltAlice] = makeCommitment(interact, _handAlice);
const commitAlice = declassify(_commitAlice);
});
Alice.publish(commitAlice)
.timeout(relativeTime(deadline), () => closeTo(Bob, informTimeout));
commit();
unknowable(Bob, Alice(_handAlice, _saltAlice));
Bob.only(() => {
const handBob = declassify(interact.getHand());
});
Bob.publish(handBob)
.timeout(relativeTime(deadline), () => closeTo(Alice, informTimeout));
commit();
Alice.only(() => {
const saltAlice = declassify(_saltAlice);
const handAlice = declassify(_handAlice);
});
Alice.publish(saltAlice, handAlice)
.timeout(relativeTime(deadline), () => closeTo(Bob, informTimeout));
checkCommitment(commitAlice, saltAlice, handAlice);
outcome = winner(handAlice, handBob);
continue;
}
assert(outcome == A_WINS || outcome == B_WINS);
transfer(2 * wager).to(outcome == A_WINS ? Alice : Bob);
commit();
each([Alice, Bob], () => {
interact.seeOutcome(outcome);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment