A game of two players. Joining costs exactly 10 ether.
contract RPS {
uint nPlayers;
mapping (address => move) public moves;
function addPlayer(uint move) returns (boolean success) {
if (nPlayers < 2 && msg.value >= 10) {
moves[msg.sender] = move;
nPlayers++;
return true;
else {
return false;
}
}
//[...]
}
Ether is not handled correctly!
Amended version
contract RPS {
uint nPlayers;
mapping (address => uint) public moves;
function addPlayer(uint move) returns (boolean success) {
if (nPlayers < 2 && msg.value >= 10) {
moves[msg.sender] = move;
nPlayers++;
msg.sender.send(msg.value - 10);
return true;
else {
msg.sender.send(msg.value);
return false;
}
}
//[...]
}
Better, but the move is still revealed!
Mistake | Solution |
---|---|
No handling of ether | Encode ether flow in the type system |
Openly communicating secret information | Include crypto schemes in the language and stdlib |
We start by including ether in the type signature:
addPlayer : Int -> (success : Bool)
{ IN: value >= 10 }
Describe ether flow:
addPlayer : Int -> (success : Bool)
{ IN: value >= 10;
SEND: success ? value - 10 : value;
SAVE: success ? 10 : 0 }
Hide player move
addPlayer : Commit Int -> (success : Bool)
{ IN: value >= 10;
SEND: success ? value - 10 : value;
SAVE: success ? 10 : 0 }
open : Commit a -> a
addPlayer : Commit Int -> (success : Bool)
{ IN: value >= 10;
SEND: success ? value - 10 : value;
SAVE: success ? 10 : 0 }
addPlayer {value} move = if !nPlayers < 2
then do save 10
send (value-10) !sender
// save move
// increment counter
return True
else do send value !sender
return False
An expressive type-system can...
- https://github.com/vindaloo-thesis/examples
- Questions? Feedback? Ideas? Talk to us! :)