From f47fd29baddd7b05439d0db5285b3c36a6da6fe3 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Tue, 3 Dec 2024 14:12:11 -0800 Subject: [PATCH] docs: more detail and more cross links --- main/guides/zoe/contract-upgrade.md | 57 ++++++++++++++------------- main/reference/zoe-api/zoe.md | 32 ++++++++++++++- snippets/zoe/src/02b-state-durable.js | 8 ++-- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/main/guides/zoe/contract-upgrade.md b/main/guides/zoe/contract-upgrade.md index 793a19ef1..d0b930a4a 100644 --- a/main/guides/zoe/contract-upgrade.md +++ b/main/guides/zoe/contract-upgrade.md @@ -1,8 +1,12 @@ # Contract Upgrade -The result of starting a contract includes the right to upgrade the contract instance. A call to [E(zoe).startInstance(...)](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) returns a record of several objects that represent different levels of access. -The `publicFacet` and `creatorFacet` are defined by the contract. -The `adminFacet` is defined by Zoe and includes methods to upgrade the contract. +The return value when starting a contract includes a capability that conveys the right to upgrade +the contract instance. A call to +[E(zoe).startInstance(...)](/reference/zoe-api/zoe.md#e-zoe-startinstance-installation-issuerkeywordrecord-terms-privateargs) +returns a record of several objects that carry different powers. The `publicFacet` and +`creatorFacet` are defined by the contract. The +[`adminFacet`](/reference/zoe-api/zoe.html#adminFacet) is defined by Zoe and includes methods to +upgrade the contract. ::: tip Upgrade Governance @@ -60,16 +64,27 @@ There are a few requirements for the contract that differ from non-upgradable co ### Upgradable Declaration -The new code bundle declares that it supports upgrade by exporting a `prepare` function in place of `start`. +The new code bundle declares that it supports upgrade by including a `meta` record in addition to +`start`. (We used to indicate upgradability by using `prepare` instead of `start`, but that +approach is deprecated.)` -<<< @/../snippets/zoe/src/02b-state-durable.js#export-prepare +`meta` is a record with any or all of `upgradability`, `customTermsShape`, and `privateArgsShape` +defined. The latter two are optional +[Patterns](https://endojs.github.io/endo/modules/_endo_patterns.html) restricting respectively +acceptable `terms`, and `privateArgs`. `upgradability` can be `none` (the contract is not +upgradable), `canUpgrade` (this code can perform an upgrade), or `canBeUpgraded` (the contract +stores kinds durably such that the next version can upgrade). + +<<< @/../snippets/zoe/src/02b-state-durable.js#export-start ### Durability -The 3rd argument, `baggage`, of the `prepare` function is a `MapStore` -that provides a way to preserve state and behavior of objects -between incarnations in a way that preserves identity of objects -as seen from other vats: + + +The 3rd argument, `baggage`, of the `start` function is a `MapStore` that is saved by the kernel +across restarts of the contract. It provides a way to preserve state and behavior of objects between +incarnations in a way that also maintains the identity of objects as seen from other [vats](/glossary/#vat). + ```js let rooms; @@ -83,7 +98,7 @@ if (!baggage.has('rooms')) { } ``` -The `provide` function supports a concise idiom for this find-or-create pattern: +The `provide` function supports a concise idiom for this get-or-create pattern: ```js import { provide } from '@agoric/vat-data'; @@ -113,7 +128,8 @@ When the contract instance is restarted, its [vat](../js-programming/#vats-the-u ### Kinds -Use `zone.exoClass()` to define state and methods of kinds of durable objects such as `Room`: +Use [`zone.exoClass()`](./contract-details.md#durable-objects) to define state and methods of kinds +of durable objects such as `Room`: <<< @/../snippets/zoe/src/02b-state-durable.js#exoclass @@ -141,8 +157,9 @@ const makeRoom = zone.exoClass('Room', RoomI, id => ({ id, value: 0 }), { }); ``` -The interface guard also needs updating. -_See [@endo/patterns](https://endojs.github.io/endo/modules/_endo_patterns.html) for more on interface guards._ +The interface guard also needs updating. _[The Durable +objects](./contract-details.md#guards-defensive-methods) section has more on interface +guards._ ```js const RoomI = M.interface('Room', { @@ -175,20 +192,6 @@ Define all exo classes/kits before any incoming method calls from other vats -- ::: -### Baggage - -baggage is a MapStore that provides a way to preserve the state and behavior of objects between [smart contract upgrades](/guides/zoe/contract-upgrade) in a way that preserves the identity of objects as seen from other [vats](#vat). In the provided contract, baggage is used to ensure that the state of various components is maintained even after the contract is upgraded. - -```js -export const start = async (zcf, privateArgs, baggage) => { - // ... - const { accountsStorageNode } = await provideAll(baggage, { - accountsStorageNode: () => E(storageNode).makeChildNode('accounts') - }); - // ... -}; -``` - ### Exo An Exo object is an exposed Remotable object with methods (aka a [`Far`](/guides/js-programming/far) object) which is diff --git a/main/reference/zoe-api/zoe.md b/main/reference/zoe-api/zoe.md index fd2c8b255..0f913c7f2 100644 --- a/main/reference/zoe-api/zoe.md +++ b/main/reference/zoe-api/zoe.md @@ -269,24 +269,54 @@ It returns a **Promise** for a **StartInstanceResult** object. The object consis - **instance**: **Instance** - **creatorInvitation**: **Payment | undefined** -The **adminFacet** has one method: + + +The **adminFacet** has four methods: - **getVatShutdownPromise()** - Returns a promise that resolves to reason (the value passed to **fail(reason)**) or completion (the value passed to **exit(completion)**) when this newly started instance terminates. +- **restartContract(newPrivateArgs?)** + - **newPrivateArgs**: **any** - Optional + - returns VatUpgradeResults (a record with one field: incarnationNumber) + + Restarts the contract without changing the contract bundle + +- **upgradeContract(contractBundleId, newPrivateArgs)** + - **contractBundleId**: **string** + - **newPrivateArgs**: **any** - Optional + + - returns VatUpgradeResults (a record with one field: incarnationNumber) + + Upgrades the contract to use source code from a new bundle. + + See [Contract Upgrade](/guides/zoe/contract-upgrade) for a description the + process of upgrading contracts. + +- **terminateContract(reason)** + - **reason**: **Error** + + terminates the contract. `reason` will be provided as the failure reason. + + + A **publicFacet** is an object available via Zoe to anyone knowing the instance they are associated with. The **publicFacet** is used for general queries and actions, such as getting a current price or creating public **[Invitations](./zoe-data-types#invitation)**. Since a facet is defined just as any other object, the contract developer can add methods to them just like they would any object. + + The **creatorFacet** is only available in this return value (i.e. only when starting a contract instance). The contract designer should use it to encapsulate things that the contract runner might not want to share, or might want to control the distribution of. The party who starts the contract should carefully consider the impact before sharing access to the **creatorFacet**. + + **creatorInvitation** is an **Invitation** that the contract instance creator can use. It is usually used in contracts where the creator immediately sells something (auctions, swaps, etc.), so it's helpful for the creator to have diff --git a/snippets/zoe/src/02b-state-durable.js b/snippets/zoe/src/02b-state-durable.js index 7571510a9..dc5083da3 100644 --- a/snippets/zoe/src/02b-state-durable.js +++ b/snippets/zoe/src/02b-state-durable.js @@ -17,9 +17,11 @@ const RoomMakerI = M.interface('RoomMaker', { }); // #endregion interface-guard -// #region export-prepare -export const prepare = (_zcf, _privateArgs, baggage) => { - // #endregion export-prepare +// #region export-start +export const meta = { upgradability: 'canUpgrade' }; + +export const start = (_zcf, _privateArgs, baggage) => { + // #endregion export-start // #region zone1 const zone = makeDurableZone(baggage); const rooms = zone.mapStore('rooms');