一:功能简介
以学习、熟悉并在一定程度上实践动态(对象)字段而设计的一个简单的闲置买卖平台。
该平台允许任何人上架自己的闲置物品,除了名称、价格、库存等常规描述之外,还可以通过vector<String>
的形式将desc_name, desc_value
依次录入,同时也提供了对应的修改描述属性的功能;
对于尚未下架的闲置物品,任何人都可以查询在售清单,并通过event
的形式触发返回;
买家挑选好物品后,将不低于价格的Coin<SUI>
作支付,即可完成交易;
卖家可以随时下架在售物件,这一操作除了常规gas
消耗之外无任何其它费用产生。
二:结构设计
2.1 商品列表
每当有人上架闲置,就会通过dynamic_object_field
动态添加一个对象字段,通过对应的package_id
进行一对一,所以就需要一个vector
来存储ID
,除此之外,平台设计者会从每一笔成功交易的订单中抽成,所以存储其地址用作转账(当然,这里可以直接存Balance<SUI>
,再写一个只供Publisher
调用的提现函数也可以,不过类似的
O
n
e
\mathit {One}
One-
T
i
m
e
\mathit {Time}
Time-
W
i
t
n
e
s
s
\mathit {Witness}
Witness 并非本篇重点,且在之前的文章当中有过不止一次使用,这里就怎么方便怎么来了)。
public struct ProductList has key {
id: UID,
product_ids: vector<ID>,
publisher: address,
}
2.2 商品信息
跟上面类似,商品的详细描述通过dynamic_field
动态添加字段,为了跟动态内容相区分、比对其用法,这里将常规的物品名、价格和库存设为非动态添加的属性。
public struct ProductInfo has key, store {
id: UID,
name: String,
price: u64,
stock: u64,
desc_keys: vector<String>,
seller: address,
}
由于这一结构生成的对象是会存储到上面的商品列表中的,所以需要具有store
这一能力。
2.3 查询事件
在顾客查询在售列表时触发的事件,将每一个商品的ID
及其所有的描述整合成一个String
进行输出,具体的整合过程请看后续功能实现。
public struct ProductEvent has copy, drop {
product_id: ID,
product_detailed_infomation: String,
}
三:功能实现
3.1 初始化
需要init
的内容不多,唯有ProductList
,它并不独属于谁,而是一个所有人共享的对象,因为任何人都可以对该对象进行操作。
fun init(ctx: &mut TxContext) {
transfer::share_object(ProductList {
id: object::new(ctx),
product_ids: vector<ID>[],
publisher: ctx.sender(),
});
}
3.2 添加闲置物品
传入的vector<String>
需要进行一些约定,从前往后依次是第一个描述属性的title
和content
,然后是第二个…第三个…以此类推。
试想,如果有前端界面的话,上架一个商品,它的各个描述应该怎么填写?
产品名、价格、库存、颜色、产地、磨损程度等等项列举出来,再由卖家一一填写,当点击提交后,就可以将对应的内容处理成上面约定的形式进行链上调用。
有了这一约定,就只要依次处理描述项和具体的描述内容即可,通过dynamic_field
添加进去,最后别忘了将这一整个商品通过dynamic_object_field
添加到product_list
当中。
当然,在对应的结构当中,用来存储动态字段的对应值的数组也需要及时进行更新。
entry fun add_product(product_list: &mut ProductList, name: String, price: u64, stock: u64, description: vector<String>, ctx: &mut TxContext) {
// check
assert!(stock > 0, ENotAddZeroStockProduct);
assert!(description.length() % 2 == 0, ENotCorrectDescription);
// create product info
let mut product_info = ProductInfo {
id: object::new(ctx),
name,
price,
stock,
desc_keys: vector<String>[],
seller: ctx.sender(),
};
// dynamic field
let mut i = 0;
while (i < description.length()) {
let key = description[i];
i = i + 1;
let value = description[i];
i = i + 1;
product_info.desc_keys.push_back(key);
dynamic_field::add(&mut product_info.id, key, value);
};
// dynamic object field
let product_id = object::id(&product_info);
product_list.product_ids.push_back(product_id);
dynamic_object_field::add(&mut product_list.id, product_id, product_info);
}
3.3 查看商品列表
遍历product_ids
,将每一件商品都进行处理并输出,其关键是如何将描述整合成一个String
,尤其是还存在着u64
数据的情况下。
首先,std::string
当中存在着拼接函数append
和append_utf8
,功能是将一个字符串或者vector<u8>
内容转成字符串再接到另一个字符串后面,换行就可以通过str.append_utf8(b"\n")
进行实现。
其次,一个数字如何转换成字符串?
M
o
v
e
\mathit {Move}
Move 似乎暂时并没有提供这一功能,但我们可以自己简单进行实现,每一次都通过
%
10
\% \text {10}
%10 来取出这个整数的最后一位,将其累加到字符
0
\text 0
0 的
b
y
t
e
\mathit {byte}
byte 值上,当这个整数为零时就处理完了这个数,最后将得到的这一系列
b
y
t
e
\mathit {byte}
byte 倒转过来再转换成字符串即可。
具体的实现如下:
fun splicing(info: &mut String, key: String, value: String) {
info.append_utf8(b"\n");
info.append(key);
info.append_utf8(b": ");
info.append(value);
info.append_utf8(b"\n");
}
fun num_to_string(mut num: u64): String {
let mut byte_num = vector<u8>[];
while (num > 0) {
byte_num.push_back(b"0"[0] + ((num % 10) as u8));
num = num / 10;
};
byte_num.reverse();
string::utf8(byte_num)
}
entry fun query_product_list(product_list: &ProductList) {
let mut i = 0;
let product_ids = &product_list.product_ids;
while (i < product_ids.length()) {
// get product id
let product_id = product_ids[i];
i = i + 1;
// get product info
let product_info: &ProductInfo = dynamic_object_field::borrow(&product_list.id, product_id);
// init product detailed infomation
let mut product_detailed_infomation = string::utf8(b"");
// name, price, stock
splicing(&mut product_detailed_infomation, string::utf8(b"name"), product_info.name);
splicing(&mut product_detailed_infomation, string::utf8(b"price"), num_to_string(product_info.price));
splicing(&mut product_detailed_infomation, string::utf8(b"stock"), num_to_string(product_info.stock));
// dynamic field desc
let mut j = 0;
let desc_keys = &product_info.desc_keys;
while (j < desc_keys.length()) {
// get key
let key = desc_keys[j];
j = j + 1;
// get value
let value: String = *dynamic_field::borrow(&product_info.id, key);
splicing(&mut product_detailed_infomation, key, value);
};
// emit event
event::emit(ProductEvent {
product_id,
product_detailed_infomation,
});
};
}
3.4 修改商品详情
非动态的描述字段这里就不赘述了,主要是如何修改动态的字段,首先需要将其取出来,以可变引用的形式,通过dynamic_object_field::borrow_mut
和dynamic_field::borrow_mut
,再将其解引用*
得到具体的值然后更新。
当然,这里传入的vector<String>
也需要满足上面的约定,如果是一个新的描述内容,则别忘记更新desc_keys
。
entry fun modify_dynamic(product_id: ID, product_list: &mut ProductList, description: vector<String>, ctx: &TxContext) {
// check exist_
assert!(dynamic_object_field::exists_(&product_list.id, product_id), ENotCorrectProductID);
// get product info
let product_info: &mut ProductInfo = dynamic_object_field::borrow_mut(&mut product_list.id, product_id);
// check permission
assert!(product_info.seller == ctx.sender(), ENotPermissionToModify);
// check desc
assert!(description.length() % 2 == 0, ENotCorrectDescription);
// modify or add new desc
let mut i = 0;
while (i < description.length()) {
let key = description[i];
i = i + 1;
let value = description[i];
i = i + 1;
if (dynamic_field::exists_(&product_info.id, key)) {
*dynamic_field::borrow_mut(&mut product_info.id, key) = value;
} else {
product_info.desc_keys.push_back(key);
dynamic_field::add(&mut product_info.id, key, value);
};
};
}
3.5 购买
购买的逻辑很简单,主要是货币的判断和转移,这在之前的文章当中已经运用过很多次,除此之外,别忘记购买成功后库存减一,当其减到 0 \text 0 0 的时候,直接将其下架。
entry fun buy(product_id: ID, product_list: &mut ProductList, mut pay: Coin<SUI>, ctx: &mut TxContext) {
// check exist_
assert!(dynamic_object_field::exists_(&product_list.id, product_id), ENotCorrectProductID);
// get product info
let product_info: &mut ProductInfo = dynamic_object_field::borrow_mut(&mut product_list.id, product_id);
// check price amount
assert!(pay.value() >= product_info.price, ENotEnoughPayCoin);
// split accurate coin
let mut accurate_coin = pay.split(product_info.price, ctx);
// deal with the remaining coin
if (pay.value() > 0) {
transfer::public_transfer(pay, ctx.sender());
} else {
pay.destroy_zero();
};
// 1% fee to the publisher
if (product_info.price / 100 > 0) {
transfer::public_transfer(accurate_coin.split(product_info.price / 100, ctx), product_list.publisher);
};
// pay accurate coin
transfer::public_transfer(accurate_coin, product_info.seller);
// update stock
product_info.stock = product_info.stock - 1;
// sold out and removed from shelves
if (product_info.stock == 0) {
destroy_product(product_id, product_list, ctx);
};
}
3.6 下架闲置物品
涉及到动态(对象)字段删除,记得删干净,容易忘记的是product_ids
和desc_keys
当中对应值的清理。
entry fun destroy_product(product_id: ID, product_list: &mut ProductList, ctx: &TxContext) {
// check exist_
let (has_id, index) = product_list.product_ids.index_of(&product_id);
assert!(has_id, ENotCorrectProductID);
// remove
product_list.product_ids.remove(index);
// remove and get product info
let mut product_info: ProductInfo = dynamic_object_field::remove(&mut product_list.id, product_id);
// check permission
assert!(product_info.stock == 0 || product_info.seller == ctx.sender(), ENotPermissionToDestroy);
// remove dynamic field
while (product_info.desc_keys.length() > 0) {
let key = product_info.desc_keys.pop_back();
let _: String = dynamic_field::remove(&mut product_info.id, key);
};
// destroy ProductInfo
let ProductInfo {
id,
name: _,
price: _,
stock: _,
desc_keys,
seller: _,
} = product_info;
object::delete(id);
desc_keys.destroy_empty();
}
3.7 其它
完整代码可点击查看。
本篇内容仅针对动态(对象)字段的学习和简单使用,具体的设计与测试逻辑可能还存在缺陷,如果你有兴趣可自行尝试完善。
四:部署与测试
4.1 上链
- 运行命令
sui client publish --gas-budget 100000000
- 重要输出
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x51d14122738441456c28b81175de663de099dd783944e99fdcbad1073e9d3b85 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::package::UpgradeCap │
│ │ Version: 28131935 │
│ │ Digest: D9zEE9bpEzfn3n74554ZbmqUArTk2wohb7ByqPYvVnqu │
│ └── │
│ ┌── │
│ │ ObjectID: 0xc7d28cb48c3fe92617c7ae7ff0d49d249a08cb0d3c8c5c2fecf529824ea46dc0 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductList │
│ │ Version: 28131935 │
│ │ Digest: DbGDofkchSpcmcyR4rigj5hkqsm4jXxK2v6TjSCcevfr │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 28131935 │
│ │ Digest: 4Xio36uvSATQ3oSmK1CrTBX2oofgA1s5YPuATu73k7oh │
│ └── │
│ Published Objects: │
│ ┌── │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Version: 1 │
│ │ Digest: Bp8mer7fouySLDpECsVkS1hy7aiXPTvWevtwfM67Tivp │
│ │ Modules: second_hand_trading_platform │
│ └── │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
- 设置环境变量
export PACKAGE=0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24
export PRODUCTLIST=0xc7d28cb48c3fe92617c7ae7ff0d49d249a08cb0d3c8c5c2fecf529824ea46dc0
4.2 添加闲置物品
- 运行命令
sui client call --package $PACKAGE --module second_hand_trading_platform --function add_product --args $PRODUCTLIST testname 666 999 "["testdes1", "testdes2", "testdes3", "testdes4"]" --gas-budget 100000000
- 重要输出
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x283917fde874adb49317f9bd8c4f2d2aee3ff534f5d0f4f0f2a89b3db6e5823e │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Object ID: ( 0xc7d28cb48c3fe92617c7ae7ff0d49d249a08cb0d3c8c5c2fecf529824ea46dc0 ) │
│ │ ObjectType: 0x2::dynamic_field::Field<0x2::dynamic_object_field::Wrapper<0x2::object::ID>, 0x2::object::ID> │
│ │ Version: 28131936 │
│ │ Digest: E2W1zxYPmAHwUZV9xXqaArzzUXqyJd1QN9Zm4Z9qQzvL │
│ └── │
│ ┌── │
│ │ ObjectID: 0xd748bd266d0c72d0614216e572046750f8b61482b487a637e2913e759117f9c0 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Object ID: ( 0x283917fde874adb49317f9bd8c4f2d2aee3ff534f5d0f4f0f2a89b3db6e5823e ) │
│ │ ObjectType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductInfo │
│ │ Version: 28131936 │
│ │ Digest: C72MpFdZJpN6rRWdX6RmRpMRTYLa8iFByNDL6GeR4Y9H │
│ └── │
│ ┌── │
│ │ ObjectID: 0xe00ab34acf37af586d928754cb9abacd618ae6d99ba47a1d29ee12cb604caf8c │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Object ID: ( 0xd748bd266d0c72d0614216e572046750f8b61482b487a637e2913e759117f9c0 ) │
│ │ ObjectType: 0x2::dynamic_field::Field<0x1::string::String, 0x1::string::String> │
│ │ Version: 28131936 │
│ │ Digest: 5emub5JhMeeBqN4ZNP4hFB7edB91eQVAVsNbzEav6Vjq │
│ └── │
│ ┌── │
│ │ ObjectID: 0xf047d1458118f1c7509f592d68135e8b7a2ab52b64bcb6def4e48e80e9849e86 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Object ID: ( 0xd748bd266d0c72d0614216e572046750f8b61482b487a637e2913e759117f9c0 ) │
│ │ ObjectType: 0x2::dynamic_field::Field<0x1::string::String, 0x1::string::String> │
│ │ Version: 28131936 │
│ │ Digest: G2qG6mjMhewjW8ff2XsJKAeaNuyFSbQsqhEyppKqs8MM │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 28131936 │
│ │ Digest: DJXmjCuekiZhxxR7KNaJnr3dUPMzHJe9PoPfnJZZRqap │
│ └── │
│ ┌── │
│ │ ObjectID: 0xc7d28cb48c3fe92617c7ae7ff0d49d249a08cb0d3c8c5c2fecf529824ea46dc0 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductList │
│ │ Version: 28131936 │
│ │ Digest: xNrL3udYAgwvLobLnJi8ffbC4zCpVYH4zkTkT1XUUTt │
│ └── │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
注意: 这里其实可以不用记录任何信息,因为都被保存进了ProductList
当中,后续可以随时进行查看,为了使查询事件更加明了,这里再添加一件商品sui client call --package $PACKAGE --module second_hand_trading_platform --function add_product --args $PRODUCTLIST testname 666 999 "["testdes8", "testdes7", "testdes6", "testdes5"]" --gas-budget 100000000
4.3 查看商品列表
- 运行命令
sui client call --package $PACKAGE --module second_hand_trading_platform --function query_product_list --args $PRODUCTLIST --gas-budget 100000000
- 重要输出
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: DusgDWLssUuNG7VwdWZ3UrYhwRMvt4AQe9aG8s54G2YN:0 │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Transaction Module: second_hand_trading_platform │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ EventType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │
│ │ │ product_detailed_infomation │ │ │
│ │ │ │ name: testname │ │
│ │ │ │ │ │
│ │ │ │ price: 666 │ │
│ │ │ │ │ │
│ │ │ │ stock: 999 │ │
│ │ │ │ │ │
│ │ │ │ testdes1: testdes2 │ │
│ │ │ │ │ │
│ │ │ │ testdes3: testdes4 │ │
│ │ │ │ │ │
│ │ ├─────────────────────────────┼────────────────────────────────────────────────────────────────────┤ │
│ │ │ product_id │ 0xd748bd266d0c72d0614216e572046750f8b61482b487a637e2913e759117f9c0 │ │
│ │ └─────────────────────────────┴────────────────────────────────────────────────────────────────────┘ │
│ └── │
│ ┌── │
│ │ EventID: DusgDWLssUuNG7VwdWZ3UrYhwRMvt4AQe9aG8s54G2YN:1 │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Transaction Module: second_hand_trading_platform │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ EventType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │
│ │ │ product_detailed_infomation │ │ │
│ │ │ │ name: testname │ │
│ │ │ │ │ │
│ │ │ │ price: 666 │ │
│ │ │ │ │ │
│ │ │ │ stock: 999 │ │
│ │ │ │ │ │
│ │ │ │ testdes8: testdes7 │ │
│ │ │ │ │ │
│ │ │ │ testdes6: testdes5 │ │
│ │ │ │ │ │
│ │ ├─────────────────────────────┼────────────────────────────────────────────────────────────────────┤ │
│ │ │ product_id │ 0x8d42df099deeb1a4bd1badaf60fe7752320a6a127c49bdc417010a2b388dcc9c │ │
│ │ └─────────────────────────────┴────────────────────────────────────────────────────────────────────┘ │
│ └── │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
假设我们后续将要操作的是第一个添加的商品,这里就对应的记录下它的product_id
:export PRODUCTID=0xd748bd266d0c72d0614216e572046750f8b61482b487a637e2913e759117f9c0
4.4 修改商品详情
- 运行命令
sui client call --package $PACKAGE --module second_hand_trading_platform --function modify_dynamic --args $PRODUCTID $PRODUCTLIST "["testdes1", "testdes13", "testdes11", "testdes10"]" --gas-budget 100000000
与添加类似,这里输出的内容其实都可以不用记录,我们通过查询命令进行查看:
- 运行命令
sui client call --package $PACKAGE --module second_hand_trading_platform --function query_product_list --args $PRODUCTLIST --gas-budget 100000000
- 重要输出
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: ALQuPd37XR9UWEyALJW3UxPcXAUCyCE9VWE5f9eWuDPx:0 │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Transaction Module: second_hand_trading_platform │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ EventType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │
│ │ │ product_detailed_infomation │ │ │
│ │ │ │ name: testname │ │
│ │ │ │ │ │
│ │ │ │ price: 666 │ │
│ │ │ │ │ │
│ │ │ │ stock: 999 │ │
│ │ │ │ │ │
│ │ │ │ testdes1: testdes13 │ │
│ │ │ │ │ │
│ │ │ │ testdes3: testdes4 │ │
│ │ │ │ │ │
│ │ │ │ testdes11: testdes10 │ │
│ │ │ │ │ │
│ │ ├─────────────────────────────┼────────────────────────────────────────────────────────────────────┤ │
│ │ │ product_id │ 0xd748bd266d0c72d0614216e572046750f8b61482b487a637e2913e759117f9c0 │ │
│ │ └─────────────────────────────┴────────────────────────────────────────────────────────────────────┘ │
│ └── │
│ ┌── │
│ │ EventID: ALQuPd37XR9UWEyALJW3UxPcXAUCyCE9VWE5f9eWuDPx:1 │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Transaction Module: second_hand_trading_platform │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ EventType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │
│ │ │ product_detailed_infomation │ │ │
│ │ │ │ name: testname │ │
│ │ │ │ │ │
│ │ │ │ price: 666 │ │
│ │ │ │ │ │
│ │ │ │ stock: 999 │ │
│ │ │ │ │ │
│ │ │ │ testdes8: testdes7 │ │
│ │ │ │ │ │
│ │ │ │ testdes6: testdes5 │ │
│ │ │ │ │ │
│ │ ├─────────────────────────────┼────────────────────────────────────────────────────────────────────┤ │
│ │ │ product_id │ 0x8d42df099deeb1a4bd1badaf60fe7752320a6a127c49bdc417010a2b388dcc9c │ │
│ │ └─────────────────────────────┴────────────────────────────────────────────────────────────────────┘ │
│ └── │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
不难发现,这个修改函数兼具了修改和新增的功能,与预期相符。
4.5 购买
- 记录Coin
sui client gas
# output:
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a │ 430473916 │ 0.43 │
│ 0x03335f68ff3616af7e000b113c56a5ad53e8e8209784ca0a5623f70997c8d948 │ 3182792690 │ 3.18 │
│ 0x8eb492cda5672e5b87541b744962f927b40b3e67119dc5ba437ee8dfb4785595 │ 1 │ 0.00 │
│ 0xd61fa7c67f44180f8987e9de59cae81e2b26215c6209e0a40bc782402344474d │ 99 │ 0.00 │
│ 0xf0d1ea4828fe7391b41b2b07cc8c4c5fd1831aee6b6a4e5195b236dea20fbde4 │ 666 │ 0.00 │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯
export COIN=0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a
- 运行命令
sui client call --package $PACKAGE --module second_hand_trading_platform --function buy --args $PRODUCTID $PRODUCTLIST $COIN --gas-budget 100000000
- 查询gas
sui client gas
# output:
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x01676de212960b0689245914312ac6be3b4d5cffa0cae91ef527441b894f746a │ 430473250 │ 0.43 │
│ 0x03335f68ff3616af7e000b113c56a5ad53e8e8209784ca0a5623f70997c8d948 │ 3179753230 │ 3.17 │
│ 0x678490e7c2b0a19f3ae1a528d96d408d3405f36c3585dd99f34ae7d08f52f4db │ 6 │ 0.00 │
│ 0x8eb492cda5672e5b87541b744962f927b40b3e67119dc5ba437ee8dfb4785595 │ 1 │ 0.00 │
│ 0xc75218afc3b460af0120cf2ac4463e63275558a6782f473d8eba7f09bf6e1223 │ 660 │ 0.00 │
│ 0xd61fa7c67f44180f8987e9de59cae81e2b26215c6209e0a40bc782402344474d │ 99 │ 0.00 │
│ 0xf0d1ea4828fe7391b41b2b07cc8c4c5fd1831aee6b6a4e5195b236dea20fbde4 │ 666 │ 0.00 │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯
由于这里的publisher
和seller
是同一个人,所以两笔收入都转入该账户(
1
%
\text 1\%
1% 的小费和剩余的支付金额),这里可以再一次查询商品列表,可以发现对应商品的库存减了一。
sui client call --package $PACKAGE --module second_hand_trading_platform --function query_product_list --args $PRODUCTLIST --gas-budget 100000000
# important output:
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: gsP2bTd74nwkswvcm5yqxtmTpuSBDeU7ymokaSFnep5:0 │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Transaction Module: second_hand_trading_platform │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ EventType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │
│ │ │ product_detailed_infomation │ │ │
│ │ │ │ name: testname │ │
│ │ │ │ │ │
│ │ │ │ price: 666 │ │
│ │ │ │ │ │
│ │ │ │ stock: 998 │ │
│ │ │ │ │ │
│ │ │ │ testdes1: testdes13 │ │
│ │ │ │ │ │
│ │ │ │ testdes3: testdes4 │ │
│ │ │ │ │ │
│ │ │ │ testdes11: testdes10 │ │
│ │ │ │ │ │
│ │ ├─────────────────────────────┼────────────────────────────────────────────────────────────────────┤ │
│ │ │ product_id │ 0xd748bd266d0c72d0614216e572046750f8b61482b487a637e2913e759117f9c0 │ │
│ │ └─────────────────────────────┴────────────────────────────────────────────────────────────────────┘ │
│ └── │
│ ┌── │
│ │ EventID: gsP2bTd74nwkswvcm5yqxtmTpuSBDeU7ymokaSFnep5:1 │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Transaction Module: second_hand_trading_platform │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ EventType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │
│ │ │ product_detailed_infomation │ │ │
│ │ │ │ name: testname │ │
│ │ │ │ │ │
│ │ │ │ price: 666 │ │
│ │ │ │ │ │
│ │ │ │ stock: 999 │ │
│ │ │ │ │ │
│ │ │ │ testdes8: testdes7 │ │
│ │ │ │ │ │
│ │ │ │ testdes6: testdes5 │ │
│ │ │ │ │ │
│ │ ├─────────────────────────────┼────────────────────────────────────────────────────────────────────┤ │
│ │ │ product_id │ 0x8d42df099deeb1a4bd1badaf60fe7752320a6a127c49bdc417010a2b388dcc9c │ │
│ │ └─────────────────────────────┴────────────────────────────────────────────────────────────────────┘ │
│ └── │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
4.6 下架闲置物品
- 运行命令
sui client call --package $PACKAGE --module second_hand_trading_platform --function destroy_product --args $PRODUCTID $PRODUCTLIST --gas-budget 100000000
成功后再一次查询商品列表:
sui client call --package $PACKAGE --module second_hand_trading_platform --function query_product_list --args $PRODUCTLIST --gas-budget 100000000
# important output:
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: 6rzDuMDNZ7YV9eHtA9ng2cLRuCJximgscyxhqT7z38sh:0 │
│ │ PackageID: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24 │
│ │ Transaction Module: second_hand_trading_platform │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ EventType: 0x89ca58de7b8aaf6982badacbc748031986f2e4391a889daf074146030e0bce24::second_hand_trading_platform::ProductEvent │
│ │ ParsedJSON: │
│ │ ┌─────────────────────────────┬────────────────────────────────────────────────────────────────────┐ │
│ │ │ product_detailed_infomation │ │ │
│ │ │ │ name: testname │ │
│ │ │ │ │ │
│ │ │ │ price: 666 │ │
│ │ │ │ │ │
│ │ │ │ stock: 999 │ │
│ │ │ │ │ │
│ │ │ │ testdes8: testdes7 │ │
│ │ │ │ │ │
│ │ │ │ testdes6: testdes5 │ │
│ │ │ │ │ │
│ │ ├─────────────────────────────┼────────────────────────────────────────────────────────────────────┤ │
│ │ │ product_id │ 0x8d42df099deeb1a4bd1badaf60fe7752320a6a127c49bdc417010a2b388dcc9c │ │
│ │ └─────────────────────────────┴────────────────────────────────────────────────────────────────────┘ │
│ └── │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
第一个添加的商品已经被删除,符合预期。
五:加入组织,共同进步!
- Sui 中文开发群(TG)
- M o v e \mathit{Move} Move 语言学习交流群: 79489587