public
Created

ocap money in scala

  • Download Gist
money.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
/** transcription of money example from "Smart Contracts"
http://www.erights.org/smart-contracts/index.html
http://www.erights.org/elib/capability/ode/ode-capabilities.html
*/
 
abstract class Purse { // should this go inside Mint somehow?
def getBalance(): Int // hmm... num type? typeclass trick?
def sprout(): Purse
def getDecr(): Object
def deposit(amount: Int, src: Purse)
}
 
class Mint(name: String) {
private val mint = this;
private val brand = new Brand[Function1[Int, Unit]](name)
 
override def toString(): String = "<#" + name + "'s mint>"
 
def makePurse(initialBalance: Int): Purse = {
assert(initialBalance >= 0)
var balance = initialBalance
 
val decr: Function1[Int, Unit] = { case (amount: Int) =>
assert(0 < amount && amount < balance)
balance -= amount
}
 
val purse = new Purse {
override def toString() = "<has #{" + balance + "} #{" + name + "} bucks>"
def getBalance() = balance
def sprout() = mint.makePurse(0)
def getDecr() = brand.sealer.seal(decr)
def deposit(amount: Int, src: Purse) {
brand.unsealer.unseal(src.getDecr())(amount)
balance += amount
}
}
return purse
}
}
 
 
/** Rights amplification
cf. http://wiki.erights.org/wiki/Walnut/Secure_Distributed_Computing/Capability_Patterns
*/
trait Sealer[T] {
def seal(it: T): Object
}
 
trait Unsealer[T] {
def unseal(x: Object): T
}
 
class Brand[T](hint: String) {
private var shared: Option[T] = None
 
override def toString() = "<brand: " + hint + ">"
 
class SealedBox(obj: T) {
def shareContent() { shared = Some(obj) }
override def toString() = "<sealed " + hint + " box>"
}
 
val sealer = new Object with Sealer[T] {
def seal(it: T) = new SealedBox(it)
override def toString() = "<sealer: " + hint + ">"
}
val unsealer = new Object with Unsealer[T] {
override def toString() = "<unsealer: " + hint + ">"
 
def unseal(x: Object): T = {
x match {
case box: SealedBox => {
shared = None
box.shareContent()
 
shared match {
case Some(content) => {
shared = None
content
}
case _ => throw new IllegalArgumentException("invalid box")
}
}
case _ => throw new IllegalArgumentException("ill-typed box")
}
}
}
}
 
 
object ocap_money extends Application {
// eyeball-test makeBrandPair
val b = new Brand[String]("bob")
val x = b.sealer.seal("abc")
println(x)
println(b.unsealer.unseal(x))
 
// example from ode-capabilities.html
val carolMint = new Mint("Carol")
println(carolMint) // value: <Carol's mint>
//println(carolMint.name) // does this compile? no. good.
 
val aliceMainPurse = carolMint.makePurse(1000)
println("alice has: " + aliceMainPurse) // value: <has 1000 Carol bucks>
 
val bobMainPurse = carolMint.makePurse(0)
println("bob has: " + bobMainPurse) // value: <has 0 Carol bucks>
 
println("transfer 50 from alice to bob.")
bobMainPurse.deposit(50, aliceMainPurse)
 
println("alice has: " + aliceMainPurse)
println("bob has: " + bobMainPurse)
 
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.