ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Chainlink VRF V2+ 测试网实战:从合约部署、订阅管理到批量 Blockhash 存储的完整操作指南

Chainlink VRF V2+ 测试网实战:从合约部署、订阅管理到批量 Blockhash 存储的完整操作指南 Chainlink VRF V2 测试网实战从合约部署、订阅管理到批量 Blockhash 存储的完整操作指南【免费下载链接】chainlinknode of the decentralized oracle network, bridging on and off-chain computation项目地址: https://gitcode.com/GitHub_Trending/ch/chainlink本指南以 Chainlink 仓库中 VRF V2 测试网脚本说明 为核心骨架系统讲解如何在任意 EVM 测试网上借助go run .脚本完成 VRF V2VRFCoordinatorV2_5全链路实操从一键部署 BHS/Coordinator/Consumer 的完整 VRF 环境到创建并资助订阅、授权消费者、发起随机数请求再到使用BatchBlockhashStore批量存取区块哈希。读完本文你将掌握 Chainlink 官方为节点运营者与集成方准备的整套测试网 CLI 工具箱并能直接对照源码main.go、super_scripts.go、util.go理解每个命令背后的链上调用。一、脚本背景与适用场景core/scripts/vrfv2plus/testnet是 Chainlink 官方为VRF V2即 VRFCoordinatorV2_5 系列支持 LINK 与原生代币双支付提供的测试网运维脚本集。它面向以下典型场景在测试网上从零部署一整套 VRF 基础设施LINK Token、LINK/Native 价格 Feed、BlockhashStore、Coordinator、Batch Coordinator、Consumer并自动完成订阅创建、资助与授权最终打印出可供 Chainlink 节点加载的 VRF / BHS / BHF Job Spec以EOA外部账户身份手动管理订阅创建、充值、转账、迁移、取消与消费者部署、授权、请求随机数在 VRF 依赖的区块哈希基础设施上进行批量回填通过BatchBlockhashStore一次交易存取多个区块哈希甚至跨越 256 区块限制反向回填历史区块哈希。脚本本质是一个单入口的 Go 命令行工具main.go中通过switch os.Args[1]分发子命令全部操作通过环境变量注入链端点与密钥非常适合 CI 与自动化脚本集成。脚本目录结构core/scripts/vrfv2plus/ └── testnet/ ├── README.md # 本指南对应的原始文档 ├── main.go # 子命令入口与参数解析约 1500 行 ├── proofs.go # VRF 证明生成辅助逻辑 └── v2plusscripts/ ├── super_scripts.go # 高级组合脚本deploy-universe、smoke、wrapper 等 └── util.go # 部署与订阅操作的底层封装二、运行前置条件在开始之前你需要准备以下资源EVM 链端点 URL可以是本地运行的节点如 geth/anvil也可以是外部托管的 RPC 服务链 IDChain ID与所选链对应的数字标识。例如原文档示例中的 Rinkeby 链 ID 为 4该测试网现已退役建议按 helpers.go 中explorerLinkPrefix支持的链 ID 选择如 Goerli5、Sepolia11155111、Arbitrum Sepolia、Optimism Goerli420 等账户私钥一个持有 LINK 与链原生代币用于支付 gas的测试账户。可以从 MetaMask 导出注意测试网请务必使用不持有真实资金的独立账户链上的 LINK 地址、VRF Coordinator 地址与 Key Hash若链上已有官方部署则直接使用否则可用下文deploy-universe自行部署Go 环境脚本用 Go 编写需要本地安装 Go 工具链。环境变量配置运行脚本前先在 shell 中导出以下环境变量main.go中的helpers.SetupEnv(false)会从环境变量读取链信息见 helpers.goexport ETH_URLYOUR ETH URL export ETH_CHAIN_IDYOUR CHAIN ID export ACCOUNT_KEYYOUR PRIVATE KEY export LINKLINK ADDRESS export LINK_ETH_FEEDADDRESS OFF LINK/ETH FEED export COORDINATORCOORDINATOR ADDRESS export KEY_HASHKEY HASH export ORACLE_ADDRESSYOUR ORACLE NODE ADDRESS export PUB_KEYYOUR UNCOMPRESSED PUBLIC KEY变量说明变量用途说明ETH_URLRPC 端点必填缺失时脚本直接 panicETH_CHAIN_ID链 ID必填决定区块浏览器链接与链特定行为ACCOUNT_KEY账户私钥hex必填脚本用其构建bind.TransactOpts签名交易LINKLINK Token 地址订阅以 LINK 支付时需要LINK_ETH_FEEDLINK/Native 价格 Feed用于计算回退 LINK 价格COORDINATORVRF Coordinator 地址VRF V2 主协调合约KEY_HASHVRF Key Hash请求随机数时指定使用的证明密钥ORACLE_ADDRESS预言机节点地址用于生成 Job SpecPUB_KEYVRF 未压缩公钥注册证明密钥时使用注意默认情况下脚本会自动估算操作的 gas 上限。可选地可以通过设置ETH_GAS_LIMIT_DEFAULT环境变量覆盖操作的 gas 上限若设置了GAS_LIMIThelpers.go 也会将其应用到交易中。此外SetupEnv 会主动把建议 gas 价格翻倍并打印出来以减少测试网上交易卡住的风险。然后进入脚本目录cd YOUR LOCAL CHAINLINK REPO/core/scripts/vrfv2/testnet从当前仓库的实际目录看VRF V2 脚本位于core/scripts/vrfv2plus/testnet原文档中的路径core/scripts/vrfv2/testnet对应 VRF V2 的旧脚本目录下文所有命令均在core/scripts/vrfv2plus/testnet目录下执行。三、一键部署完整 VRF 环境deploy-universedeploy-universe是官方提供的超级脚本会按顺序完成 BHS、Batch BHS、Coordinator、Batch Coordinator、LINK Token、LINK/Native Feed、Consumer 的部署并完成订阅创建、资助、消费者授权最后打印出可供节点使用的 VRF 主/备 Job Spec、BHS Job Spec 与 BHF Job Spec。go run . deploy-universe \ --link-address$LINK \ --link-eth-feed$LINK_ETH_FEED \ --subscription-balance5000000000000000000 \ #5 LINK --subscription-balance-native1000000000000000000 \ #1 ETH --uncompressed-pub-keyVRF Uncompressed Public Key \ --vrf-primary-node-sending-keyssending-key1-address,sending-key2-address \ #used to fund the keys and for sample VRF Job Spec generation --sending-key-funding-amount 100000000000000000 \ #0.1 ETH, fund addresses specified in vrf-primary-node-sending-keys --batch-fulfillment-enabled false \ #only used for sample VRF Job Spec generation --register-vrf-key-against-addresseoa address # from this address you can perform coordinator.oracleWithdraw to withdraw earned funds from rand request fulfilments参数行为说明结合 super_scripts.go 中DeployUniverseViaCLI的源码--link-address与--link-eth-feed均可省略省略时脚本会自动部署一个新的 LINK Token 合约和新的 LINK/Native FeedMock Aggregator精度 18 位初始价格为--fallback-wei-per-unit-link默认6e16即 0.06 ETH/LINK用于资助订阅见VRFV2PlusDeployUniverse中 Deploying LINK Token... 分支--subscription-balance以 juels 计1 LINK 10^18 juels示例5000000000000000000即 5 LINK设为 0 表示不用 LINK 资助--subscription-balance-native以 wei 计示例1000000000000000000即 1 个原生代币走FundSubscriptionWithNative调用--uncompressed-pub-keyVRF 未压缩公钥。脚本会将其从0x前缀转换为04开头的 ECDSA 格式并推导出压缩公钥与 key hash然后调用coordinator.RegisterProvingKey注册证明密钥见 util.go。注册证明密钥时是针对 EOA 账户注册的这样之后可以方便地通过coordinator.oracleWithdraw将随机数履行赚取的费用提回该 EOA--vrf-primary-node-sending-keys逗号分隔的节点发送地址脚本会为这些地址打款--sending-key-funding-amount默认 0.1 ETH并在生成的 VRF Job Spec 中填充fromAddresses--batch-fulfillment-enabled仅影响生成的 Job Spec 中是否启用批量履行默认值来自 constants.go 的BatchFulfillmentEnabled--coordinator-type必须指定为layer1、arbitrum或optimism之一其他值会直接 panic分别部署VRFCoordinatorV25、VRFCoordinatorV25Arbitrum与VRFCoordinatorV25Optimism见 util.go。若选择 optimism还可通过--optimism-l1-fee-mode0/1/2与--optimism-l1-fee-coefficient1-100设置 L1 费用计算参数该命令同时支持--bhs-address、--batch-bhs-address、--coordinator-address、--batch-coordinator-address传入已存在的合约地址避免重复部署。部署完成后脚本会打印所有合约地址、订阅 ID、订阅余额以及两条可直接执行的请求/查询命令eoa-load-test-request-with-metrics与eoa-load-test-read-metrics还会输出完整的type vrfJob Spec 模板节点运营者可直接将其写入 Chainlink 节点创建 VRF 任务Job Spec 的生成逻辑见 super_scripts.go模板定义在 jobs.go。四、部署消费者合约VRFV2PlusExternalSubOwnerExample由 gethwrappers 生成的vrf_v2plus_sub_owner封装允许其所有者EOA在它被授权为某个已资助 VRF 订阅的消费者之后代表该订阅发起随机数请求。部署命令go run . eoa-consumer-deploy --coordinator-address$COORDINATOR --link-address$LINK成功输出Consumer address YOUR CONSUMER ADDRESS hash YOUR TX HASH将返回的地址保存为环境变量后续步骤使用export CONSUMERYOUR CONSUMER ADDRESS从源码看EoaDeployConsumer实际调用DeployVRFV2PlusExternalSubOwnerExample(e.Owner, e.Ec, coordinator, link)部署合约见 util.go。该命令要求同时提供coordinator-address与link-address两个参数main.go 中ParseArgs校验。五、搭建 VRF V2 订阅新部署的消费者合约要想发起 VRF 请求必须先被授权到一个已资助的订阅上。整个流程分为四步。5.1 创建订阅go run . eoa-create-sub --coordinator-address$COORDINATOR成功输出Create sub TX hash YOUR TX HASH从源码看EoaCreateSub在交易确认后会解析交易收据中的SubscriptionCreated日志并直接返回订阅 ID见 util.go同时 main.go 也会打印 Created subscription ID: 。若你使用的是旧版脚本或想自己核对也可以通过区块浏览器输入交易哈希在交易详情页的 Logs 标签中找到创建订阅的日志获取订阅 ID 的十进制表示。拿到 ID 后导出export SUB_IDYOUR SUBSCRIPTION ID5.2 资助订阅向订阅充值 10 LINK10000000000000000000 10 * 10^18 juelsgo run . eoa-fund-sub --coordinator-address $COORDINATOR --link-address$LINK --sub-id$SUB_ID --amount10000000000000000000 # 10e18 or 10 LINK成功输出Initial account balance: YOUR LINK BEFORE FUNDING YOUR ADDRESS Funding amount: 10000000000000000000 Funding sub 61 hash YOUR FUNDING TX HASH原理EoaFundSubWithLink先读取 EOA 的 LINK 余额并打印然后调用 LINK Token 的transferAndCall方法把金额与编码后的subIdABI 编码为uint256一次性转给 Coordinator见 util.go。如果希望用原生代币资助订阅可以使用go run . eoa-fund-sub-with-native-token --coordinator-address $COORDINATOR --sub-id $SUB_ID --amount AMOUNT IN WEI对应源码为EoaFundSubWithNativeutil.go它设置e.Owner.Value amount后调用coordinator.FundSubscriptionWithNative。5.3 可选查询订阅余额go run . sub-balance --coordinator-address $COORDINATOR --sub-id$SUB_ID成功输出sub id YOUR SUB ID balance: YOUR SUB BALANCE该命令通过coordinator.GetSubscription读取订阅的余额字段并打印见 main.go。5.4 添加消费者将消费者合约授权到订阅上go run . eoa-add-sub-consumer --coordinator-address $COORDINATOR --sub-id$SUB_ID --consumer-address$CONSUMER底层调用coordinator.AddConsumer确认出块后结束见 util.go。至此消费者已具备从该订阅发起请求的权限。5.5 其他订阅管理命令除上述四步外脚本还提供完整的订阅生命周期管理子命令均在 main.go 中实现子命令作用eoa-transfer-sub发起订阅所有权转移RequestSubscriptionOwnerTransfereoa-accept-sub接受订阅所有权转移eoa-cancel-sub/owner-cancel-subEOA 取消订阅 / 合约所有者取消订阅coordinator-subscription打印订阅完整结构余额、消费者列表等eoa-create-fund-authorize-sub一步完成创建 资助 授权消费者coordinator-migrate-sub/coordinator-register-migratable-coordinator订阅在 Coordinator 之间迁移六、请求随机数当消费者被授权且订阅有余额后即可发起随机数请求go run . eoa-request --consumer-address$CONSUMER --sub-id$SUB_ID --key-hash$KEY_HASH --num-words 1成功输出TX hash: 0x599022228ffca10b0192e0b13bea64ff74f6dab2f0a3002b0825cbe22bd98249将交易哈希放入区块浏览器可以跟踪进度。交易确认后通常只需几分钟你会看到第二笔进入消费者合约的随机数履行交易其中包含随机数结果。从源码看eoa-request还支持更多可选参数main.go--cb-gas-limit回调 gas 上限默认1000000--request-confirmations最小请求确认数默认 3--num-words请求随机词个数默认 3--native-payment是否用原生代币支付默认 falseLINK 支付。它最终调用consumer.RequestRandomWords(e.Owner, subId, cbGasLimit, requestConfirmations, numWords, keyHash, nativePayment)并等待交易出块后打印收据所在区块号。若希望做更大规模的压测可以部署带指标统计的消费者go run . eoa-load-test-consumer-deploy --coordinator-address $COORDINATOR --link-address $LINK go run . eoa-load-test-consumer-with-metrics-deploy --coordinator-address $COORDINATOR前者对应VRFLoadTestExternalSubOwner后者对应带延迟统计的VRFV2PlusLoadTestWithMetrics其请求/读取/重置子命令分别为eoa-load-test-request、eoa-load-test-request-with-metrics、eoa-load-test-read-metrics、eoa-load-test-reset-metrics。eoa-load-test-read-metrics会输出响应计数、请求计数、平均/最慢/最快履行时间以及 P90/P95 履行延迟百分位计算逻辑见 util.go。七、调试回退的交易交易回退revert可能有多种根因常见的有订阅 LINK 或原生代币余额不足合约地址配置错误Coordinator / LINK / 消费者地址不匹配消费者未被授权到订阅非所有者账户越权调用例如原文档给出的案例一个非所有者尝试从VRFExternalSubOwnerExample请求随机词导致回退。调试建议将交易哈希输入区块浏览器查看 revert 原因使用 Tenderly 等交易模拟工具逐条追踪调用栈定位是哪个内部调用失败核对脚本打印的 gas 估算与账户余额对于履行交易回退脚本还提供manual-fulfill子命令从 Chainlink 节点日志中按 request IDhexgrep 出 VRF pipeline 中vrfv2plus任务的 output 字段示例 Loki 查询{appapp-name} | json | taskTypevrfv2plus |~ request-id-hex然后通过--txdatas传入交易数据、--coordinator-address指定 Coordinator配合--gas-multiplier默认 1.1手动补发履行交易见 main.go。八、使用 BatchBlockhashStore 合约BatchBlockhashStore合约充当BlockhashStore的代理允许调用者在单笔交易中存储和读取多个区块哈希是 VRF 区块哈希回填的核心基础设施。8.1 部署 BatchBlockhashStore 实例go run . batch-bhs-deploy -bhs-address $BHS_ADDRESS其中$BHS_ADDRESS指向一个已存在的BlockhashStore合约。如果没有现成的 BHS可以先用以下命令部署一个go run . bhs-deploy从源码看DeployBHS直接部署BlockhashStoreDeployBatchBHS则部署以 BHS 地址为构造参数的BatchBlockhashStore见 util.go。8.2 单笔交易存储多个区块哈希go run . batch-bhs-store -batch-bhs-address $BATCH_BHS_ADDRESS -block-numbers 10298742,10298741,10298740,10298739-block-numbers是逗号分隔的区块号列表脚本解析后调用batchBHS.Store一次上链见 main.go。约束这些区块号距最新区块头不能超过 256 个区块否则存储会失败——因为 EVM 的BLOCKHASH操作码只对最近 256 个区块有效。8.3 单笔交易读取多个区块哈希go run . batch-bhs-get -batch-bhs-address $BATCH_BHS_ADDRESS -block-numbers 10298742,10298741,10298740,10298739脚本逐行打印每个区块号对应的哈希blockhash(num) 0x...见 main.go。8.4 存储 256 区块以外的历史区块哈希要回填早于 256 个区块的历史哈希需要使用BatchBlockhashStore的storeVerifyHeader方法——它接收 RLP 编码的区块头用于验证从而不依赖BLOCKHASH操作码go run . batch-bhs-storeVerify -batch-bhs-address $BATCH_BHS_ADDRESS -num-blocks 25 -start-block 10298739参数说明-num-blocks要存储的区块数量单笔交易内完成上限 150超出会报错-start-block起始区块向前回溯存储的锚点。该区块号必须已存在于 BlockhashStore 中否则命令无法工作——这正是 main.go 中blockhashstore.DecreasingBlockRange与GetRlpHeaders配合的验证链它先取start-block之后递减的区块范围通过 RPC 批量拉取子块的 RLP 头部利用子块头部中的parentHash字段见 helpers.go再调用batchBHS.StoreVerifyHeader一次性上链。8.5 Batch BHS Backwards Mode反向回填模式当需要向某个目标区块号回填大量历史区块哈希时可以使用 Backwards Mode。你需要准备一个已存储在 BHS 中的区块号作为-start-block锚点。它越接近目标区块区间效果越好。可查看 BHS 合约上最旧的、仍领先于目标区间的 Store 交易。例如要存储区块 100~200而 210 和 220 已存在则把-start-block设为210目标区块号-end-block存储到此区块后停止。该数字不必已在 BHS 中但必须小于-start-block批大小-batch-size单笔交易尝试存储的数量。大区块区间通常建议 50~75源码默认值 162注释说明这是 Ronin 链在 131072 字节限制下的最大安全值见 main.goBatch BHS 地址-batch-bhs-address与BHS 地址-bhs-address脚本会做地址一致性校验不一致直接 panic见 main.go。示例go run . batch-bhs-backwards -batch-bhs-address $BATCH_BHS_ADDRESS -start-block 25814538 -end-block 25811350 -batch-size 50该脚本刻意保持简单每笔交易等待出块后再进行下一笔以避免交易发送后未被打包入块、导致后续storeVerifyHeader调用失败的连锁问题。源码中的执行循环main.go还会在每一批开始前重新查询建议 gas 价格并按--gas-price-multiplier默认 1放大防止 gas 价格过低导致交易卡死每批先打印[i/N]进度再逐批调用StoreVerifyHeader并等待确认。另外若使用支持storeTrusted的TrustedBlockhashStore可用trusted-bhs-store子命令配合近期区块哈希完成批量存储见 main.go。九、从源码看命令背后的实现链路如果希望深入理解这些命令建议按以下路径阅读源码main.go所有子命令的入口。switch os.Args[1]分发命令flag.NewFlagSet定义参数helpers.ParseArgs校验必填参数缺失会 panicsuper_scripts.goDeployUniverseViaCLI/VRFV2PlusDeployUniverse是deploy-universe的核心实现包含完整的部署编排与 Job Spec 生成SmokeTestVRF展示了一条完整的请求 → 提取 RandomWordsRequested 日志 → 生成本地证明 → 提交履行链路可作为理解 VRF 工作原理的参考util.go封装DeployBHS、DeployBatchBHS、DeployCoordinatorlayer1/arbitrum/optimism 三态、EoaCreateSub、EoaFundSubWithLink/Native、RegisterCoordinatorProvingKey等原子操作helpers.goSetupEnv读取环境变量构建签名交易器ConfirmTXMined/ConfirmContractDeployed统一等待出块并打印区块浏览器链接GetRlpHeaders通过批量 RPC 拉取区块头针对 Avalanche、Polygon Edge、Ronin 等链有专门的头结构适配constants.go与jobs.godeploy-universe各参数默认值来源与 VRF/BHS/BHF Job Spec 模板定义。补充说明文档与源码路径的对应关系原文档中引用的 Solidity 示例合约路径contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusExternalSubOwnerExample.sol等在本仓库中对应的是链上 ABI 的 Go 生成封装vrf_v2plus_sub_owner、vrf_v2plus_single_consumer、vrf_load_test_external_sub_owner等 gethwrappers这些封装被 main.go 与 util.go 直接 import 使用Solidity 源码本体维护在独立的合约子模块仓库中不在本仓库内。十、结语通过本文你已经掌握了 Chainlink VRF V2 测试网脚本的完整用法deploy-universe一键搭建全链路 VRF 环境、EOA 驱动的订阅全生命周期管理、随机数请求与回退调试以及BatchBlockhashStore的四种批量区块哈希操作含反向回填模式。这些命令不仅是测试网验证 Chainlink VRF 集成的捷径其源码实现main.go 与 v2plusscripts 包也是理解 Chainlink 节点 VRF 任务内部调用链日志解码 → 证明生成 → gas 估算 → 履行模拟的最佳入门教材。下一阶段你可以基于deploy-universe打印的 Job Spec 配置 Chainlink 节点真正跑通请求-履行闭环。【免费下载链接】chainlinknode of the decentralized oracle network, bridging on and off-chain computation项目地址: https://gitcode.com/GitHub_Trending/ch/chainlink创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表