使用 Magicblock 从零到实时
Magicblock 的 Ephemeral Rollups 旨在解决 Solana L1 上的高延迟和吞吐量限制问题,以及 L2 链带来的流动性碎片化和互操作性问题。它通过创建临时的、高速的执行层,实现 10-50 毫秒的端到端延迟,并保持与 Solana 的同步,无需跨链桥或多链设置,并提供链上扩展功能,从而为开发者提供构建响应迅速、可扩展的区块链应用所需的快速、弹性和安全保障。

Magicblock 解决了什么问题?
L1 Solana 上的高延迟和有限吞吐量
- 对于游戏、流媒体、高频交易或聊天等实时用例来说,Solana 约 400 毫秒的区块时间太慢了。
- 高频写入可能既昂贵又缓慢,从而限制了无缝应用。
L2 链的碎片化和摩擦
- 应用专用链(L2/appchains)提高了速度,但也使流动性碎片化,并且需要桥。
- 构建者失去了可组合性,需要笨拙的跨链设置。
Magicblock 的解决方案
短暂 Rollups
- 直接连接到 Solana 的临时、高速执行层。
- 实现 10–50 毫秒的端到端延迟,处理数百万 TPS。
- 完全弹性和共址。没有忙等待。大规模自动缩放。
无需桥或多链
- 状态与 Solana 保持同步。没有单独的代币或流动性碎片化。
- Rollups 使用欺诈证明提交结果。继承 Solana 的安全性和可组合性。
Solana 插件
- 添加强大的链上扩展,如实时价格提要、可验证的随机性、AI 预言机、自定义交易排序等。
- 这些扩展干净地集成到短暂 rollups 中,而无需离开 Solana。
MagicBlock 短暂 Rollups 实际解决了什么问题
MagicBlock 的短暂 rollups 解决了构建响应迅速、可扩展的区块链应用程序的核心限制。它们消除了逐块执行的延迟,消除了对桥或 appchains 的需求,并为开发者提供了感觉像 Web2 的即时、弹性计算;但以 Web3 保证运行。
无论你是构建实时游戏、闪电般快速的 DeFi,还是传感器驱动的 DePIN 网络,MagicBlock 都能为你提供速度、规模和安全性
基础层执行
以下是一个事务通常如何在**基础层(约 400 毫秒)**上流动:

基础层执行
短暂 Rollup 执行
以下是相同的交互在 **MagicBlock 短暂 Rollup(约 50 毫秒)**上的运行情况:

真实示例:Send Arcade 的 LanaRoads
要了解 MagicBlock 的实际应用,请查看 LanaRoads —— 一款完全使用 MagicBlock 的短暂 rollups 在 Solana 上构建的快节奏游戏

