首页 全国天气 空气质量 景点天气 国际天气 天气生活

热门城市

  • 天津天气
  • 唐山天气
  • 秦皇岛天气
  • 邯郸天气
  • 太原天气
  • 沈阳天气
  • 营口天气
  • 阜新天气
  • 辽阳天气
  • 盘锦天气
  • 铁岭天气
  • 朝阳天气

选择省市

  • 北京
  • 天津
  • 河北
  • 山西
  • 内蒙古
  • 辽宁
  • 吉林
  • 黑龙江
  • 上海
  • 江苏
  • 浙江
  • 安徽
  • 福建
  • 江西
  • 山东
  • 河南
  • 湖北
  • 湖南
  • 广东
  • 广西
  • 海南
  • 重庆
  • 四川
  • 贵州
  • 云南
  • 西藏
  • 陕西
  • 甘肃
  • 青海
  • 宁夏
  • 新疆
  • 香港
  • 澳门
  • 台湾
    手机看天气

    扫码下载app,天气随时看

    扫码下载app,天气随时看
    收藏网页
    当前位置:天气宝  >  WEB3.0 > 正文

    Solana开发学习笔记(一)——从HelloWorld出发

    发布时间:2024-08-06 20:22:24 编辑:佚名 阅读:8
    #css #git #区块链

    笔者注:因近期笔者工作需要,开始接触 solana 链上程序开发。本系列文章是笔者的学习笔记,既是为了备忘,也是希望得到 solana 开发者的指点与交流。本系列文章将默认读者已经掌握 rust 的基础语法,故不涉及对 rust 语法细节的解释。如果读者对 rust 基础语法还不熟练的话,本文下方推荐的 rust 入门书籍《rust 编程入门、实战与进阶》学习。

    1.1 Solana 简介

    Solana 是一个高性能、无许可的底层公链,专注于在不牺牲去中心化或安全性的前提下提供可扩展性。Solana 主网于 2020 年一季度上线,目前主网的全球节点超过 800 个,TPS 最高可达 6.5 万,出块时间约 400 毫秒。

    Solana 的共识算法采用 PoH(历史证明),其核心是一个去中心化时钟,该时钟旨在解决缺乏单个可信赖时间源在分布式网络中的时间问题。PoH 免除了在节点网络中广播时间戳的需求,从而提高整个网络的效率。

    1.1.1 链上程序

    Solana 的智能合约叫做链上程序(On-chain Program),Solana 官方提供了 Rust 和 C 的 SDK 来支持开发链上程序。链上程序的开发工作流如图 1-1 所示,开发者可以使用工具将程序编译成 Berkley Packet Filter (BPF) 字节码(文件以 .so 为扩展名),再部署到 Solana 链上,通过 Sealevel 并行智能合约运行时去执行智能合约的逻辑。此外,基于 Solana JSON RPC API,官方提供了诸多 SDK 用于客户端与 Solana 链上数据交互。

    图 1-1 链上程序开发工作流

    1.1.2 账户模型

    与以太坊类似,Solana 也是基于账户模型的区块链。通过将任意状态存储于链上账户并同步复制给集群中的所有节点,可以创建复杂而强大的去中心化应用程序。

    Solana 提供了一套不同于以太坊的账户模型,账户定义的字段如表 1-1 所示。Solana 的账户可以分为可执行账户和不可执行账户。

    可执行账户:存储不可变的数据,主要用于存储程序的 BPF 字节码。 不可执行账户:存储可变的数据,主要用于存储程序的状态。

    表 1-1 账户定义字段

    字段 描述 lamports 账户余额 owner 账户所有者 executable 是否为可执行账户 data 账户存储的数据 rent_epoch Solana链上程序的部署是按其账户大小进行定期收费的,如果账户无法支付租金,系统将清除该账号

    我们知道以太坊上每个智能合约的代码和状态都存储在同一个账户中,而 Solana 链上程序是只读或无状态的,即程序的账户(可执行账户)只存储 BPF 字节码,不存储任何状态,程序会把状态存储在其他独立的账户(不可执行账户)中。为了区分某个账户是用作哪个程序的状态存储,每个账户都指定了一个程序作为其所有者。程序可以读取其不作为所有者的账户中的状态,但只有作为所有者的程序才能修改账户中的状态,任何其他程序所做的修改都会被还原并导致交易失败。

    更多关于账户模型的资料可以参见官方文档:https://solana.wiki/zh-cn/docs/account-model/

    1.2 搭建编程环境

    在开始 Solana 链上程序开发之前,需要先安装和配置相关的编程环境。首先请正确安装 Node、NPM 和 Rust 的最新稳定版本,下面来安装 Solana CLI 并配置相关环境。

    1.2.1 安装 Solana CLI

    Solana CLI 是与 Solana 集群进行交互的命令行管理工具,包含节点程序 solana-validator、密钥对生成工具 solana-keygen,以及合约开发工具 cargo-build-bpf、cargo-test-bpf 等。

    在终端运行以下命令,可完成 Solana CLI 最新稳定版的下载与安装。

    sh -c "$(curl -sSfL https://release.solana.com/stable/install)"登录后复制

    如果安装成功,会出现以下内容。

    downloading stable installer ✨ stable commit e9bef425 initializedAdding export PATH="~/.local/share/solana/install/active_release/bin:$PATH" to ~/.profileAdding export PATH="~/.local/share/solana/install/active_release/bin:$PATH" to ~/.bash_profileClose and reopen your terminal to apply the PATH changes or run the following in your existing shell: export PATH="~/.local/share/solana/install/active_release/bin:$PATH"登录后复制

    Solana CLI 的所有命令行工具都安装在 ~/.local/share/solana/install/active_release/bin 中,并会自动将该路径加入 ~/.profile 和 ~/.bash_profile 文件的 PATH 环境变量。

    运行以下命令,检查 PATH 环境变量是否已正确设置。

    solana --version// solana-cli 1.7.18 (src:e9bef425; feat:140464022)登录后复制

    如果能显示 solana-cli 的版本号、版本哈希等信息,代表环境变量设置成功。如果未看到这些信息,请检查相关文件中 PATH 环境变量设置的路径是否正确。

    如果已安装过 Solana CLI,想升级到最新版本,可在终端运行以下命令。

    solana-install update登录后复制

    1.2.2 配置 Solana CLI

    1. 连接到集群

    Solana 的集群有本地集群(localhost)和公开集群。根据不同的用途,公开集群又分为开发者网络(devnet)、测试网(testnet)和主网(mainnet-beta)。

    devnet 是适用于开发者的集群,开发者可获得 SOL token 的空投,但这个 SOL token 不具有真实价值,仅限测试使用。devnet 的 RPC 链接是https://api.devnet.solana.com。 testnet 是用于测试最新功能的集群,如网络性能、稳定性和验证程序行为等。同样可获得 SOL token 的空投,但也仅限测试使用。testnet 的 RPC 链接是https://api.testnet.solana.com。 mainnet-beta 是主网集群,在 Mainnet Beta 上发行的 SOL token 具有真实价值。mainnet-beta 的 RPC 链接是https://api.mainnet-beta.solana.com。

    运行以下命令,根据实际需要来选择集群。

    // 选择localhost集群solana config set --url localhost// 选择devnet集群solana config set --url devnet登录后复制

    2. 创建账户

    如果是第一次使用 Solana CLI,需要先创建一个账户。运行以下命令,根据操作提示可以设置一个 BIP39 规范的密码,此密码用来增强助记词的安全性,当然也可以为空。生成新的账户后,密钥对会被自动写入 ~/.config/solana/id.json 文件中。需要注意的是,这种存储密钥对的方式是不安全的,仅限开发测试使用。

    solana-keygen new登录后复制

    要查看当前这个账户的公钥,运行以下命令。

    solana-keygen pubkey登录后复制

    当前如果是在 devnet 集群,该账户的余额为 0 SOL,可以运行以下命令查询余额。

    solana balance登录后复制

    在 devnet 上申请 SOL 空投,运行以下命令后再次查询当前账户的余额,会发现余额为 2 SOL。

    solana airdrop 2登录后复制

    1.3 第一个 Solana 项目——Hello World

    Hello World 是一个官方演示项目,展示了如何使用 Rust 和 C 开发链上程序,并使用 Solana CLI 来构建与部署,以及使用 Solana JavaScript SDK 与链上程序进行交互。

    1.3.1 Hello World 源码解读

    example-helloworld 项目的目录结构如下所示,其中 program-rust 目录下是 Rust 开发的程序源代码,client 目录下是客户端的源代码。

    example-helloworld|+-- src| || +-- client| | || | +-- hello_world.ts| | || | +-- main.ts| | || | +-- utils.ts| || +-- program-rust| | || | +-- src| | | || | | +-- lib.rs| | || | +-- tests| | | || | | +-- lib.rs| | || | +-- Cargo.toml| | || | +-- Xargo.toml|+-- .gitignore|+-- package.json|+-- tsconfig.json登录后复制

    1. 链上程序源码解读

    program-rust/src/lib.rs 是链上程序的核心代码,如代码清单 1-1 所示,实现了将程序被调用次数存储在链上账户中。

    第 1 行代码将 borsh::BorshDeserialize 和 borsh::BorshSerialize 引入本地作用域,用于序列化和反序列化数据。第 2~9 行代码将 Solana Rust SDK 的模块引入本地作用域,使用 Rust 编写程序都需要这个 SDK。

    第 13~16 行代码定义了 GreetingAccount 结构体作为存储在账户中的状态类型,里面有一个 u32 类型的字段 counter,用于记录程序被有效调用的次数。

    第 19 行代码 entrypoint 声明了 process_instruction 函数是程序入口,每个程序都有一个唯一的入口。第 22~26 行代码是 process_instruction 函数签名,它要接收 3 个参数:

    program_id:链上程序的部署地址,在这里也就是 helloworld 程序账户的公钥。 accounts:与程序交互的账户列表,当前程序会使用账户列表中的账户来存储状态或修改账户中的数据。如果当前程序不是某个账户的所有者,那就无法使用该账户存储状态或修改数据,当前交易会执行失败。 instruction_data:指令数据,比如要转账的代币数量、转账地址等。

    process_instruction 函数的返回值类型是 ProgramResult,ProgramResult 类型的定义如下所示。

    pub type ProgramResult = Result<(), ProgramError>;登录后复制

    当程序的逻辑执行成功时返回 Ok(()),否则将 ProgramError 错误返回。ProgramError 是自定义错误的枚举类型,其中包含程序可能失败的各种原因。

    第 27 行代码使用 msg! 宏将字符串输出到日志中,方便观察业务的执行逻辑和调试信息。第 30 行代码通过 iter 方法将账户列表转换为迭代器,以安全的方式获取账户地址。第 33 行代码使用了 ? 操作符,如果迭代器中有账户地址,会将账户地址与变量 account 绑定。如果迭代器中没有账户地址,? 操作符会让程序执行失败。

    第 36~39 行代码判断存储状态的账户所有者是否是当前程序。只有账户所有者才能修改数据,否则输出日志并返回。

    第 42~44 行代码先对账户中的数据进行反序列化操作,再将 counter 加一,最后将其序列化后存储到账户中。

    代码清单 1-1 helloworld 链上程序

    use borsh::{BorshDeserialize, BorshSerialize};use solana_program::{ account_info::{next_account_info, AccountInfo}, entrypoint, entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey,};/// Define the type of state stored in accounts#[derive(BorshSerialize, BorshDeserialize, Debug)]pub struct GreetingAccount { /// number of greetings pub counter: u32,}// Declare and export the program's entrypointentrypoint!(process_instruction);// Program entrypoint's implementationpub fn process_instruction( program_id: &Pubkey, // Public key of the account the hello world program was loaded into accounts: &[AccountInfo], // The account to say hello to _instruction_data: &[u8], // Ignored, all helloworld instructions are hellos) -> ProgramResult { msg!("Hello World Rust program entrypoint"); // Iterating accounts is safer then indexing let accounts_iter = &mut accounts.iter(); // Get the account to say hello to let account = next_account_info(accounts_iter)?; // The account must be owned by the program in order to modify its data if account.owner != program_id { msg!("Greeted account does not have the correct program id"); return Err(ProgramError::IncorrectProgramId); } // Increment and store the number of times the account has been greeted let mut greeting_account = GreetingAccount::try_from_slice(&account.data.borrow())?; greeting_account.counter += 1; greeting_account.serialize(&mut &mut account.data.borrow_mut()[..])?; msg!("Greeted {} time(s)!", greeting_account.counter); Ok(())}登录后复制

    2. 客户端程序源码解读

    要想测试链上程序,我们必须通过 Solana JSON RPC API 去和链上程序进行交互。example-helloworld 项目提供的客户端用 Typescript 编写,使用了 web3.js 库这个 Solana JavaScript SDK。

    在 client 目录下,客户端执行的入口是 main.ts 文件,它按特定的顺序执行任务,每个任务的业务逻辑代码在 hello_world.ts 文件。

    首先,客户端调用 establishConnection 函数与集群建立连接。

    export async function establishConnection(): Promise<void> { const rpcUrl = await getRpcUrl(); connection = new Connection(rpcUrl, 'confirmed'); const version = await connection.getVersion(); console.log('Connection to cluster established:', rpcUrl, version);}登录后复制

    接着,客户端调用 establishPayer 函数来确保有一个有支付能力的账户。

    export async function establishPayer(): Promise<void> { let fees = 0; if (!payer) { const {feeCalculator} = await connection.getRecentBlockhash(); // Calculate the cost to fund the greeter account fees += await connection.getMinimumBalanceForRentExemption(GREETING_SIZE); // Calculate the cost of sending transactions fees += feeCalculator.lamportsPerSignature * 100; // wag try { // Get payer from cli config payer = await getPayer(); } catch (err) { // Fund a new payer via airdrop payer = await newAccountWithLamports(connection, fees); } } const lamports = await connection.getBalance(payer.publicKey); if (lamports < fees) { // This should only happen when using cli config keypair const sig = await connection.requestAirdrop( payer.publicKey, fees - lamports, ); await connection.confirmTransaction(sig); } console.log( 'Using account', payer.publicKey.toBase58(), 'containing', lamports / LAMPORTS_PER_SOL, 'SOL to pay for fees', );}登录后复制

    然后,客户端调用 checkProgram 函数从 src/program-rust/target/deploy/helloworld-keypair.json 中加载已部署程序的密钥对(此操作前需先构建链上程序,详见 1.3.2 节),并使用密钥对的公钥来获取程序账户。如果程序不存在,客户端会报错并停止执行。如果程序存在,将创建一个新账户来存储状态,并以该程序作为新账户所有者。这里新账户存储的状态,就是程序被调用的次数。

    export async function checkProgram(): Promise<void> { // Read program id from keypair file try { const programKeypair = await createKeypairFromFile(PROGRAM_KEYPAIR_PATH); programId = programKeypair.publicKey; } catch (err) { const errMsg = (err as Error).message; throw new Error( `Failed to read program keypair at '${PROGRAM_KEYPAIR_PATH}' due to error: ${errMsg}.`, ); } // Check if the program has been deployed const programInfo = await connection.getAccountInfo(programId); if (programInfo === null) { if (fs.existsSync(PROGRAM_SO_PATH)) { throw new Error( 'Program needs to be deployed with `solana program deploy dist/program/helloworld.so`', ); } else { throw new Error('Program needs to be built and deployed'); } } else if (!programInfo.executable) { throw new Error(`Program is not executable`); } console.log(`Using program ${programId.toBase58()}`); // Derive the address (public key) of a greeting account from the program so that it's easy to find later. const GREETING_SEED = 'hello'; greetedPubkey = await PublicKey.createWithSeed( payer.publicKey, GREETING_SEED, programId, ); // Check if the greeting account has already been created const greetedAccount = await connection.getAccountInfo(greetedPubkey); if (greetedAccount === null) { console.log( 'Creating account', greetedPubkey.toBase58(), 'to say hello to', ); const lamports = await connection.getMinimumBalanceForRentExemption( GREETING_SIZE, ); const transaction = new Transaction().add( SystemProgram.createAccountWithSeed({ fromPubkey: payer.publicKey, basePubkey: payer.publicKey, seed: GREETING_SEED, newAccountPubkey: greetedPubkey, lamports, space: GREETING_SIZE, programId, }), ); await sendAndConfirmTransaction(connection, transaction, [payer]); }}登录后复制

    客户端再调用 sayHello 函数向链上程序发送交易。一个交易可以包含一个或多个不同的指令,当前该交易包含了一个指令,指令中带有要调用链上程序的 Program Id 以及客户端要交互的账户地址。需要注意的是,如果交易中包含多个不同的指令,其中有一个指令执行失败,那么所有指令所做的操作都会被还原。

    export async function sayHello(): Promise<void> { console.log('Saying hello to', greetedPubkey.toBase58()); const instruction = new TransactionInstruction({ keys: [{pubkey: greetedPubkey, isSigner: false, isWritable: true}], programId, data: Buffer.alloc(0), // All instructions are hellos }); await sendAndConfirmTransaction( connection, new Transaction().add(instruction), [payer], );}登录后复制

    最后,客户端调用 reportGreetings 函数访问账户数据,查询链上程序被有效调用的次数。

    export async function reportGreetings(): Promise<void> { const accountInfo = await connection.getAccountInfo(greetedPubkey); if (accountInfo === null) { throw 'Error: cannot find the greeted account'; } const greeting = borsh.deserialize( GreetingSchema, GreetingAccount, accountInfo.data, ); console.log( greetedPubkey.toBase58(), 'has been greeted', greeting.counter, 'time(s)', );}登录后复制

    1.3.2 Hello World 构建与部署

    1. 创建项目

    使用 git clone 命令下载 example-helloworld 项目。

    git clone https://github.com/solana-labs/example-helloworld.gitcd example-helloworld登录后复制

    2. 构建链上程序

    运行以下命令,在 program-rust 目录下构建链上程序。

    cd src/program-rust/cargo build-bpf登录后复制

    构建完成后,src/program-rust/target/deploy 目录下的 helloworld.so 就是可在 Solana 集群部署的链上程序的 BPF 字节码文件。

    3. 启动本地集群

    当前项目在本地集群部署运行,因此首先选择 localhost 集群,运行以下命令。

    solana config set --url localhost登录后复制

    本地集群设置成功,会出现以下内容。

    Config File: ~/.config/solana/cli/config.ymlRPC URL: http://localhost:8899WebSocket URL: ws://localhost:8900/ (computed)Keypair Path: ~/.config/solana/id.jsonCommitment: confirmed登录后复制

    再运行以下命令,启动 localhost 集群。

    solana-test-validator登录后复制

    看到以下内容,代表本地集群已成功启动。

    Ledger location: test-ledgerLog: test-ledger/validator.logIdentity: A4HuRgmABNCe94epY2mU7q6WqEHCo2B9iBFE5Yphiw5uGenesis Hash: 96TF9n1uuyFv4rAKECffA61jLrgYjMjNRZ3hJpP6HSr7Version: 1.7.18Shred Version: 13390Gossip Address: 127.0.0.1:1024TPU Address: 127.0.0.1:1027JSON RPC URL: http://127.0.0.1:8899⠉ 00:00:42 | Processed Slot: 45430 | Confirmed Slot: 45430 | Finalized Slot: 45398 | Snapshot Slot: 45300 | Transactions: 45452 | ◎499.772930000登录后复制

    4. 部署链上程序

    运行以下命令,在 localhost 集群部署链上程序。

    solana program deploy target/deploy/helloworld.so// Program Id: 6AArMEBpFhhtU2mBnEMEPeEH7xkhfUwPseUeG4fhLYto登录后复制

    链上程序部署成功会返回 Program Id,它类似于以太坊智能合约的地址。

    5. 调用链上程序

    helloworld 已成功部署,可以与它进行交互了!example-helloworld 项目提供了一个简单的客户端,在运行客户端之前先安装依赖软件包。

    npm install登录后复制

    由于我们调整了链上程序的构建方式,没有使用该项目默认的 npm run build:program-rust 命令,因此需要修改 client 目录下的 hello_world.ts 文件,将第 48 行代码定义的变量 PROGRAM_PATH 的路径由“../../dist/program”改为“../program-rust/target/deploy”。 再运行以下命令,启动客户端去调用链上程序。

    npm run start登录后复制

    客户端成功调用链上程序,输出内容如下所示。如果再次运行客户端,第 10 行所显示的次数会加一。至此,我们已经成功在 Solana 集群部署链上程序并与之交互了。

    > helloworld@0.0.1 start> ts-node src/client/main.tsLet's say hello to a Solana account...Connection to cluster established: http://localhost:8899 { 'feature-set': 3179062686, 'solana-core': '1.6.23' }Using account 4xRm2FYmRB8WdxJk6nXicVMgsPnsxChEnpQwFDGwdcSS containing 499999999.93435186 SOL to pay for feesUsing program 6AArMEBpFhhtU2mBnEMEPeEH7xkhfUwPseUeG4fhLYtoCreating account Eq7bcsg5p6AaYiPnfiia99ESsuq4B4jYpVbWZhQ94Zvy to say hello toSaying hello to Eq7bcsg5p6AaYiPnfiia99ESsuq4B4jYpVbWZhQ94ZvyEq7bcsg5p6AaYiPnfiia99ESsuq4B4jYpVbWZhQ94Zvy has been greeted 1 time(s)Success登录后复制

    如果没有输出期望值,请首先确认是否已正确启动了本地集群,构建并部署好了链上程序。此外,可以运行以下命令查看程序日志,日志包括程序日志消息以及程序失败信息。

    solana logs登录后复制

    包含程序失败信息的日志如下所示,检查日志找出程序失败的原因。

    @@##@@<code>Transaction executed in slot 5621:Signature: 4pya5iyvNfAZj9sVWHzByrxdKB84uA5sCxLceBwr9UyuETX2QwnKg56MgBKWSM4breVRzHmpb1EZQXFPPmJnEtsJStatus: Error processing Instruction 0: Program failed to completeLog Messages: Program G5bbS1ipWzqQhekkiCLn6u7Y1jJdnGK85ceSYLx2kKbA invoke [1] Program log: Hello World Rust program entrypoint Program G5bbS1ipWzqQhekkiCLn6u7Y1jJdnGK85ceSYLx2kKbA consumed 200000 of 200000 compute units Program failed to complete: exceeded maximum number of instructions allowed (200000) at instruction #334 Program G5bbS1ipWzqQhekkiCLn6u7Y1jJdnGK85ceSYLx2kKbA failed: Program failed to complete登录后复制

    1.4 本章小节

    本章对 Solana 区块链的基本概念进行了简要介绍,Solana 的智能合约叫做链上程序。在开始 Solana 链上程序开发之前,需要先安装和配置相关的编程环境,我们着重介绍了 Solana CLI 的安装和配置。

    Hello World 是一个官方演示项目,通过对这个项目源码的解读,我们了解了如何使用 Rust 开发链上程序,并使用 Solana CLI 来构建与部署,以及使用 Solana JavaScript SDK 与链上程序进行交互。

    Solana开发学习笔记(一)——从Hello World出发

    以上就是Solana开发学习笔记(一)——从Hello World出发的详细内容,更多请关注天气宝其它相关文章!

    免责声明:本站发布的天气生活文章(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场。
    如果本文侵犯了您的权益,请联系底部站长邮箱进行举报反馈,一经查实,我们将在第一时间处理,感谢您对本站的关注!

    上一篇:Coinbase公布第二季财报:交易收入下降但订阅和服务收入有所提升
    下一篇:微策略财报:引入比特币收益率KPI指标!预估每年4~8%成长

    相关推荐

    • 2025年度数字资产交易所综合实力排行榜前十汇总
    • 2025-W未流通的美国银鹰以创纪录的$91价格首次亮相
    • BinanceCoin(BNB)以$680的抵抗力为MANTIX(MTX)PRESALE增长动量
    • 虚拟货币交易平台APP最新排行榜(top10虚拟币交易平台盘点)
    • 2025年十大交易平台数字货币app排行榜汇总
    • 2025十大比特币交易平台推荐比特币现货交易所排行榜前十名
    • 2025年十大虚拟货币交易平台排名汇总数字货币app排名最新推荐
    • 比特币交易平台现货交易平台推荐2024十大比特币交易平台哪个好
    • HamsterKombat(HMSTR)什么时候推出
    • Bitstamp交易所归属国及大陆注册情况
    • Bitstamp是正规交易平台吗Bitstamp交易平台怎么样
    • Bitstamp交易所究竟怎么样Bitstamp交易所安全吗
    • Bitstamp是正规交易所吗Bitstamp交易所排名多少
    • Bitstamp交易所是正规交易所吗Bitstamp网交易所排名多少
    • Bitstamp交易所pro怎么注册安全吗正规吗
    • Solana开发学习笔记(一)——从HelloWorld出发

    热点精选

    2024年06月10日全国主要公路气象预报 科普一读:八月台风零登陆 副高西伸,强度异常所致 京津冀河南山东等地有持续性高温 江南等地有较强降雨 南极地区持续高温 极端事件增多增强或引发多重风险 台风“摩羯”成登陆我国最强秋台风,多位专家权威解读成因及影响 基于20世纪中期以来资料探析我国主雨季极端小时降水—频发而强烈 极端而复杂 数据新闻丨气象数据回看高温天气 “七下八上”期间,京津冀地区多夜雨吗? 八月台风零登陆 副高西伸,强度异常所致 在长城,如何防范雷击风险?留意预报预警!别爬野长城! 雷电是如何发生的?户外活动如何防范雷击风险? 2024年06月08日发布全国主要公路气象预报

    最新预警信息

    • 宁夏回族自治区泾源县发布大风蓝色预警
    • 宁夏回族自治区隆德县发布大风蓝色预警
    • 宁夏回族自治区西吉县发布大风蓝色预警
    • 新疆维吾尔自治区米东区发布高温黄色预警
    • 宁夏回族自治区海原县发布大风黄色预警
    • 宁夏回族自治区中宁县发布大风黄色预警
    • 宁夏回族自治区沙坡头区发布大风黄色预警
    • 宁夏回族自治区彭阳县发布大风黄色预警
    • 宁夏回族自治区固原市发布大风黄色预警
    • 宁夏回族自治区发布大风黄色预警

    导航网址

    关于我们 免责声明 法律声明 联系我们 网站地图 全国天气 国际天气 景点天气 天气资讯 空气质量 反馈邮箱:xiucai@vip.qq.com

    扫码手机端浏览

    安卓下载 App store
    天气宝版权所有,未经书面授权禁止使用 Copyright©tianqibao.com 粤ICP备2025425621号