<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>KimmySol (Kimmy)</title>
    <link>https://soldev.cn/KimmySol</link>
    <description/>
    <language>en-us</language>
    <item>
      <title>Agave 2.0: Solana 的新一代验证节点客户端</title>
      <description>&lt;h2 id="Agave 2.0: Solana 的新一代验证节点客户端"&gt;Agave 2.0: Solana 的新一代验证节点客户端&lt;/h2&gt;&lt;h2 id="概述"&gt;概述&lt;/h2&gt;&lt;h3 id="什么是 Agave？"&gt;什么是 Agave？&lt;/h3&gt;
&lt;p&gt;Agave 是 Solana 区块链的新一代验证节点客户端软件。于 2024 年 11 月正视发布。它的主要作用是帮助验证节点更高效地处理交易、验证区块和维护网络安全。作为 Solana 生态系统的核心组件，Agave 致力于提供更好的性能、更高的可靠性和更优的用户体验。&lt;/p&gt;
&lt;h2 id="主要更新内容"&gt;主要更新内容&lt;/h2&gt;&lt;h3 id="1. 性能优化"&gt;1. 性能优化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;验证节点运行速度显著提升&lt;/li&gt;
&lt;li&gt;优化节点同步机制&lt;/li&gt;
&lt;li&gt;新的交易调度器&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2. 计算单元定价更新"&gt;2. 计算单元定价更新&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;基于账户大小的计算单元收费&lt;/li&gt;
&lt;li&gt;每 32KB 数据消耗 8 个计算单元&lt;/li&gt;
&lt;li&gt;支持通过 &lt;code&gt;ComputeBudget&lt;/code&gt; 优化成本&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3. QUIC 协议支持"&gt;3. QUIC 协议支持&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;验证节点投票采用 QUIC 协议&lt;/li&gt;
&lt;li&gt;提供更好的消息过滤&lt;/li&gt;
&lt;li&gt;需要至少 17 个可用端口&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="不兼容变更"&gt;不兼容变更&lt;/h2&gt;&lt;h3 id="API 变更"&gt;API 变更&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;移除的 RPC 方法：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getRecentBlockhash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;其他已废弃的调用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新增 API 功能：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;更高效的区块查询&lt;/li&gt;
&lt;li&gt;改进的账户订阅&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="构建工具更新"&gt;构建工具更新&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;废弃：&lt;code&gt;cargo build-bpf&lt;/code&gt; 和 &lt;code&gt;cargo test-bpf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;新增：工具版本声明功能&lt;/li&gt;
&lt;li&gt;支持：工作空间和程序级别版本控制&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="开发者指南"&gt;开发者指南&lt;/h2&gt;&lt;h3 id="迁移建议"&gt;迁移建议&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;API 迁移
```rust
// 旧方法
let blockhash = rpc_client.get_recent_blockhash()?;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;// 新方法
   let blockhash = rpc_client.get_latest_blockhash()?;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
2. 计算单元优化
   ```rust
   // 设置计算单元预算
   TransactionInstruction::new_with_compute_budget(
       ComputeBudgetInstruction::set_compute_unit_limit(200_000)
   );
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="最佳实践"&gt;最佳实践&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;及时更新废弃的 API 调用&lt;/li&gt;
&lt;li&gt;注意账户数据大小对性能的影响&lt;/li&gt;
&lt;li&gt;使用最新的构建工具链&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="采用情况"&gt;采用情况&lt;/h2&gt;
&lt;p&gt;目前网络上约 95-96% 的质押量运行在 Agave 2.0 上，显示出社区对新版本的高度认可。&lt;/p&gt;
&lt;h2 id="未来规划"&gt;未来规划&lt;/h2&gt;
&lt;p&gt;Agave 2.1 开发计划：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] 新的 "no Alok" 入口点&lt;/li&gt;
&lt;li&gt;[ ] 性能进一步优化&lt;/li&gt;
&lt;li&gt;[ ] 改进 Windows 开发支持&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="资源链接"&gt;资源链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.solana.com" rel="nofollow" target="_blank" title=""&gt;Solana Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/solana-labs/solana" rel="nofollow" target="_blank" title=""&gt;Agave GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forums.solana.com" rel="nofollow" target="_blank" title=""&gt;开发者论坛&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="结语"&gt;结语&lt;/h2&gt;
&lt;p&gt;Agave 2.0 是 Solana 网络的一次重要升级，它不仅提升了网络性能，还为未来的发展奠定了基础。我们建议所有开发者尽快熟悉新版本的特性，并更新相关代码以适应这些变化。&lt;/p&gt;
&lt;h2 id="参考资料"&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://solanacompass.com/learn/Changelog/solana-changelog-nov-20-agave-validator-v20-loaded-account-costs" rel="nofollow" target="_blank" title=""&gt;Solana Compass - Agave 2.0 更新日志&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>KimmySol</author>
      <pubDate>Thu, 12 Dec 2024 11:50:24 +0800</pubDate>
      <link>https://soldev.cn/topics/116</link>
      <guid>https://soldev.cn/topics/116</guid>
    </item>
    <item>
      <title> 十分钟开始使用多签工具 SQUADS</title>
      <description>&lt;h2 id="十分钟开始使用多签工具SQUADS"&gt;十分钟开始使用多签工具 SQUADS&lt;/h2&gt;
