gun-eth 1.3.6 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -5,42 +5,41 @@
5
5
 
6
6
  ## Table of Contents
7
7
 
8
- 1. [DESCRIPTION](#description)
9
- 2. [SMART CONTRACT](#smart-contract)
10
- 3. [KEY FEATURES](#key-features)
11
- 4. [HOW TO INSTALL](#how-to-install)
12
- 5. [HOW TO USE](#how-to-use)
13
- 6. [HOW IT WORKS](#how-it-works)
14
- 7. [CORE FUNCTIONS](#core-functions)
15
- 8. [SHINE](#shine)
16
- 9. [STANDALONE MODE](#standalone-mode)
17
- 10. [SECURITY CONSIDERATIONS](#security-considerations)
18
- 11. [CONTRIBUTING](#contributing)
19
- 12. [LICENSE](#license)
20
- 13. [CONTACT](#contact)
8
+ 1. [Description](#description)
9
+ 2. [Smart Contracts](#smart-contracts)
10
+ 3. [Key Features](#key-features)
11
+ 4. [Installation](#installation)
12
+ 5. [Usage](#usage)
13
+ 6. [How It Works](#how-it-works)
14
+ 7. [Core Functions](#core-functions)
15
+ 8. [Proof of Integrity](#proof-of-integrity)
16
+ 9. [Stealth Addresses](#stealth-addresses)
17
+ 10. [Local Development](#local-development)
18
+ 11. [Security Considerations](#security-considerations)
19
+ 12. [Contributing](#contributing)
20
+ 13. [License](#license)
21
21
 
22
- ## DESCRIPTION
22
+ ## Description
23
23
 
24
- Gun-eth is a plugin for GunDB that integrates Ethereum and Web3 functionality. This plugin extends GunDB's capabilities by allowing interaction with the Ethereum blockchain and providing cryptographic and signature management features.
24
+ Gun-eth is a plugin for GunDB that integrates Ethereum and Web3 functionality. This plugin extends GunDB's capabilities by enabling interaction with the Ethereum blockchain, providing cryptographic signature management, proof of integrity, and stealth address features.
25
25
 
26
- ## SMART CONTRACT
26
+ ## Smart Contracts
27
27
 
28
- SHINE Smart Contract deployed on Optimism Sepolia: [0x43D838b683F772F08f321E5FA265ad3e333BE9C2](https://sepolia-optimism.etherscan.io/address/0x43D838b683F772F08f321E5FA265ad3e333BE9C2)
28
+ - **ProofOfIntegrity Contract** (Optimism Sepolia): [address]
29
+ - **StealthAnnouncer Contract** (Optimism Sepolia): [address]
29
30
 
30
- Currently, the contract is deployed only on Optimism Sepolia. In the future, it will be deployed on multiple chains.
31
+ Currently deployed on Optimism Sepolia testnet.
31
32
 
32
- ## No time? Check the [TUTORIAL](./TUTORIAL.md)
33
+ ## Key Features
33
34
 
34
- ## KEY FEATURES
35
+ - **Ethereum Signature Verification**: Verify Ethereum signatures for messages
36
+ - **Password Generation**: Generate secure passwords from Ethereum signatures
37
+ - **Encrypted Key Pair Management**: Create, store, and retrieve encrypted key pairs
38
+ - **Proof of Integrity**: Verify data integrity on-chain
39
+ - **Stealth Addresses**: Private transaction capabilities
40
+ - **Hybrid Storage**: Support for both on-chain and off-chain data storage
35
41
 
36
- - **Ethereum Signature Verification**: Verify Ethereum signatures for messages.
37
- - **Password Generation**: Generate secure passwords from Ethereum signatures.
38
- - **Signature Creation**: Create Ethereum signatures for messages.
39
- - **Encrypted Key Pair Management**: Create, store, and retrieve encrypted key pairs.
40
- - **SHINE Implementation**: Implement the SHINE for data verification on the blockchain.
41
- - **Custom Token Management**: Set and retrieve custom tokens for Gun operations.
42
-
43
- ## HOW TO INSTALL
42
+ ## Installation
44
43
 
45
44
  ```bash
46
45
  npm install gun-eth
@@ -55,14 +54,14 @@ const gun = Gun();
55
54
  await gun.generatePassword("YOUR_SIGNATURE");
56
55
  ```
57
56
 
58
- ## HOW TO USE
57
+ ## Usage
59
58
 
60
59
  Learn more about Gun.js [here](https://gun.eco/docs/Getting-Started).
61
60
 
62
61
  Learn more about plugin implementation [here](https://github.com/amark/gun/wiki/Adding-Methods-to-the-Gun-Chain#abstraction-layers).
63
62
 
64
63
 
65
- ## HOW IT WORKS
64
+ ## How It Works
66
65
 
67
66
  ### Create KeyPair
68
67
 
@@ -74,7 +73,7 @@ Learn more about plugin implementation [here](https://github.com/amark/gun/wiki/
74
73
 
75
74
  [![](https://mermaid.ink/img/pako:eNplUsluwjAQ_ZWRz_ADObQCEiggOLAc2iQHN56ABbGjsU2FAv_erBBBLs7Yb5lnT8ESLZB5LD3rv-TIycLOjxSU3yjc7kabnQcbtCTxgrDEa84lxTAcfsC42BskyElfpEADXAhCU65KgJEHxa0j_Lw3WuOKcvtGc4NJ-NBDldA1tyjg1ChDSjqDmVP-OG6Ik9rLL4J3qHZKdPr-Uz8IfayxD6QzUh26RnvNtRZBbTEtWprUCoxLkjJL6s6dwfRpMKsCOFIg8KWnuI9d6xt8dVAk0uTBXvHfM4LVHTfut18x5i-M9spBadskjvsXWjEWL4yVNHXe7j00vSWe1YmXYbD2nw7Uvkrn8NWAmmLeLxZNwQYsQ8q4FOX4FNVRxOwRM4yYV_4KTqeI1dvqXmK5s3p7VQnzLDkcMNLucGReys-mrFwuuEVf8gPx7LGLQlpNq2ZC60EdsJyrH607zP0f6c7pXw?type=png)](https://mermaid.live/edit#pako:eNplUsluwjAQ_ZWRz_ADObQCEiggOLAc2iQHN56ABbGjsU2FAv_erBBBLs7Yb5lnT8ESLZB5LD3rv-TIycLOjxSU3yjc7kabnQcbtCTxgrDEa84lxTAcfsC42BskyElfpEADXAhCU65KgJEHxa0j_Lw3WuOKcvtGc4NJ-NBDldA1tyjg1ChDSjqDmVP-OG6Ik9rLL4J3qHZKdPr-Uz8IfayxD6QzUh26RnvNtRZBbTEtWprUCoxLkjJL6s6dwfRpMKsCOFIg8KWnuI9d6xt8dVAk0uTBXvHfM4LVHTfut18x5i-M9spBadskjvsXWjEWL4yVNHXe7j00vSWe1YmXYbD2nw7Uvkrn8NWAmmLeLxZNwQYsQ8q4FOX4FNVRxOwRM4yYV_4KTqeI1dvqXmK5s3p7VQnzLDkcMNLucGReys-mrFwuuEVf8gPx7LGLQlpNq2ZC60EdsJyrH607zP0f6c7pXw)
76
75
 
77
- ## CORE FUNCTIONS
76
+ ## Core Functions
78
77
 
79
78
  - `verifySignature(message, signature)`: Verifies an Ethereum signature for a given message.
80
79
 
@@ -112,91 +111,301 @@ Learn more about plugin implementation [here](https://github.com/amark/gun/wiki/
112
111
  gun.shine("optimismSepolia", nodeId, data, callback);
113
112
  ```
114
113
 
115
- ## SHINE
114
+ ## Security Considerations
115
+
116
+ - Use a secure Ethereum provider (e.g., MetaMask) when interacting with functions that require signatures.
117
+ - Generated passwords and key pairs are sensitive. Handle them carefully and avoid exposing them.
118
+ - Keep Gun.js and Ethereum dependencies up to date for security.
119
+ - Be aware of gas costs associated with blockchain interactions when using SHINE.
120
+
121
+ ## Contributing
122
+
123
+ We welcome contributions! Please open an issue or submit a pull request on GitHub.
116
124
 
117
- SHINE (Secure Hash Integrity Network Ethereum) provides a mechanism for verifying data integrity using Ethereum and Gun.js.
118
125
 
119
126
 
120
- [![](https://mermaid.ink/img/pako:eNplk1GTmjAQx79KJs_oICAiD9epQoX25Dq1006LPqRkPTMHiRODdx763S8Ez7N3PCXZ__73txvS4EJQwCFel-Kx2BCp0M9oyZH-PucL1e4XSZrF6BdItmYFUUzwFer1btCkSfm2ViHi2iGln05d2qQNHv_A7oim-Q9QksEeECWKoLUUFZrVPJqsOu3UGEVNZKKi5heX6M0lzuMnJUmhUCG4Aq4SstusrmWZOKIvecxpiIwTF6pzO6tiU2aWmx4OHYvgPd0u42fJzEiSjmRPSkYvilek5A0pzWegUEkU7BSSUAhJu-b-laJ4uPZNLoBf3wHuzUDhlTE1AN-uRO8E19Nt_W41AwepGRCHx_MlnLW3xmyeTyW08Y9zmxtBpm9YSECM_3crmQne5b8l08mCf-zqzii-d7CZrm5GumvN6ApbuAJZEUb1b9W0CUusNlDBEod6SYl8WGJzzE9aS2olFgde4FDJGiwsRX2_weGalDu9q7faGiJG7iWpLqdbwnHY4Ccc9pxxf-wEA9exPc92A384tPABh8NB33WDwdCxfcfxAy84WfhZCG0x6HuuZ49HI98PRjpojywMlGn2efcSzIMwNf6ahBbr9AJRuPoz?type=png)](https://mermaid.live/edit#pako:eNplk1GTmjAQx79KJs_oICAiD9epQoX25Dq1006LPqRkPTMHiRODdx763S8Ez7N3PCXZ__73txvS4EJQwCFel-Kx2BCp0M9oyZH-PucL1e4XSZrF6BdItmYFUUzwFer1btCkSfm2ViHi2iGln05d2qQNHv_A7oim-Q9QksEeECWKoLUUFZrVPJqsOu3UGEVNZKKi5heX6M0lzuMnJUmhUCG4Aq4SstusrmWZOKIvecxpiIwTF6pzO6tiU2aWmx4OHYvgPd0u42fJzEiSjmRPSkYvilek5A0pzWegUEkU7BSSUAhJu-b-laJ4uPZNLoBf3wHuzUDhlTE1AN-uRO8E19Nt_W41AwepGRCHx_MlnLW3xmyeTyW08Y9zmxtBpm9YSECM_3crmQne5b8l08mCf-zqzii-d7CZrm5GumvN6ApbuAJZEUb1b9W0CUusNlDBEod6SYl8WGJzzE9aS2olFgde4FDJGiwsRX2_weGalDu9q7faGiJG7iWpLqdbwnHY4Ccc9pxxf-wEA9exPc92A384tPABh8NB33WDwdCxfcfxAy84WfhZCG0x6HuuZ49HI98PRjpojywMlGn2efcSzIMwNf6ahBbr9AJRuPoz)
127
+ ## Stealth Addresses
121
128
 
129
+ ### Simple Explanation
130
+ Stealth addresses allow you to receive payments without revealing your actual Ethereum address to anyone. It's like having a secret mailbox that only you can access, but anyone can send mail to. Each time someone wants to send you ETH, they generate a new, unique address that only you can unlock.
122
131
 
132
+ ### Key Benefits
133
+ - **Privacy**: Your real address is never exposed
134
+ - **Unlinkability**: Each payment uses a different address
135
+ - **Security**: Only you can access the funds
136
+ - **Decentralized**: Works without any central server
123
137
 
124
- #### SHINE Contract Configuration
138
+ ### Technical Details
139
+ The stealth address system implements a protocol similar to Umbra, using:
125
140
 
126
- Currently, SHINE supports only the Optimism Sepolia network. The contract address is managed internally:
141
+ 1. **Key Pairs**:
142
+ - Viewing Key Pair: For decrypting payment notifications
143
+ - Spending Key Pair: For accessing received funds
144
+
145
+ 2. **Protocol Flow**:
146
+ ```mermaid
147
+ sequenceDiagram
148
+ participant Bob as Sender (Bob)
149
+ participant Contract as StealthAnnouncer Contract
150
+ participant Alice as Recipient (Alice)
151
+
152
+ Bob->>Bob: Generate stealth address using Alice's public keys
153
+ Bob->>Contract: Announce payment (stealthAddress, metadata)
154
+ Bob->>Blockchain: Send ETH to stealth address
155
+ Alice->>Contract: Scan for announcements
156
+ Alice->>Alice: Derive private key for stealth address
157
+ Alice->>Blockchain: Access funds using derived key
158
+ ```
159
+
160
+ 3. **Key Components**:
161
+ - **StealthAnnouncer Contract**: Manages payment announcements on-chain
162
+ - **GunDB Integration**: Stores encrypted key pairs and metadata
163
+ - **ECDH**: For shared secret generation
164
+ - **Key Derivation**: For stealth address generation
165
+
166
+ ### Usage Example
127
167
 
128
168
  ```javascript
129
- const SHINE_OPTIMISM_SEPOLIA = "0x43D838b683F772F08f321E5FA265ad3e333BE9C2";
169
+ // Setup recipient (Alice)
170
+ await gun.createAndStoreEncryptedPair(aliceAddress, aliceSignature);
171
+
172
+ // Generate stealth address (Bob)
173
+ const stealthInfo = await gun.generateStealthAddress(aliceAddress, bobSignature);
174
+
175
+ // Announce payment (Bob)
176
+ await gun.announceStealthPayment(
177
+ stealthInfo.stealthAddress,
178
+ stealthInfo.senderPublicKey,
179
+ stealthInfo.spendingPublicKey,
180
+ bobSignature,
181
+ { onChain: true }
182
+ );
183
+
184
+ // Recover funds (Alice)
185
+ const recoveredWallet = await gun.recoverStealthFunds(
186
+ stealthAddress,
187
+ senderPublicKey,
188
+ aliceSignature,
189
+ spendingPublicKey
190
+ );
130
191
  ```
131
192
 
132
- To support other chains in the future, the plugin will select the appropriate address based on the `chain` parameter provided to the `shine` function.
193
+ ### Features
194
+ - **Hybrid Storage**: Supports both on-chain and off-chain announcements
195
+ - **Dev Fee System**: Optional fee system for protocol sustainability
196
+ - **Batch Processing**: Efficient scanning of multiple announcements
197
+ - **Key Recovery**: Secure key pair backup and recovery
198
+ - **Multi-chain Support**: Ready for deployment on any EVM chain
133
199
 
134
- #### SHINE Helper Functions
200
+ ### Security Considerations
201
+ - Keep your viewing and spending keys secure
202
+ - Never reuse stealth addresses
203
+ - Verify contract addresses before interacting
204
+ - Consider gas costs for on-chain announcements
205
+ - Use appropriate entropy for key generation
135
206
 
136
- SHINE uses several internal helper functions to interact with the blockchain:
207
+ For more technical details, check the [StealthAnnouncer.sol](./src/contracts/StealthAnnouncer.sol) contract and [stealth.js](./src/node/stealth.js) implementation.
137
208
 
138
- - `getSigner()`: Retrieves an Ethereum signer from the browser provider (e.g., MetaMask).
139
- - `verifyOnChain(nodeId, contentHash)`: Verifies data integrity on the blockchain.
140
- - `writeOnChain(nodeId, contentHash)`: Writes the content hash to the blockchain.
141
- - `getLatestRecord(nodeId)`: Retrieves the latest record associated with a nodeId from the blockchain.
209
+ ## Proof of Integrity
142
210
 
143
- These functions are used internally by the `shine` method and are not directly exposed to the user.
211
+ The Proof of Integrity system provides on-chain verification of data integrity using smart contracts. This feature allows you to:
144
212
 
145
- ### Usage Examples
213
+ - Store cryptographic proofs of data on-chain
214
+ - Verify data hasn't been tampered with
215
+ - Track data modifications
216
+ - Maintain an immutable audit trail
146
217
 
147
- #### Verifying Data by NodeId
218
+ ### How It Works
219
+
220
+ 1. When data is written:
221
+ - Data is stored in GunDB
222
+ - A content hash is generated
223
+ - The hash is stored on-chain via smart contract
224
+ - The original data remains in GunDB
225
+
226
+ 2. When data is verified:
227
+ - The current data is hashed
228
+ - The hash is compared with on-chain record
229
+ - Timestamp and updater info is retrieved
230
+ - Any modifications are detected
231
+
232
+ ### Example Usage
148
233
 
149
234
  ```javascript
150
- const nodeId = "your-node-id-here";
235
+ // Write data with proof
236
+ gun.proof("localhost", null, { message: "Hello, blockchain!" }, (ack) => {
237
+ if (ack.ok) {
238
+ console.log("Data written with proof:", ack.nodeId);
239
+ }
240
+ });
151
241
 
152
- gun.shine("optimismSepolia", nodeId, null, (ack) => {
242
+ // Verify data integrity
243
+ gun.proof("localhost", nodeId, null, (ack) => {
153
244
  if (ack.ok) {
154
- console.log("Data verified on blockchain", ack);
155
- console.log("Timestamp:", ack.timestamp);
156
- console.log("Updater:", ack.updater);
157
- console.log("Latest Record:", ack.latestRecord);
158
- } else {
159
- console.log("Data not verified or not found", ack);
245
+ console.log("Data verified on blockchain");
246
+ console.log("Last update:", new Date(ack.timestamp * 1000));
247
+ console.log("Updated by:", ack.updater);
160
248
  }
161
249
  });
162
250
  ```
163
251
 
164
- #### Storing New Data
252
+ ### Batch Operations
253
+
254
+ You can also verify multiple nodes at once:
165
255
 
166
256
  ```javascript
167
- const data = { message: "Hello, blockchain!" };
257
+ gun.proof("localhost", null, [
258
+ { nodeId: "id1", data: "data1" },
259
+ { nodeId: "id2", data: "data2" }
260
+ ], callback);
261
+ ```
168
262
 
169
- gun.shine("optimismSepolia", null, data, (ack) => {
170
- if (ack.ok) {
171
- console.log("Data stored on Gun.js and blockchain", ack);
172
- console.log("New Node ID:", ack.nodeId);
173
- console.log("Transaction Hash:", ack.txHash);
174
- } else {
175
- console.log("Error storing data", ack);
176
- }
177
- });
263
+ ## Local Development
264
+
265
+ 1. Clone the repository:
266
+ ```bash
267
+ git clone https://github.com/scobru/gun-eth
268
+ cd gun-eth
178
269
  ```
179
270
 
180
- ## STANDALONE MODE
271
+ 2. Install dependencies:
272
+ ```bash
273
+ yarn install
274
+ ```
181
275
 
182
- For users who want to run the plugin without a browser wallet, you can use the standalone mode. This requires setting up an RPC URL and a private key:
276
+ 3. Start local Hardhat node:
277
+ ```bash
278
+ yarn start-node
279
+ ```
183
280
 
184
- ```javascript
185
- gun.setStandaloneConfig("https://your-rpc-url", "your-private-key");
281
+ 4. Deploy contracts:
282
+ ```bash
283
+ yarn deploy-local
186
284
  ```
187
285
 
188
- Make sure to keep your private key secure and never expose it in client-side code.
286
+ 5. Build the project:
287
+ ```bash
288
+ yarn build
289
+ ```
189
290
 
190
- ### Security Considerations
291
+ 6. Run examples:
292
+ ```bash
293
+ # Test stealth addresses
294
+ yarn test-stealth
191
295
 
192
- - Use a secure Ethereum provider (e.g., MetaMask) when interacting with functions that require signatures.
193
- - Generated passwords and key pairs are sensitive. Handle them carefully and avoid exposing them.
194
- - Keep Gun.js and Ethereum dependencies up to date for security.
195
- - Be aware of gas costs associated with blockchain interactions when using SHINE.
296
+ # Test proof of integrity
297
+ yarn test-proof
298
+ ```
299
+
300
+ ### Environment Setup
301
+
302
+ Create a `.env` file with:
303
+
304
+ ```env
305
+ PRIVATE_KEY=your_private_key
306
+ RPC_URL=your_rpc_url
307
+ CHAIN_ID=your_chain_id
308
+ ```
309
+
310
+ ### Testing
311
+
312
+ The project includes several test examples:
313
+
314
+ - `examples/eth2gun.html`: Browser demo for key pair management
315
+ - `examples/proof.html`: Browser demo for proof of integrity
316
+ - `examples/stealth-example.js`: Node.js demo for stealth addresses
317
+ - `examples/proof-example.js`: Node.js demo for proof of integrity
318
+
319
+ ## Bundle Information
320
+
321
+ The project is bundled using Rollup and provides three different formats:
322
+
323
+ 1. **UMD Bundle** (Browser)
324
+ - File: `dist/gun-eth.min.js`
325
+ - Usage:
326
+ ```html
327
+ <script src="dist/gun-eth.min.js"></script>
328
+ ```
329
+
330
+ 2. **ES Module**
331
+ - File: `dist/gun-eth.esm.js`
332
+ - Usage:
333
+ ```javascript
334
+ import GunEth from 'gun-eth';
335
+ ```
336
+
337
+ 3. **CommonJS**
338
+ - File: `dist/gun-eth.cjs.js`
339
+ - Usage:
340
+ ```javascript
341
+ const GunEth = require('gun-eth');
342
+ ```
343
+
344
+ ## API Reference
345
+
346
+ ### Core Methods
347
+
348
+ | Method | Description | Parameters | Returns |
349
+ |--------|-------------|------------|---------|
350
+ | `verifySignature` | Verifies an Ethereum signature | `message`, `signature` | `Promise<address>` |
351
+ | `generatePassword` | Generates password from signature | `signature` | `string` |
352
+ | `createSignature` | Creates an Ethereum signature | `message` | `Promise<string>` |
353
+ | `createAndStoreEncryptedPair` | Creates and stores key pair | `address`, `signature` | `Promise<void>` |
354
+ | `getAndDecryptPair` | Retrieves stored key pair | `address`, `signature` | `Promise<Object>` |
355
+ | `proof` | Manages proof of integrity | `chain`, `nodeId`, `data`, `callback` | `Gun` |
356
+
357
+ ### Stealth Methods
358
+
359
+ | Method | Description | Parameters | Returns |
360
+ |--------|-------------|------------|---------|
361
+ | `generateStealthAddress` | Generates stealth address | `recipientAddress`, `signature` | `Promise<Object>` |
362
+ | `announceStealthPayment` | Announces payment | `stealthAddress`, `senderPublicKey`, `spendingPublicKey`, `signature` | `Promise<void>` |
363
+ | `recoverStealthFunds` | Recovers funds from stealth address | `stealthAddress`, `senderPublicKey`, `signature` | `Promise<Object>` |
364
+
365
+ ## Security Considerations
366
+
367
+ 1. **Key Management**
368
+ - Store private keys securely
369
+ - Never expose signatures or passwords
370
+ - Use hardware wallets when possible
371
+
372
+ 2. **Network Security**
373
+ - Use secure RPC endpoints
374
+ - Implement rate limiting
375
+ - Validate all input data
376
+
377
+ 3. **Smart Contract Interaction**
378
+ - Verify contract addresses
379
+ - Check gas costs before transactions
380
+ - Monitor for contract upgrades
381
+
382
+ 4. **Data Privacy**
383
+ - Use stealth addresses for sensitive transactions
384
+ - Encrypt sensitive data before storage
385
+ - Regularly rotate keys
196
386
 
197
387
  ## Contributing
198
388
 
199
- We welcome contributions! Please open an issue or submit a pull request on GitHub.
389
+ 1. Fork the repository
390
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
391
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
392
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
393
+ 5. Open a Pull Request
394
+
395
+ ### Development Guidelines
396
+
397
+ - Follow JavaScript Standard Style
398
+ - Add tests for new features
399
+ - Update documentation
400
+ - Maintain backward compatibility
401
+
402
+ ## Support
403
+
404
+ For support, please:
405
+
406
+ 1. Check the [documentation](https://github.com/scobru/gun-eth#readme)
407
+ 2. Search [existing issues](https://github.com/scobru/gun-eth/issues)
408
+ 3. Create a new issue if needed
200
409
 
201
410
  ## License
202
411
 
@@ -205,3 +414,9 @@ This project is released under the MIT license.
205
414
  ## Contact
206
415
 
207
416
  For questions or support, please open an issue on GitHub: https://github.com/scobru/gun-eth
417
+
418
+ ## Acknowledgments
419
+
420
+ - [GunDB](https://gun.eco/) team
421
+ - [Ethereum](https://ethereum.org/) community
422
+ - All contributors