Source

coffee-craft / money.coffee

Dan Connolly 682d06f 































































































# 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

# ugh... in tracebacks, node.js gives .js line numbers, not .coffee


# js doesn't have immutable function args, does it?
# Guards can be translated to assert, but it's a little messy.

assert = require('assert')

makeMint = (name) ->
  [sealer, unsealer] = makeBrandPair(name)
  mint = {
    __printOn: (out) ->
      out.print("<#{name}'s mint>")

    makePurse: (balance) ->
      assert.ok(typeof balance == 'number' && balance >= 0)

      decr = (amount) ->
        assert.ok(0 < amount && amount < balance)
        balance -= amount

      purse = {
        __printOn: (out) ->
          out.print("<has #{balance} #{name} bucks>")
        getBalance: () -> balance
        sprout: () -> mint.makePurse(0)
        getDecr: () -> sealer.seal(decr)

        deposit: (amount, src) ->
          assert.ok(typeof amount == 'number')
          unsealer.unseal(src.getDecr())(amount)
          balance += amount
        }
      return purse
  }
  return mint


# let's see if I remember how to do this...
# nope. looked it up:
# http://wiki.erights.org/wiki/Walnut/Secure_Distributed_Computing/Capability_Patterns
makeBrandPair = (hint) ->
  noObject = new Object()
  shared = noObject
  content = null
  makeSealedBox = (obj) -> { shareContent: () -> shared = obj }

  sealer = {
    seal: (it) -> makeSealedBox(it)
  }
  unsealer = {
    unseal: (box) ->
      shared = noObject
      box.shareContent()
      if (shared == noObject)
        throw new Error('invalid box')
      contents = shared
      shared = noObject
      contents
  }
  return [sealer, unsealer]


# eyeball-test makeBrandPair
[s, u] = makeBrandPair('bob')
x = s.seal('abc')
console.log(x)
console.log(u.unseal(x))

# connect the dots between node.js's console
# and http://wiki.erights.org/wiki/TextWriter
out = {
  print: (s) -> console.log(s)
}

# example from ode-capabilities.html
carolMint = makeMint("Carol")
carolMint.__printOn(out)
# value: <Carol's mint>

aliceMainPurse = carolMint.makePurse(1000)
aliceMainPurse.__printOn(out)
# value: <has 1000 Carol bucks>

bobMainPurse = carolMint.makePurse(0)
bobMainPurse.__printOn(out)
# value: <has 0 Carol bucks>


# struggling to figure out node.js module conventions
# I think module caching threw me off.
exports.makeBrandPair = makeBrandPair
exports.makeMint = makeMint