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_Csui client switch --address $ADDR_A
sui client ptb --move-call $PKG::stock_market::allocate @$ADMIN @$SHARES 2000sui 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_IDsui client gas
╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
│ gasCoinId                                                          │ mistBalance (MIST) │ suiBalance (SUI) │
├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
│ 0x15789f7840c3d7758a024545376a8f6ee61e8162b3593ac8f3ae9a7f7b499200 │ 9995882960         │ 9.99             │
│ 0xc06d80746fd966134e89e527d24484afa647f60f919db31d373dcb9a292b046c │ 1000000            │ 0.00             │
╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯ 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!