文章
关于Sui的教育材料和教程
帖子
14- 文章Apr 13, 2025
对象访问控制和接收机制
这是 “Sui Move 中的亲子对象” 系列的第 2 部分. 你可以在这里阅读第 1 部分 对象访问控制传输:: receive 机制 因此,您已将对象X放入父对象P(通过将 X 转移到 P 的 ID),如何将其取回或使用?🤔 这就是 Sui 的特殊接收机制的用武之地. 当一个对象被转移到父对象时,它不会自动弹出. 它坐落在那里,归P所有. 要在交易中使用或移除该子对象,您必须接收该子对象. Sui 使用接收票证和 transfer:: receive 函数提供了一种结构化的方法来实现此目的. ##收货单 可以将 Receiving 视为类型为 T 的子对象的索赔凭证. 在事务中,您不是直接将子对象(您尚未拥有)传递给函数,而是传递一个 Receiving,本质上是对 “父级 X 拥有的 ID 为 Y 的对象” 的引用. 这个 Receiving 是一个特殊的 Move 结构,它包含待接收对象的 ID、版本和摘要. 它只有掉落能力,这意味着它可以短暂存在但不能永久存储换句话说,这是交易内的一次性使用票. 你如何获得收据?通常,通过执行传输. 在可编程交易区块 (PTB) 中,一个步骤可以将对象C转移到父级P,这会生成一个接收票证供下一步使用. 如果子对象已经位于先前交易的父对象中,则可以提供接收作为新事务的输入(Sui SDK/CLI 允许您按其 ID 和父对象指定子对象以生成票证). 重要:接收不是对象本身,它尚未赋予您所有权. 它只是表示 “具有此 ID 的 T 类型的对象归该父对象所有,我打算将其接受. ”要真正抓取对象,你必须调用 transfer:: receive: module example::toy_box { use sui::transfer::{Self, Receiving}; struct Toy has key { id: UID, name: vector } struct Box has key { id: UID } /// Remove a Toy child from a Box, returning the Toy to the caller. public entry fun take_toy(box: &mut Box, toy_ticket: Receiving): Toy { // Use the parent's UID and the Receiving ticket to get the Toy let toy = transfer::receive(&mut box.id, toy_ticket); // Now toy is an owned value we can return (or transfer to someone). toy } } 在 take_toy 中,toy_ticket: Rece iving 表示属于盒子的玩具. 通过调用 transfer:: receive(&mut box.id,toy_ticket),我们调用 Sui 的原生逻辑来实际从盒子里检索玩具对象. 这做了一些关键的事情: -它在运行时验证toy_ticket确实引用了盒子当前拥有的对象(使用父级的UID). 如果某些内容不匹配(错误的父对象,或者对象实际上不在那里),它将中止. -然后,它将实际的玩具对象作为交易中的自有值返回,这意味着现在玩具由我们的函数控制. 请注意,我们必须传递 &mut box.id. Sui 强制我们有一个对父级 UID 的可变引用**来调用 receive. 这是一种巧妙的访问控制:只有能够生成父级 &mut UID 的模块才能允许接收. 通常,父类型的定义模块将暴露诸如 take_toy 之类的内部调用 receive 的函数. 如果父模块不公开任何给出 &mut UID 的函数(直接或间接),则任何外部代码都无法抢夺其子级. 这样,家长的模块就可以控制访问孩子的方式和时间. 在示例中,Box 有一个 id: UID 字段. 由于 take_toy 在同一个模块中,它可以借用 &mut box.id. 外部模块或交易可以调用 take_toy(box_obj,票证),但它们自己无法在 Box 上调用 transfer:: receive,因为 box.id 是私有的. *这种模式确保只有授权码才能找回孩子. *✅ 嵌套对象呢?如果 Toy 的确是 Box 中的一个田地(比如 Box {id,toy: Toy}),我们就不需要任何接收物了——只要你有 &mut Box 就可以拿到这个玩具. 但这也意味着将其移除或分开处理更难(就像盒子的一部分). 对于子对象,我们将存储空间分开:玩具是分开的,必须明确取出. 这种明确性是 Sui 需要接听票据并接听电话的原因,它使取回孩子成为一项授权操作. 可变引用要求:你可能想知道,为什么 &mut UID 而不只是 &UID?Mutable 确保在接收操作期间父节点处于*锁定状态,从而防止并发修改,并确保调用者实际上有权修改该父级(通常意味着他们是所有者). 这是 Sui 动态所有权检查的一部分——通过对父母的 UID 进行可变借用,Sui 保证在你带出孩子时不会有其他交易或并行行动干扰. 这有点像在取出内容之前锁上父母的门. 交易区块中的用法示例:假设一个 Box 对象归爱丽丝所有,而她有一个玩具物体她想放进盒子里,然后也许 我们稍后再把它拿出来. 以下是它可能看起来不错的样子: 将玩具装在盒子上:**Alice 在 PTB 中呼叫转接:: public_transfer(玩具,@);这会将玩具转移到盒子下面(我们在这里使用 public_transfer 是因为这是一个交易环境——稍后会详细介绍). 现在这个玩具是盒子里的孩子了. -在相同或另一笔交易中,取回玩具:Alice 调用示例:: toy_box:: take_toy (box_obj,),其中 Receiving 指的是玩具. 在幕后,take_toy 调用接收、验证关系并返回玩具. 现在,玩具将成为交易的输出,通常会回到爱丽丝的地址下(因为我们是从输入函数返回的). 关键要点: -默认情况下,子对象不可访问;您需要接收票证和相应的功能才能将其取出. -父模块决定如何检索(通过提供带有 &mut UID 的函数). -transfer:: receive 用于 在父模块的定义模块内用于该模块或其朋友的对象. 如果孩子的类型是在其他地方定义的,则需要另一种方法(输入 public_receive...). 在继续之前,还有一个细节:如果物体类型 T 只有按键能力(没有存储),Sui 会将其视为受到更多限制. 此类对象不能通过其模块之外的泛型代码接收. 实际上,这意味着,如果 T 仅限密钥并成为子级,则需要在自己的模块或使用自定义规则的父模块中处理其检索. 如果 T 也有存储,我们可以通过 public_receive 获得更大的灵活性. 接下来让我们来探讨一下.
- Sui
2 - 文章Apr 12, 2025
✏️ Sui Move 中的亲子物品
在 Sui Move 中,对象可以拥有其他对象,就像账户拥有的对象一样. 这为开发人员开辟了新的设计模式(和一些问题). 在本指南中,我将把 Sui Move 中的父子对象概念分为四个部分: Sui Move 亲子概念简介 对象访问控制和接收机制 3.使用 public_receive 进行跨模块儿童管理 灵魂绑定逻辑和退货收据模式 最后,你将了解如何嵌套对象,如何通过 transfer:: receive 检索子对象,使用 public_receive 跨模块管理子对象,甚至创建回旋回其所有者的灵魂绑定对象. Sui Move 亲子概念简介 ###什么是父对象和子对象? 在 Sui 中,每个对象都有一个唯一的 ID 和一个 所有者. 通常,所有者是一个地址(例如用户的账户),但所有者也可以是另一个对象. 如果对象 A 拥有对象 B,我们称对象 A 为父对象,B 为子对象. 子级是对象所有的,而不是地址所有的. 传输到对象:Sui 实际上并没有在幕后区分地址和对象 ID ——两者都只是 32 字节的标识符. 这意味着你可以像转移到用户地址一样将一个对象转移到另一个对象的 ID. 当你这样做时,你实际上是在将一个对象嵌套在父对象中. Sui 的运行时将孩子的所有者字段设置为父母的 ID(而不是地址) 那么为什么这很酷呢? 因为子级保留自己的唯一 ID 并独立存在于存储空间中,但现在它已绑定到父级. 这就像给你的朋友一个独特的收藏品来存放在他们的储物柜里——收藏品会保留自己的身份证件并且可以被追踪,但你朋友的储物柜现在被列为其所有者. 区分唯一对象与嵌套对象和子对象很重要: 唯一对象(地址所有):**地址拥有的常规对象(例如用户账户). 这是默认情况——比如直接存放在用户钱包中的 NFT、硬币等. 每个都有唯一的 ID,存储空间最高. 嵌套(封装)对象:存储在*另一个对象的数据中*的对象(例如,作为结构中的字段). 在这种情况下,内部对象是*封装的*,不是**单独的顶级实体. 它不会按其 ID 显示在全局存储中,因为它是父级字节内容的一部分. 在 Sui 中,如果您在未进行特殊处理的情况下将一个对象作为字段放在另一个对象中,���该对象会被封装. 子对象(对象拥有者):*由另一个对象拥有的对象 *但未直接包装在其字段中. 子对象仍然是存储空间中的一个单独的顶级对象(有自己的 ID 和数据),父对象的 ID 作为所有者记录在子元数据中. 这意味着您可以通过孩子的ID(具有正确的权限)查询或访问孩子. 它不是物理上嵌入到家长的内容中,只是逻辑上所有的. 用我们的比喻,就像你把你的收藏品交给朋友保管一样,它仍然有单独的标签和可追踪,只是存放在他们的储物柜里. 创建子对象(通过传输)而不是对其进行包装的好处是,子对象的 ID 仍然可以从外部访问. 例如,资源管理器或钱包可以按 ID 列出子对象,而包装的对象在其父对象之外不可见. 即使子对象在所有者之间移动或嵌套在不同的父对象中,它们也能保持稳定的 ID. 这对于链上库存或 “钱包里面的钱包” 模式之类的东西非常有用,在这些模式中,你希望容器对象可以容纳许多其他人仍然可以单独引用的物品 所有权和访问权限:如果一个对象归另一个对象所有,则通常只有父对象的所有者才能访问或使用子对象. 这是一种动态授权. 例如,如果 Alice 拥有父对象 P,而 P 拥有子对象 C,则只有 Alice(或 Alice 签署的交易)可以操作 C. Sui 强制执行此操作,因此拥有父对象就像持有其所有子对象的密钥一样 🔑. 也许你知道: Sui 的转移到对象功能本质上赋予了我们 树状对象所有权. 父母可以有许多孩子(这些孩子可以有自己的孩子,形成等级制度). 这是通过将对象 ID 视为传输地址来实现的. 我们有: 地址拥有的对象**(普通的唯一对象), 对象拥有的对象**(子对象,仍是顶级对象,但与父对象绑定), 封装的对象**(嵌套在另一个对象的数据中,而不是顶层). 在接下来的文章中,我们将了解如何实际检索子对象或与子对象进行交互(因为它们不能像地址拥有的对象那样直接访问),以及如何围绕它们执行规则.
- Sui
- Move
3 - 文章Apr 10, 2025
使用 Sui Move 和现代用户界面构建下一代 NFT 彩票 dApp
🧩 使用 Sui Move 和现代用户界面构建下一代 NFT 彩票 dApp 这是你使用Sui Move构建游戏化、基于NFT的彩票DApp的终极指南,它具有多轮支持、推荐系统、DAO治理和Z世代会喜欢的设计系统. 从合约架构到用户界面流程——让我们全力以赴. 📦 阶段分解 第一阶段 — 核心彩票 -多回合游戏 -NFT 票务 -推荐奖励系统 -基本的 DAO 投票 第 2 阶段 — 市场和游戏化 -NFT 市场整合 -助推器(增加获胜机会) -大奖系统 -隐藏的空投 第 3 阶段 — DAO 和多链 -跨链兼容性 -带有高级提案的 DAO -动态定价 -链上分析 🧠 关于 Sui Move 的智能合约深度研究 合约结构 module nft_lottery_x::nft_lottery_x { use sui::object; use sui::balance::{Balance, zero}; use sui::coin::{Self, Coin}; use sui::clock::Clock; use sui::random::Random; use sui::event::emit; use sui::transfer; use sui::tx_context::TxContext; use std::option; use std::signer; const EGameNotStarted: u64 = 1000; const EGameAlreadyFinished: u64 = 1001; const EInvalidPayment: u64 = 1002; const ENoTickets: u64 = 1003; const EWinnerAlreadyChosen: u64 = 1004; const ENotWinner: u64 = 1005; public struct Game has key { id: UID, ticket_price: u64, start_time: u64, end_time: u64, total_tickets: u32, round: u32, winner: Option, balance: Balance, referral_bonus: u64, } public struct Ticket has key { id: UID, game_id: ID, ticket_number: u32, buyer: address, referrer: Option, } public struct GameCreated has copy, drop { game_id: ID, start_time: u64, end_time: u64, ticket_price: u64, } public struct TicketBought has copy, drop { game_id: ID, ticket_number: u32, buyer: address, referrer: Option, } public struct WinnerAnnounced has copy, drop { game_id: ID, winner_ticket: u32, round: u32, } public struct RewardClaimed has copy, drop { game_id: ID, ticket_number: u32, amount: u64, } public fun create_game( start_time: u64, end_time: u64, ticket_price: u64, referral_bonus: u64, ctx: &mut TxContext ) { let game = Game { id: object::new(ctx), ticket_price, start_time, end_time, total_tickets: 0, round: 1, winner: option::none(), balance: zero(), referral_bonus, }; emit(GameCreated { game_id: object::id(&game), start_time, end_time, ticket_price, }); transfer::share_object(game); } public fun buy_ticket( game: &mut Game, coin: Coin, clock: &Clock, referrer: Option, ctx: &mut TxContext ): Ticket { assert!(clock.timestamp_ms() >= game.start_time, EGameNotStarted); assert!(clock.timestamp_ms() (TicketBought { game_id: object::id(game), ticket_number: ticket.ticket_number, buyer: ticket.buyer, referrer: ticket.referrer, }); ticket } public entry fun determine_winner( game: &mut Game, rand: &Random, clock: &Clock, ctx: &mut TxContext ) { assert!(clock.timestamp_ms() >= game.end_time, EGameNotStarted); assert!(game.winner.is_none(), EWinnerAlreadyChosen); assert!(game.total_tickets > 0, ENoTickets); let mut generator = rand.new_generator(ctx); let winning_ticket = generator.generate_u32_in_range(1, game.total_tickets); game.winner = option::some(winning_ticket); emit(WinnerAnnounced { game_id: object::id(game), winner_ticket: winning_ticket, round: game.round, }); } public fun claim_reward( ticket: Ticket, game: Game, ctx: &mut TxContext ): Coin { assert!(object::id(&game) == ticket.game_id, EInvalidPayment); let ticket_num = ticket.ticket_number; assert!(game.winner.contains(&ticket_num), ENotWinner); let amount = game.balance.value(); let reward = game.balance.into_coin(ctx); emit(RewardClaimed { game_id: object::id(&game), ticket_number: ticket.ticket_number, amount, }); object::delete(object::id(&game)); reward } } 关键要点: -✅ Balance确保类型安全和正确处理硬币 -✅ Option清楚地表明是否选中了赢家 -✅ 事件为前端和探索者提供可追溯性 🛠 Sui CLI 命令 sui client call --package --module nft_lottery_x --function create_game --args --gas-budget 10000000 要购买彩票、确定赢家或领取奖励,请遵循类似的 CLI 流程. 🔮 未来新增内容 -下一回合的自动重置逻辑 claim_reward -发出更多事件,比如 ReferralRewardDistributed -将累积奖金和推荐重构为子模块 如果你想在第 2 部分中构建 UI 并集成到 Sui 测试网上,请告诉我!
- Sui
3 - 文章Apr 09, 2025
Sui 交易指南:从设置到执行和验证
Sui 交易指南:从设置到执行和验证 如果你对在Sui区块链上执行交易的细节感到好奇,并想要一份深入而实用的指南,引导你完成每一个步骤. 在本文中,我们将探讨整个过程——从设置客户环境、检查钱包对象、计算汽油费,到签署和执行交易,最后验证其详细信息. 让我们逐步分解一下: 是什么让 Sui 如此特别?🔥 Sui 为去中心化应用程序 (dApps) 和智能合约提供了高度优化的平台. 其在管理汽油费和交易逻辑方面的优雅设计使其成为希望突破 Web3 技术界限的开发人员的一个令人兴奋的游乐场. 2. 入门:环境设置和钱包配置 ⚙️ 2.1. 配置您的 Sui 客户端环境 在进行交易之前,请确保您的Sui客户端设置正确. Sui 支持多个网络(开发网络、主网、测试网),你可以使用以下命令查看哪个网络处于活动状态: ➜ sui client envs ╭─────────┬─────────────────────────────────────┬────────╮ │ alias │ url │ active │ ├─────────┼─────────────────────────────────────┼────────┤ │ devnet │ https://fullnode.devnet.sui.io:443 │ │ │ mainnet │ https://fullnode.mainnet.sui.io:443 │ │ │ testnet │ https://fullnode.testnet.sui.io:443 │ * │ ╰─────────┴─────────────────────────────────────┴────────╯ 这确认你已连接到测试网. 进入正确的网络是成功交易的第一步. 2.2. 查看您的活跃钱包 接下来,验证您的有效钱包地址. 这至关重要,因为每笔交易都与您的钱包身份息息相关: ➜ sui client active-address 0x35370841d2e69b495b1e2f944a3087e4242f314e503691a00b054e0ee2a45a73 2.3. 查询拥有的对象 使用 SUIX_GetownedObjects API,你可以获取有关你在区块链上拥有的对象(如硬币)的详细信息. 此命令可帮助您检查账户余额和可用于交易的资产: { "jsonrpc": "2.0", "id": 1, "method": "suix_getOwnedObjects", "params": [ "0x35370841d2e69b495b1e2f944a3087e4242f314e503691a00b054e0ee2a45a73", { "filter": { "MatchAll": [ { "StructType": "0x2::coin::Coin" } ] }, "options": { "showType": true, "showOwner": true, "showPreviousTransaction": true } } ] } 此步骤对于在尝试进行任何交易之前验证您的钱包中是否有必要的硬币(在本例中为SUI硬币)至关重要. 3. 燃气计算:交易成本预算 💸 天然气是推动区块链交易的燃料. 必须了解天然气价格和天然气预算,以避免交易失败. 3.1. 获取汽油价格 可以使用 suix_getreferenceGasPrice API 调用来检索当前的汽油价格: { "jsonrpc": "2.0", "id": 1, "method": "suix_getReferenceGasPrice", "params": [] } 如果 API 返回 “1000”,则表示每单位气体消耗 1000 MIST. 请记住,1 个 SUI 等于 10^9 MIST,因此即使是 MIST 中的很小数字,在预算时也会累积起来. 3.2. 设定天然气预算 您的汽油预算是您愿意花费的最大汽油量(以 MIST 计). 以我们的示例为例,假设您的天然气预算为 4964000 MIST. 交易的总成本通常按以下方式计算: 总成本 = 计算成本 + 存储成本 — 存储折扣 例如: • 计算成本:1,000,000 MIST • 存储成本:2,964,000 MIST • 存储返利:978,120 MIST 因此,净成本变为 1,000,000 + 2,964,000 − 978,120 = 2,985,880 MIST. 准确设定您的天然气预算可确保您的交易有足够的资金来成功执行. 4. 精心策划交易:信心试跑 🔧 在发送实时交易之前,最好进行 “试运行” 以发现任何潜在问题. 这使您无需花费任何精力即可验证交易逻辑. 4.1. 建立试运行交易 这是一个 TypeScript 函数示例,它演示了如何准备和执行试运行交易. 此代码概述了如何拆分硬币和准备转账操作: export const signSuiDryRunTransaction = async (requestParams: SignDryRequestParams): Promise => { const { gasPrice, privateKey, coinRefs, network, recipients } = requestParams; const keypair = Ed25519Keypair.fromSecretKey(privateKey); const tx = newTransaction(); // Configure gas payment, price, and sender tx.setGasPayment(coinRefs); tx.setGasPrice(gasPrice); tx.setSender(keypair.toSuiAddress()); // Split coins based on each recipient's amount const coins = tx.splitCoins(tx.gas, recipients.map((transfer) => transfer.amount)); recipients.forEach((transfer, index) => { tx.transferObjects([coins[index]], transfer.to); }); // Build and sign the transaction with the client const client = newSuiClient({ url: getFullnodeUrl(network) }); const bytes = await tx.build({ client }); const { signature } = await keypair.signTransaction(bytes); await verifyTransactionSignature(bytes, signature, { address: keypair.getPublicKey().toSuiAddress() }); return JSON.stringify([toBase64(bytes), signature]); }; 这个试运行步骤对于确保在投入实际资金之前每个细节都正确无误至关重要. 5. 签署和执行交易:将所有内容放在一起 ✍️ 成功试运行后,下一步是在区块链上签署并发送您的交易. 5.1. 签署交易 以下是使用指定燃气预算签署交易的精简示例函数: const signSuiTransaction = async (requestParams: SignRequestParams): Promise => { const { gasBudget, gasPrice, privateKey, coinRefs, network, recipients } = requestParams; const keypair = Ed25519Keypair.fromSecretKey(privateKey); const tx = newTransaction(); // Set up gas parameters, including the gas budget tx.setGasPayment(coinRefs); tx.setGasPrice(gasPrice); tx.setGasBudget(gasBudget); tx.setSender(keypair.toSuiAddress()); // Split coins for each recipient const coins = tx.splitCoins(tx.gas, recipients.map((transfer) => transfer.amount)); recipients.forEach((transfer, index) => { tx.transferObjects([coins[index]], transfer.to); }); // Build the transaction and sign it const client = newSuiClient({ url: getFullnodeUrl(network) }); const bytes = await tx.build({ client }); const { signature } = await keypair.signTransaction(bytes); await verifyTransactionSignature(bytes, signature, { address: keypair.getPublicKey().toSuiAddress() }); return JSON.stringify([toBase64(bytes), signature]); }; 该功能集成了所有必要的参数,包括气体详细信息和接收者,确保您的交易经过安全签名并做好执行准备. 5.2. 执行交易 签署后,交易将使用 SUI_executeTransactionBlock API 端点发送到区块链: curl --location 'https://fullnode.testnet.sui.io:443' \ --header 'Content-Type: application/json' \ --data '{ "jsonrpc": "2.0", "id": 1, "method": "sui_executeTransactionBlock", "params": [ "", [""], { "showInput": true, "showRawInput": true, "showEffects": true, "showEvents": true, "showObjectChanges": true, "showBalanceChanges": true }, "WaitForLocalExecution" ] }' 此调用返回详细的 JSON 响应,其中包含交易摘要、耗气量、对象修改和余额更新等信息. 6. 验证您的交易:交叉检查所有内容 🔍 执行交易后,必须验证所有内容是否按预期执行. 6.1. 浏览器验证 你可以在像Suivision测试网浏览器这样的区块链浏览器上查看你的交易. 浏览器以直观的可视格式显示所有交易细节,从而更容易发现任何问题. 6.2. 命令行验证 要进行更详细的审计,请使用命令行: sui client tx-block -- 3FopuDy5qzKm1kLRFZCdi8Lynadym9j15NaVxzUH6nYD 此命令提供了交易的全面细分,包括发送者详细信息、天然气支付、对象更改和执行状态. 7. 分析 JSON 响应:了解交易的层级 让我们解压您在执行交易后收到的 JSON 响应: 7.1. 交易概述 -jsonrpc 和 id:JSON-RPC 协议的标准字段. -摘要:用于跟踪的唯一交���哈希(例如,“3fopudy5qzkm1klrfzcdi8lynadym9j15navxzuh6NYD”). -TimeStampMS 和检查点:提供有关交易何时执行以及当时区块链检查点的背景信息. 7.2. 交易内容 -发送者和天然气数据:包括发件人的地址和所有与天然气相关的配置(付款、价格、预算). -操作(交易):交易逻辑包括以下操作: -SplitCoins:将汽油币分成小部分. -转移对象:将硬币段移至指定的收件人地址. -签名:加密签名(Base64 编码)确保交易的真实性. 7.3. 执行效果 -状态:“成功” 状态确认交易的处理没有错误. -燃气使用量:详细说明计算和存储成本以及任何适用的折扣. -对象变更:概述哪些对象因事务而被修改、创建或更新. -依赖关系:列出此交易所依赖的相关交易哈希. 这种精细的细分对于调试和提高 dApp 的性能至关重要. 8. 实用开发者见解:提示和要点 了解此过程的每个步骤将使您具备在 Sui 上构建安全、高效的 Web3 应用程序的技能. 这些见解不仅可以帮助您解决问题,还可以使您在 Sui 生态系统中自信地进行创新.
- Sui
- SDKs and Developer Tools
- Transaction Processing
3 - 文章0xduckmove135Apr 08, 2025
👀 SEAL-我认为 Web3 数据隐私即将改变
👀 SEAL 已在 Sui 测试网上线 — 我认为 Web3 数据隐私即将改变 在 Web3 中,经常会听到诸如“用户拥有自己的数据”或“通过设计去中心化”之类的短语. 但是,仔细观察,许多应用程序仍然依赖集中式基础设施来处理敏感数据——使用 AWS 或 Google Cloud 等服务进行密钥管理. 这就引入了一个矛盾:表面上的去中心化,底层的集中化. 但是,如果有一种方法可以在不放弃权力下放的情况下安全地管理机密呢?介绍 SEAL — 去中心化机密管理 (DSM),现已在 Sui 测试网上线. SEAL 旨在修复 Web3 最大的虚伪之处之一:在秘密使用 AWS 的同时大声疾呼去中心化 你可能会问我:海豹突击队是什么? SEAL 是一种协议,可让您安全、分散地管理敏感数据——专为 Web3 世界构建. 可以将其视为插入 dApp 的隐私优先访问控制层. 您可以将 SEAL 视为一种可编程的数据锁. 你不只是手动锁定和解锁,而是使用Move on Sui将策略直接写入智能合约. 假设你正在构建一个 DApp,其中: -只有 NFT 持有者才能解锁高级教程 -或者,在泄露敏感文件之前,DAO 可能必须进行投票 -或者你想对元数据进行时间锁定并且只能在特定日期之后访问 海豹突击队使所有这些成为可能. 访问控制在链上 运行,完全自动化,无需管理员进行管理. 只是逻辑,直接融入区块链. 海豹突击队使所有这些成为可能. 访问控制在链上 运行,完全自动化,无需管理员进行管理. 只是逻辑,直接融入区块链. 另一个有趣的文章是SEAL如何处理加密. 它使用所谓的阈值加密,这意味着:没有一个节点可以解密数据. 需要一组服务器才能协同工作——有点像多重签名,但用于解锁机密. 这样可以分配信任,避免常见的单点故障问题. 为了保证信息的真正私密性,SEAL 会加密和解密客户端的所有内容. 任何后端都看不到您的数据. 从字面上看,它会留在你的手中,放在你的设备上. 而且 SEAL 不在乎你在哪里存储数据. 无论是 IPFS、Arweave、Walrus 还是其他平台,SEAL 都不会试图控制这部分. 它只关注谁可以看到什么,而不是东西的存储位置. 所以是的,它不仅仅是一个库或 API,它是 dApp 的链上优先、访问控制、默认隐私层. SEAL 填补了一个非常关键的空白. 让我们再分解一下. 如果你正在构建一个处理任何形式的敏感数据(封闭内容、用户文档、加密消息,甚至是锁定时间的 NFT 元数据)的 dApp,你也会遇到同样的问题: ➡️ 如何在不依赖集中服务的情况下安全地管理访问权限? 如果没有像海豹突击队这样的队伍,大多数队伍都会: 使用 AWS KMS 或 Firebase 等集中式工具,这显然与去中心化背道而驰 或者尝试自己修补半生不熟的加密逻辑,这些逻辑通常会变得脆弱且难以审计 https://x.com/EmanAbio/status/1908240279720841425?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1908240279720841425%7Ctwgr%5E697f93dc65359d0c8c7d64ddede66c0c4adeadf1%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fwww.notion.so%2Fharryph%2FSEAL-Launches-on-Sui-Testnet-1cc4f8e09bb380969c0dcc627b96cc22 这两个比例都不好. 尤其是在你尝试跨多个链或社区构建无需信任的应用程序时. *SEAL 使整个过程模块化和可编程. * 您可以在Move智能合约中定义访问规则,SEAL会处理其余的——密钥生成、解密批准和访问强制执行——所有这些都无需任何人手动颁发密钥或进行后端检查. 更好的是,这些规则是可审计和不可改变的——一旦上链,它们就会遵循合同,而不是人工管理员. 因此,与其问 “谁应该管理对这些数据的访问权限?”你只要问: “应该用什么逻辑来定义访问权限?” >... 然后让链条来处理. 简洁且可扩展. 这就是SEAL不仅仅涉及 “安全工具” 的原因——它是*任何关心隐私、合规性或动态访问逻辑的DApp的基础层. * 这是一个很小的转变——但它改变了我们对 Web3 中数据的看法. *与其在部署后进行加密,或依赖外部服务,不如从内置隐私开始——访问权限完全由智能合约逻辑处理. * 而这正是 Web3 现在需要的. SEAL 实际上是如何运作的? 我们已经介绍了什么是 SEAL以及为什么 Web3 需要它,让我们来看看它在幕后是如何构建的. 这部分是技术性更强的地方,但还是不错的. 一旦你看到所有部分是如何组合在一起的,建筑就会变得很优雅. 总体而言,SEAL的工作原理是使用一种名为基于身份的加密(IBE)的技术,将链上访问逻辑与链下密钥管理相结合. 这允许开发人员将数据加密为身份,然后依靠智能合约来定义允许谁对其进行解密. 步骤 1:智能合约中的访问规则(在 Sui 上) 一切都从智能合约开始. 当你使用 SEAL 时,你需要在你的 Move 合约中定义一个名为 seal_approve 的函数,你可以在这里写下解密条件. 例如,以下是用 Move 编写的简单时间锁定规则: entry fun seal_approve(id: vector, c: &clock::Clock) { let mut prepared: BCS = bcs::new(id); let t = prepared.peel_u64(); let leftovers = prepared.into_remainder_bytes(); assert!((leftovers.length() == 0) && (c.timestamp_ms() >= t), ENoAccess); } 一旦部署,该合约将充当看门人. 每当有人想要解密数据时,他们的请求都会被根据这个逻辑进行检查. 如果通过,密钥将被释放. 如果没有,他们就会被封锁. 没有人需要干预. ##步骤 2:基于身份的加密 (IBE) 这就是魔法发生的地方. SEAL 没有加密特定钱包地址(如 PGP 或 RSA)的数据,而是使用身份字符串——这意味着你可以加密成类似的内容: -0x 钱包地址 -dao_voted: proposal_xyz -pkgid_2025_05_01(基于时间戳的规则) -甚至是 game_user_nft_holder 当数据加密后,它看起来像这样: Encrypt(mpk, identity, message) -mpk = 主公钥(众所周知) -身份 = 逻辑定义的收件人 -消息 = 实际数据 之后,如果有人想解密,密钥服务器会检查他们是否符合政策(通过链上的 seal_approve 调用). 如果获得批准,它将返回该身份的派生私钥. Derive(msk, identity) → sk Decrypt(sk, encrypted_data) 然后,用户可以在本地解密内容. 因此,无需提前知道谁将解密即可完成加密. 您只需定义条件,SEAL 稍后再计算其余部分. 它是动态的. ##第 3 步:密钥服务器 — 脱链,但未集中化 你可能想知道:谁在拿着这些万能钥匙? 这就是 SEAL 的密钥服务器的用武之地. 可以把它看作是一个后端: -持有主密钥 (msk) -关注链上合约(比如你的 seal_approve 逻辑) -仅在满足条件时才发出派生密钥 但是——这是关键——海豹突击队不只依赖一台密钥服务器. 你可以在阈值模式下运行它,在发放解密密钥之前,需要多个独立服务器达成一致. 例如:五分之三的密钥服务器必须批准请求. 这避免了中心故障点,也允许在密钥管理层进行权力下放. 更好的是,将来SEAL将支持MPC(多方计算)和基于飞地的设置(例如TEE),因此您可以在不影响可用性的情况下获得更强的保障. ##步骤 4:客户端解密 将密钥返回给用户后,实际的解密将在用户的设备上进行**. 这意味着: -服务器永远看不到你的数据 -后端从不存储解密的内容 -只有用户可以访问最后的消息 这是一个可靠的隐私模型. 即使有人破坏了存储层(IPFS、Arweave 等),如果不传递访问逻辑,他们仍然无法读取数据. 以下是快速思维模型: 这种结构使您可以轻松构建访问规则不是硬编码的去中心化应用程序,它们是动态的、可审计的,并且完全集成到您的链逻辑中. ##SEAL 背后的团队 SEAL 由区块链安全社区的知名人物Samczsun领导. 他曾是Paradigm的研究合伙人,曾审计过多个生态系统并将其从重大漏洞中拯救出来. 现在,他全职致力于将 SEAL 建成 Web3 隐私基础设施的核心部分. 凭借他的背景和信誉,SEAL 不仅仅是另一个实验工具,它是一次严肃的尝试,旨在使去中心化数据隐私既实用又可扩展. 随着 SEAL 在 Sui 测试网上线,它为 Web3 应用程序如何管理机密带来了新的标准. 通过结合链上访问控制、阈值加密和客户端隐私,SEAL 为去中心化数据处理提供了更值得信赖的基础. 无论你是在构建 dApp、DAO 还是去中心化游戏,SEAL 都提供了一个强大的工具包,可以在不影响去中心化的前提下执行访问控制和保护用户数据. 如果 Web3 要向前发展,像 SEAL 这样的安全基础设施不是可选的——这是必不可少的
- Sui
- Architecture
- SDKs and Developer Tools
4 - 文章Lokie13Mar 16, 2025
Step by step guide to create a Suiet wallet
Step by step guide to create a Suiet wallet: Download suiet extension: https://suiet.app/ After successful installation, click on the Suiet icon in your browser and select "Create New". Set a strong password to protect your wallet. Write down and save your recovery phrase in a safe place. This phrase is needed to recover your wallet if needed Done
- Sui
1 - 文章Bahador85Mar 15, 2025
作为 SUI Move 智能合约开发者的旅程
在今天的文章中,我想为那些喜欢进入SUI move开发方式的人深入探讨一个路线图建议. 1. 了解区块链基础知识 核心概念:* 熟悉关键的区块链概念,例如去中心化、共识机制、加密原语和智能合约. SUI 区块链概述:* 了解 SUI 的独特之处——其以对象为中心的数据模型、性能目标以及它如何处理状态管理. 2. 学习动作语言 语言基础知识:* 从 Move 编程语言的基础知识开始. 重点关注: 资源类型:*资源如何运作以确保安全和所有权. 模块和结构:*如何定义模块和数据结构. 入场功能:*如何通过指定入口点执行交易. -推荐资源: 利用官方 Move 语言教程、文档和示例代码存储库. 3.设置您的开发环境 工具和 CLI:* 安装 SUI CLI 并在本地计算机上设置 Move 工具链. 本地测试环境:* 配置本地 SUI 开发网络或使用可用的测试网. 这可以帮助您在上线之前尝试智能合约的部署和测试. IDE 和调试:* 选择支持 Move 的集成开发环境 (IDE)(例如,带有 Move 扩展的 VSCode),熟悉调试和测试合约. 4. 建立你的第一个简单合约 动手教程:* 从一个简单的项目开始,例如代币合约. 这将允许你应用基本的 Move 结构. 探索 SUI 特定模式:* 使用 SUI 的对象模型,了解如何在 SUI 生态系统中处理交易. 文档和示例:* 利用 SUI 的开发人员文档和示例项目来了解最佳实践. 5. 深入了解 SUI 的特定功能 以对象为中心的模型:* 了解 SUI 如何将对象与以太坊等基于账户的区块链区别对待. 天然气和交易模式:* 研究汽油费是如何计算的,以及如何在SUI中管理交易执行. 状态管理:* 了解 SUI 的状态存储、模块化更新和对象生命周期管理方法. 6. 测试、调试和部署 单元和集成测试:* 编写测试以验证智能合约的逻辑和安全性. 确保涵盖边缘案例和潜在漏洞. 本地和测试网部署:* 在受控环境中部署合约,以查看它们在实际条件下的表现. 工具:* 利用 SUI 的调试工具和日志记录功能来迭代和改进您的代码. 7. 安全最佳实践和代码审计 了解常见陷阱:* 研究智能合约中的常见安全漏洞(例如可重入性、访问控制不当),以及Move的设计如何缓解这些漏洞. 代码评论:* 参与社区代码审查或与同行合作审核和改进您的代码. 形式验证:* 探索任何可用的 Move 形式验证工具,以数学方式证明合同的正确性. 8. 加入 SUI 开发者社区 社区频道:* 通过论坛、Discord 频道或社区电话与其他开发者互动. 分享经验和挑战是无价的. 开源贡献:* 为与 SUI 和 Move 相关的开源项目或开发者存储库做出贡献. 保持最新状态:* 关注 SUI 和 Move 博客、GitHub 存储库和社交媒体渠道,以跟踪新的发展、更新和最佳实践. 9. 探索高级主题 复杂应用程序:* 当你变得更舒服时,可以尝试更先进的智能合约设计,例如去中心化金融 (DeFi) 协议、NFT 或多重签名钱包. 互操作性和集成:* 学习如何与其他智能合约进行交互以及如何将SUI Move模块与链下系统集成. 性能和可扩展性:* 探索在 SUI 区块链上优化合约的技术,以提高速度和成本效益. 10. 建立投资组合并继续练习 展示项目:* 制定并记录一系列项目,以证明您的理解和专业知识. 持续学习:* 区块链和 Move 正在迅速发展——通过重温文档、参加研讨会和参与黑客马拉松,让持续学习成为一种习惯. 反馈回路:* 使用社区反馈来完善您的技能,并在智能合约开发中保持领先地位. 尽管以上物品是建议,并不是成为 SUI 开发者的唯一途径,但我希望它对你们有所帮助. 祝您编码愉快. 起诉愉快!
- Sui
- SDKs and Developer Tools
- Move
2 - 文章0xduckmove135Mar 12, 2025
Setting Up a Project to Test the SUI Name Service (SuiNS)
The SUI Name Service (SuiNS) is a decentralized naming system on the SUI blockchain that allows users to map human-readable names (e.g., "0xduck.sui") to blockchain addresses or other data, enhancing usability and accessibility. For developers, testing the SuiNS SDK is an essential step to ensure applications can resolve these names correctly. In this article, we’ll walk you through the process of setting up a project to test the SuiNS SDK, from preparing your development environment to querying a name record like "0xduck.sui" and understanding the results. Introduction to SUI Name Service The SUI Name Service (SuiNS) simplifies blockchain interactions by allowing users to register memorable names instead of using complex cryptographic addresses. For example, instead of sending tokens to "0x1234...abcd", you could send them to "0xduck.sui". Testing the SuiNS SDK ensures that your application can correctly interact with this system, retrieving and interpreting name records as needed. In this project, we’ll set up a Node.js environment, connect to the SUI mainnet, and write a script to query the name record for "0xduck.sui". By the end, you’ll have a working setup to explore SuiNS further. Prerequisites Before starting, ensure you have the following: Node.js (version 14 or higher) and npm (version 6 or higher) installed. Download them from nodejs.org if needed. Basic understanding of JavaScript, particularly asynchronous programming (e.g., async/await). A code editor like Visual Studio Code (VS Code) for writing and running scripts. An internet connection to install packages and connect to the SUI. Setting Up the Development Environment Let’s create a new project directory and initialize it as a Node.js project. This will provide a clean workspace for our test. Step-by-Step Instructions: Open your terminal (e.g., Command Prompt, PowerShell, or a Unix shell). Create a new directory: mkdir suins-test-project cd suins-test-project Initialize a Node.js project: Run this command to create a package.json file with default settings: npm init -y Your project is now set up with a basic structure. Installing Dependencies Run the following in your terminal: npm install @mysten/suins @mysten/sui Verify the Installation: Check that the packages are added to package.json under dependencies. You can also confirm the installed versions by running: npm list @mysten/suins @mysten/sui This should output something like: suins-test-project@1.0.0 ├── @mysten/sui@x.x.x └── @mysten/suins@y.y.y Configuring the SUI Client The SUI client connects your project to the SUI blockchain. For testing, we’ll use the mainnet. Create a Script File: In your project directory, create a file named test-suins.js: touch test-suins.js # On Unix/macOS echo. > test-suins.js # On Windows Open test-suins.js in your editor and add the following: import { getFullnodeUrl, SuiClient } from '@mysten/sui/client'; // Create a SUI client connected to the testnet const suiClient = new SuiClient({ url: getFullnodeUrl('testnet') }); Note: If you encounter an error about ES modules (e.g., "Cannot use import statement outside a module"), add "type": "module" to your package.json: { "name": "suins-test-project", "version": "1.0.0", "type": "module", ... } Testing the Name Service Now, let’s write a script to query the name record for "0xduck.sui" and log the result. import { getFullnodeUrl, SuiClient } from '@mysten/sui/client'; import { SuinsClient } from '@mysten/suins'; // Create a SUI client connected to the testnet // const suiClient = new SuiClient({ url: getFullnodeUrl('mainnet') }); const client = new SuiClient({ url: getFullnodeUrl('mainnet') }); // Create a SuiNS client using the SUI client const suinsClient = new SuinsClient({ client, network: 'mainnet', }); // Function to test the name service async function testNameService() { try { // Query the name record for 'demo.sui' const nameRecord = await suinsClient.getNameRecord('0xduck.sui'); // Log the result console.log('Name Record for "0xduck.sui":', nameRecord); } catch (error) { console.error('Error fetching name record:', error.message); } } testNameService(); In your terminal, execute: node test-suins.js
- SDKs and Developer Tools
3 - 文章Bahador85Mar 11, 2025
Suibase, a great tool to experience the SUI
As I was checking some resources for the SUI development, I faced a tool named, suibase. In my exploration on that, I found it very helpful, especially when using localnet which a local explorer will be set up on our local system. I loved it so much. as there is stated in the official website of Suibase: Suibase makes it easy to create "workdirs", each defining a distinct development environment targeting a network. It seems like virtual env in python programming. As far as I found this tool, there are many usefull functionalities which we can take benefit of: Key functionalities of Suibase include: Workdir Management: Suibase enables the creation of isolated workdirs for each network, ensuring that configurations and dependencies are maintained separately. This isolation facilitates organized and efficient development workflows. Suibase Simplified Command-Line Interface:* The tool provides scripts such as lsui, dsui, tsui, and msui, which serve as frontends to the Mysten Labs sui binaries for localnet, devnet, testnet, and mainnet, respectively. These scripts eliminate the need to manually switch environments, as they automatically execute the appropriate sui client and keystore for the targeted network. Localnet Operations:* Suibase offers commands like localnet start, localnet stop, and localnet status to manage the local network. Additionally, the localnet regen command allows developers to reset the network to its initial state, complete with predefined addresses and aliases, which is particularly useful for testing purposes. Faucet Functionality:* The localnet faucet command enables the distribution of Sui coins to specified addresses or all addresses within the localnet, facilitating testing and development activities. Independent Installation:* Suibase operates independently of other Mysten Labs installations and keystores, ensuring that it does not interfere with existing setups. This design allows Suibase to coexist safely with standard installations on the same system. By providing these features, Suibase enhances the development experience on the Sui network, offering a structured and efficient environment for building and testing applications. I recommend testing it!
- Sui
- SDKs and Developer Tools
3 - 文章Bahador85Mar 11, 2025
How to fix the SUI installation error?
When I try to install and build the SUI binary on my local system with this command: cargo install --git https://github.com/MystenLabs/sui.git --bin sui --branch devnet I face this error: Please specify a package, e.g. cargo install --git https://github.com/MystenLabs/sui.git anemo-benchmark. After some digging, I found the solution and was able to install and build it error-free and completely using some modification in the above command: For Devnet: cargo install --locked --git https://github.com/MystenLabs/sui.git sui --branch devnet For Testnet: cargo install --locked --git https://github.com/MystenLabs/sui.git sui --branch devnet This way, you can install and build SUI on your local machine and start on your way! Best of luck.
- Sui
- Move
3
- Sui
- SDKs and Developer Tools
- Architecture
- Move
- NFT Ecosystem
- Transaction Processing
- Security Protocols