版本迁移指南"/>
Sui V0.28 + V0.29版本迁移指南
Sui V0.28 + V0.29版本引入一些不兼容更新,可能需要更新你的应用或调整程序,才能正常运行。本指南提供了迁移步骤来帮助更新,同时也将介绍新版本中一些新增功能。
Sui Move 更新
本节将介绍有关Sui Framework相关的更新。
Sui Framework拆分成了两个包#
更新时间2023年3月27日
sui-framework包含了Sui Move中object、 transfer和dynamic_field等核心包。在Sui上开发的合约常常依赖sui-framework包。此前,sui-framework包含一个governance文件夹,里面定义了一些与Sui系统运行相关的模块,比如validator_set和staking_pool。这模块与framework内的其他模块有根本区别,开发人员不常用。 为了简化,此版本将sui-framework拆分为两个,以提高模块化、可用性和升级性。
在PR 9618中,sui-framework在packages目录中包含3个包:sui-system、sui-framework和move-stdlib:
- sui-system中包含sui-framework/sources/governance目录中的模块, 其中所有验证节点管理和质押相关函数,都发布在以0x3命名的sui_system地址上。
- sui-framework包含不在governance文件夹中的所有其他模块,该framework为开发人员提供标准库和工具类模块,它仍然在0x2命名的sui地址上。
- move-stdlib包含以前位于sui-framework/deps文件夹中,它仍然在0x1 命名的std地址上。
如果您依赖sui-framework开发代码库,包管理配置文件Move.toml必须更改路径地址:
发布V0.28版本之前
[package]
name = “Example”
version = “0.0.1”
published-at = “0x42”[dependencies]
Sui = { git = “.git", subdir=”crates/sui-framework/”, rev = “devnet” }[addresses]
example = “0x42”
发布V0.28版本之后
[package]
name = “Example”
version = “0.0.1”
published-at = “0x42”[dependencies]
Sui = { git = “.git", subdir=”crates/sui-framework/packages/sui-framework/”, rev = “devnet” }[addresses]
example = “0x42”
就是subdir字段修改成crates/sui-framework/packages/sui-framework/
如果您的代码使用governance文件夹中如下的模块:
genesis.move、sui_system.move、validator_cap.move、voting_power.move、stake_subsidy.move、sui_system_state_inner.move、validator_set.move、staking_pool.move、validator.move或者validator_wrapper.move
这些模块现在位于sui-system包中,您必须将SuiSystem列为依赖项,并通过0x3或sui_system命名地址来访问它们。
ecdsa_k1 ecrecover和secp256k1_verify#
在这个版本中,ecdsa_k1::ecrecover和ecdsa_k1::secp256k1_verify要求用户输入原始信息而不是哈希后的信息
- ecdsa_k1::ecrecover(sig, hashed_msg, hash_function) ,升级成:ecdsa_k1::secp256k1_ecrecover(sig, msg, hash_function)
- ecdsa_k1::secp256k1_verify(sig, pk, hashed_msg),升级成:ecdsa_k1::secp256k1_verify(sig, pk, msg, hash_function)
当您调用这些 API 时,必须提供原始信息而不是哈希后的信息用于verify或ecrevover。 您还必须提供由u8数组表示的hash_function名称。 有关详细信息,请参阅源代码:
- ecdsa_k1.md
- ecdsa_r1.md
ID不能构造传入#
当您建立一个object时,UID必须使用未被注册过的,也就是UID必须来自object::new(或用于测试的test_scenario::new_object)。 想要迁移已有的项目,之前将UID作为参数来构造object的任何函数现需要用TxContext来生成新的ID。
例如,在V0.28之前的版本中,创建一个object代码:
fun new(id: UID): Counter {Counter { id, count: 0 }
}
而在V0.28版本中,创建一个object代码:
fun new(ctx: &mut TxContext): Counter {Counter { id: object::new(ctx), count: 0 }
}
Publisher#
Publisher增加了一个重要的补充性功能,即Publisher object现在需要的OTW(一次性见证者),可以通过sui::package::claim调用在package内的任何模块来实现:
module example::dummy {use sui::package;use sui::tx_context::TxContext;
struct DUMMY has drop {}
fun init(otw: DUMMY, ctx: &mut TxContext) {// creates a Publisher object and sends to the `sender`package::claim_and_keep(otw, ctx)}
}
要了解更多有关Publisher的信息,请参阅Publisher。
Sui Object Display 标准#
这个版本包含了Sui Object Display 标准,是一种使用通用模板来描述类型object的新方式,使其链下展示更标准,RPC API已经支持该新标准。
想要获取更详细的描述和标准制定的动机,请参阅Sui Object Display提案。
在Sui Move中, 可以通过调用display::new<T>(&Publisher)来claim Display object。函数签名中规定,需要用到Publisher object。Display claim后,可以通过向其添加新字段(模板)来修改Display。当object准备好发布时,需要调用display::update_version(&mut Display)来发布并使其可用,每当添加/编辑Display应当再次调用update_version来声明已经更新。
我们建议在Display中使用的字段如下:
- name:显示的名称
- link:对象的app链接/外部链接
- description:描述信息
- image_url:图片的URL或者blob类型的图片
- project_url:网站的链接
- creator:以任何方式提及创作者(文本、链接、地址等)
请在Display中查阅其他信息和示例。
API和SDK更新#
本节将介绍Sui API和SDK更新后的相关内容。
读取objects#
sui_getObject端点现在采用一种附加配置参数的方法SuiObjectDataOptions来控制端点检索字段的类型。默认情况下,端点仅检索object的引用,除非客户端请求时明确指定其他数据,例如type、owner或者bcs数据类型。
TypeScript迁移#
import { JsonRpcProvider } from “@mysten/sui.js”;
const provider = new JsonRpcProvider();
// Prior to release .28
const txn = await provider.getObject(“0xcff6ccc8707aa517b4f1b95750a2a8c666012df3”
);
const txns = await provider.getObjectBatch([“0xcff6ccc8707aa517b4f1b95750a2a8c666012df3”,“0xdff6ccc8707aa517b4f1b95750a2a8c666012df3”,
]);
// Updated for release .28
const txn = await provider.getObject({id: “0xcff6ccc8707aa517b4f1b95750a2a8c666012df3”,// fetch the object content field and displayoptions: {showContent: true,showDisplay: true,},
});
const txns = await provider.multiGetObjects({ids: [“0xcff6ccc8707aa517b4f1b95750a2a8c666012df3”,“0xdff6ccc8707aa517b4f1b95750a2a8c666012df3”,],// only fetch the object typeoptions: { showType: true },
});
JSON RPC迁移#
# Prior to release .28curl — location — request POST ‘:443' \— header ‘Content-Type: application/json’ \— data-raw ‘{“jsonrpc”: “2.0”,“id”: 1,“method”: “sui_getObject”,“params”: {“object_id”: “0x08240661f5504c9bb4a487d9a28e7e9d6822abf692801f2a750d67a44d0b2340”,}}’
# Updated for release .28
curl — location — request POST ‘:443' \— header ‘Content-Type: application/json’ \— data-raw ‘{“jsonrpc”: “2.0”,“id”: 1,“method”: “sui_getObject”,“params”: {“object_id”: “0x08240661f5504c9bb4a487d9a28e7e9d6822abf692801f2a750d67a44d0b2340”,“options”: {“showContent”: true,“showOwner”: true,}}}’
# If you use sui_getRawObject, enable the showBcs option to retrieve itcurl — location — request POST ‘:443' \— header ‘Content-Type: application/json’ \— data-raw ‘{“jsonrpc”: “2.0”,“id”: 1,“method”: “sui_getObject”,“params”: {“object_id”: “0x08240661f5504c9bb4a487d9a28e7e9d6822abf692801f2a750d67a44d0b2340”,“options”: {“showBcs”: true}}}’
Display#
要获取object的Display ,请将附加标志传递给sui_getObject调用。
{showDisplay: true;
}
返回值是某个类型的处理模板,例如,对于Sui Capys,它可以为:
{“name”: “Capy — one of many”,“description”: “Join our Capy adventure”,“link”: “/capy/0x00000000....",“image_url”: “/capys/0x000adadada..../svg",“project_url”: “/",“creator”: “Capybara Lovers”
}
读交易#
sui_getTransactionBlock和sui_multiGetTransaction函数现在新增一个可选参数options。使用options指定要检索的字段,例如交易、变动或事件。 默认情况下,它只返回交易签名。
import { JsonRpcProvider } from “@mysten/sui.js”;
const provider = new JsonRpcProvider();
// Prior to release .28
const provider = new JsonRpcProvider();
const txn = await provider.getTransactionWithEffects(“6mn5W1CczLwitHCO9OIUbqirNrQ0cuKdyxaNe16SAME=”
);
// You can also fetch multiple transactions in one batch request
const txns = await provider.getTransactionWithEffectsBatch([“6mn5W1CczLwitHCO9OIUbqirNrQ0cuKdyxaNe16SAME=”,“7mn5W1CczLwitHCO9OIUbqirNrQ0cuKdyxaNe16SAME=”,
]);
// Updated for release .28
const provider = new JsonRpcProvider();
const txn = await provider.getTransactionBlock({digest: “6mn5W1CczLwitHCO9OIUbqirNrQ0cuKdyxaNe16SAME=”,// only fetch the effects fieldoptions: { showEffects: true },
});
// You can also fetch multiple transactions in one batch request
const txns = await provider.multiGetTransactionBlocks({digests: [“6mn5W1CczLwitHCO9OIUbqirNrQ0cuKdyxaNe16SAME=”,“7mn5W1CczLwitHCO9OIUbqirNrQ0cuKdyxaNe16SAME=”,],// fetch both the input transaction data as well as effectsoptions: { showInput: true, showEffects: true },
});
读事件#
此版本对读事件进行了以下更新:
- 删除系统事件,例如Publish、TransferObject、NewObject,只保留 MoveEvents
- 在SuiTransactionResponse中添加了object_changes和balance_changes字段
import { JsonRpcProvider } from “@mysten/sui.js”;
const provider = new JsonRpcProvider();
// Prior to release .28
provider.getEvents({ Sender: toolbox.address() }, null, 2);
// Updated for release .28
const events = provider.queryEvents({query: { Sender: toolbox.address() },limit: 2,
});
// Subscribe events
// Prior to release .28
const subscriptionId = await provider.subscribeEvent({ SenderAddress: “0xbff6ccc8707aa517b4f1b95750a2a8c666012df3” },(event: SuiEventEnvelope) => {// handle subscription notification message here. This function is called once per subscription message.}
);
// later, to unsubscribe
// calls RPC method ‘sui_unsubscribeEvent’ with params: [ subscriptionId ]
const subFoundAndRemoved = await provider.unsubscribeEvent(subscriptionId);
// Updated for release .28
// calls RPC method ‘sui_subscribeEvent’ with params:
// [ { Sender: ‘0xbff6ccc8707aa517b4f1b95750a2a8c666012df3’ } ]
const subscriptionId = await provider.subscribeEvent({filter: { Sender: “0xbff6ccc8707aa517b4f1b95750a2a8c666012df3” },onMessage(event: SuiEvent) {// handle subscription notification message here. This function is called once per subscription message.},
});
// later, to unsubscribe
// calls RPC method ‘sui_unsubscribeEvent’ with params: [ subscriptionId ]
const subFoundAndRemoved = await provider.unsubscribeEvent({id: subscriptionId,
});
分页#
此版本更新了分页的定义。
发布V0.28版本之前
pub struct Page<T, C> {pub data: Vec<T>,pub next_cursor: Option<C>,}
发布V0.28版本之后
pub struct Page<T, C> {pub data: Vec<T>,pub next_cursor: Option<C>,pub has_next_page: bool,}
备注:next_cursor现在不会有Null值了,如果data不为空,它总是指向最后一项数据;要检查当前页面是否是最后一页,现在您可以简单地使用has_next_page,而不是执行next_cursor.is_none()。
如果使用Page是一页一页的读取,现在读取到最新一页时,无需手动处理next_cursor返回的None值,而是可以一直使用返回的next_cursor作为读取下一页的输入参数。在此版本之前,读取过程将从头开始直到结束,并且没有正确处理None值。
构建和执行交易#
Signer和SignableTransaction接口之前的transaction builder方法已被删除,并替换为新的Transaction builder类。这个新的transaction builder充分利用了Programmable Transactions优点。
// Construct a new transaction:
const tx = new Transaction();
// Example replacement for a SUI token transfer:
const [coin] = tx.splitCoins(tx.gas, [tx.pure(1000)]);
tx.transferObjects([coin], tx.pure(keypair.getPublicKey().toSuiAddress()));
// Merge a list of coins into a primary coin:
tx.mergeCoin(tx.object(“0xcoinA”), [tx.object(“0xcoinB”),tx.object(“0xcoinC”),
]);
// Make a move call:
tx.moveCall({target: `${packageObjectId}::nft::mint`,arguments: [tx.pure(“Example NFT”)],
});
// Execute a transaction:
const result = await signer.signAndExecuteTransaction({ transaction: tx });
交易现在支持列表中提供的硬币作为交易时gas的支付。 默认情况下,transaction builder会自动计算gas和选择硬币用于支付。当然你还可以选择设置这些值,例如设置预算、更改gas价格或gas支付选择:
// Set an explicit gas price. By default, uses the current reference gas price:
tx.setGasPrice(100);
// Change the gas budget (in SUI). By default, this executes a dry run and uses the gas consumed from that as the budget.
tx.setGasBudget(customBudgetDefined);
// Set the vector of gas objects to use as the gas payment.
tx.setGasPayment([coin1, coin2]);
质押更新#
本节将介绍与Sui质押更新相关的内容。
解除用于质押锁定的 Coin#
此版本之前,用户可以将其Coin<SUI>或LockedCoin<SUI>质押给验证节点,此版本更新后,取消了对用于质押锁定Coin的支持,因此质押功能现只支持Coin<SUI>。
更新质押Sui object布局#
在此版本之前,质押的Sui结构具有以下定义:
struct StakedSui has key {id: UID,/// The validator we are staking with.validator_address: address,/// The epoch at which the staking pool started operating.pool_starting_epoch: u64,/// The epoch at which the delegation is requested.delegation_request_epoch: u64,/// The staked SUI tokens.principal: Balance<SUI>,/// If the stake comes from a Coin<SUI>, this field is None. If it comes from a LockedCoin<SUI>, this/// field will record the original lock expiration epoch, to be used when unstaking.sui_token_lock: Option<EpochTimeLock>,}
随着对用于质押锁定Coin的移除以及Sui质押流程的改变,新的结构定义为:
struct StakedSui has key {id: UID,/// ID of the staking pool we are staking with.pool_id: ID,/// The validator we are staking with.validator_address: address,/// The epoch at which the stake becomes active.stake_activation_epoch: u64,/// The staked SUI tokens.principal: Balance<SUI>,}
存入/取出质押API的更新#
此版本包括以下与存入/取出质押请求相关的更新:
- 移除request_switch_delegation函数
- 重命名所有委托功能以使用“质押”而不是“委托”
在V0.28版本之前,函数名称为:
/// Add delegated stake to a validator’s staking pool using multiple coins and amount.#[method(name = “requestAddDelegation”)]async fn request_add_delegation(&self,/// the transaction signer’s Sui addresssigner: SuiAddress,/// Coin<SUI> or LockedCoin<SUI> object to delegatecoins: Vec<ObjectID>,/// delegation amountamount: Option<u64>,/// the validator’s Sui addressvalidator: SuiAddress,/// gas object to be used in this transaction, node will pick one from the signer’s possession if not providedgas: Option<ObjectID>,/// the gas budget, the transaction will fail if the gas cost exceed the budgetgas_budget: u64,) -> RpcResult<TransactionBlockBytes>;/// Withdraw a delegation from a validator’s staking pool.#[method(name = “requestWithdrawDelegation”)]async fn request_withdraw_delegation(&self,/// the transaction signer’s Sui addresssigner: SuiAddress,/// Delegation object IDdelegation: ObjectID,/// StakedSui object IDstaked_sui: ObjectID,/// gas object to be used in this transaction, node will pick one from the signer’s possession if not providedgas: Option<ObjectID>,/// the gas budget, the transaction will fail if the gas cost exceed the budgetgas_budget: u64,) -> RpcResult<TransactionBlockBytes>;/// Switch delegation from the current validator to a new one.#[method(name = “requestSwitchDelegation”)]async fn request_switch_delegation(&self,/// the transaction signer’s Sui addresssigner: SuiAddress,/// Delegation object IDdelegation: ObjectID,/// StakedSui object IDstaked_sui: ObjectID,/// Validator to switch tonew_validator_address: SuiAddress,/// gas object to be used in this transaction, node will pick one from the signer’s possession if not providedgas: Option<ObjectID>,/// the gas budget, the transaction will fail if the gas cost exceed the budgetgas_budget: u64,) -> RpcResult<TransactionBlockBytes>;
从V0.28版本开始生效,函数名称为:
/// Add stake to a validator’s staking pool using multiple coins and amount.#[method(name = “requestAddStake”)]async fn request_add_stake(&self,/// the transaction signer’s Sui addresssigner: SuiAddress,/// Coin<SUI> object to stakecoins: Vec<ObjectID>,/// stake amountamount: Option<u64>,/// the validator’s Sui addressvalidator: SuiAddress,/// gas object to be used in this transaction, node will pick one from the signer’s possession if not providedgas: Option<ObjectID>,/// the gas budget, the transaction will fail if the gas cost exceed the budgetgas_budget: u64,) -> RpcResult<TransactionBlockBytes>;/// Withdraw stake from a validator’s staking pool.#[method(name = “requestWithdrawStake”)]async fn request_withdraw_stake(&self,/// the transaction signer’s Sui addresssigner: SuiAddress,/// Delegation object IDdelegation: ObjectID,/// StakedSui object IDstaked_sui: ObjectID,/// gas object to be used in this transaction, node will pick one from the signer’s possession if not providedgas: Option<ObjectID>,/// the gas budget, the transaction will fail if the gas cost exceed the budgetgas_budget: u64,) -> RpcResult<TransactionBlockBytes>;
getDelegatedStakes的更新#
委托质押的函数(getDelegatedStakes )函数已重命名为getStakes, getStakes函数返回验证节点按质押池分组地址的所有质押,以及到目前为止获得的预估质押奖励。
{“jsonrpc”: “2.0”,“result”: [{“validatorAddress”: “0x8760b337dcb641811414daff8f98e6824caf7e5ca28530c4248557057ddc9004”,“stakingPool”: “0x628ffd0e51e9a6ea32c13c2739a31a8f344b557d3429e057b377a9c499b9bb13”,“stakes”: [{“stakedSuiId”: “0xa3cc3319d355dc92afee3669cd8f545de98c5ee380b6e1275b891bebdd82ad28”,“stakeRequestEpoch”: 3,“stakeActiveEpoch”: 4,“principal”: 99999999998977,“status”: “Active”,“estimatedReward”: 998}]},{“validatorAddress”: “0x6b34f8d6d70676db526017b03ec35f8f74ec67ee10426e2a3049a42045c90913”,“stakingPool”: “0xd5d9aa879b78dc1f516d71ab979189086eff752f65e4b0dea15829e3157962e1”,“stakes”: [{“stakedSuiId”: “0x5ee438610276e8fcfe0c0615caf4a2ca7c408569f47c5a622be58863c35b357b”,“stakeRequestEpoch”: 2,“stakeActiveEpoch”: 3,“principal”: 100000000000000,“status”: “Active”,“estimatedReward”: 1998},{“stakedSuiId”: “0x9eac8bd615977f8d635dc2054d13c463829161be41425d701ba8f9a444ca69e9”,“stakeRequestEpoch”: 5,“stakeActiveEpoch”: 6,“principal”: 100000000000000,“status”: “Pending”}]}],“id”: 1}
增加getStakesByIds函数#
新的getStakesByIds函数,可以使用已质押的SUI IDs数组查询委托的质押。 该函数返回验证节点按质押池分组地址的所有质押,以及到目前为止获得的预估质押奖励。
Secp256k1导出密钥对#
在函数签名上将Secp256k1.deriveKeypair与Ed25519进行匹配,以接受助记词字符串和可选路径字符串,而不是必需的路径字符串和助记符字符串。有关详细信息,请参阅PR 8542。
关于 Sui Network
Sui是基于第一原理重新设计和构建而成的L1公有链,旨在为创作者和开发者提供能够承载Web3中下一个十亿用户的开发平台。Sui上的应用基于Move智能合约语言,并具有横向可扩展性,让开发者能够快速且低成本支持广泛的应用开发。获取更多信息:
官网|Twitter|Discord|英文电报群|中文电报群
更多推荐
Sui V0.28 + V0.29版本迁移指南
发布评论