Skip to content

@dckc /money.scala
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
ocap money in scala
/** 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)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.