# SUI+Move快速上手 **Published by:** [lolieatapple](https://paragraph.com/@lolieatapple-2/) **Published on:** 2022-11-02 **URL:** https://paragraph.com/@lolieatapple-2/sui-move ## Content Sui Move,一切以对象为核心。 官方文档: https://docs.sui.io/build 开发文档: https://examples.sui.io/1. 安装sui cli命令行工具$ cargo install --locked --git https://github.com/MystenLabs/sui.git --branch devnet sui sui-node 2. 初始化测试环境,创建本地测试地址$ sui client $ sui client addresses 可以看到,sui的地址长度与以太坊相同,都是20个字节,与Aptos不同。3. 安装sui浏览器插件钱包在插件钱包页面上申请测试币。 https://chrome.google.com/webstore/detail/sui-wallet/opcgpfmipidbgpenhmajoajpbobppdilrequest devnet sui token在sui浏览器中查看钱包地址信息: https://explorer.devnet.sui.io/addresses/0xdd36d012f391deb5cbf56a54285ac8f735b2736b 在sui app页面可以测试NFT mint。还有几款网页游戏和NFT市场可以体验。4. 命令行转账向命令行测试地址转账一些SUI,之后可以使用如下指令查看地址余额(不转账测试币的话命令查不到信息):$ sui client gas $ sui client objects 通过objects命令可以看到地址下数据对象信息,可以看到sui token默认的数据结构和地址是:0x2::coin::Coin<0x2::sui::SUI> 这里与Aptos不同。(Aptos是0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>,可以看到地址与数据类型均不同) 使用如下指令可以创建命令行新地址,新地址助记词在命令执行后展示,请自行备份。$ sui client new-address ed25519 SUI token默认的decimals是9,这里与Aptos默认是8不同。 SUI的每次转账都会为接收地址创建一个新的Coin对象,默认不会自动合并。这里与Aptos不同。 用户可以自己通过命令来拆分或合并objects。 在调用transfer转账时,必须有另一个object来支付gas费,才能将一个object转走。因此,我们可以总结一个命令行转账过程如下: 1)拆分ojbect,将想要转出的部分拆分出独立的object,剩余部分是另一个object; 2)将拆分好的object转给对方; 3)接收方可以根据需要,决定是否要合并接收到的object到自己现有的object。 这个合并和拆分的过程,看起来有点类似于BTC的UTXO。估计是为了提升TPS而做出的设计。5. 命令行调用Move代码$ sui client call --function transfer --module sui --package 0x2 --args 0x187f2af1f680bc1c9ae103dbcb28dc98b151c7fa 0xb5dede8f99c57266a221f1a88bc8cb71da6dd241 --gas-budget 1000 使用call指令,指定function名称,module名称,package地址和传入参数即可完成Move接口调用。 这里需要注意,这里即使是使用Move合约接口转账,依然需要有独立的object来支付gas费。与上一节转账时提到过程类似。 Object内容每次发生变更时,version号回自动加一。6. 开发Move代码新建一个工程目录:$ sui move new my_first_package sui的代码目录结构与Aptos相似:基础目录结构用户代码放在sources目录下,这里需要注意几点与Aptos不同: 1)框架库在sui::下面,标准库std::位置和内容与Aptos有所差别 2)module的默认初始化函数名和定义不同,sui是fun init(ctx: &mut TxContext), Aptos是:fun init_module(sender: &signer)sui的函数入口参数中没有默认的signer对象,sui的entry函数可以包含一个ctx: &mut TxContext对象作为函数的最后一个参数,另外参数只能传入owner为sender或shared的objectsui使用transfer::transfer的方式来转移对象,而不是Aptos的move_to一个object的owner既可以是一个地址,也可以是另一个object编译Move使用指令:$ sui move build (这里与Aptos不同,aptos用的是aptos move compile) 单元测试指令:$ sui move test 7. 部署sui代码官方文档: https://docs.sui.io/build/cli-client#publish-packages$ sui client publish --path $PATH_TO_PACKAGE/my_move_package --gas-budget 30000 部署完成后的合约默认是一个不可变更的对象(object)。部署过程中,会消耗gas费对象,生成合约对象和数据对象。8. Sui Move LibrarySui提供了一系列在Move中操作object的接口。 Sui中对象的ownership所有权限分为:owner为地址;owner为另一个对象;owner为shared and immutable, 即对象公开但不可再更改;owner为可shared and mutable, 对象公开并且任何人均可以更改;(未开发完成功能)操作object的接口包括:use sui::transfer; transfer::transfer(obj, recipient); transfer::transfer_to_object(obj, &mut owner); transfer::transfer_to_object_id(child, parent); transfer::transfer_child_to_object(child, child_ref, &mut new_parent); transfer::transfer_child_to_address(child, child_ref, recipient); transfer::freeze_object(obj); transfer::share_object(obj); Transaction Context:// assmue `ctx` has type `&mut TxContext`. let info = sui::object::new(ctx); sui::tx_context::sender(ctx) 9. 基础语法一个可以创建sui对象的结构体,第一个参数必须为id,并且定义key能力(key代表其具有全局索引的能力):use sui::object::UID; struct ColorObject has key { id: UID, red: u8, green: u8, blue: u8, } UID可以使用object::new(ctx)接口创建,其中ctx是entry类型函数参数可选自带的交易信息(只能是最后一个参数)。entry类型函数表示是可以被交易直接调用的函数。 使用transfer函数可以将object的owner转给对应的地址。每一个object必须有对应的owner,owner可以是一个地址,一个obj,或者shared。 因为Sui的全局对象存储在Move之外,因此不使用Move全局api语法。同时,单元测试的时候,也只能通过test_scenario来访问内部对象。 test_scenario的主要接口包括:test_scenario::begin test_scenario::next_tx test_scenario::ctx test_scenario::has_most_recent_for_sender test_scenario::take_from_sender test_scenario::return_to_sender object::id_from_address(tx_context::last_created_object_id(ctx)) test_scenario::take_from_sender_by_id test_scenario::take_immutable test_scenario::return_immutable ... 例如:let owner = @0x1; // Create a ColorObject and transfer it to @owner. let scenario_val = test_scenario::begin(owner); let scenario = &mut scenario_val; { let ctx = test_scenario::ctx(scenario); color_object::create(255, 0, 255, ctx); }; (大括号外面的分号是必须的) 在Sui中,只有Owner可以在交易中使用Object,不论是读或者写。 删除不用的Object可使用:public fun delete(id: UID) { ... } 在多个struct结构体互相包含时,子结构体需要具备store能力。 当一个对象被包装在另一个对象中时,子对象不能作为函数参数传递,除非将其转移出来完成解包。10. Sui Walletconst Permissions = ['viewAccount','suggestTransactions'] as const; // Check connection status of wallet const result = await window.suiWallet.requestPermissions(Permissions); const result = await window.suiWallet.mi(Permissions); const result = await window.suiWallet.getAccounts(); // Note interface MoveCallTransaction { packageObjectId: ObjectId; module: string; function: string; typeArguments: string[]; arguments: SuiJsonValue[]; gasPayment?: ObjectId; gasBudget: number; } // Sign transaction const result = await window.suiWallet.executeMoveCall(txs) // Sign transaction (with Serialized) const result = await window.suiWallet.executeSerializedMoveCall(tx.toString()) 11. SDKJavaScript SDK: https://github.com/MystenLabs/sui/tree/main/sdk/typescript/ ## Publication Information - [lolieatapple](https://paragraph.com/@lolieatapple-2/): Publication homepage - [All Posts](https://paragraph.com/@lolieatapple-2/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@lolieatapple-2): Subscribe to updates