Skip to content

Commit

Permalink
docs: revamp sapphire stucture
Browse files Browse the repository at this point in the history
  • Loading branch information
rube-de committed Jan 13, 2025
1 parent 7a9e452 commit 1e7e515
Show file tree
Hide file tree
Showing 18 changed files with 502 additions and 329 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ This repository includes all relevant Sapphire and dependencies organized into
the following directories:

- [`clients`](./clients): the Go, Python and JavaScript/TypeScript clients
- [`contracts`](./contracts): Sapphire and [OPL](https://docs.oasis.io/dapp/opl/) smart contracts
- [`contracts`](./contracts): Sapphire and [OPL](https://docs.oasis.io/build/opl/) smart contracts
- [`docs`](./docs): topic-oriented Sapphire documentation
- [`examples`](./examples/): sample code snippets in popular Ethereum
development environments
Expand All @@ -76,7 +76,7 @@ development environments
## Documentation

The Sapphire documentation is deployed as part of the official
[Oasis documentation](https://docs.oasis.io/dapp/sapphire/). To make changes
[Oasis documentation](https://docs.oasis.io/build/sapphire/). To make changes
visible on the docs website:

1. Merge any changes in the `docs` folder to the `main` branch.
Expand Down
4 changes: 2 additions & 2 deletions clients/go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
style.

[@oasisprotocol/sapphire-paratime]: https://pkg.go.dev/github.com/oasisprotocol/sapphire-paratime/go/
[Sapphire ParaTime]: https://docs.oasis.io/dapp/sapphire
[Sapphire ParaTime]: https://docs.oasis.io/build/sapphire

## Building

Expand Down Expand Up @@ -96,5 +96,5 @@ _ = c.SendTransaction(ctx, signedTx)
## See Also

- [Oasis Testnet Faucet](https://faucet.testnet.oasis.io/)
- [Creating dapps for Sapphire](https://docs.oasis.io/dapp/sapphire/quickstart)
- [Creating dapps for Sapphire](https://docs.oasis.io/build/sapphire/quickstart)
- [How to Transfer ROSE into an EVM ParaTime](https://docs.oasis.io/general/manage-tokens/how-to-transfer-rose-into-paratime/)
4 changes: 2 additions & 2 deletions clients/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The Sapphire wrapper with automatically encrypt the `eth_call`, `eth_estimateGas
and `eth_signTransaction` JSON-RPC calls

[@oasisprotocol/sapphire-paratime]: https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime
[sapphire paratime]: https://docs.oasis.io/dapp/sapphire/
[sapphire paratime]: https://docs.oasis.io/build/sapphire/

_If your dapp doesn't port in under 10 minutes, it's a bug!_<br />
If you have more than a little trouble, please file an issue.<br />
Expand Down Expand Up @@ -59,5 +59,5 @@ signed queries manually using the `overrides` parameter to `SignedCallDataPack.m
## See Also

- [Oasis Testnet Faucet](https://faucet.testnet.oasis.io/)
- [Creating dapps for Sapphire](https://docs.oasis.io/dapp/sapphire/quickstart)
- [Creating dapps for Sapphire](https://docs.oasis.io/build/sapphire/quickstart)
- [How to Transfer ROSE into an EVM ParaTime](https://docs.oasis.io/general/manage-tokens/how-to-transfer-rose-into-paratime/)
4 changes: 2 additions & 2 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ contract RandomNumber {

## Documentation

See the user's guide for [Sapphire](https://docs.oasis.io/dapp/sapphire/) and
[OPL](https://docs.oasis.io/dapp/opl/).
See the user's guide for [Sapphire](https://docs.oasis.io/build/sapphire/) and
[OPL](https://docs.oasis.io/build/opl/).

The generated API reference is hosted at
[api.docs.oasis.io](https://api.docs.oasis.io/sol/sapphire-contracts).
Expand Down
17 changes: 10 additions & 7 deletions docs/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ crypto gaming
### Getting Started

Develop and deploy a dApp on Sapphire:

- follow along with a video walkthrough via [quickstart][quickstart]
- start with a working dApp [demo][demo]
- explore showcase dApps deployed on Sapphire on the [playground][playground]
Expand All @@ -29,16 +30,18 @@ Develop and deploy a dApp on Sapphire:

### Understanding EVM compatibility

Get to know the differences between Sapphire and Ethereum, and learn about
the high level concepts of developing a confidential smart contract with our
[guide][guide].
Get to know the differences between [Sapphire and Ethereum], and learn about
the high level [concepts] of developing DApps.

[guide]: ./guide.mdx
[Sapphire and Ethereum]: ./ethereum.md
[concepts]: ./develop/concept.mdx

### Building on Sapphire
### Develop on Sapphire

Take your existing dApp building knowledge and add Sapphire with our developer
[cheatsheet](./images/cheatsheet.pdf).
[cheatsheet](./images/cheatsheet.pdf) or visit the [develop] chapter.

[develop]: ./develop/README.mdx

### Network Information

Expand All @@ -59,5 +62,5 @@ Visit the [faucet][faucet] to obtain testnet tokens for development purposes.
findSidebarItem('/node/run-your-node/paratime-node'),
findSidebarItem('/node/run-your-node/paratime-client-node'),
findSidebarItem('/node/web3'),
findSidebarItem('/dapp/tools/other-paratimes/'),
findSidebarItem('/build/tools/other-paratimes/'),
]} />
81 changes: 81 additions & 0 deletions docs/develop/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
description: Build DApps on Sapphire
---

# Build

As Sapphire is EVM-compatible, you can use the same dev tooling as you would
when building on Ethereum. Additionally, we build tools to support you in
creating secure and confidential DApps.

Feel free to check out the [concept] page to get a better understanding of the
transaction flow and the contract state.

[concept]: ./concept.mdx

## Contract Development

Sapphire is programmable using any language that targets the EVM, such as Solidity,
Fe or Vyper. If you prefer to use an Ethereum framework like Hardhat or Foundry,
you can also use those with Sapphire; all you need to do is set your Web3 gateway URL.
You can find the details of the Oasis Sapphire Web3 endpoints
[here](../network.mdx#rpc-endpoints).

### Features

- [Deployment and Proxies][deployment]
- [Gasless and Onchain Signing][gasless]
- [Security considerations][security]
- [View-call authentication][view-call]
- [Randomness, Subcalls and More Precompiles][sapphire-contracts]

[deployment]: ./deployment.md
[gasless]: ./gasless.md
[security]: ./security.md
[view-call]: ./authentication.md
[sapphire-contracts]: https://api.docs.oasis.io/sol/sapphire-contracts

## Frontend Development

To connect your frontend to your smart contracts, see the [browser] chapter.

[browser]: ./browser.md

:::info More Frontend Framworks

We support the common frontend libraries with the v2 client:

- [Ethers v6][ethers]
- [Viem][viem]
- [Wagmi][wagmi]

:::

[ethers]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/integrations/ethers-v6
[viem]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/integrations/viem-v2
[wagmi]:https://github.com/oasisprotocol/sapphire-paratime/tree/main/integrations/wagmi-2

## Backend Development

If you want to connect and execute transactions from your backend.
Sapphire has three clients in different programming languages:

- Sapphire [JS]
- Sapphire [Go]
- Sapphire [Py]

[JS]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/clients/js/README.md
[Go]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/clients/go/README.md
[Py]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/clients/py/README.md

## Examples

See our [examples] page for demo DApps that bring all the above together.

[examples]: ../examples.mdx

Should you have any questions or ideas to share, feel free to reach out to us
on [discord and other social media channels][social-media].

[social-media]: https://github.com/oasisprotocol/docs/blob/main/docs/get-involved/README.md#social-media-channels

2 changes: 1 addition & 1 deletion docs/authentication.md → docs/develop/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ which created the contract, calling `isOwner` will return:
* `false`, with `sapphire.wrap` but without an attached signer
* `true`, with `sapphire.wrap` and an attached signer
* `true`, if called via the contract which created it
* `true`, if called via transaction
* `true`, if called via transaction

## Caching Signed Queries

Expand Down
20 changes: 9 additions & 11 deletions docs/browser.md → docs/develop/browser.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,11 @@ access them!**

The contract in the Hardhat boilerplate is ERC-20-compatible and emits the
`transfer` event. If your wish to preserve confidentiality, you can comment
out [line 66]. Read [the guide](guide.mdx#contract-logs) to learn more.
out [line 66]. Read the [concept] chapter to learn more.

:::

[`wagmi`]: https://wagmi.sh/
[`viem`]: https://viem.sh/
[concept]: ./concept.mdx#contract-logs

## Signing Sapphire Calls and Transactions in Browser

Expand Down Expand Up @@ -155,21 +154,21 @@ npm run start
If all goes well the web server will spin up and your browser should
automatically open `http://localhost:3000`.

![Hardhat boilerplate frontend](images/hardhat-boilerplate-frontend1.png)
![Hardhat boilerplate frontend](../images/hardhat-boilerplate-frontend1.png)

Go ahead and connect the wallet. If you haven't done it yet, you will have
to add the [Sapphire ParaTime Testnet network to your
Metamask][sapphire-testnet]. Once connected, the frontend will make an unsigned
call to the `balanceOf` view and show you the amount of `MHT`s in your selected
Metamask account.

![MHT balance of your account](images/hardhat-boilerplate-frontend2.png)
![MHT balance of your account](../images/hardhat-boilerplate-frontend2.png)

Next, let's transfer some `MHT`s. Fill in the amount, the address and hit the
*Transfer* button. Metamask will show you the popup to sign and submit the
transfer transaction. Once confirmed, Metamask will both **sign and encrypt** the transaction.

![Sign and encrypt the transfer transaction](images/hardhat-boilerplate-frontend3.png)
![Sign and encrypt the transfer transaction](../images/hardhat-boilerplate-frontend3.png)

Once the transaction is processed, you will get a notification from Metamask
and the balance in the dApp will be updated.
Expand Down Expand Up @@ -207,14 +206,13 @@ we recommend that you check out the official [Oasis starter] files.
:::

[block explorer]: https://explorer.oasis.io/testnet/sapphire/tx/0x3303dea5d48291d1564cad573f21fc71fcbdc2b862e17e056287fd9207e3bc53
[guide-transaction-calls]: guide.mdx#transactions--calls
[guide-transaction-calls]: ./concept.mdx#transactions--calls
[Hardhat boilerplate repo]: https://github.com/NomicFoundation/hardhat-boilerplate
[Hardhat boilerplate]: https://hardhat.org/tutorial/boilerplate-project
[Hardhat tutorial]: https://hardhat.org/tutorial
[line 66]: https://github.com/NomicFoundation/hardhat-boilerplate/blob/13bd712c1285b2de572f14d20e6a750ae08565c0/contracts/Token.sol#L66
[quickstart]: quickstart.mdx#add-the-sapphire-testnet-to-hardhat
[sapphire-testnet]: ./network.mdx#rpc-endpoints
[quickstart]: ../quickstart.mdx#add-the-sapphire-testnet-to-hardhat
[sapphire-testnet]: ../network.mdx#rpc-endpoints
[Sapphire ParaTime examples]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/examples/hardhat-boilerplate
[social-media]: https://github.com/oasisprotocol/docs/blob/main/docs/get-involved/README.md#social-media-channels
[pnpm]: https://pnpm.io
[TEST tokens]: quickstart.mdx#get-some-sapphire-testnet-tokens
[TEST tokens]: ../quickstart.mdx#get-some-sapphire-testnet-tokens
100 changes: 100 additions & 0 deletions docs/develop/concept.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
description: Sapphire concepts
---

import DocCard from '@theme/DocCard';
import {findSidebarItem} from '@site/src/sidebarUtils';

# Concept

### Transactions & Calls

{/*-- https://github.com/oasisprotocol/docs/blob/455980674563cad92ff1e1b62a7a5f2d4d6809f0/docs/general/images/architecture/client-km-compute.svg -->*/}
![Client, Key Manager, Compute Node diagram](../../../general/images/architecture/client-km-compute.svg)

The figure above illustrates the flow of a **confidential smart contract
transaction** on Sapphire.

Transactions and calls must be encrypted and signed for maximum security.
The [@oasisprotocol/sapphire-paratime] npm package will make your life
easy. It'll handle cryptography and signing for you.

You should be aware that taking actions based on the value of private data may
**leak the private data through side channels** like time spent, gas use and
accessed memory locations. If you need to branch on private data, you should in
most cases ensure that both branches exhibit the same time/gas and storage
patterns.

You can also make **confidential smart contract calls** on Sapphire. If you
use `msg.sender` for access control in your contract, the call **must be
signed**, otherwise `msg.sender` will be zeroed. On the other hand, set the
`from` address to all zeros, if you want to avoid annoying signature popups in
the user's wallet for calls that do not need to be signed. The JS library will
do this for you.

:::note

Inside the smart contract code, there is no way of knowing whether the
client's call data were originally encrypted or not.

:::

<details>
<summary>Detailed confidential smart contract transaction flow on Sapphire</summary>

![Diagram of the detailed confidential smart contract transaction flow on Sapphire](../diagrams/c10l-smart-contract-tx.mmd.svg)

</details>

<details>
<summary>Detailed confidential smart contract call flow on Sapphire</summary>

![Diagram of the detailed confidential smart contract call flow on Sapphire](../diagrams/c10l-smart-contract-call.mmd.svg)

</details>

### Contract State

The Sapphire state model is like Ethereum's except for all state being encrypted
and not accessible to anyone except the contract. The contract, executing in an
active (attested) Oasis compute node is the only entity that can request its
state encryption key from the Oasis key manager. Both the keys and values of the
items stored in state are encrypted, but the **size of either is not hidden**. Your
app may need to pad state items to a constant length, or use other obfuscation.
Observers may also be able to infer computation based on storage access patterns,
so you may need to obfuscate that, too. See [Security chapter] for more
recommendations.

[Security chapter]: ./security.md#storage-access-patterns

:::danger Contract state leaks a fine-grained access pattern

Contract state is backed by an encrypted key-value store. However, the trace of
encrypted records is leaked to the compute node. As a concrete example, an ERC-20
token transfer would leak which encrypted record is for the sender's account
balance and which is for the receiver's account balance. Such a token would be
traceable from sender address to receiver address. Obfuscating the storage access
patterns may be done by using an ORAM implementation.

:::

Contract state may be made available to third parties through logs/events, or
explicit getters.

### Contract Logs

Contract logs/events (e.g., those emitted by the Solidity `emit` keyword)
are exactly like Ethereum. Data contained in events is *not* encrypted.
Precompiled contracts are available to help you encrypt data that you can
then pack into an event, however.

:::danger Unmodified contracts may leak state through logs

Base contracts like those provided by OpenZeppelin often emit logs containing
private information. If you don't know they're doing that, you might undermine
the confidentiality of your state. As a concrete example, the ERC-20 spec
requires implementers to emit an `event Transfer(from, to, amount)`, which is
obviously problematic if you're writing a confidential token. What you can
do instead is fork that contract and remove the offending emissions.

:::
File renamed without changes.
7 changes: 4 additions & 3 deletions docs/gasless.md → docs/develop/gasless.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ features such as the browser support are not fully implemented yet.
## On-Chain Signer

The on-chain signer is a smart contract which:

1. receives the user's transaction,
2. checks whether the transaction is valid,
3. wraps it into a meta-transaction (which includes paying for the transaction
Expand All @@ -44,7 +45,7 @@ The on-chain signer is a smart contract which:
The steps above are executed as a confidential read-only call. Finally, the user
then submits the obtained transaction to the network.

![Diagram of the On-Chain Signing](images/gasless-on-chain-signer.svg)
![Diagram of the On-Chain Signing](../images/gasless-on-chain-signer.svg)

### EIP155Signer

Expand Down Expand Up @@ -271,7 +272,6 @@ creators can close the poll.

[demo-voting]: https://github.com/oasisprotocol/demo-voting
[demo-voting-playground]: https://playground.oasis.io/demo-voting
[dao-opl]: https://github.com/oasisprotocol/docs/blob/main/docs/dapp/opl/host.md
[EIP-155]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md

## Gas Station Network
Expand All @@ -280,7 +280,7 @@ creators can close the poll.
Sapphire in a forked `@oasislabs/opengsn-cli` package. The diagram below
illustrates a flow for signing a transaction by using a GSN[^1].

![Diagram of the Gas Station Network Flow](images/gasless-gsn-flow.jpg)
![Diagram of the Gas Station Network Flow](../images/gasless-gsn-flow.jpg)

[^1]: The GSN flow diagram is courtesy of [OpenGSN documentation][opengsn-docs].

Expand Down Expand Up @@ -374,6 +374,7 @@ requests and forward them to the relay hub on Sapphire Testnet.

We can test whether a relayed request can be forwarded and processed correctly.
Scroll up to find the GSN deployment response and use the following parameters:

- `Forwarder` as `--to`,
- `Paymaster` as `--paymaster`,
- your account address as `--from`
Expand Down
File renamed without changes.
Loading

0 comments on commit 1e7e515

Please sign in to comment.