code review: bet, mailing list contracts  


Member Moderator
Joined:10 months  ago
Posts: 24
19/05/2018 5:06 am  

At the dev conference in boulder, a bunch of us fumbled our way through writing a couple smart contracts: bet.rho and mailing-list.rho. After flailing around for most of the afternoon trying to figure out which language spec and examples went with which version of the interpreter, we we pretty happy to get something going. They do something, but I don't think they have the security properties one would expect and I doubt they are idiomatic rholang (is there such a thing?).

Is anyone interested to suggest improvements?

The bet contract should enforce the usual rules: both parties put in some money; based on the outcome of, say, a sporting match, one of us gets all of it and the other gets none. Neither of us nor any third party should be able to violate these usual rules. Each party should be assigned one or more channels to interact with. Some sketch about how to model a trusted oracle that announces the winner of the match would be nice.

In the mailing list contract, each party should be able to subscribe, and then when a message goes to the mailing list, each of us receives it. The contract should prevent me from forging a subscription request on behalf of anyone else, etc.

Member Moderator
Joined:11 months  ago
Posts: 42
21/05/2018 2:20 pm  

The bet contract you linked to doesn't seem to have much substance to it yet. I'll give an outline of how I would approach it though. Let's assume that the way oracles work is by passing their results on some known channels (e.g. maybe the basketball scores oracle gives data on the name `@"rho:nba/scores"`). I would write a "bet contract generator" contract which takes two arguments: the oracle data channel and a processing contract. The processing contract would map the data feed onto the domain of outcomes union an "undecided" element. For example, if the NBA oracle publishes data of the form `[date, [team1, score1], [team2, score2]]` and we were interested in a particular game between two particular teams then our processing contract would return "undecided" for any datum with the wrong date or teams and the winning team otherwise. These two arguments would need to be agreed upon by the participants out-of-band to begin with, and from them they would generate their betting contract. The betting contract itself would then be pretty straightforward. It would have a listener on the given data feed and when a new entry appeared it would processes and if the result was "undecided" then continue waiting, otherwise award the participant(s) who chose the winning value. Participants would register with the contract by providing three arguments: a purse containing their bet, the value they wish to bet on and the return channel on which their winnings should be sent. The betting contract would take the tokens from the given purse and put them in its own holder purse. Other logic would probably need to be included in practice like mandating a minimum betting amount, something related to odds, etc. But that is the bare basics of it.


The way you have your mailing list set up is fine as is I think (apart from a bug that you don't put back your subscribers after reading it in the mailbox method, line 14). To prevent "forging" a subscription, just divorce identity from the subscription to begin with. The subscribe method can just take one argument, the return channel, which will give the caller a new unforgable name they can listen on to get messages from the mailing list. So the call would look something like `subscribeMethod!(*ret) | for(ch <- ret){ contract ch(mailingListMessage){ ... } }`. This means that only those who actually call subscribe can receive messages from the mailing list. Perhaps a more interesting question is how to handle unsubscribing/garbage collection. You could do this by having the subscribe return an acknowledge channel as well, which expects a response back to say the message was received and if some number of acknowledgements are missed then remove the associated unforgable name from the mailing list. So then the subscribe call would look something like `subscribeMethod!(*ret) | for(ch, ack <- ret){ contract ch(mailingListMessage){ ack!("Message received!") | ... } }`.

dckc liked

Please Login or Register