Skip to content

Access Control with Objects

In our third smart contract, we will demostrate how to control access to different functions of a smart contract. So far, we have only used publicFacet to expose all functions. There is an other facet, called creatorFacet that is provided only to the caller who creates the contract instance. In this smart contract, we limit the publicFacet API to a read-only function get(), and use creatorFacet API to expose the set() method to the caller who creates the contract instanace.

Here is the complete code for 03-access.js smart contract:

js
import { Far } from '@endo/far';

export const start = () => {
  let value = 'Hello, World!';
  const get = () => value;
  const set = v => (value = v);

  return {
    publicFacet: Far('ValueView', { get }),
    creatorFacet: Far('ValueCell', { get, set }),
  };
};

We can write a simple test as below to make sure that trying to set using the publicFacet throws an exception, but using the creatorFacet works:

js
test('access control', async t => {
  const { publicFacet, creatorFacet } = access.start();
  t.is(await E(publicFacet).get(), 'Hello, World!');
  await t.throwsAsync(E(publicFacet).set(2), { message: /no method/ });
  await E(creatorFacet).set(2);
  t.is(await E(publicFacet).get(), 2);
});

Note that the set() method has no access check inside it. Access control is based on separation of powers between the publicFacet, which is expected to be shared widely, and the creatorFacet, which is closely held. We'll discuss this object capabilities approach more later. If you're having trouble, check out the tut-03-access branch in the example repo.

Next, let's look at minting and trading assets with Zoe.