Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guess37 mutiple participants #23

Merged
merged 5 commits into from
Oct 29, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 54 additions & 39 deletions smart-contracts-tutorial/first-contract.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
### Tutorial on creating and running the simplest Smart Contract
# Tutorial on creating and running the simplest Smart Contract

This first contract will be a one-player game where the player tries to guess a number. If they guess right, they win, otherwise, they lose. The game can be played any number of times and there is no actual stake. For the purpose of keeping things simple, the number is hardcoded to be `37`


#### Set up the environment for the contract
## Set up the environment for the contract

Clone the [cosmic-swingset repository](https://github.com/Agoric/cosmic-swingset):
```sh
Expand All @@ -13,7 +13,7 @@ git clone [email protected]:Agoric/cosmic-swingset.git
Follow the instruction to [build and setup cosmic-swingset](https://github.com/Agoric/cosmic-swingset#build-from-source) (~20 minutes)


#### Write a contract
## Write a contract

```sh
# Make sure you're in the cosmic-swingset root directory
Expand All @@ -23,13 +23,11 @@ echo $PWD
# (optional) create a git branch
# git branch -c my-contract-tutorial

# Create a directory for the contract
mkdir contracts
# Create the contract file
touch contracts/guess37.js
touch lib/ag-solo/vats/guess37-contract.js
```

- copy/paste the following code in the file:
**copy/paste the following code in the contract file:**
```js
function guess37Contract(terms, inviteMaker) {
const seat = harden({
Expand All @@ -44,46 +42,41 @@ function guess37Contract(terms, inviteMaker) {
}

export default guess37Contract.toString();

```

The contract is materialized by the source code of the `start` function. JavaScript makes it possible to retrieve the source code of a function by calling [toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString) on the function

<small>
```md
TODO a documentation of the contract format
- Explain the contract host
- Explain `terms` and `inviteMaker` arguments
- Explain the [provided top-level variables](https://github.com/Agoric/ERTP/blob/8f42af53581821bb16a9f4e3d62603833354ef8b/core/contractHost.js#L53-L63)
- Explain Jessie
</small>
```

Change the content of `lib/ag-solo/vats/vat-demo.js` to be the following:
Replace the content of `lib/ag-solo/vats/vat-pixel.js` with the following:

```js
import harden from '@agoric/harden';
import guess37ContractSource from '../../contracts/guess37.js';
import { makeHandoffService } from '@agoric/ertp/more/handoff/handoff';
import guess37ContractSource from './guess37-contract.js';

function build(E, log) {
let sharedGame;
let contractHost

async function startup(host) {
const guess37Installation = await E(host).install({
start: guess37ContractSource,
});
const { playerInvite } = await E(guess37Installation).spawn();
const game = await E(host).redeem(playerInvite);

sharedGame = game;
contractHost = host
}

async function createDemoClientBundle() {
const chainBundle = {
game: sharedGame,
};
return harden(chainBundle);
async function createPixelBundle() {
return harden({
contractHost,
handoffService: makeHandoffService(),
guess37ContractSource,
});
}

return harden({ startup, createDemoClientBundle });
return harden({ startup, createPixelBundle });
}

export default function setup(syscall, state, helpers) {
Expand All @@ -94,11 +87,10 @@ export default function setup(syscall, state, helpers) {
helpers.vatID,
);
}

```


#### Run the contract
## Run the contract

[Run "scenario 3"](https://github.com/Agoric/cosmic-swingset#scenario-3--no-testnet-develop-off-chain-demo)

Expand All @@ -109,30 +101,53 @@ make scenario3-run-client

Open a web browser to http://localhost:8000/

<small>
```
currently, this is the UI of the Pixel Gallery demo
TODO : provide a proper UI
</small>
```

In the REPL, try the following commands in the same order:
```
home
home!game!guess(14)
home!game!guess(37)
host = home~.contractHost
DavidBruant marked this conversation as resolved.
Show resolved Hide resolved
installation = host~.install({start: home.guess37ContractSource})
invites = installation~.spawn()
playerInvite = invites~.playerInvite
seat = host~.redeem(playerInvite)

seat~.guess(14)
seat~.guess(37)
```

The first `home` command shows what was defined in `lib/ag-solo/vats/vat-demo.js` as `chainBundle`
### Commands breakdown

The first `home` command shows what was defined in `lib/ag-solo/vats/vat-pixel.js` as return value of `createPixelBundle`
It is a presence for an object containing the properties `contractHost`, `handoffService` and `guess37ContractSource`
DavidBruant marked this conversation as resolved.
Show resolved Hide resolved

`home!game!guess(14)` is a losing guess
`home!game!guess(37)` is a winning guess
`host = home.contractHost` retrieves the contractHost presence and stores it in the `host` variable for convenience

`installation = host~.install({start: home.guess37ContractSource})` installs the guess37 contract in the contract host

`invites = installation~.spawn()` runs the contract (here, the `guess37Contract` function) and store the invites bundle returned by the contract

`playerInvite = invites~.playerInvite` extracts the `playerInvite` from the invites bundle

`seat = host~.redeem(playerInvite)` redeems the invitation. This allows to participate to the contract. What is returned is stored in a `seat` variable as if the contract/game was a table and you were retrieving a seat at this table
DavidBruant marked this conversation as resolved.
Show resolved Hide resolved

`seat~.guess(14)` is a losing guess as defined by the `guess37` contract
`seat~.guess(37)` is a winning guess

As you have guessed (pun intended!), `guess` refers to the function with the same name defined in the contract

<small>
TODO : explain infix-bang syntax
</small>
The contractHost/install/spawn/invites/redeem choregraphy is part of the [ERTP framework](https://github.com/Agoric/ERTP) developed by Agoric. You can read more about it [in the dedicated repo](https://github.com/Agoric/ERTP/blob/master/core/contractHost.chainmail). [More detailled documentation is coming soon](https://github.com/Agoric/Documentation/pull/17)


## Conclusion and next steps

**Congratulations!**\
You've successfully written a smart contract in JavaScript and run it in a solo node

In the next steps, we'll discover how to make **more interesting contracts** and **how to run them in a proper blockchain**
In the next steps, we'll discover how to make someone else play the `guess37` game


`TODO : explain ~. syntax`