Dacade平台 SUI Move 挑战者合约实践 —— 物流公司(Logistics Company)
需要一个Balance<SUI>
来存储提成,所以该对象需要共享可变。<br>但是提现操作只能是创始人自己,因此通过 $\mathit {One}$-$\mathit {Time}$-$\mathit {Witness}$ 来创建一个Publisher
在后续调用时表明身份。
// Define ADMIN(one time witness) struct
struct ADMIN has drop {}
// Define Admin struct
struct Admin has key {
id: UID,
balance: Balance<SUI>,
}
公司的各项信息都应该透明,尤其是价格方面,所以该对象也应该是共享甚至是可变的,因为当顾客下单后,需要将物品相关信息暂存入公司。<br>类似的,收益提现以及由公司确认收货操作都需要公司管理者才有权限,因此再创建一个所有者为个人的凭证对象。
// Define CompanyCap struct
struct CompanyCap has key {
id: UID,
}
// Define Company struct
struct Company has key {
id: UID,
name: String,
price_per_hundred_grams: u64,
waiting_for_receipt: LinkedTable<ID, ItemInfo>,
can_be_cashed: Balance<SUI>,
all_profit: u64,
}
其中用到了LinkedTable
,这是一个通过 $\mathit {Key}$-$\mathit {Value}$ 存储的自带的数据结构,拥有头插,尾插,从头部取出,从尾部取出等功能,用来维护待确认收货的物流信息比较合适,具体可以点击查看源码。
顾客下单后会得到与公司相对应的快递单(通过公司的 $\mathit {ID}$ 进行对应),该快递单不对外公开,仅下单的顾客拥有。<br>同时生成相对应的信息,包括下单时期以及金额等。
// Define TransportItem struct
struct TransportItem has key {
id: UID,
logistics_company: String,
company_id: ID,
weight: u64,
price: u64,
}
// Define ItemInfo struct
struct ItemInfo has store {
epoch: u64,
transport_price: Balance<SUI>,
}
在发布该合约的时候自动调用的init
函数当中,通过只能在这里使用的 $\mathit {One}$-$\mathit {Time}$-$\mathit {Witness}$ 来创建Publisher
,并将其拥有权递交给发布者。<br>同时,在该函数当中,创建一个共享可变的Admin
,用作各大公司提现时获取提成的账户。
// Function to init the publisher and admin
fun init(otw: ADMIN, ctx: &mut TxContext) {
// create Publisher and transfer it to the sender
package::claim_and_keep(otw, ctx);
// create Admin and share it with all users
transfer::share_object(Admin {
id: object::new(ctx),
balance: balance::zero(),
});
}
通过Publisher
确认身份,当Admin
当中的抽成大于零的时候可以对其进行提现(将 $\mathit {SUI}$ 的 $\mathit {balance}$ 包装成 $\mathit {Coin}$ 发送给平台创始人)。
// Function to withdraw(only the publisher can withdraw)
public entry fun withdraw(_publisher: &Publisher, admin: &mut Admin, ctx: &mut TxContext) {
// get the value amount
let amount = balance::value(&admin.balance);
// it's necessary to make sure the amount > 0
assert!(amount > 0, ERROR_NOT_BALANCE);
// transfer the coin with the all balance to the sender
transfer::public_transfer(coin::take(&mut admin.balance, amount, ctx), tx_context::sender(ctx));
}
不仅要根据信息创建公开的Company
,还需要创建仅创建者持有的CompanyCap
用作后续的身份凭证(在这里的功能效果类似于上面的Publisher
)。
// Function to create company
public entry fun create_company(name: String, price_per_hundred_grams: u64, ctx: &mut TxContext) {
// create CompanyCap and transfer it to the sender
// this is a testament to the company's managers
transfer::transfer(CompanyCap {
id: object::new(ctx),
}, tx_context::sender(ctx));
// create Company and share it with all users
transfer::share_object(Company {
id: object::new(ctx),
name,
price_per_hundred_grams,
waiting_for_receipt: linked_table::new<ID, ItemInfo>(ctx),
can_be_cashed: balance::zero(),
all_profit: 0,
});
}
只有下单后超过 $\text {15}$ 个周期的货物,公司有权进行确认收货
操作。<br>在此之前,我们先来明确一个隐性的条件,那就是每当有顾客下单,对应的信息被push_back
进linked_table
,其中所存储的epoch
是下单时的值,而下单
这个操作本身是有序的,时间也不可能乱序,所以在link_table
中所存储的信息,从前到后的epoch
理论上来说也应该是非严格递增的。<br>基于上述理论,在该函数当中,可以通过从前到后的循环进行,直到linked_table
为空或者front
不满足epoch
条件时跳出循环。<br>为了更清晰明了地演示一步步地取值过程,这里采用了loop
无限循环(要注意其跳出循环的条件,因为合约发布时并不能明确这是否是正确的),如果对取值以及数据之间调用比较熟悉的,可以直接将跳出循环的条件写在一起当做判决用while
。<br>当然,想要进行这一操作,需要你拥有对应公司的管理员权限,也就是CompanyCap
。
// Function to unconfirmed receipt items with confirmation epoch greater than 15
// Company managers can only confirm the company's transport items
public entry fun confirm_items(_company_cap: &CompanyCap, company: &mut Company, ctx: &mut TxContext) {
// get the now epoch
let now_epoch = tx_context::epoch(ctx);
// to be confirmed list
let items = &mut company.waiting_for_receipt;
// theoretically, the linked table is sorted according to epoch
// because when user call function, linked_table push_back, this is orderly in itself
loop {
// items need to be not empty
if (linked_table::is_empty(items)) break;
// linked_table::front -> &Option<Element>
// option::borrow -> &Element
// in this module, Element is ID
let key = *option::borrow(linked_table::front(items));
// linked_table::borrow -> &Value
// in this module, Value is ItemInfo
let transport_epoch = linked_table::borrow(items, key).epoch;
// the front item's epoch is longer than 15
if (transport_epoch + 15 >= now_epoch) break;
// pop the front and get the ItemInfo
let (_, item_info) = linked_table::pop_front(items);
// destroy ItemInfo and get the price
let ItemInfo {
epoch: _,
transport_price,
} = item_info;
// add to the all_profit
company.all_profit = company.all_profit + balance::value(&transport_price);
// add the profit
balance::join(&mut company.can_be_cashed, transport_price);
};
}
需要管理员权限CompanyCap
才可调用,这里的关键是需要取出 $\text 1\%$ 存入Admin
,由于 $\mathit {Move}$ 语言目前对浮点数的支持有限,所以这里平台创始人吃点亏,只抽取 $\lfloor \frac{\mathit{profit}}{\text{100}} \rfloor$。
// Function to cash
public entry fun cash(_company_cap: &CompanyCap, admin: &mut Admin, company: &mut Company, ctx: &mut TxContext) {
// get the amount of balance
let can_be_cashed = &mut company.can_be_cashed;
let amount = balance::value(can_be_cashed);
// check the amount
assert!(amount > 0, ERROR_NOT_BALANCE);
// admin profit: 1% of the balance
let admin_profit = balance::split(can_be_cashed, amount / 100);
// add to the admin balance
let admin_balance = admin::get_balance_mut(admin);
balance::join(admin_balance, admin_profit);
// the remaining amount belongs to the company
amount = balance::value(can_be_cashed);
transfer::public_transfer(coin::take(can_be_cashed, amount, ctx), tx_context::sender(ctx));
}
解构创建的与公司有关的对象,也就是CompanyCap
和Company
,注意,后者内部的LinkedTable
和Balance
都需要手动摧毁,如果其中不为空,则会报错,同时恢复到该交易之前的状态。
// Function to destroy company
public entry fun destroy_company(company_cap: CompanyCap, company: Company) {
// deconstruct the CompanyCap
let CompanyCap {id} = company_cap;
// delete the id
object::delete(id);
// deconstruct the Company
let Company {
id,
name: _,
price_per_hundred_grams: _,
waiting_for_receipt,
can_be_cashed,
all_profit: _,
} = company;
// delete the id
object::delete(id);
// destroy linked_table
linked_table::destroy_empty(waiting_for_receipt);
// destroy balance
balance::destroy_zero(can_be_cashed);
}
选择公司,提供物品重量,支付对应的金额(多退少报错),顾客得到仅自己可见的快递单,而对应的信息则存储入Company
当中的LinkedTable
,其中作为 $\mathit {Key}$ 的 $\mathit {ID}$ 取自对应的快递单,也就是TransportItem
。
// Function to create transport item
public entry fun create_item(company: &mut Company, weight: u64, sui: Coin<SUI>, ctx: &mut TxContext) {
// if the weight is less than 100g, it will be calculated as 100g
// in other words: weight / 100 rounded up multiply by price_per_hundred_grams
let price = (weight + 99) / 100 * company.price_per_hundred_grams;
// check enough price
assert!(coin::value(&sui) >= price, ERROR_NOT_ENOUGH_COIN);
// split the right price
let transport_price = coin::split(&mut sui, price, ctx);
// destroy or transfer the remaining coin to the owner
if (coin::value(&sui) == 0) {
coin::destroy_zero(sui);
} else {
transfer::public_transfer(sui, tx_context::sender(ctx));
};
// create TransportItem
let transport_item = TransportItem {
id: object::new(ctx),
logistics_company: company.name,
company_id: object::id(company), // corresponding company ID
weight,
price,
};
// get the ID through transport_item to achieve a one-on-one relationship
let id = object::id(&transport_item);
// create ItemInfo
let item_infomation = ItemInfo {
epoch: tx_context::epoch(ctx),
transport_price: coin::into_balance(transport_price),
};
// transfer the credentials to the user
transfer::transfer(transport_item, tx_context::sender(ctx));
// store the item_info to the company
linked_table::push_back(&mut company.waiting_for_receipt, id, item_infomation);
}
下单后不超过 $\text 3$ 个周期的订单才可以退款,而且TransportItem
当中的company_id
必须与退款公司相一致,当然,该订单必须存在且未被确认收货。
// Function to refunds if no more than 3 epoch
public entry fun refunds(transport_item: TransportItem, company: &mut Company, ctx: &mut TxContext) {
// check whether it corresponds to the company
assert!(transport_item.company_id == object::id(company), ERROR_NOT_ORDERED_COMPANY);
// get waiting_for_receipt
let waiting_for_receipt = &mut company.waiting_for_receipt;
// get the ID through transport_item
let id_key = object::id(&transport_item);
// determine whether it is the correct item or whether it is receipted
assert!(linked_table::contains(waiting_for_receipt, id_key), ERROR_NOT_ITEM_OR_RECEIPTED);
// must not exceed 3 epochs
assert!(linked_table::borrow(waiting_for_receipt, id_key).epoch + 3 >= tx_context::epoch(ctx), ERROR_NOT_REFUNDS);
// deconstruct the ItemInfo
let ItemInfo {
epoch: _,
transport_price,
} = linked_table::remove(waiting_for_receipt, id_key);
// get the balance amount
let amount = balance::value(&transport_price);
// refunds
transfer::public_transfer(coin::take(&mut transport_price, amount, ctx), tx_context::sender(ctx));
// destroy the zero balance
balance::destroy_zero(transport_price);
// destroy TransportItem
destroy_transport_item(transport_item);
}
通过TransportItem
到对应的Company
确认收货,成功后快递单将被销毁,而对应的款项将被转移到公司的账户。<br>如果该信息已经超过了 $\text {15}$ 个周期且物流公司确认收货了,那么此函数仅执行销毁快递单的操作。
// Function to confirm receipt by correct TransportItem
public entry fun confirm_receipt(transport_item: TransportItem, company: &mut Company) {
// check whether it corresponds to the company
assert!(transport_item.company_id == object::id(company), ERROR_NOT_ORDERED_COMPANY);
// get waiting_for_receipt
let waiting_for_receipt = &mut company.waiting_for_receipt;
// get the ID through transport_item
let id_key = object::id(&transport_item);
// determine whether it is the correct item or whether it is receipted
if (linked_table::contains(waiting_for_receipt, id_key)) {
// deconstruct the ItemInfo
let ItemInfo {
epoch: _,
transport_price,
} = linked_table::remove(waiting_for_receipt, id_key);
// add to the all_profit
company.all_profit = company.all_profit + balance::value(&transport_price);
// add the profit
balance::join(&mut company.can_be_cashed, transport_price);
};
// destroy TransportItem
destroy_transport_item(transport_item);
}
sui client publish --gas-budget 100000000
╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x64adbd96a562851de6dc79eeec7f5b8c173914aa667083693aa295f162deeb0d │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::package::Publisher │
│ │ Version: 81313247 │
│ │ Digest: H9BpBvmMayuLeGwbrtMXgmQiYVFT6LjscSiwpxaRp1jm │
│ └── │
│ ┌── │
│ │ ObjectID: 0xa9c37253c81a63606a697eb6d249790aac5443b2c9063fd61ea7a2072498e010 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::package::UpgradeCap │
│ │ Version: 81313247 │
│ │ Digest: H2b31NtMkE4PhtZ1e3VhjS5YqKH8HkpewgyYjHkpqUVT │
│ └── │
│ ┌── │
│ │ ObjectID: 0xd5785555e3c0d1745a502633353cf9aaad1b79d1fd04fb0fa4943bdea98006af │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::admin::Admin │
│ │ Version: 81313247 │
│ │ Digest: 5FPD5bwqPENjnH2TpmKw4pt2pgGyZprteSE5besGyAiC │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313247 │
│ │ Digest: 8RKM8DLrFPWMLFjaE4k5yNCvfbwXFfE57mJFxucUbLLw │
│ └── │
│ Published Objects: │
│ ┌── │
│ │ PackageID: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6 │
│ │ Version: 1 │
│ │ Digest: 8u1KT2dfoqfkFk7C5eoFVkMH7czoph4LoNsY8HupUHiY │
│ │ Modules: admin, company │
│ └── │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
export PACKAGE_ID=0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6
export PUBLISHER=0x64adbd96a562851de6dc79eeec7f5b8c173914aa667083693aa295f162deeb0d
export ADMIN=0xd5785555e3c0d1745a502633353cf9aaad1b79d1fd04fb0fa4943bdea98006af
sui client call --package $PACKAGE_ID --module company --function create_company --args NightCandle 100 --gas-budget 10000000
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0xbb83fb182eaaa0054dd465eb0f600056b0e81aa600b053b1577cf49ce0c54898 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::CompanyCap │
│ │ Version: 81313248 │
│ │ Digest: 7ZRmFTb4Xe2idgiw3PM5qMEUGGJ5ieg1xeEaepwoyRGZ │
│ └── │
│ ┌── │
│ │ ObjectID: 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::Company │
│ │ Version: 81313248 │
│ │ Digest: DZqQn4hw6koM6fjrKUYTDHe7TJnAfPbp7hP9jA93L3Lr │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313248 │
│ │ Digest: 2Z2CDce9ck99QwMT7UtqeAQK4Trr9iLgysnXqF4gjr37 │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯
export COMPANYCAP=0xbb83fb182eaaa0054dd465eb0f600056b0e81aa600b053b1577cf49ce0c54898
export COMPANY=0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2
sui client switch --address <alias>
sui client gas
export COIN=0xca1e96b358f722d601accc962d54460068244d4f7f75ee122d50e1132d25ee36
sui client call --package $PACKAGE_ID --module company --function create_item --args $COMPANY 1 $COIN --gas-budget 10000000
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x9128a11aae6362040052e943098e12d8a8e625a3fd164aa0772cdb7c6209c0f7 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Object ID: ( 0xfb39822d0d3883ed1a02d720ed6bc1f38a09b8c2b7ad33d00a466d28306860c5 ) │
│ │ ObjectType: 0x2::dynamic_field::Field<0x2::object::ID, 0x2::linked_table::Node<0x2::object::ID, 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::ItemInfo>> │
│ │ Version: 81313254 │
│ │ Digest: 3EzLVtMtZj88Q3JzqQU3SkARE6ZBLiwou7csLiJkATdT │
│ └── │
│ ┌── │
│ │ ObjectID: 0xcc9581fae40a69c7e8681a0f497a900a38cc1379abf420039a2ce783a0d9cb28 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b ) │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::TransportItem │
│ │ Version: 81313254 │
│ │ Digest: EAtDCZAR8vZiAZ7FWy4bTU2kQn7KUYnT8uRSeUH6bdpQ │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0xa5e9cc06d7bfb34b49fd2f6631e0580129fa8124a36030ae5107ebf785fca37c │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313254 │
│ │ Digest: J9w5dNToKgigdoc3VtM5KucRKbMZkyVzqM4cuLeLBUDm │
│ └── │
│ ┌── │
│ │ ObjectID: 0xca1e96b358f722d601accc962d54460068244d4f7f75ee122d50e1132d25ee36 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313254 │
│ │ Digest: 97oxDW1DDton7k1S81HgkoC9rexw7YGvUDXw1aMGKjXd │
│ └── │
│ ┌── │
│ │ ObjectID: 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::Company │
│ │ Version: 81313254 │
│ │ Digest: 5hTdm7unYsfMEiopZwHwDDanfvEDwW2cSaY8GtvA462D │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
export TRANSPORTITEM=0xcc9581fae40a69c7e8681a0f497a900a38cc1379abf420039a2ce783a0d9cb28
sui client gas
sui client call --package $PACKAGE_ID --module company --function create_item --args $COMPANY 999 $COIN --gas-budget 10000000
export TRANSPORTITEM999=0x73a317b42fe947049085edca5117a49e59e8d17f8c90cecd8437fbaeb73b20a2
sui client call --package $PACKAGE_ID --module company --function refunds --args $TRANSPORTITEM $COMPANY --gas-budget 10000000
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0x990be8a45b632a81cf7e5ed6dc763b195edbaa994d827e5d6ac6f0db1eedc3d5 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313256 │
│ │ Digest: Eo4kQG93h8nUwYCmJbkQ2J7spFPgtZpdx2dWhtvRUp4f │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x393096cbb4b767cc89988c7ef1566b30ce0ed69f367c1a2dc46a394e33c4a358 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Object ID: ( 0xfb39822d0d3883ed1a02d720ed6bc1f38a09b8c2b7ad33d00a466d28306860c5 ) │
│ │ ObjectType: 0x2::dynamic_field::Field<0x2::object::ID, 0x2::linked_table::Node<0x2::object::ID, 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::ItemInfo>> │
│ │ Version: 81313256 │
│ │ Digest: BX5RYwdf94HGfqyxqj49LdoxDxFHf19YaSezM6ZLysup │
│ └── │
│ ┌── │
│ │ ObjectID: 0xa5e9cc06d7bfb34b49fd2f6631e0580129fa8124a36030ae5107ebf785fca37c │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313256 │
│ │ Digest: bAY6jemHXqpQ7B9P234ueRHC76mz9sE6FxoYUdjXtP9 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::Company │
│ │ Version: 81313256 │
│ │ Digest: 5WNobseyxFD5isae3QDzY4aaT18ysesgfLVbzXfBJK5C │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
sui client gas
# output:
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x990be8a45b632a81cf7e5ed6dc763b195edbaa994d827e5d6ac6f0db1eedc3d5 │ 100 │ 0.00 │
│ 0xa5e9cc06d7bfb34b49fd2f6631e0580129fa8124a36030ae5107ebf785fca37c │ 40997689 │ 0.04 │
│ 0xca1e96b358f722d601accc962d54460068244d4f7f75ee122d50e1132d25ee36 │ 8241140 │ 0.00 │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯
# 100 is a refund
sui client call --package $PACKAGE_ID --module company --function confirm_receipt --args $TRANSPORTITEM999 $COMPANY --gas-budget 10000000
╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├──────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0xa5e9cc06d7bfb34b49fd2f6631e0580129fa8124a36030ae5107ebf785fca37c │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Account Address ( 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313257 │
│ │ Digest: 51dpW1fdGD8N4gNNscivJ1Bj4xH6NbviAknscBWJK2U1 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 │
│ │ Sender: 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::Company │
│ │ Version: 81313257 │
│ │ Digest: 5VGyDPiy1eQAG41j7QrKtWrUpu3tfsP34d1697B3efys │
│ └── │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯
sui client call --package $PACKAGE_ID --module company --function cash --args $COMPANYCAP $ADMIN $COMPANY --gas-budget 10000000
RPC call failed: ErrorObject { code: ServerError(-32002), message: "Transaction execution failed due to issues with transaction inputs, please review the errors and try again: Transaction was not signed by the correct sender: Object 0xbb83fb182eaaa0054dd465eb0f600056b0e81aa600b053b1577cf49ce0c54898 is owned by account address 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67, but given owner/signer address is 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b.", data: None }
Caused by:
RPC call failed: ErrorObject { code: ServerError(-32002), message: "Transaction execution failed due to issues with transaction inputs, please review the errors and try again: Transaction was not signed by the correct sender: Object 0xbb83fb182eaaa0054dd465eb0f600056b0e81aa600b053b1577cf49ce0c54898 is owned by account address 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67, but given owner/signer address is 0xf6029b82e355f627b0e3d8941d63e139c4b73b495a2017ef48aaf17cc377457b.", data: None }
因为你不是该公司的管理员,需要先切换至对应用户。
sui client switch --address <alias>
sui client call --package $PACKAGE_ID --module company --function cash --args $COMPANYCAP $ADMIN $COMPANY --gas-budget 10000000
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0xb24851602eeb642a28821f6608f74f4137c7657f0a2ef51fe8081fe680dc275f │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313258 │
│ │ Digest: 8K3U4WEqjzMhjh2RhWFwVYpr35jkroAtXUoHEtSzxdqD │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313258 │
│ │ Digest: CPzvjMrt83jp6UhdpMaJMkid5Z3uqQa46uVGYWBkvzYM │
│ └── │
│ ┌── │
│ │ ObjectID: 0xbb83fb182eaaa0054dd465eb0f600056b0e81aa600b053b1577cf49ce0c54898 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::CompanyCap │
│ │ Version: 81313258 │
│ │ Digest: 9xw1ApyAkSEZjQA24ixvK4h5CGvdpQHxRTLS81SXRNYp │
│ └── │
│ ┌── │
│ │ ObjectID: 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::Company │
│ │ Version: 81313258 │
│ │ Digest: AEnTkUuctn8S7eGhDVdhMCBb49pttjjyivBJksqpg9a2 │
│ └── │
│ ┌── │
│ │ ObjectID: 0xd5785555e3c0d1745a502633353cf9aaad1b79d1fd04fb0fa4943bdea98006af │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::admin::Admin │
│ │ Version: 81313258 │
│ │ Digest: 5zoMeLAmpr29RFUxMbAvdNethPXbreEnpJdhzdxFu9kv │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯
sui client object $COMPANY
# outputs
╭───────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ objectId │ 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 │
│ version │ 81313258 │
│ digest │ AEnTkUuctn8S7eGhDVdhMCBb49pttjjyivBJksqpg9a2 │
│ objType │ 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::Company │
│ owner │ ╭────────┬─────────────────────────────────────────╮ │
│ │ │ Shared │ ╭────────────────────────┬────────────╮ │ │
│ │ │ │ │ initial_shared_version │ 81313248 │ │ │
│ │ │ │ ╰────────────────────────┴────────────╯ │ │
│ │ ╰────────┴─────────────────────────────────────────╯ │
│ prevTx │ HL7sXWFe2bGSHd7sE8VCkksBBzQP3VwuS3NVwWdiRvyM │
│ storageRebate │ 1892400 │
│ content │ ╭───────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ │ dataType │ moveObject │ │
│ │ │ type │ 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::Company │ │
│ │ │ hasPublicTransfer │ false │ │
│ │ │ fields │ ╭─────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ │
│ │ │ │ │ all_profit │ 1000 │ │ │
│ │ │ │ │ can_be_cashed │ 0 │ │ │
│ │ │ │ │ id │ ╭────┬──────────────────────────────────────────────────────────────────────╮ │ │ │
│ │ │ │ │ │ │ id │ 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 │ │ │ │
│ │ │ │ │ │ ╰────┴──────────────────────────────────────────────────────────────────────╯ │ │ │
│ │ │ │ │ name │ NightCandle │ │ │
│ │ │ │ │ price_per_hundred_grams │ 100 │ │ │
│ │ │ │ │ waiting_for_receipt │ ╭────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ │ │
│ │ │ │ │ │ │ type │ 0x2::linked_table::LinkedTable<0x2::object::ID, 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::company::ItemInfo> │ │ │ │
│ │ │ │ │ │ │ fields │ ╭──────┬───────────────────────────────────────────────────────────────────────────────╮ │ │ │ │
│ │ │ │ │ │ │ │ │ head │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ id │ ╭────┬──────────────────────────────────────────────────────────────────────╮ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ id │ 0xfb39822d0d3883ed1a02d720ed6bc1f38a09b8c2b7ad33d00a466d28306860c5 │ │ │ │ │ │
│ │ │ │ │ │ │ │ │ │ ╰────┴──────────────────────────────────────────────────────────────────────╯ │ │ │ │ │
│ │ │ │ │ │ │ │ │ size │ 0 │ │ │ │ │
│ │ │ │ │ │ │ │ │ tail │ │ │ │ │ │
│ │ │ │ │ │ │ │ ╰──────┴───────────────────────────────────────────────────────────────────────────────╯ │ │ │ │
│ │ │ │ │ │ ╰────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │
│ │ │ │ ╰─────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │ │
│ │ ╰───────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰───────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
可以发现,all_profit
是 $\text {1000}$,理论上来说,平台发布者赚取 $\text {10}$,公司管理者赚取 $\text {990}$,可以通过sui client gas
来查看,当然,你首先需要用Publisher
进行提现。
sui client call --package $PACKAGE_ID --module admin --function withdraw --args $PUBLISHER $ADMIN --gas-budget 10000000
╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects: │
│ ┌── │
│ │ ObjectID: 0xfcf76783c005cd1119624a38c7fea70508eb6f6e8e3998dc3f08cb454ec58341 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313259 │
│ │ Digest: 31FWkR7WmpdBEgZCaSsh28Ffs8AFLJQMMz2T7vQT1bHz │
│ └── │
│ Mutated Objects: │
│ ┌── │
│ │ ObjectID: 0x64adbd96a562851de6dc79eeec7f5b8c173914aa667083693aa295f162deeb0d │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::package::Publisher │
│ │ Version: 81313259 │
│ │ Digest: 6XkP1sj42fcPY413r6TrVWxgwCv9qa2ic8wc95t5cgBM │
│ └── │
│ ┌── │
│ │ ObjectID: 0x6a8d2d47ad669e0ff5d4c4d32ddb282014daca375f3eabf454a42701beb1ec06 │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Account Address ( 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 ) │
│ │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI> │
│ │ Version: 81313259 │
│ │ Digest: UfJzotSMJAFTPQRqtsVwdKpX3qfxcEyVhxa5ZfvJdkU │
│ └── │
│ ┌── │
│ │ ObjectID: 0xd5785555e3c0d1745a502633353cf9aaad1b79d1fd04fb0fa4943bdea98006af │
│ │ Sender: 0x9e4092b6a894e6b168aa1c6c009f5c1c1fcb83fb95e5aa39144e1d2be4ee0d67 │
│ │ Owner: Shared │
│ │ ObjectType: 0x9bf00314ecf5c82bce70a7afac8905960734d600e76ac31d78588d81ed63d2d6::admin::Admin │
│ │ Version: 81313259 │
│ │ Digest: EMiBCe4QXLrhEpexZaiV8FGyHVbi6WYnAwCZ1dSvwCxq │
│ └── │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
sui client call --package $PACKAGE_ID --module company --function destroy_company --args $COMPANYCAP $COMPANY --gas-budget 10000000
sui client object $COMPANY
# outputs
Internal error, cannot read the object: Object has been deleted object_id: 0xcab6bc0ebef6ccf8cd18fcb424e3b5ee5d35544e03536aac66a0f8b0738363a2 at version: SequenceNumber(81313260) in digest o#7gyGAp71YXQRoxmFBaHxofQXAipvgHyBKPyxmdSJxyvz
本项目仅供学习使用,相关代码逻辑及测试尚不完善,同时也并不能保证其交易安全性,如用于商业用途请自行承担可能的后果。
源码可点击查看,后续可能对代码进行更新与优化,请以 $\mathit {github}$ 上的内容为准。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!