Skip to content
Turadg Aleahmad edited this page Feb 11, 2023 · 7 revisions

Once a person / object / process has a capability, it can always delegate by sending it to someone else. The caretaker pattern lets us grant access but then revoke it later.

As given in E, it's just a handful of lines of code:

def revocableCapabilityMaker(baseCapableObject)  {
     var capableObject := baseCapableObject
     def forwarder {
         to revoke() {capableObject := null}
         match [verb, args] {E.call(capableObject, verb, args)}
     }
     return forwarder
}

JavaScript provides Proxy.revocable. It's part of the ECMAScript language specification but if you were to implement it it would be something like:

function revocableCapabilityMaker(baseCapableObject)  {
  let capableObject = baseCapableObject;
  function revoke() { capableObject = null; }
  const proxy = new Proxy(baseCapableObject, {
    get(_obj, prop) { return capableObject[prop] }
  });
  return harden({ proxy, revoke });
}

As noted in #14, the js code is untested and somewhat incomplete, and an implementation in Rholang is complicated by lack of a spread operator to handle an arbitrary number of process arguments in a for construct.

new MakeRevokableForwarder in {
 2   contract MakeRevokableForwarder(target, ret) = {
 3     new port, kill, forwardFlag in {
 4       ret!(*port, *kill) |
 5       forwardFlag!(true) |
 6       contract port(msg) = {
 7         for (@status <- forwardFlag) {
 8           forwardFlag!(status) |
 9           match status { true => target!(*msg) }
10         }
11       } |
12       for (_ <- kill; _ <- forwardFlag) {
13         forwardFlag!(false)
14       }
15     }
16   }
17 }

References

Clone this wiki locally