Skip to content

Instantly share code, notes, and snippets.

@TheCyberWatchers
Created October 3, 2022 08:20
Show Gist options
  • Save TheCyberWatchers/208b7e759d682dfc5b232d211fbba3a0 to your computer and use it in GitHub Desktop.
Save TheCyberWatchers/208b7e759d682dfc5b232d211fbba3a0 to your computer and use it in GitHub Desktop.
//index.mjs
import { loadStdlib } from "@reach-sh/stdlib";
import * as backend from './build/index.main.mjs';
const stdlib = loadStdlib();
const startingBalance = stdlib.parseCurrency(100);
const accAlice = await stdlib.newTestAccount(startingBalance);
const accBob = await stdlib.newTestAccount(startingBalance);
const fmt = (x) => stdlib.formatCurrency(x, 4);
const getBalance = async (who) => fmt(await stdlib.balanceOf(who));
const beforeAlice = await getBalance(accAlice);
const beforeBob = await getBalance(accBob);
const ctcAlice = accAlice.contract(backend);
const ctcBob = accBob.contract(backend, ctcAlice.getInfo());
const HAND = ['Rock', 'Paper', 'Scissors'];
const OUTCOME = ['Bob Wins!', 'Draw', 'Alice Wins!'];
const Player = (Who) => ({
...stdlib.hasRandom,
getHand: () => {
const hand = Math.floor(Math.random() * 3);
console.log(`${Who} played ${HAND[hand]}`)
return hand;
},
seeOutcome: (outcome) => {
console.log(`${Who} saw outcome ${OUTCOME[outcome]}`);
}
})
await Promise.all([
ctcAlice.p.Alice({
// Alice interact object here
...Player('Alice'),
wager: stdlib.parseCurrency(5),
}),
ctcBob.p.Bob({
// Bob interact object here
...Player('Bob'),
acceptWager: (amt) => {
console.log(`Bob accepts the wager of ${fmt(amt)}.`);
},
}),
]);
const afterAlice = await getBalance(accAlice);
const afterBob = await getBalance(accBob);
console.log(`Alice went from ${beforeAlice} to ${afterAlice}`);
console.log(`Bob went from ${beforeBob} to ${afterBob}`);
//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),
}
export const main = Reach.App(() => {
const Alice = Participant('Alice', {
// specify Alice's interact interface here
...Player,
wager: UInt,
})
const Bob = Participant('Bob', {
...Player,
acceptWager: Fun([UInt], Null),
})
init()
// write program here
Alice.only(() => {
const amount = declassify(interact.wager);
const _handAlice = interact.getHand();
const [ _commitAlice, _saltAlice ] = makeCommitment(interact, _handAlice);
const commitAlice = declassify(_commitAlice);
})
Alice.publish(commitAlice, amount)
.pay(amount)
commit()
unknowable(Bob, Alice(_handAlice, _saltAlice));
Bob.only(() => {
interact.acceptWager(amount);
const handBob = declassify(interact.getHand())
})
Bob.publish(handBob)
.pay(amount)
commit()
Alice.only(() => {
const saltAlice = declassify(_saltAlice);
const handAlice = declassify(_handAlice);
});
Alice.publish(saltAlice, handAlice);
checkCommitment(commitAlice, saltAlice, handAlice);
const outcome = winner(handAlice, handBob);
const [forAlice, forBob] =
outcome == A_WINS ? [2, 0] :
outcome == B_WINS ? [0, 2] :
[1, 1];
transfer(forAlice * amount).to(Alice);
transfer(forBob * amount).to(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