&lt;p&gt;(论坛对 markdown 的渲染可能有点问题，具体教程可以直接在 github repo 中查看。&lt;a href="https://github.com/kimmy1886/squads_quickstart" rel="nofollow" target="_blank"&gt;https://github.com/kimmy1886/squads_quickstart&lt;/a&gt; )&lt;/p&gt;
&lt;h2 id="关于squads"&gt;关于 squads&lt;/h2&gt;
&lt;p&gt;Squads 是 Solana 区块链上领先的多重签名 (multisig) 解决方案，已经为超过 100 亿美元的资产提供安全保障。它提供直观的用户界面和完善的安全机制，让团队能够安全地管理数字资产、程序升级权限和验证者节点。作为一个去中心化的自托管工具，Squads 支持多种功能，包括资金库管理、代币发行、NFT 操作以及与 Solana 生态系统中其他 DeFi 应用的集成。其核心特点是要求多方签名才能执行交易，大大提升了资产安全性，特别适合 DAO 组织和 Web3 项目团队使用。&lt;/p&gt;
&lt;h2 id="什么是多重签名(multisig)"&gt;什么是多重签名 (multisig)&lt;/h2&gt;
&lt;p&gt;多重签名 (Multisig) 是一种数字资产安全管理机制，要求多个预设的密钥持有者共同授权才能执行某项操作。与传统的单一签名不同，多重签名通常设置为"M-of-N"模式，即在 N 个授权者中需要至少 M 个授权者同意才能完成交易。例如，在 3-of-5 的多重签名设置中，需要 5 个授权者中的至少 3 个同意才能执行交易。这种机制有效防止了单点故障，即使某个密钥丢失或被盗，资产仍然是安全的。&lt;/p&gt;
&lt;h2 id="快速开始"&gt;快速开始&lt;/h2&gt;
&lt;p&gt;接下来我们会有一个简单的教程展示如何使用 Typescript 在测试网上与 SQUADS 协议交互。 &lt;/p&gt;

&lt;p&gt;首先，创建目录和文件结构：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir squads_quickstart
cd squads_quickstart
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;创建 &lt;code&gt;tsconfig.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"esModuleInterop": true
}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建 &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
"scripts": {
"test": "npx mocha -r ts-node/register 'main.ts' --timeout 10000"
},
"dependencies": {
"@solana/web3.js": "^1.73.0",
"@sqds/multisig": "^2.1.3"
},
"devDependencies": {
"@types/chai": "^4.3.3",
"@types/mocha": "^10.0.6",
"chai": "^4.3.6",
"mocha": "^10.3.0",
"ts-mocha": "^10.0.0",
"typescript": "^4.8.3"
}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创建 main.ts
本文将会带领读者创建一个脚本逐步进行如下几步，创建多签，提出一个新的转账，进行投票并且执行。
首先，设置多签成员并且创建地址&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("Interacting with the Squads V4 SDK", () =&amp;gt; {
const creator = Keypair.generate();
const secondMember = Keypair.generate();
before(async () =&amp;gt; {
const airdropSignature = await connection.requestAirdrop(
  creator.publicKey,
  1 * LAMPORTS_PER_SOL
);
await connection.confirmTransaction(airdropSignature);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;const createKey = Keypair.generate();&lt;/p&gt;

&lt;p&gt;// 从多签账户中派生 PDA
  const [multisigPda] = multisig.getMultisigPda({
    createKey: createKey.publicKey,
  });&lt;/p&gt;

&lt;p&gt;it("Create a new multisig", async () =&amp;gt; {
    const programConfigPda = multisig.getProgramConfigPda({})[0];&lt;/p&gt;

&lt;p&gt;console.log("Program Config PDA: ", programConfigPda.toBase58());&lt;/p&gt;

&lt;p&gt;const programConfig =
      await multisig.accounts.ProgramConfig.fromAccountAddress(
        connection,
        programConfigPda
      );&lt;/p&gt;

&lt;p&gt;const configTreasury = programConfig.treasury;&lt;/p&gt;

&lt;p&gt;// 生成多签
    const signature = await multisig.rpc.multisigCreateV2({
      connection,
      //一次性密钥
      createKey,
      // 创建者和费用支付这
      creator,
      multisigPda,
      configAuthority: null,
      timeLock: 0,
      members: [
        {
          key: creator.publicKey,
          permissions: Permissions.all(),
        },
        {
          key: secondMember.publicKey,
          // 这里的权限代表用户只可以投票
          permissions: Permissions.fromPermissions([Permission.Vote]),
        },
      ],
      // 这里代表至少需要两票才可以使提案通过
      threshold: 2,
      rentCollector: null,
      treasury: configTreasury,
      sendOptions: { skipPreflight: true },
    });
    await connection.confirmTransaction(signature);
    console.log("Multisig created: ", signature);
  });&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
生成转账提案

现在，我们可以进行转账提案的生成。 我们希望这个多签账户向生成者发送0.1 SOL。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it("Create a transaction proposal", async () =&amp;gt; {
    const [vaultPda] = multisig.getVaultPda({
      multisigPda,
      index: 0,
    });
    const instruction = SystemProgram.transfer({
      // 转账是从 Squads 金库签名的，这就是为什么我们使用 VaultPda
      fromPubkey: vaultPda,
      toPubkey: creator.publicKey,
      lamports: 1 * LAMPORTS_PER_SOL,
    });
    // 这个消息包含了交易将要执行的指令
    const transferMessage = new TransactionMessage({
      payerKey: vaultPda,
      recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
      instructions: [instruction],
    });&lt;/p&gt;

&lt;p&gt;// 获取当前多签交易索引
    const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress(
      connection,
      multisigPda
    );&lt;/p&gt;

&lt;p&gt;const currentTransactionIndex = Number(multisigInfo.transactionIndex);&lt;/p&gt;

&lt;p&gt;const newTransactionIndex = BigInt(currentTransactionIndex + 1);&lt;/p&gt;

&lt;p&gt;const signature1 = await multisig.rpc.vaultTransactionCreate({
      connection,
      feePayer: creator,
      multisigPda,
      transactionIndex: newTransactionIndex,
      creator: creator.publicKey,
      vaultIndex: 0,
      ephemeralSigners: 0,
      transactionMessage: transferMessage,
      memo: "Transfer 0.1 SOL to creator",
    });&lt;/p&gt;

&lt;p&gt;await connection.confirmTransaction(signature1);&lt;/p&gt;

&lt;p&gt;console.log("Transaction created: ", signature1);&lt;/p&gt;

&lt;p&gt;const signature2 = await multisig.rpc.proposalCreate({
      connection,
      feePayer: creator,
      multisigPda,
      transactionIndex: newTransactionIndex,
      creator,
    });&lt;/p&gt;

&lt;p&gt;await connection.confirmTransaction(signature2);&lt;/p&gt;

&lt;p&gt;console.log("Transaction proposal created: ", signature2);
  });&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;向提案投票，这里我们使用教程开始部分生成的两个密钥
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it("Vote on the created proposal", async () =&amp;gt; {
    // 获取当前多签账户的交易索引
    const transactionIndex =
      await multisig.accounts.Multisig.fromAccountAddress(
        connection,
        multisigPda
      ).then((info) =&amp;gt; Number(info.transactionIndex));&lt;/p&gt;

&lt;p&gt;// 第一个成员（创建者）对提案进行投票
    const signature1 = await multisig.rpc.proposalApprove({
      connection,
      feePayer: creator,      // 交易费用支付者
      multisigPda,            // 多签账户地址
      transactionIndex: BigInt(transactionIndex),  // 交易索引
      member: creator,        // 投票成员
    });&lt;/p&gt;

&lt;p&gt;// 等待第一个投票交易确认
    await connection.confirmTransaction(signature1);&lt;/p&gt;

&lt;p&gt;// 第二个成员对提案进行投票
    const signature2 = await multisig.rpc.proposalApprove({
      connection,
      feePayer: creator,      // 交易费用仍由创建者支付
      multisigPda,            // 多签账户地址
      transactionIndex: BigInt(transactionIndex),  // 交易索引
      member: secondMember,   // 第二个投票成员
    });&lt;/p&gt;

&lt;p&gt;// 等待第二个投票交易确认
    await connection.confirmTransaction(signature2);
  });&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;执行交易

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it("Execute the proposal", async () =&amp;gt; {
    const transactionIndex =
      await multisig.accounts.Multisig.fromAccountAddress(
        connection,
        multisigPda
      ).then((info) =&amp;gt; Number(info.transactionIndex));&lt;/p&gt;

&lt;p&gt;const [proposalPda] = multisig.getProposalPda({
      multisigPda,
      transactionIndex: BigInt(transactionIndex),
    });
    const signature = await multisig.rpc.vaultTransactionExecute({
      connection,
      feePayer: creator,
      multisigPda,
      transactionIndex: BigInt(transactionIndex),
      member: creator.publicKey,
      signers: [creator],
      sendOptions: { skipPreflight: true },
    });&lt;/p&gt;

&lt;p&gt;await connection.confirmTransaction(signature);
    console.log("Transaction executed: ", signature);
  });&lt;/p&gt;

&lt;p&gt;});&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;###
最后，使用
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;yarn test&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;来执行脚本

好了,现在脚本已经执行完成，复制地址可以在[solana explorer](https://explorer.solana.com/?cluster=custom)中查看。

完整代码可以参考
https://github.com/kimmy1886/squads_quickstart
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>KimmySol</author>
      <pubDate>Wed, 04 Dec 2024 01:46:26 +0800</pubDate>
      <link>https://soldev.cn/topics/112</link>
      <guid>https://soldev.cn/topics/112</guid>
    </item>
  </channel>
</rss>
