Skip to content

Commit

Permalink
Remove Truffle example from Sapphire
Browse files Browse the repository at this point in the history
  • Loading branch information
aefhm committed Oct 3, 2023
1 parent 41f4d63 commit 7b01ef8
Showing 1 changed file with 19 additions and 218 deletions.
237 changes: 19 additions & 218 deletions docs/dapp/sapphire/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,228 +7,31 @@ import {findSidebarItem} from '@site/src/sidebarUtils';
<iframe style={{margin: 'auto', display:'block'}} width="560" height="315" src="https://www.youtube.com/embed/LDLz06X_KNY?si=tS1-b1hncG6wo9oL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</p>

In this tutorial, you'll port an Eth project in under 10 minutes, and then go on
to deploy a unique dApp that requires confidentiality to work.
By the end of the tutorial, you should feel comfortable setting up your Eth
development environment to target Sapphire, and know how and when to use
confidentiality.
In this tutorial, you will build and deploy a unique dApp that requires
confidentiality to work. By the end of the tutorial, you should feel
comfortable setting up your Eth development environment to target Sapphire,
and know how and when to use confidentiality.

The expected completion time of this tutorial is 30 minutes.
The expected completion time of this tutorial is 15 minutes.

## Port an Eth project
:::info Sunsetting Truffle


:::tip

This tutorial uses [pnpm](https://pnpm.io/installation), an efficient Node
package manager. You can just as easily use `npm` or `yarn` by replacing
`pnpm` with either of those.
Per Consensys [announcement], Oasis will no longer support Truffle as of
2023-10-05 and encourage immediate [migration] to Hardhat. Please see our
repository for the archived Truffle [tutorial] and the deprecated [example].

:::

### Deploy to Emerald (non-confidential EVM)

#### Get some Emerald Testnet tokens

In order to deploy to the Emerald Testnet, we'll need some tokens.
Get those by heading to [Oasis Testnet faucet] and selecting "Emerald" as
the first dropdown.
Set the second box to the address of a burner wallet.
It'll take a few moments to receive your tokens after submitting the form.

[Oasis Testnet faucet]: https://faucet.testnet.oasis.dev/



#### Do the Truffle Thing

You'll want a script to run some methods on the contract.
Pop open your favorite editor and paste in this code:

```typescript
const keccak256 = require("web3").utils.keccak256;

const MetaCoin = artifacts.require("MetaCoin");

async function exerciseContract() {
const mc = await MetaCoin.deployed();

const tx = await mc.sendCoin(mc.address, 42);
console.log(`\nSent some coins in ${tx.tx}.`);
const t = tx.logs[0].args;
console.log(`A Transfer(${t[0]}, ${t[0]}, ${t[2].toNumber()}) was emitted.`);

const storageSlot = await new Promise((resolve, reject) => {
const getStoragePayload = {
method: "eth_getStorageAt",
params: [
mc.address,
keccak256(
"0x" + "00".repeat(12) + mc.address.slice(2) + "00".repeat(32)
),
"latest",
],
jsonrpc: "2.0",
id: "test",
};
mc.contract.currentProvider.send(getStoragePayload, (err, res) => {
if (err) reject(err);
else resolve(res.result);
});
});
console.log(`The balance storage slot contains ${storageSlot}.`);

const balance = await mc.getBalance(mc.address);
console.log(`The contract now has balance: ${balance.toNumber()}.`);
}

module.exports = async function (callback) {
try {
await exerciseContract();
} catch (e) {
console.error(e);
}
callback();
};
```

Save it to `scripts/exercise.contract.js`.
We'll use it in just a bit.

Next, you can run the following and see the contract being deployed.

```sh
PRIVATE_KEY="0x..." truffle migrate --network emerald_testnet
```

Everything should be succeeding so far.

Finally, run this line and observe some output.

```
> PRIVATE_KEY="0x..." truffle exec --network emerald_testnet scripts/exercise.contract.js`
Sent some coins in 0xf415ab586ef1c6c61b84b3bd803ae322f375d1d3164aa8ac13c9ae83c698a002
A Transfer(0x56e5F834F88F9f7631E9d6a43254e173478cE06a, 0x56e5F834F88F9f7631E9d6a43254e173478cE06a, 42) was emitted.
The balance storage slot contains 0x2a.
The contract now has balance: 42
```

Great!
That'll be the baseline for our confidential deployment.

### Deploy to Sapphire (confidential EVM)

#### Get some Sapphire Testnet tokens

Now for the fun part.
As for Emerald, we need to configure the Sapphire network and get some tokens.
Hit up the one and only [Oasis Testnet faucet] and this time select "Sapphire".
Submit the form and on your way.

#### Add the Sapphire Testnet to Truffle

And another diff for your applying pleasure:

```diff
diff --git a/truffle-config.js b/truffle-config.js
index 7af2f42..0cd9d36 100644
--- a/truffle-config.js
+++ b/truffle-config.js
@@ -58,6 +58,11 @@ module.exports = {
new HDWalletProvider([process.env.PRIVATE_KEY], "https://testnet.emerald.oasis.dev"),
network_id: 0xa515,
},
+ // This is Testnet! If you want Mainnet, add a new network config item.
+ sapphire_testnet: {
+ provider: () =>
+ new HDWalletProvider([process.env.PRIVATE_KEY], "https://testnet.sapphire.oasis.dev"),
+ network_id: 0x5aff,
+ },
},

