-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #41 from Agoric/doc-tasks--dom
Completes some documentation tasks
- Loading branch information
Showing
10 changed files
with
245 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
# Contract Hosts | ||
|
||
ContractHost provides a way to install and run verifiable contracts. | ||
|
||
Install(source) creates Installations. Installations represent particular | ||
contract forms, which can be spawn()'d to create Contract instances | ||
initialized with specific terms. These Contracts manage invitations for | ||
multiple seats, each of which repesents a "role" in an interaction. | ||
|
||
Some seats provide the methods `getWinnings()` and `getRefunds()`, which return | ||
promises for payments for the outputs of the interaction. We provide the | ||
`collect()` method (described later) to simplify collection of winnings and | ||
refunds into appropriate purses. | ||
|
||
## contractHost.install(contractSrc) | ||
- `contractSrc` `{String}` - contractSrc is the source code for a Contract. See Contract for details. | ||
- Returns: `{Installation}` | ||
|
||
Install the source code for a Contract. | ||
|
||
```js | ||
const someEscrowInstallation = E(someHost).install(someEscrowExchangeSrc); | ||
``` | ||
|
||
## contractHost.getInstallationSourceCode(installation) | ||
- `installation` `{Installation}` | ||
- Returns: `{String}` | ||
|
||
Get the actual source code of the Installation. | ||
|
||
```js | ||
const theSourceCode = E(someHost).getInstallationSourceCode(someInstallation); | ||
``` | ||
|
||
## contractHost.redeem(invite) | ||
- `invite` `{Payment}` | ||
- Returns: `{Object}` | ||
|
||
Seat invitations are packaged as payments from the Invite Assay. Redeeming an invite returns a seat object with an arbitrary interface (the interface is at the discretion of the contract) which supports interaction according to the terms. | ||
|
||
```js | ||
const someSeat = E(someHost).redeem(someInvite); | ||
``` | ||
|
||
## contractHost.getInviteAssay() | ||
- Returns: `{Assay}` | ||
|
||
The assay allows holders of seat invitations to get exclusive access to a Seat. | ||
|
||
```js | ||
const assayWithExclusiveAccess = E(someHost).getInviteAssay(); | ||
``` | ||
|
||
## installation.spawn(terms) | ||
- `terms` `{Terms}` | ||
- Returns: `{Invites <Object>}` | ||
|
||
Create a new `InviteMaker`, then call the Contract's `start()` method and return its results. The results are often a collection of seat invitations for the seats in the contract, but see [`coveredCall`](https://github.com/Agoric/ERTP/blob/master/core/coveredCall.js) for an exception. | ||
|
||
```js | ||
import harden from '@agoric/harden'; | ||
|
||
const terms = harden({ left: whatPartyAWants, right: whatPartyBWants }); | ||
const invitePayments = E(someInstallation).spawn(terms); | ||
``` | ||
|
||
## installation.checkUnits(installation, inviteUnits, terms) | ||
- `installation` `{Installation}` | ||
- `inviteUnits` `{Units}` | ||
- `terms` `{Terms}` | ||
|
||
The writer of the contract can provide methods to help users of the contract verify that the terms of the contract match their expectation. These methods are defined with the installation as the first parameter, so the verifiers can validate that the caller's invitation was issued by the same one. The invocation by clients should omit the installation parameter, as they will be supplied with a copy of the function with that information already supplied. | ||
|
||
As a general rule of thumb, these methods' parameters should follow this order: | ||
1. `{Installation}` - Only required for development of contract, otherwise, omit. | ||
2. `{Units}` | ||
3. `{Terms}` | ||
4. Any additional parameters | ||
|
||
Users usually want to validate their invitation, the terms of the deal they're attempting to participate in, and which seat they are taking. If the invitation is invalid `checkUnits()` will throw an error. | ||
|
||
For example, the writer may provide a `checkUnits()` method that accepts the following parameters: `installation`, `inviteUnits`, `terms` and `seat`. However, on the user end, they would call `checkUnits()` and only use the `inviteUnits`, `terms` and `seat` parameters. | ||
|
||
```js | ||
// If `allegedInviteUnits` is valid and matches the terms of the | ||
// contract, then the code will continue as expected. | ||
// Otherwise, `checkUnits()` will throw an error. | ||
E(escrowExchangeInstallationP) | ||
.checkUnits(allegedInviteUnits, { left, right }, 'left') | ||
.then(() => { | ||
return E(inviteAssayP).claimExactly( | ||
allegedInviteUnits, | ||
allegedInvitePaymentP, | ||
'verified invite', | ||
); | ||
}); | ||
``` | ||
|
||
## contract.start(terms, inviteMaker) | ||
- `terms` `{Terms}` | ||
- `inviteMaker` `{InviteMaker}` | ||
- Returns: `{Object}` | ||
|
||
Start execution of the contract. May return invites for seats. | ||
|
||
```js | ||
import harden from '@agoric/harden'; | ||
|
||
const aNewContract = harden({ | ||
start: (terms, inviteMaker) => { | ||
// add contract code | ||
} | ||
}) | ||
|
||
export { aNewContract } | ||
|
||
// Now, `aNewContract` can be imported into other parts of your code | ||
// and used as an Installation using `contractHost.install(aNewContract)` | ||
// Also, see `installation.spawn()` above. | ||
``` | ||
|
||
## inviteMaker.make(seatDesc, seat, name) | ||
- `seatDesc` `{String}` - Must be unique for each contract instantiation. | ||
- `seat` `{Object}` - An arbitrary object defined by the contract. | ||
- `name` `{String}` - Labels the invite payment for this seat. Optional. | ||
- Returns: `{Payment}` | ||
|
||
Creates a payment for an invite for a seat in a contract. The returned Payment can be passed to `contractHost.redeem()` to get a seat Object. | ||
|
||
```js | ||
import harden from '@agoric/harden'; | ||
|
||
const aNewContract = harden({ | ||
start: (terms, inviteMaker) => { | ||
// other contract code | ||
const someSeat = harden({ | ||
// code for this seat | ||
}) | ||
return inviteMaker.make('writer', someSeat) | ||
} | ||
}) | ||
``` | ||
|
||
## collector.collect(seatP, winPurseP, refundPurseP, name) | ||
- `seatP` `{Object}` | ||
- `winPurseP` `{Purse}` | ||
- `refundPurseP` `{Purse}` | ||
- `name` `{String}` - Default: 'collecting' | ||
- Returns: `{winsAndRefunds <Object>}` | ||
|
||
`collect()` calls `getWinnings()` and `getRefund()` on `seatP` and deposits the proceeds respectively into `winPurseP` and `refundPurseP`. `name` (which defaults to 'collecting') is converted to a String, and used for logging the results. | ||
|
||
```js | ||
const purseA = assayA.makeEmptyPurse(); | ||
const purseB = assayB.makeEmptyPurse(); | ||
const seatP = E(someHost).redeem(someInvite); | ||
|
||
collect(seatP, purseA, purseB, 'a log message'); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Other Concepts | ||
|
||
When looking at the code in our [tests](https://github.com/Agoric/ERTP/tree/master/test), you might see some new | ||
concepts: | ||
|
||
* __Vats__: All user code runs in what we call a vat. Within a vat, code is run synchronously. Communication with another vat happens asynchronously. The [SwingSet infrastructure](https://github.com/Agoric/SwingSet) creates the vats and makes communication between vats possible. | ||
|
||
* __E() and tildot (~.)__: Instead of `obj.foo()`, we can write `E(obj).foo()` or the syntactic sugar, `obj~.foo()` and get a promise for the result. The syntax means "deliver the message foo() to the actual object asynchronously, in its own turn, wherever and whenever it is, even if it is local." Using `E` or `~.`, you can talk asynchronously to local and remote objects in exactly the same way. | ||
|
||
* __Presences__: Presences are our name for the local object that stands in for the remote object. If `obj` is a presence of a remote object, we can send messages to the remote object by using "~." on `obj`, as in the above example. |