首页 游戏 软件 资讯 排行榜 专题
首页
web3.0
Solana开发学习笔记(一)——从Hello World出发

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

热心网友
74
转载
2025-07-03

笔者注:因近期笔者工作需要,开始接触 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 账户定义字段

我们知道以太坊上每个智能合约的代码和状态都存储在同一个账户中,而 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 CLI1. 连接到集群

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;
登录后复制

当程序的逻辑执行成功时返回 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 {  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 {  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 

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

export async function checkProgram(): Promise {  // 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 {  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 {  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: https://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: https://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: https://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
登录后复制

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

@@##@@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出发
来源:https://www.php.cn/faq/921786.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

CSS模拟x86 CPU:大神实现浏览器直接运行机器码
电脑教程
CSS模拟x86 CPU:大神实现浏览器直接运行机器码

2月26日消息,开发者Lyra Rebane近日完成了一项足以颠覆认知的壮举,仅用CSS,不借助一行JavaScript代码,成功打造出一个可运行的8086 CPU模拟器。用户甚至可以用C语言编写程

热心网友
02.27
CSS原生支持SQL查询:前端直接操作数据库新方法
科技数码
CSS原生支持SQL查询:前端直接操作数据库新方法

TailwindSQL能让你用Tailwind风格的类名编写SQL查询语句,直接在React服务端组件中通过className属性就能直连数据库执行查询! 这个东西最近爆火!!!

热心网友
02.04
人工智能如何重塑写作:语法无误是AI的挑战还是机遇
科技数码
人工智能如何重塑写作:语法无误是AI的挑战还是机遇

一、“AI起号速成班”AI拥有近乎零门槛的强大文本生成能力,正被无数用户用于互联网的各个角落,制造并散播着海量的“内容垃圾”。互联网这片曾经最美好的创意沃土与数字原野,如今俨然已有变成AI内容垃圾场

热心网友
01.25
GPT-5.2连肝7天,30万行代码打造Chrome级浏览器
AI
GPT-5.2连肝7天,30万行代码打造Chrome级浏览器

新智元报道编辑:定慧 艾伦【新智元导读】一个大模型持续写代码,能写多久?一小时?一天?还是像大部分AI编程工具那样,完成一个任务就结束对话?Cursor的CEO MichaelTruell决定搞一次

热心网友
01.15
AI框架陷绝境:创始人深夜痛呼裁员75%,仅剩6个月
AI
AI框架陷绝境:创始人深夜痛呼裁员75%,仅剩6个月

新智元报道编辑:Aeneas【新智元导读】一则消息震惊了整个开发者社区:开发了前端基础设施的Tailwind因为做AI做得太好,反而收入暴降80%,裁掉四分之三的员工!CEO绝望录制了一段播客,好在

热心网友
01.12

最新APP

火柴人传奇
火柴人传奇
动作冒险 04-01
街球艺术
街球艺术
体育竞技 04-01
飞行员模拟
飞行员模拟
休闲益智 04-01
史莱姆农场
史莱姆农场
休闲益智 04-01
绝区零
绝区零
角色扮演 04-01

热门推荐

跌势出现转机?Bitfinex:比特币3月写下半年来首次月线收正纪录
web3.0
跌势出现转机?Bitfinex:比特币3月写下半年来首次月线收正纪录

进入2026年二季度,加密货币市场在平静的表面下暗流涌动。根据Bitfinex Alpha报告的最新数据,比特币(BTC)在3月份成功打破了长达半年的下跌趋势,以约68,300美元的价格收官,实现了自去年9月以来的首次月度正增长。这一关键信号是否预示着熊市阴霾的彻底消散?深入分析资金流向与衍生品市场

热心网友
04.03
什么是一目云图?一文详解加密货币交易中的一目均衡云
web3.0
什么是一目云图?一文详解加密货币交易中的一目均衡云

加密交易中的导航利器:深入解析一目均衡图(一目云图) 在瞬息万变的加密货币市场中,交易者不断寻求能够提供清晰、全面视角的分析工具。其中,源自日本的技术分析瑰宝——一目均衡表(Ichimoku Kinko Hyo),因其独树一帜的“一览无余”特性,正成为越来越多资深币圈玩家的核心策略装备。它不仅是一个

热心网友
04.03
《失控进化》全网预约人数突破3200万人!公测时间尚未确定!
游戏资讯
《失控进化》全网预约人数突破3200万人!公测时间尚未确定!

生存对抗手游《失控进化》今日宣布,全网预约人数已突破3200万,成为近期SOC开放世界生存建造赛道中关注度极高的新作之一。 就在今天,生存对抗手游领域传来了一个重磅消息:《失控进化》官宣,其全网预约量已经冲破了3200万大关。这个数字,无疑让它成了近期SOC开放世界生存建造赛道里,风头最劲的那个选手

热心网友
04.03
由Winklevoss、中本聪支持的Treasury公司正式启动,初始储备1000枚比特币(BTC)详解
web3.0
由Winklevoss、中本聪支持的Treasury公司正式启动,初始储备1000枚比特币(BTC)详解

欧洲比特币市场新纪元:Treasury携千枚BTC储备强势入场 在数字资产与传统金融加速融合的浪潮下,欧洲资本市场迎来了一颗瞩目的新星。一家名为Treasury的比特币储备公司正式宣布,已完成其首轮大额融资,并将总计1,000枚比特币(BTC)纳入公司核心资产储备,以当前市值计算,这笔启动资金价值超

热心网友
04.03
蚂蚁新村3月27日答案更新2026
游戏攻略
蚂蚁新村3月27日答案更新2026

蚂蚁新村每日一题2026:3月27日答案与解析 蚂蚁新村每日问答小游戏,每日更新一道职业知识题目,趣味性十足。用户答对题目后,可以有效提升自己的“木兰币”生产速度,实现了寓教于乐的效果。不过,由于每日题目与答案都会更换,寻找正确答案有时并不容易。为此,我们为您详细整理了2026年3月27日的职业知识

热心网友
04.03