// Set default mocha options here, use special reporters etc.
```

#### Port to Sapphire

Here's where things start to get interesting.
We're going to add confidentiality to this starter project in exactly two lines
of code.

You'll need to grab the Sapphire compatibility library
([`@oasisprotocol/sapphire-paratime`]), so make that happen by issuing

```sh
pnpm add -D @oasisprotocol/sapphire-paratime # npm also works
```

So far so good.
Next, import it by adding this line to the top of `truffle-config.js`:

```typescript
const sapphire = require('@oasisprotocol/sapphire-paratime');
```

That's the first line of code.
Here's the second:

```diff
diff --git a/truffle-config.js b/truffle-config.js
index 0cd9d36..7db7cf8 100644
--- a/truffle-config.js
+++ b/truffle-config.js
@@ -60,7 +60,7 @@ module.exports = {
},
sapphire_testnet: {
provider: () =>
- new HDWalletProvider([process.env.PRIVATE_KEY], "https://testnet.sapphire.oasis.dev"),
+ sapphire.wrap(new HDWalletProvider([process.env.PRIVATE_KEY], "https://testnet.sapphire.oasis.dev")),
network_id: 0x5aff,
},
},
```

This `wrap` function takes any kind of provider or signer you've got and turn
it into one that works with Sapphire and confidentiality.
For the most part, wrapping your signer/provider is the most you'll need to do
to get your dApp running on Sapphire, but that's not a complete story since an
unmodified contract may leak state through normal operation.

And now for the moment we've all been waiting for:

```
> PRIVATE_KEY="0x..." truffle migrate --network sapphire_testnet
> PRIVATE_KEY="0x..." truffle exec --network sapphire_testnet scripts/exercise.contract.js
Sent some coins in 0x6dc6774addf4c5c68a9b2c6b5e5634263e734d321f84012ab1b4cbe237fbe7c2.
A Transfer(0x56e5F834F88F9f7631E9d6a43254e173478cE06a, 0x56e5F834F88F9f7631E9d6a43254e173478cE06a, 42) was emitted.
The balance storage slot contains 0x0.
The contract now has balance: 42.
```

So basically nothing changed, which is pretty much what we're going for.
But take a look at that second to last line where it says what's in the storage
slot. Before, it said `0x2a`, but now it says `0x0`.

Clearly the slot does contain data or else the contract balance couldn't have
been returned.
What's happened here is that the Web3 gateway does not have the key used to
decrypt the storage slot, so a default value is returned.

Indeed, the gateway does not even have the key needed to decrypt the _key_ in
the MKVS; it can tell _that_ a storage slot was written, but not which one
(although it can make a very good guess by reading the contract code).

All in all, you can see that confidentiality is in effect, but it's not
something end-users need to think too much about.
[announcement]: https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat
[migration]: https://trufflesuite.com/docs/truffle/how-to/migrate-to-hardhat/
[tutorial]: https://github.com/oasisprotocol/docs/blob/2f4a1a3c217b82687ab9440bf051762ae369ed45/docs/dapp/sapphire/quickstart.mdx
[example]: https://github.com/oasisprotocol/sapphire-paratime/tree/3a85e42e6c1cc090c28a521cf7df6353aa8a30c8/examples/truffle

[`@oasisprotocol/sapphire-paratime`]: https://www.npmjs.com/package/@oasisprotocol/sapphire-paratime

## Create a Sapphire-Native dApp

Porting an existing Eth app is cool, and can already provide benefits like
protecting against MEV.
Porting an existing Eth app is cool, and will provide benefits such as
protection against MEV.
However, starting from scratch with confidentiality in mind can unlock some
really novel dApps and provide a [higher level of security].

Expand All @@ -242,7 +45,8 @@ Let's make it happen!

### Init a new Hardhat project

We're going to use Hardhat this time because it's very convenient to use.
We're going to use Hardhat, but Sapphire should be compatible with your dev
environment of choice. Let us know if things are not as expected!

1. Make & enter a new directory
2. `npx hardhat@~2.12.0` then create a TypeScript project.
Expand All @@ -258,7 +62,6 @@ We're going to use Hardhat this time because it's very convenient to use.
### Add the Sapphire Testnet to Hardhat

Open up your `hardhat.config.ts` and drop in these lines.
They should remind you a lot about what happened with Truffle.

```diff
diff --git a/hardhat.config.ts b/hardhat.config.ts
Expand Down Expand Up @@ -376,9 +179,8 @@ Best of luck on your future forays into confidentiality!

:::info Example

Visit the Sapphire ParaTime repository to download the final [Truffle]
[truffle-example] and [Hardhat][hardhat-example] examples of this
quickstart.
Visit the Sapphire ParaTime repository to download the [Hardhat][hardhat-example]
example of this quickstart.

:::

Expand All @@ -390,6 +192,5 @@ quickstart.

[social-media]: ../../get-involved/README.md#social-media-channels
[guide]: guide.mdx
[truffle-example]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/examples/truffle
[hardhat-example]: https://github.com/oasisprotocol/sapphire-paratime/tree/main/examples/hardhat
[`@oasisprotocol/sapphire-hardhat`]: https://www.npmjs.com/package/@oasisprotocol/sapphire-hardhat

0 comments on commit 7b01ef8

Please sign in to comment.