You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/introduction/developer-quickstart.md
+84-83Lines changed: 84 additions & 83 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,38 +2,39 @@
2
2
sidebar_position: 4
3
3
---
4
4
5
-
# Migrate your dApp to Ten
6
-
Migrating to Ten is a straightforward process that immediately unlocks "Programmable Encryption".
5
+
# Migrate your dApp to TEN
7
6
8
-
There are a couple of changes you need to make:
7
+
Migrating to TEN enables your dApp to leverage "Programmable Encryption". Below are steps to help you transition smoothly.
9
8
10
-
1. Change your hardhat deployment script so that you can use `--network ten`.
11
-
2. Add logic to your view functions to protect data (if needed).
12
-
3. Configure event log visibility (if needed).
13
-
4. Add a widget to your javascript UI to onboard Ten users.
9
+
### Key Migration Steps
10
+
11
+
1. Update your Hardhat deployment to support the `--network ten` option.
12
+
2. Add data protection logic to your view functions (if applicable).
13
+
3. Configure visibility rules for event logs and internal storage.
14
+
4. Add the TEN onboarding widget to your JavaScript UI.
14
15
15
16
## 1. Configuring Hardhat
16
17
17
-
To begin building on Ten, you can start by setting up a Hardhat project as usual.
18
+
First, set up a Hardhat project if you haven't already.
18
19
19
-
### 1.1 Installing the Ten Hardhat Plugin
20
+
### 1.1 Installing the TEN Hardhat Plugin
20
21
21
-
To integrate the Ten Network into your Hardhat project, install the ten-hardhat-plugin:
22
+
To add TEN Network compatibility, install the `ten-hardhat-plugin`:
22
23
23
24
```bash
24
25
npm install ten-hardhat-plugin
25
26
```
26
27
27
-
Note: Plugins can be installed using `npm` or `yarn`.
28
+
_You can use `npm` or `yarn` to install plugins._
28
29
29
-
### 1.2 Configuring `hardhat.config.js` for the Ten Testnet
30
+
### 1.2 Configuring `hardhat.config.js`
30
31
31
-
Open`hardhat.config.js` in your project's root directory and configure it in the following way:
32
+
Modify`hardhat.config.js` in your project’s root directory as follows:
32
33
33
34
```javascript
34
-
import {HardhatUserConfig} from"hardhat/config";
35
+
import {HardhatUserConfig} from"hardhat/config";
35
36
import"@nomiclabs/hardhat-waffle";
36
-
import'ten-hardhat-plugin'
37
+
import"ten-hardhat-plugin";
37
38
38
39
module.exports= {
39
40
solidity:"0.8.10",
@@ -42,35 +43,37 @@ module.exports = {
42
43
// Configuration for the Hardhat Network
43
44
},
44
45
ten: {
45
-
url:"https://testnet.ten.xyz/v1/",
46
-
chainId:443,
46
+
url:"https://testnet.ten.xyz/v1/",
47
+
chainId:443,
47
48
accounts: ["your-private-key"],
48
49
},
49
50
},
50
51
};
51
52
52
53
exportdefaultconfig;
53
54
```
54
-
Now, you can start writing or migrating the smart contracts.
55
55
56
-
# 2. Writing Smart Contracts
56
+
Once configured, you can start writing or migrating your smart contracts.
57
57
58
-
Ten performs bytecode execution in the EVM identically to Ethereum, allowing developers to leverage their existing codebase and tools.
58
+
## 2. Writing Smart Contracts for TEN
59
59
60
-
The main difference is that, during execution, private variables and the internal state of the contract are hidden from everyone, including node operators and the sequencer.
61
-
This is a major advantage that represents "Programmable Privacy".
60
+
TEN executes smart contracts within the EVM similarly to Ethereum, so you can reuse your existing code.
61
+
However, the execution and the internal state are hidden from everyone, including node operators and the sequencer.
62
62
63
63
:::info
64
-
In Ten, the internal node database is encrypted, and the execution itself is also encrypted inside the TEE.
64
+
TEN encrypts both the execution and its internal database using Trusted Execution Environments (TEEs).
65
65
:::
66
66
67
-
The calls to [getStorageAt](https://docs.alchemy.com/reference/eth-getstorageat) are disabled by default, so all data access will be performed through view functions which are under the control of the smart contract developer. Note that public variables are accessible to everyone because Solidity automatically generates a getter function for them.
67
+
The [getStorageAt](https://docs.alchemy.com/reference/eth-getstorageat) method is disabled by default on TEN, so data access relies on view functions that you define.
68
+
Public variables remain accessible as Solidity automatically creates getters for them.
69
+
70
+
Let's illustrate with a basic storage dApp example where users can store and retrieve a number.
68
71
69
-
We'll illustrate how this works by creating a simple data storage example. In this dApp, users can store a number and retrieve it later.
72
+
At every step, we'll add a new feature and explain the difference between `TEN`and `Ethereum`.
70
73
71
-
## Step 1: Declaring a Public Variable
74
+
## Step 1: Basic contract with a Public Variable
72
75
73
-
### Code:
76
+
### Code
74
77
75
78
```solidity
76
79
// SPDX-License-Identifier: MIT
@@ -85,13 +88,17 @@ contract StorageExample {
85
88
}
86
89
```
87
90
88
-
### Explanation:
91
+
### Explanation
92
+
93
+
In this step, we created a public variable `storedValues` that maps the provided value to the address of the user who called the `storeValue` function.
89
94
90
-
In this step, we've declared a public variable `storedValues`. Solidity automatically generates a public getter view function for it, so on both Ethereum and Ten, you can call this view function without any restrictions. We also created a function that allows users to store a value against their address.
95
+
Because the variable is public, Solidity will provide a default public getter for it.
91
96
92
-
## Step 2: Transitioning to a Private Variable with a Getter Function
97
+
Since there are no data access restrictions, on both Ethereum and TEN, everyone will be able to read the values of all users.
93
98
94
-
### Code:
99
+
## Step 2: Converting to a Private Variable with an explicit Getter Function
100
+
101
+
### Code
95
102
96
103
```solidity
97
104
contract StorageExample {
@@ -107,19 +114,18 @@ contract StorageExample {
107
114
}
108
115
```
109
116
110
-
### Explanation:
117
+
### Explanation
111
118
112
-
We've now made our data variable private, meaning it can't be accessed directly from outside the contract. To fetch its value, we've provided a custom public view function `getValue`where the user provides the address. On both Ethereum and Ten, if you call this function you will retrieve the number stored by that address.
119
+
The `storedValues` variable is now private, and we added a basic `getValue` function for users to retrieve their value.
113
120
114
-
:::caution
115
-
In Ethereum, the `_storedValues` variable can also be accessed directly using the `getStorageAt` method, but not in Ten.
116
-
:::
121
+
On both Ethereum and TEN, anyone can call `getValue` to retrieve any value.
122
+
On Ethereum, `_storedValues` can also be accessed directly with `getStorageAt`
117
123
118
-
## Step 3: Implementing Data Access Control
124
+
## Step 3: Data Access Control
119
125
120
-
In this step, we aim to restrict users to only access their own value. This feature can only be implemented in Ten because as mentioned above, `_storedValues` is not hidden in Ethereum.
126
+
In this step, we'll add restrictions so users can only access their own data.
121
127
122
-
### Code:
128
+
### Code
123
129
124
130
```solidity
125
131
contract StorageExample {
@@ -136,21 +142,23 @@ contract StorageExample {
136
142
}
137
143
```
138
144
139
-
### Explanation:
145
+
### Explanation
140
146
141
-
Since `getValue` is the only function which exposes the values, we can add a check like this: `require(tx.origin == account, "Not authorized!");` If anyone, other than the original account, asks for the value, they will get an error.
147
+
The key line is: ``require(tx.origin == account, "Not authorized!");``, which ensures that the caller of the view function is the owner of the data.
142
148
143
149
:::info
144
-
In Ethereum, since all data is accessible anyway, there is no need to sign calls to view functions, so `tx.origin` can be spoofed.
150
+
TEN uses "Viewing Keys" to authenticate view function calls.
145
151
:::
146
152
147
-
In Ten, the platform ensures that calls to view functions are authenticated, which means that behind the scenes, there is a "Viewing Key" signature of the `tx.origin` address.
153
+
**When deployed on TEN, this code guarantees that all users can only access their own values, and nobody can read the `_storedValues`.**
154
+
155
+
## Step 4: Emitting Events - Default Visibility
148
156
149
-
## Step 4: Emitting Events - Default visibility
157
+
Event logs notify UIs about state changes in smart contracts.
150
158
151
-
Events in Ethereum are crucial for UIs to react to smart contract state changes. In this step, we'll emit an event when a user stores a value. We'll also gauge the popularity of our contract by emitting an event when certain milestones are reached.
159
+
To improve our smart contract, we’ll emit an event when a user stores a value and milestone events when a specific size threshold is met.
152
160
153
-
### Code:
161
+
### Code
154
162
155
163
```solidity
156
164
contract StorageExample {
@@ -176,50 +184,38 @@ contract StorageExample {
176
184
}
177
185
```
178
186
179
-
### Explanation:
187
+
### Explanation
180
188
181
-
On Ethereum, events are visible to anyone. For example, you can subscribe to the `DataChanged`event and receive notifications in real time about the data of everyone else.
189
+
Notice how we defined the two events: `DataChanged` and `MilestoneReached`, and are emitting them in the `storeValue` function.
182
190
183
-
The programmable encryption of Ten allows you full control over visibility but also has sensible defaults.
184
-
Event logs can be queried using `eth_getLogs` or subscribed to using the `logs` endpoint. Both these calls are authenticated, and the platform makes sure to return only visible logs.
191
+
In Ethereum, everyone can query and subscribe to these events. This obviously can't be the case for TEN because it would completely break the functionality.
185
192
186
-
In our case, the requirements are very simple and common sense:
193
+
Notice how in this version, we have no configuration for event log visibility, so we are relying on the default rules.
187
194
188
-
- The `DataChanged` event is specific to an account, so it should only be received by that user.
189
-
-`MilestoneReached`, on the other hand, is intended for everyone, as we want to show how popular our contract is.
195
+
Rule 1: Event logs that contain EOAs as indexed fields (topics) are only visible to those EOAs.
196
+
Rule 2: Event logs that don't contain any EOA are visible to everyone.
190
197
191
-
The behaviour you desire is to restrict the visibility of `DataChanged`, but not that of `MilestoneReached`. **Which is exactly how it works by default!**
198
+
In our case, the default rules ensure that:
199
+
-`DataChanged` is visible only to the address that is storing the value.
200
+
-`MilestoneReached` is publicly visible.
192
201
193
-
Default behaviour:
194
202
195
-
-`DataChanged` - has an address as a topic (an indexed field), which instructs the platform that the event log is only visible to that address.
196
-
-`MilestoneReached` - has no address topic which by default means it is visible to everyone.
203
+
## Step 5: Customizing Event Visibility
197
204
198
-
All you have to do is emit events as usual, and the platform applies common-sense visibility rules.
205
+
The default visibility rules are a good starting point, but complex dApps require greater flexibility.
199
206
207
+
TEN give you explicit control over event visibility.
@@ -272,11 +268,16 @@ contract StorageExample is ContractTransparencyConfig{
272
268
}
273
269
```
274
270
275
-
### Explanation:
271
+
### Explanation
272
+
273
+
The `ContractTransparencyConfig` interface is known by the TEN platform.
274
+
When a contract is deployed, the platform will call the `visibilityRules` function, and store the `VisibilityConfig`.
276
275
277
-
By implementing the `ContractTransparencyConfig.visibilityRules` method you can configure the visibility concerns of the current contract.
276
+
For each event type, you can configure which fields can access it.
277
+
This allows the developer to configure an event to be public even if it has EOAs or to allow the sender of the transaction to access events emitted even if the address is not in the event.
278
278
279
-
A `ContractCfg.PUBLIC` contract behaves exactly like a contract deployed on Ethereum. The storage slots are exposed, and all contracts are public.
279
+
Notice how in the `visibilityRules` above, we configure the `DataChanged` event to be visible to the first field and the sender, and the `MilestoneReached` to be visible to everyone.
280
280
281
-
For private contracts, you can configure the visibility of each individual event type you're emitting by specifying the "fields" that can receive it.
282
-
`Field.EVERYONE` means that this is a public event.
281
+
The other configuration: `VisibilityConfig.contractCfg` applies to the entire contract:
282
+
-`ContractCfg.TRANSPARENT`: The contracts will have public storage and events, behaving exactly like Ethereum.
283
+
-`ContractCfg.PRIVATE`: The default TEN behaviour, where the storage is not accessible and the events are individually configurable.
0 commit comments