LanaRoads
以下是它在实践中解决的问题:
- 玩家输入和游戏响应之间无延迟
- 每次移动都没有钱包弹出窗口
- 每次移动都可验证,并与 Solana 的安全性相关联
使用短暂 Rollups 构建的核心原则
要使用短暂 Rollups 构建快速、实时的应用程序,遵循一些核心原则非常重要。这些原则确保 rollup 与 Solana 保持同步,并且你的应用程序可以在大规模下可靠地工作。
首先在 Solana 上创建帐户
Rollups 不创建帐户。所有帐户都必须源自 Solana 基础层。
仅委派需要速度的内容
委派执行高频操作的帐户。保持范围最小且有目的性。
委托的帐户暂时由 rollup 拥有
在委托期间,帐户状态由 rollup 控制。在此期间,Solana 无法读取或写入它们。
使用 rollup RPC,而不是 Solana 的
将所有涉及委托帐户的事务发送到短暂 Rollup RPC。Solana 的 RPC 会拒绝它们。
定期提交状态
以适当的间隔将帐户状态同步回 Solana。仅提交仍在委托的帐户。
取消委派以将控制权返回给 Solana
一旦不再需要实时执行,请取消委派。该帐户再次可以在 Solana 上完全访问。
为什么这些原则很重要
这些规则不仅仅是约定。它们由 Solana 的帐户模型在底层的工作方式强制执行。
Solana 上的每个帐户都有一个所有者程序,用于控制其写入权限。当你将帐户委托给短暂 Rollup 时,你将通过 CPI 调用委托程序,暂时将该所有权转移到 rollup 的验证器。
这会更改谁有权控制帐户:
- 委托后,基础层会锁定该帐户。
- 写入权限授予 rollup 验证器。
- 该帐户在 Solana 上变为只读,直到取消委派。
如果你尝试从 rollup 中修改非委托帐户,则事务将失败 —— 因为 rollup 没有权限。
这种所有权切换使实时执行成为可能,而不会破坏 Solana 的安全性或可组合性模型。但这也意味着你必须小心管理委托。
将 Solana 计数器转换为短暂 Rollup 应用程序
让我们将一个基本的 Solana 计数器程序转换为由 MagicBlock 的短暂 Rollups 提供支持的实时应用程序。
从基本 Anchor 计数器开始
以下是使用 Anchor 的基本程序逻辑:
##[program]
pub mod base_counter {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let counter = &mut ctx.accounts.counter; // counter 变量
counter.count = 0; // count 计数器初始化为0
Ok(())
}
pub fn increment(ctx: Context<Increment>) -> Result<()> {
let counter = &mut ctx.accounts.counter; // counter 变量
counter.count += 1; // 计数器加1
Ok(())
}
}
##[account]
pub struct Counter {
pub count: u64,
}
添加短暂 Rollups SDK
在你的项目中安装 SDK:
cargo add ephemeral_rollups_sdk
在你的程序中导入它:
use ephemeral_rollups_sdk::anchor::{commit, delegate, ephemeral};
use ephemeral_rollups_sdk::cpi::DelegateConfig;
use ephemeral_rollups_sdk::ephem::{commit_accounts, commit_and_undelegate_accounts};
添加 \#[ephemeral] 宏
这会将你的程序标记为与 MagicBlock 的短暂执行层兼容:
##[ephemeral]
##[program]
pub mod anchor_counter { ... }
这可确保该程序可以在 rollup 验证器中运行以进行快速执行。
定义你的程序逻辑
你现在像以前一样定义你的程序逻辑,但添加了以下附加函数:
- 委托
- 手动提交
- 取消委托
示例:increment_and_commit 函数
pub fn increment_and_commit(ctx: Context<IncrementAndCommit>) -> Result<()> {
let counter = &mut ctx.accounts.counter;
counter.count += 1;
msg!("PDA {} count: {}", counter.key(), counter.count); // 打印 PDA key 和当前的计数
commit_accounts(
&ctx.accounts.payer,
vec![&ctx.accounts.counter.to_account_info()],
&ctx.accounts.magic_context,
&ctx.accounts.magic_program,
)?;
Ok(())
}
使用宏定义帐户上下文
#[commit] 和 #[delegate] 宏会自动注入 MagicBlock 所需的上下文:
##[delegate]
##[derive(Accounts)]
pub struct DelegateInput<'info> {
pub payer: Signer<'info>,
#[account(mut, del)]
pub pda: AccountInfo<'info>, // 被委托的帐户
}
##[commit]
##[derive(Accounts)]
pub struct IncrementAndCommit<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(mut, seeds = [TEST_PDA_SEED], bump)]
pub counter: Account<'info, Counter>,
}
委托、执行、提交、取消委托
你现在在程序中有 3 个重要方法:
delegate:将帐户的控制权转移到 rollup 验证器commit:将 rollup 状态写回 Solanaundelegate:将控制权返回给 Solana 基础层
ctx.accounts.delegate_pda(
&ctx.accounts.payer,
&[TEST_PDA_SEED],
DelegateConfig::default(),
)?;
commit_and_undelegate_accounts(
&ctx.accounts.payer,
vec![&ctx.accounts.counter.to_account_info()],
&ctx.accounts.magic_context,
&ctx.accounts.magic_program,
)?;
底层发生了什么
- 你的 PDA 委托给 rollup。
- 它变为仅在 rollup 内可写。
- 你将快速事务发送到 ER RPC,它会立即更新状态。
- 定期地,你将最新的状态提交回 Solana。
- 完成后,你将取消委托,从而恢复 Solana 控制。
在短暂 Rollups 上进行测试
设置提供程序
const provider = anchor.AnchorProvider.env(); // Solana 基础层
const providerEphemeralRollup = new anchor.AnchorProvider(
new anchor.web3.Connection(
process.env.PROVIDER_ENDPOINT || "https://devnet.magicblock.app/",
{
wsEndpoint: process.env.WS_ENDPOINT || "wss://devnet.magicblock.app/",
}
),
anchor.Wallet.local()
);
步骤 1:将 PDA 委托给 Rollup
it("Delegate Counter to ER", async () => {
let tx = await program.methods
.delegate()
.accounts({
owner: owner.publicKey,
pda: counterPda,
})
.transaction();
tx.feePayer = owner.publicKey;
tx.recentBlockhash = (await provider.connection.getLatestBlockhash()).blockhash;
// 由 ER 钱包签名(重要!)
tx = await providerEphemeralRollup.wallet.signTransaction(tx);
const txHash = await provider.sendAndConfirm(tx, [], {
skipPreflight: true,
commitment: "confirmed",
});
});
步骤 2:在 Rollup 上执行
it("Increase Counter on ER", async () => {
let tx = await program.methods
.increment()
.accounts({
owner: owner.publicKey,
counter: counterPda,
})
.transaction();
tx.feePayer = providerEphemeralRollup.wallet.publicKey;
tx.recentBlockhash = (
await providerEphemeralRollup.connection.getLatestBlockhash()
).blockhash;
tx = await providerEphemeralRollup.wallet.signTransaction(tx);
const txHash = await anchor.web3.sendAndConfirmTransaction(
providerEphemeralRollup.connection,
tx,
[owner.payer],
{
skipPreflight: true,
commitment: "confirmed",
}
);
});
步骤 3:将 ER 状态提交到 Solana
it("Commit Counter on ER", async () => {
let tx = await program.methods
.commit()
.accounts({
owner: owner.publicKey,
counter: counterPda,
})
.transaction();
tx.feePayer = providerEphemeralRollup.wallet.publicKey;
tx.recentBlockhash = (
await providerEphemeralRollup.connection.getLatestBlockhash()
).blockhash;
tx = await providerEphemeralRollup.wallet.signTransaction(tx);
const txHash = await anchor.web3.sendAndConfirmTransaction(
providerEphemeralRollup.connection,
tx,
[owner.payer],
{
skipPreflight: true,
commitment: "confirmed",
}
);
// 等待基础层确认包含
const txCommitSgn = await GetCommitmentSignature(
txHash,
providerEphemeralRollup.connection
);
});
步骤 4:提交 + 取消委托
it("Commit and undelegate counter on ER", async () => {
let tx = await program.methods
.undelegate()
.accounts({
owner: owner.publicKey,
counter: counterPda,
})
.transaction();
tx.feePayer = owner.publicKey;
tx.recentBlockhash = (
await provider.connection.getLatestBlockhash()
).blockhash;
tx = await providerEphemeralRollup.wallet.signTransaction(tx);
const txHash = await anchor.web3.sendAndConfirmTransaction(
providerEphemeralRollup.connection,
tx,
[owner.payer],
{
skipPreflight: true,
commitment: "confirmed",
}
);
});
原子 ER 操作
在某些用例中,你可能想要组合操作:
await program.methods
.incrementAndCommit()
.accounts({ owner: owner.publicKey, counter: counterPda })
.rpc();
await program.methods
.incrementAndUndelegate()
.accounts({ owner: owner.publicKey, counter: counterPda })
.rpc();
结论
MagicBlock 使在 Solana 上构建快速、实时的应用程序变得简单。短暂 Rollups 为你提供低延迟执行、大规模扩展和完全的可组合性,而无需忍受桥的痛苦或碎片化的流动性。
委托帐户,运行高速逻辑,并在需要时提交回 Solana。它感觉像 Web2,但以 Web3 安全性运行。
如果你正在构建游戏、DeFi 或实时系统,MagicBlock 将帮助你从零变为实时。
了解更多
参考存储库
如果你对去中心化基础设施、链上数据系统或使用预言机网络构建真实项目感兴趣,请关注:
- 原文链接: blog.blockmagnates.com/f...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~