1.需求:使用suimove实现购买股票,根据股票分红sui支持把钱转给一个对象地址,提供一种机制,将对象地址拥有的钱,提取到这个对象的owner的钱包。如下图,12:用户A发布合约,拥有分红权限34:用户B花钱购买了股票,合约里面增加了钱5:将股票自由转移
sui 支持把钱转给一个对象地址, 提供一种机制,将对象地址拥有的钱,提取到这个对象的owner的钱包。
如下图,
1 2 : 用户A 发布合约,拥有分红权限
3 4 :用户B 花钱购买了股票 ,合约里面增加了钱
5 : 将股票自由转移给C,不需要通知用户A
6 :用户A 分红,将分红发给股票, 这个例子里面分红20%
----这里可能经过了很多运营,合约里面的钱增值了, 本文不涉及相关逻辑
7 :用户C 拿着股票,到合约来领取分红到钱包
#[allow(lint(self_transfer),unused_use)]
module book::stock_market
{
use sui::coin::{Self,Coin};
use sui::sui::SUI;
use sui::balance::{Self,Balance};
use sui::table::{Table,Self};
use sui::transfer::{Receiving};
//
public struct Share has store {
id : address,
amount : u64
}
public struct Shares has key {
id : UID,
count : u32,
holders : Table<u32, Share > ,
balances : Balance<SUI>,
supply : u64,
}
//控制权限,分红需要此权限
public struct AdminCap has key{
id : UID,
}
public struct Stock has key,store{
id : UID,
amount : u64,
}
fun init( ctx : &mut TxContext){
let shares = Shares{
id : object::new(ctx),
count : 0,
holders : table::new<u32,Share>(ctx),
balances : balance::zero<SUI>(),
supply : 0
};
transfer::share_object(shares);
let admin = AdminCap{
id : object::new(ctx)
};
transfer::transfer(admin,ctx.sender());
}
// 创建股票和份额
fun create_share(amount :u64 , ctx : &mut TxContext) : (Stock,Share){
let stock_id = object::new(ctx);
let stock_addr = stock_id.uid_to_address();
let stock= Stock{
id : stock_id,
amount : amount
};
//记录股票地址,方便给股票地址转账
let share = Share{
amount : amount,
id : stock_addr,
};
return (stock,share)
}
//记录份额
fun add_share(shares : &mut Shares,share : Share){
shares.supply = shares.supply + share.amount;
table::add(&mut shares.holders,shares.count,share);
shares.count = shares.count + 1;
}
// 花钱购买stock
entry fun buy_stock(shares: &mut Shares,coin : Coin<SUI>, ctx : &mut TxContext){
let value = coin::value(&coin);
balance::join(&mut shares.balances, coin.into_balance());
let (stock,share) = create_share(value,ctx);
add_share(shares, share);
transfer::transfer(stock,ctx.sender());
}
//阶段性分红,percent: 百分比乘以10000, 根据份额,把一部分钱发给股票
public fun allocate(_cap : &AdminCap,
shares :&mut Shares,
percent : u64,
ctx : &mut TxContext){
let mut index :u32 = 0;
let supply = shares.supply;
while(index < shares.count){
let share = sui::table::borrow(&shares.holders,index);
let value = share.amount * shares.balances.value() * percent /(10000) / supply;
if(value > 0){
let coin = coin::from_balance( balance::split(&mut shares.balances,value),ctx);
let coin_id = object::id_to_address(&object::id(&coin));
//分红发到股票地址
transfer::public_transfer(coin, share.id);
};
index = index + 1;
}
}
// 将股票拥有的钱提取到股票拥有者的钱包.只有拥有股票的人才能使用这个stock参数
entry fun receive_stock_share(stock: &mut Stock, receiver : Receiving<Coin<SUI>>,ctx :& TxContext){
let coin = transfer::public_receive<Coin<SUI>>(&mut stock.id ,receiver );
transfer::public_transfer(coin,ctx.sender());
}
}
export ADDR_A=0xf7ec2215e565b7a18d7b00e70fccda74b30c3ecceffb5857b1b3d2249e28e94f export ADDR_B=0x6560a053cd8d98925b33ab2b951d656736d0133734def0b5d679402fc555576c export ADDR_C=0x540105A7D2F5F54A812C630F2996F1790ED0E60D1F9A870CE397F03E4CEC9B38
sui client switch --address $ADDR_A
sui client publish
┌── │
│ │ ObjectID: 0xa041d96de7c3f9a6823c3f73203705ebe69a6ca376d4233c65604c04b2dcc5fe │
│ │ Sender: 0xf7ec2215e565b7a18d7b00e70fccda74b30c3ecceffb5857b1b3d2249e28e94f │
│ │ Owner: Shared( 51 ) │
│ │ ObjectType: 0x6c6b4cad96bf40d9be1ecb2954747924e49c7966208d453557980c26cbf4dccf::stock_market::Shares │
│ │ Version: 51 │
│ │ Digest: 4VMCG7NvCu7UPD45ZcmWa8mkpz84WsJzj3greNTt1V2t │
│ └── │
│ ┌── │
│ │ ObjectID: 0xe40ab477a340442774f77668d4b6708ea366b195c25f9a9cf455eb94222c1b8b │
│ │ Sender: 0xf7ec2215e565b7a18d7b00e70fccda74b30c3ecceffb5857b1b3d2249e28e94f │
│ │ Owner: Account Address ( 0xf7ec2215e565b7a18d7b00e70fccda74b30c3ecceffb5857b1b3d2249e28e94f ) │
│ │ ObjectType: 0x6c6b4cad96bf40d9be1ecb2954747924e49c7966208d453557980c26cbf4dccf::stock_market::AdminCap │
│ │ Version: 51 │
│ │ Digest: 9A6jXJfMgi87jfnJFJKFZT5PSfH8KRw5NKGKoGuHYi5C
export SHARES=0xa041d96de7c3f9a6823c3f73203705ebe69a6ca376d4233c65604c04b2dcc5fe
export ADMIN=0xe40ab477a340442774f77668d4b6708ea366b195c25f9a9cf455eb94222c1b8b
export PKG=0x6c6b4cad96bf40d9be1ecb2954747924e49c7966208d453557980c26cbf4dccf
sui client switch --address $ADDR_B
sui client faucet
# 查看当前的gas值
sui client gas
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x729890d6387c699f2a586fffe1daf803f0cba18a6b3cc481d922df304f40fbe7 │ 10000000000 │ 10.00 │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯
从现有gas中切出5000000个mist ,用来购买股票
sui client ptb --split-coins gas [5000000] \ --assign new_coin \ --move-call $PKG::stock_market::buy_stock @$SHARES new_coin
根据输出信息,可以获得STOCK
Created Objects: │ │ ┌── │ │ │ ObjectID: 0x16b4b76e57c92325dc44a47cf5734b4241f11ba25eb9360d77bdf8a0e2b8cbd8 │ │ │ Sender: 0x6560a053cd8d98925b33ab2b951d656736d0133734def0b5d679402fc555576c │ │ │ Owner: Account Address ( 0x6560a053cd8d98925b33ab2b951d656736d0133734def0b5d679402fc555576c ) │ │ │ ObjectType: 0x6c6b4cad96bf40d9be1ecb2954747924e49c7966208d453557980c26cbf4dccf::stock_market::Stock │ │ │ Version: 54 │ │ │ Digest: BfuEtZjb2TL6wrrsajwH7ZamgsnV71LB6W2mVHwkmjma │ │ └──
export STOCK=0x16b4b76e57c92325dc44a47cf5734b4241f11ba25eb9360d77bdf8a0e2b8cbd8
sui client ptb --transfer-objects [@$STOCK] @$ADDR_C
sui client switch --address $ADDR_A
sui client ptb --move-call $PKG::stock_market::allocate @$ADMIN @$SHARES 2000
sui client objects $STOCK
得到
╭───────────────────────────────────────────────────────────────────────────────────────╮
│ ╭────────────┬──────────────────────────────────────────────────────────────────────╮ │
│ │ objectId │ 0xc06d80746fd966134e89e527d24484afa647f60f919db31d373dcb9a292b046c │ │
│ │ version │ 55 │ │
│ │ digest │ ntJJXEPdJz0gE+8IqFXtHt7pOgf36Tapb0YV16cp+Gg= │ │
│ │ objectType │ 0x0000..0002::coin::Coin │ │
│ ╰────────────┴──────────────────────────────────────────────────────────────────────╯ │
根据输出的objectId,配置需要提取的COIN_ID
export COIN_ID=0xc06d80746fd966134e89e527d24484afa647f60f919db31d373dcb9a292b046c
sui client switch --address $ADDR_C
sui client gas
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x15789f7840c3d7758a024545376a8f6ee61e8162b3593ac8f3ae9a7f7b499200 │ 9996916552 │ 9.99 │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯
sui client ptb --move-call $PKG::stock_market::receive_stock_share @$STOCK @$COIN_ID
sui client gas
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x15789f7840c3d7758a024545376a8f6ee61e8162b3593ac8f3ae9a7f7b499200 │ 9995882960 │ 9.99 │
│ 0xc06d80746fd966134e89e527d24484afa647f60f919db31d373dcb9a292b046c │ 1000000 │ 0.00 │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!