# jLab：郭宇的Web3开发最佳实践阅读笔记-7



### jLab：郭宇的最佳实践阅读笔记-7

### 概述

阅读大牛郭宇的文章

https://guoyu.mirror.xyz/RD-xkpoxasAU7x5MIJmiCX4gll3Cs0pAd5iM258S1Ek

第六篇笔记见这里：[here](https://blog.jlab.tech/jlab-web3-fullstack-engineer-6)，主要是客户端和开发、测试环境。

本篇主要说服务器端方案，包括编码技术栈和集成发布方案。

#### 概述

个人见解，未来应用的部署方式（服务器端），会是复杂和交叉的，云计算，边缘计算，甚至自己还思考过类似P2P的点即服务的雨计算（这个话题有兴趣的可以聊），都会存在。因为以太坊这个世界计算机还在进化之中，目前

1. 链上存储和计算成本昂贵

2. 链上技术能力也无法支持类似传统服务器的各种操作系统和Runtime

3. 交互体验不好，反复授权签名
4. 一些过程数据、索引和交叉计算，链上成本和性能都很差。

所以Uniswap直接抛弃了服务器，只有前端页面和合约，但这个是特殊的，大部分需要特地个的业务计算，网页的WebAssembly还在发展之中，因此Server是保障业务正常和较好体验的保障。

而对于UI来说，目前可以IPFS活着ARweave等等方式去中心了，但警惕：不要过度依赖Server端来运行业务，郭宇举例是：不能将核心逻辑放在私有服务器中依赖，或者一味使用服务端储存的机器人钱包私钥来操作区块链，这个很重要，否则你的就不是DApp了，呵呵。

目前习惯的使用Node技术，一部分和`Provider/Signer`交互的业务逻辑可能复用。

#### 开发环境

1. 使用Node，技术栈是Next.js + Vercel直接github repo 自动构建，这里有个注意事项，可以建立dev分支，本地测试稳定后，再merge到main分支，然后线上自动发布，否则会持续自动发布。如果你使用的Fleek免费版，是有构建时间限额的。

2. 对于复杂DApp来说，多个对象、关系表，需要多次聚合和计算的，使用FaaS，郭宇推荐Firebase，我个人是没怎么用过FaaS的，记得用过最多的是图片处理的一些FaaS。郭宇推荐：你可以使用 Firebase 快速连接实时数据库，整合 Twitter 或 GitHub 的第三方登录，它还提供非常好用的本地模拟器工具套件，以及，它能够非常好地支持跨平台，Google的招牌足够大，倒是可以考虑。其他方案前面说过。[Firebase](https://firebase.google.com/docs/web/setup?hl=zh-cn)

3. Server端有两个Web3技术栈

   1>SIWE，Ethereum官方推荐的登录集成体系，自己写个Demo就了解了，两个API，`/nonce` 和 `/vertify`，参考这里：[Demo](https://github.com/spruceid/siwe-quickstart)。

   钱包登录只需要使用前端脚本连接钱包即可，但这种逻辑很容易被 hack，因为任何客户端状态都能够被低成本修改，因此要使用稳定方案[SIWE](https://docs.login.xyz/general-information/siwe-overview/eip-4361),标准化开发者使用钱包登录授权 Off-chain 产品的逻辑。

   2> SIWE支持广泛：JavaScript, Rust, Python, Golang, Ruby，可以使用Next.js的[NextAuth](https://next-auth.js.org/) 来快速整合它。

   Siwe 通过对服务端发行的随机 `nonce` 和其他标准输入进行签名，再通过服务端验证签名内容的方式来确认提交方的地址，简单说，就是一个签名+校验机制，和OAuth2简单点。

   3> Server和Relay交互

   郭宇：使用Provider 与 Relay Network 通信（只读模式），比如，我们通过整合区块高度，某个合约状态和订阅事件，来组建我们自己的数据缓存服务并提供 API，那我们只需要按照前端的方式与 Relay Network 建立通信即可。在这种模式下，我们可以把 access key 存放在生产环境的环境变量中，我推荐你使用 [dotenv](https://github.com/motdotla/dotenv) 去处理它们，利用系统机制保护密钥，Node使用`process.env`获取。

   这里不难理解，如果读写模式，例如币安这样的大型交易所，或者自己的DEX，都会涉及机器人钱包和密钥的问题。

   做这些之前，要进行安全规划，分清边界、风险来源、最大风险和应对、check以及措施。类似于公司的合规风控一样，这里是核心，否则死都不知道怎么死的。

   使用环境变量绝对是自杀，因为往往会全局，明显是范围扩大，作死。传统的，郭宇建议是采用专业的私钥管理服务来管理，例如使用 [Google Secret Manager](https://cloud.google.com/secret-manager) 或者 [AWS Secrets Manager](https://aws.amazon.com/cn/secrets-manager/) 来进行管理。

   4>其他

   通过 Provider 和 Signer 与 Relay Network 进行通信只需要传递钱包私钥给对应的 `Provider/Signer` 实例即可完成操作，与本地进行单元测试的机器人钱包一样，它不会有额外的确认过程（这个千万记住了，等于家门钥匙给别人了，以前是你交互确认，给别人开门），因此，我们需要确认钱包中有足够的 ETH 或其他 Gas token 余额，否则该交易会失败。

4. 一些SDK

   更方便地在服务端与合约进行通信，有集成的例如[ThirdWeb](https://thirdweb.com/)，这个没用过，因为自己还没有开发过大型的复杂DApp，郭宇推荐：Thirdweb 提供了一个 SaaS 合约开发平台，你可以通过它的前端 App 发布预设功能的合约，例如 NFT Drop 或者 NFT 交易平台，也可以使用它提供的第三方 access key 与已发布的合约进行通信（而无需依赖合约的 ABI）。听起来不错。

   使用范例：（Next），[JavaScript SDK](https://github.com/thirdweb-dev/typescript-sdk)（Typescript）

   ```
   import { ThirdwebSDK } from "@thirdweb-dev/sdk";
   
   // The RPC url determines which blockchain you want to connect to
   const rpcUrl = "https://polygon-rpc.com/";
   // instantiate the SDK as read only on a given blockchain
   const sdk = new ThirdwebSDK(rpcUrl);
   
   // access your deployed contracts
   const nftDrop = sdk.getNFTDrop("0x...");
   const marketplace = sdk.getMarketplace("0x...");
   
   // Read from your contracts
   const claimedNFTs = await nftDrop.getAllClaimed();
   const listings = await marketplace.getActiveListings();
   ```

   
