diff --git a/basic/08-hardhat-graph/README-CN.md b/basic/08-hardhat-graph/README-CN.md index 3a1392e6f..f49a61a7d 100644 --- a/basic/08-hardhat-graph/README-CN.md +++ b/basic/08-hardhat-graph/README-CN.md @@ -405,7 +405,7 @@ Alchemy 也提供了 Subgraph 功能,用户可以轻松的从 Thegraph 上把 - 部署 部署流程和 thegraph host service 流程一样,编写完 ts 代码后进行 codegen、build,最后deploy 的时候需要输入 deploy-key 这个参数,这个 key 需要在 Dashboard 界面获取 -
+
参考: https://docs.alchemy.com/reference/subgraphs-quickstart @@ -413,12 +413,13 @@ Alchemy 也提供了 Subgraph 功能,用户可以轻松的从 Thegraph 上把 2. Alchemy Subgraph Pricing 默认情况下,使用的是 Free Plan, 对于开发者自己使用是足够的,当用于项目时,需要升级 Plan,解锁更都的查询次数 -
+
3. Thegraph Pricing Growth Plan 一个月 $49, 有 100,0000 的查询次数,平均 $0.000049/次,而 thegraph 查询 100,0000 次,需要约 186 GRT, GRT 按照 $0.2 计算的话,thegraph 平均 $0.000037/次 -
+ +
参考:https://www.alchemy.com/pricing @@ -427,16 +428,17 @@ Growth Plan 一个月 $49, 有 100,0000 的查询次数,平均 $0.000049/次 1. 本地构建 使用 `envio init` 初始化项目目录,然后使用 `envio dev` 启动本地 Indexer。 envio 本地 indexer 启动很快,启动后便可通过 [http://localhost:8080/](http://localhost:8080/console) 进行访问 -
+
2. 部署 Host Service 把使用 envio init 初始化后的项目上传到 github, 然后对授权这个 repo 的访问权限个 envio,那么提交 commit 后,envio 就会自动进行部署 -
+ +
3. 部署成功 部署成功后,即可在 envio 的 Host Service 处查看访问 -
+
参考:https://docs.envio.dev/docs/HyperIndex/hosted-service-deployment @@ -448,7 +450,8 @@ envio 本地 indexer 启动很快,启动后便可通过 [http://localhost:8080 ### Ponder 1. 本地构建 Ponder 也可以本地进行构建,但是他需要使用 Ethereum RPC 到节点去获取数据,类似 Alchemy 的 subgraph ,受限于 Ethereum RPC 节点的访问频率。官方网站推荐使用 Alchemy 的 RPC, 但根据上面介绍的,Alchemy 的 RPC 有访问限制 -
+ +
2. Host Service 构建 目前 ponder 只在 [Railway](https://railway.app/) 上进行了全面的测试兼容,对于其他的平台,没有进行完整的测试。 diff --git a/basic/80-crossChainTransfer/layerZero/README-cn.md b/basic/80-crossChainTransfer/layerZero/README-cn.md index 78f74fae6..484b33fdf 100644 --- a/basic/80-crossChainTransfer/layerZero/README-cn.md +++ b/basic/80-crossChainTransfer/layerZero/README-cn.md @@ -4,7 +4,58 @@ ## 概览 LayerZero 是一种全链互操作性协议,专注于链与链之间的数据消息传递,允许任何数据,包括代币、链的状态、合约调用、NFT 或治理投票等,从链 A 转移到链 B。 -LayerZero 通过 Relayer 和 Oracle 结合的方式实现数据的跨链传输。其中 Oracle 提交跨链申请,Relayer 提交跨链证明,从而防止作恶 +LayerZero 通过 Relayer 和 Oracle 结合的方式实现数据的跨链传输。其中 Oracle 提交跨链申请,Relayer 提交跨链证明,从而防止作恶。 +简单地说,LayerZero 处理通信,应用程序处理其它一切问题。这种组合允许应用安全地在所有链上统一资产的平衡。 + +### LayerZero 角色 +LayerZero 的核心角色分为 Oracle 和 Relayer, 承担着两条链之间信息传递 +
+ +### Oracle 和 Relayer 的分工 +简单来说,Oracle(预言机)的主要作用是让目标链上的合约知道什么时候验证和验证的答案是什么。而 Relayer(中继器)则负责提供验证交易所需的证明过程以及跨链信息的具体内容。 + +1. Oracle 的作用 +将源头链上跨链请求所在的 Blockhash 和 Block Receiptsroot 传递到目标链上. +Blockhash: 告知目标链上的合约哪个区块里有用户的跨链请求 +Block Receiptsroot: 用来验证交易中继器传递的消息 + +2. Relayer 的作用 +将跨链消息所在的 Receipt 和 Merkle Proof 所需的路径信息传递到目标链上的合约用以验证。 +其中 Receipt 收据是指交易回执信息,其中主要包含着交易执行结果、交易哈希和交易事件日志。 +交易执行结果:源链上交易本身是否成功。 +交易哈希:每一笔交易的全局唯一哈希。 +交易事件日志:跨链信息的具体内容。 +这里的路径信息就是下图的红色箭头,比如将中继者依次将 L2 -> Hash 0-0 -> Hash 1 信息告诉链上节点后。比对预言机给出的 TopHash,以及基于中继者给出的信息合约进行二次计算后一致则说明中继者是正确的。 +
+ +3. LayerZero 的跨链生命周期 + +
+整体流程概述如下: + +一个交易从用户应用程序(UA)启动一个交易(即在链上执行某些操作)开始。然后,通过预言机和中继器在 LayerZero 端点的协助下,将这个交易分解成多个部分(证明和区块头)。一旦预言机和中继器在目标链上发送各自的信息(签署交易上链),并且 LayerZero Endpoint(合约)验证了信息的正确性,消息就会被转化并在目标链上执行。 + +展开详细步骤如下(对照上图看): + +步骤 1:用户应用程序 UA(如 Stargate 桥)LayerZero 的通信器(Communicator)发送请求,包括交易标识符 t、从 A 到 B 转移的数据(payload 有效负载)、或指向 Chain B 上用户应用程序智能合约的标识符或者中继器 (relayer_args) 等交易信息。 + +步骤 2:通信器将这些数据以 LayerZero 数据包(packet)的形式发送给验证器(Validator) + +步骤 3:验证器将交易标识符和链 B 上智能合约的标识符等发送给网络层(NetWork)。网络层的工作也被触发,有待传递的信息需要通过 oracle 将源链 A 的区块头发送到目标链 B。 + +步骤 4:验证器将此信息(packet)转发给中继器。中继器被通知后则取交易证明(第 7 步的 Proof)链下存储,并将其发送到 Chain B(第 11 步),chainB 的端点亦可发起申请要求获取指定块哈希的结果 (第 10 步)。 + +步骤 5:网络层将 Chain B 上智能合约的标识符和交易块的块 ID 一起发送给预言机。当预言机被通知则获取 Chain A 上当前块的块头(第 6 步)并将其发送到 Chain B(第 8 步)。 + +可以看到这时候其实 6、7、8、10、11 的部分都内嵌在中继器和预言机的环节执行了。 + +步骤 9:网络层将获取到的区块哈希发送到验证器(触发超轻节点的验证)。 + +步骤 12:验证器通过查看网络层存储的交易证明和块头来确保交易有效且已提交。如果块头和交易证明匹配,则将交易信息(Packet)发送到通信器。 + +步骤 13:通信器将信息(Packet)转发送到 Chain B 上的用户应用程序中,执行任意功能。 + +整体跨链是在源链上执行首笔交易的时候收取的 Gas 手续费,到了目标链上则是对应 3 笔,构成是中继器+预言机+Layer Zero: Executor(某个 EOA 账号)。 ## 测试环境要求 node 版本需要为 v20.11.0, 可以使用 nvm 切换当前 node 版本 @@ -108,4 +159,6 @@ npx hardhat run scripts/sendTokens/7-checkResultOnOpsepolia.js --network optim_s - example for OmniCounter: https://github.com/LayerZero-Labs/solidity-examples/blob/main/test/examples/OmniCounter.test.js - blog: https://senn.fun/layerzero-v1 - layerzero scan: https://testnet.layerzeroscan.com/ -- Whitepaper: https://layerzero.network/publications/LayerZero_Whitepaper_V1.1.0.pdf \ No newline at end of file +- Whitepaper: https://layerzero.network/publications/LayerZero_Whitepaper_V1.1.0.pdf +- https://www.theblockbeats.info/news/42610 +- https://foresightnews.pro/article/detail/2100 \ No newline at end of file diff --git a/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/1-deployOmniCounterOnSepolia.js b/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/1-deployOmniCounterOnSepolia.js index 870485a27..9b2328ed0 100644 --- a/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/1-deployOmniCounterOnSepolia.js +++ b/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/1-deployOmniCounterOnSepolia.js @@ -15,6 +15,7 @@ async function main() { const [deployer] = await ethers.getSigners(); // for sepolia, endpoint address is fixed, refer to : https://layerzero.gitbook.io/docs/technical-reference/testnet/testnet-addresses + // for mainnet endpoint address, please refer to : https://docs.layerzero.network/v1/developers/evm/technical-reference/mainnet/mainnet-addresses const omniCounter = await ethers.deployContract("OmniCounter", ["0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1"]); await omniCounter.waitForDeployment(); diff --git a/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/2-deployOmniCounterOnOptimSepolia.js b/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/2-deployOmniCounterOnOptimSepolia.js index a56c1efd4..d1e83cd58 100644 --- a/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/2-deployOmniCounterOnOptimSepolia.js +++ b/basic/80-crossChainTransfer/layerZero/scripts/sendMessage/2-deployOmniCounterOnOptimSepolia.js @@ -14,6 +14,7 @@ async function main() { const [deployer] = await ethers.getSigners(); // for sepolia, endpoint address is fixed, refer to : https://layerzero.gitbook.io/docs/technical-reference/testnet/testnet-addresses + // for mainnet endpoint address, please refer to : https://docs.layerzero.network/v1/developers/evm/technical-reference/mainnet/mainnet-addresses const omniCounter = await ethers.deployContract("OmniCounter", ["0x55370E0fBB5f5b8dAeD978BA1c075a499eB107B8"]); await omniCounter.waitForDeployment();