Skip to content

Instantly share code, notes, and snippets.

@dckc
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dckc/a14b55af1d17d3100810 to your computer and use it in GitHub Desktop.
Save dckc/a14b55af1d17d3100810 to your computer and use it in GitHub Desktop.
# cf. http://www.erights.org/elib/capability/ode/ode-capabilities.html
def makeBrandPair := import("sealing")
def __makeOrderedSpace := import("regions") # for 0..balance
def makeMint(name):
def [sealer, unsealer] := makeBrandPair(name)
object mint:
to _printOn(out):
out.print(`<$name's mint>`) # ')
to makePurse(var balance :(int >= 0)) :any:
def decr(amount :(0..balance)) :void:
balance -= amount
object purse:
to _printOn(out) :void:
out.print(`<has $balance $name bucks>`)
to getBalance() :int:
return balance
to sprout() :any:
return mint.makePurse(0)
to getDecr() :any:
return sealer.seal(decr)
to deposit(amount :int, src) :void:
unsealer.unseal(src.getDecr())(amount)
balance += amount
return purse
return mint
def runTests := import("unittest")
def abc(assert):
def updoc(value, printed):
assert.equal(`$value`, printed)
def pay10():
# ... let's walk through how Alice pays Bob $10. First, let's
# model our initial conditions, where Alice and Bob each have
# a main purse of the same currency, and Alice already has at
# least $10.
updoc(def carolMint := makeMint("Carol"),
"<Carol's mint>")
updoc(def aliceMainPurse := carolMint.makePurse(1000),
"<has 1000 Carol bucks>")
updoc(def bobMainPurse := carolMint.makePurse(0),
"<has 0 Carol bucks>")
updoc(def paymentForBob := aliceMainPurse.sprout(),
"<has 0 Carol bucks>")
# Let's imagine that Carol (the mint owner) sends these purses
# as arguments in messages to Alice and Bob respectively.
# First, playing Alice, we would sprout a new purse from our
# main purse, and then transfer $10 into it:
paymentForBob.deposit(10, aliceMainPurse)
# Then, we send a foo request to Bob, providing the purse
# containing $10 as payment:
# ...
# So playing Bob, we perform
bobMainPurse.deposit(10, paymentForBob)
# Our new balances are
updoc(bobMainPurse.getBalance(),
"10")
updoc(aliceMainPurse.getBalance(),
"990")
return [pay10]
runTests([abc])
makeMint
# from wiki.erights.org/wiki/Walnut/Secure_Distributed_Computing/Capability_Patterns#Sealers_and_Unsealers
def makeBrandPair(nickname):
object noObject:
pass
var shared := noObject
def makeSealedBox(obj):
object box:
to shareContent():
shared := obj
to _printOn(t):
t.print(`<$nickname sealed box>`)
return box
object sealer:
to seal(obj):
return makeSealedBox(obj)
to _printOn(t):
t.print(`<$nickname sealer>`)
object unsealer:
to unseal(box):
shared := noObject
box.shareContent()
if (shared == noObject):
throw("invalid box")
def contents := shared
shared := noObject
return contents
to _printOn(t):
t.print(`<$nickname unsealer>`)
return [sealer, unsealer]
def runTests := import("unittest")
def t(assert):
def happy():
def [s, u] := makeBrandPair("bob")
assert.equal(`$s`, "<bob sealer>")
assert.equal(`$u`, "<bob unsealer>")
def x := s.seal("abc")
assert.equal(`$x`, "<bob sealed box>")
assert.equal(u.unseal(x), "abc")
def evil():
def [s, u] := makeBrandPair("bob")
def x := s.seal("abc")
def [ss, uu] := makeBrandPair("evil")
assert.raises(def _(fail){
uu.unseal(x)
})
return [happy, evil]
runTests([t])
makeBrandPair
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment