From 6dde02900259cd5440d40a479c444706aa38c26a Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Mon, 2 Dec 2024 09:31:20 -0800 Subject: [PATCH] Revert "docs: durable contract details collected in one place" This reverts commit 28cb2fb234d6fc011e4687fc031504754725fe1b. --- main/.vitepress/config.mjs | 4 - main/guides/zoe/contract-details.md | 122 ---------------------------- 2 files changed, 126 deletions(-) delete mode 100644 main/guides/zoe/contract-details.md diff --git a/main/.vitepress/config.mjs b/main/.vitepress/config.mjs index 02289f3ad..b797ad72a 100644 --- a/main/.vitepress/config.mjs +++ b/main/.vitepress/config.mjs @@ -216,10 +216,6 @@ export default defineConfig({ text: 'Complete Contract Walk-Through', link: '/guides/zoe/contract-walkthru', }, - { - text: 'Durable Contract Details', - link: '/guides/zoe/contract-details', - }, { text: 'Contract Upgrade', link: '/guides/zoe/contract-upgrade', diff --git a/main/guides/zoe/contract-details.md b/main/guides/zoe/contract-details.md deleted file mode 100644 index 3f3dfa25d..000000000 --- a/main/guides/zoe/contract-details.md +++ /dev/null @@ -1,122 +0,0 @@ -# Durable Contract Details - -Zoe allows you to write smart contracts that manage interactions between cooperative, but possibly untrusting, -parties. Some contracts perform a single simple task like trading one good for another, and then are -done. Others stay around and manage assets and interactions over time. The first kind don't need persistence -or the ability to upgrade, while the second kind need to make use of more sophisticated functionality. - -When a contract is intended to continue running and serving many customers over a long time, its objects and -data need to be persistent, its owners or managers may need to be able to adjust parameters or perform other -governance actions, and it needs to be upgradeable so that the code can adapt over time. - -## Durable Objects - -The first step toward contracts that can be upgraded is storing all the data that a later incarnation will -need. This means putting relevant state in -[Baggage](http://localhost:5173/guides/zoe/contract-upgrade.html#baggage), and ensuring that reachable objects -that will be accessible to users have an identity that can be maintained as the behavior changes with contract -upgrades. - -We use zone.exo(), zone.exoClass(), and zone.exoClassKit() to define durable objects. - -[Zone](http://localhost:5173/glossary/#zone) provides an interface for defining objects and classes that -supports both ephemeral objects (allocated on the heap), and durable objects that can persist and that -SwingSet will page in or out on demand. - -Our persistent objects are designed to encapsulate their state, and can present different facets to different -clients to distinguish different aspects of authority. `zone.exoClass()` defines a kind with a single facet, -while `zone.exoClassKit()` defines a kind with multiple facets. (Here are some relevant [naming -conventions](https://docs.agoric.com/guides/ertp/#method-naming-structure).) - -``` -zone.exoClassKit(tag, guard, init, methodKit, options) -zone.exoClass(tag, guard, init, methods, options) -zone.exo(tag, guard, methods, options) -``` - -The next several sub-sections explain how the parameters to those functions are used. - -### Tag: naming kinds of objects - -The `tag` provides the identity of the kind of object, which is associated with the defined behavior. When a -contract (or other vat) is restarted or upgraded, SwingSet requires that all kinds that were previously -defined in a vat be defined again. With an upgrade, the behavior can be changed. We use the term "null -upgrade" to refer to upgrades that don't change the behavior. - -### Init: specifying state - -The `init` parameter defines a function that is used to define the state associated with each instance of an -object. Notice that `exo()` doesn't take `init` as a parameter; this limits the defined (singleton) object to -referencing values defined in the enclosing scope. Classes can also refer to variables in their defining -scope, but any values inherited from the scope will be accessible to all instances of that type. The `init` -function's parameters become the parameters of the maker function returned by `exoClass()` and -`exoClassKit()`. `init`'s return value is the state that will be preserved by SwingSet for each -object. `exo()` doesn't have an init parameter, so it creates and returns the singleton immediately rather -than returning a maker. - -The Exo objects (or just "Exos") defined by these functions are both persistent and virtualizable. SwingSet -knows their complete state, so it can page them out when space is tight, and page them back in when they are -referenced again. - -Fields of the object returned by the `init` function become fields of the persistent state. (These cannot -currently be changed on upgrade, though we're considering relaxing that restriction.) Within methods they can -each be accessed as fields of `this.state`. Our convention is to extract the fields that will be used in a -method on its first line, like `const { a, b } = this.state;` Once that has been done, those variable can be -read or written as normal javascript variables, and the values will persist. (For more details, see [the note -here](https://docs.agoric.com/guides/zoe/contract-upgrade.html#kinds)). - -### Methods: defining behavior - -The methods argument of `exoClass()` is a bag of methods, written in [concise method -syntax](https://github.com/Agoric/agoric-sdk/wiki/Arrow-Function-Style#far-classes-do-not-use-arrow-function-style). -`exoClass()` defines a single facet. - -The methodKit parameter to `exoClassKit` is a record of labelled bags of methods. Each label defines a facet -of the object. All facets of each object share access to the same state, but each facet is a separate -capability. Within the methods, other facets can be reached by name within `this.facets`. The maker you get -from `exoClassKit()` builds a new object each time it is called, and return all the facets. The caller can -decide which of the facets to pass to each recipient. - -### Guards: defensive methods - -These objects and facets are designed to be durable and shareable across address space boundaries. Since code -in different vats might not be mutually trusting, code needs to be defensive about parameters received from -remote callers. Interface Guards let us express in code what parameters each method expects and can handle -safely. If a caller provides a parameter that doesn't match the template specified in the guard, SwingSet -returns an exception to the caller without notifying the receiver. If the return value doesn't match, the -function returns an exception to the caller. - -`exoClass()` takes a guard for a single interface, defined by - -``` -M.interface('name', { - methodA: M.call(paramsAShape).returns(resultAShape), - methodB: M.callWhen(M.await(paramsBShape)).returns(resultBShape), -} -``` - -`M.call()` verifies that all parameters match the guard before passing them through to the -method. `M.callWhen(M.await(paramsBGuard))` awaits the resolution of the parameter, and then verifies that the -result matches before invoking the method. When a guard is written this latter way, the method doesn't have to -be `async`. In both cases, the method doesn't have to check for compliance with the guard. - -[Shapes can specify](https://endojs.github.io/endo/interfaces/_endo_patterns.PatternMatchers.html) simple -types like `M.string()`, `M.remotable()`, and `M.number()`, as well as complex structures of records and -arrays. The list of parameters can specify required and optional parameters, as well as allowing unspecified -rest parameters. - -If you want to make use of the power of this type-checking within methods, you can call `mustMatch(specimen, -pattern)` or `matches(specimen, pattern)` directly. The former throws if the pattern doesn't match, while the -latter returns a boolean. - -### Options: finish and stateShape - -All the type definers can also take an [options -argument](https://endojs.github.io/endo/types/_endo_exo.FarClassOptions.html) at the end, which is commonly -used for a `finish()` function to complete initialization, or a stateShape, which can enforce invariants on -the state values. - -`finish()`, if provided, is called after instances have been created but before they are returned to the -caller. They can be used to send an initial state update, or to complete initialization which couldn't be done -in `init`. `finish` has access to state and facets if needed. -