Move语言开发合约,SUI链WebApp演示

简介

Move是一种新的编程语言,为 Libra 区块链提供安全、可编程的基础。 Libra区块链中的帐户作为容器,包含了任意数量的Move资源和Move模块。 提交给 Libra 区块链的每个交易都使用 Move 编写的交易脚本来实现其逻辑。 交易脚本可以通过调用模块声明的过程(procedures)来更新区块链的全局状态。

最大的特色

以太坊, 以及其他几乎所有的系统(银行,支付宝,微信 ...),里面的货币都是数字表示,转账就是一个账户余额加,另一个账户余额减。这就存在很多可利用的漏洞,随意修改数值,造成各种损失。 而 Move 里面,实现了现实中的货币的概念,比如你有一张100元纸币,去买20块钱的东西,那么先要把100元换成50+20+20+10 4张纸币,然后用一张20元的纸币支付。这就是Move里面的货币的实现,每笔余额都是唯一object, 在支付前都需要先拆散成更小的面额。

本DEMO知识点

1. 消息  2. 权限  3. 货币的分割/合并  4. 共享object  5. 转账  6. 前端连接钱包  7. 前端调用合约

开发一个合约

我们选择Sui Chain, 来开发一个去中心化的聊天室合约。类似的Solidity的合约网上有不少。原理都是:用户发送一条消息,合约产出一个Event,WebApp 查询Events 和 监听消息。

定义一个消息,消息必须是 copy drop 的。

    struct MessageSended has copy, drop {
        sender: address,
        message: String,
    }

发送一个消息,只记录发送者address和内容message就好。

public entry fun send_msg(chatfee: &mut ChatFee, payment: &mut Coin<SUI>, msg_bytes: vector<u8>, ctx: &mut TxContext) {
	let sender = tx_context::sender(ctx);
    event::emit(MessageSended {
        sender: sender,
        message: string::utf8(msg_bytes)
    });
}

光这样还是比较简陋,再加点东西,比如发一条消息收费 100 Sui , 使用 share_object 来实现。

    struct OwnerCap has key { id: UID }

    struct ChatFee has key {
        id: UID,
        fee: u64,
        balance: Balance<SUI>
    }


    fun init(ctx: &mut TxContext) {
        transfer::transfer(OwnerCap {id: object::new(ctx)}, tx_context::sender(ctx));
        transfer::share_object(ChatFee {
            id: object::new(ctx),
            fee: 100,
            balance: balance::zero()
        });
    }

最终合约里面堆积的余额来个提现,当然只能是合约owner才行,上面代码里面的 OwnerCap 就相当于 Solidity 里面的 OnlyOwner 一个意思,在 init 里面创建,transfer 给 合约创建人。后面的提现函数的第一个参数就是这个object,也就意味着只能owner 才能调用成功。

    public entry fun collect_profits(_: &OwnerCap, chatfee: &mut ChatFee, ctx: &mut TxContext) {
        let amount = balance::value(&chatfee.balance);
        let profits = coin::take(&mut chatfee.balance, amount, ctx);
        transfer::transfer(profits, tx_context::sender(ctx))
    }

WebApp调用合约

第一步连接钱包,使用 suiet wallet react kit ,文档这里:Quick Start | Suiet Wallet Kit

root.render(
  <React.StrictMode>
    <WalletProvider defaultWallets={[
      SuietWallet,
      SuiWallet,
      EthosWallet
    ]}>
      <App />
    </WalletProvider>
  </React.StrictMode>
);

获取历史消息列表,使用 sui.js 请求 RPC API 获取

async function queryMsg() {
  const msgs = [];
  try {
    const { data: events } = await provider.getEvents({
      MoveModule: { package: ContractInfo.package, module: ContractInfo.module }
    });
    for (let i = 0; i < events.length; i++) {
      const moveEvent = events[i].event.moveEvent;
      if (!moveEvent) continue;
      if (moveEvent.type != ContractInfo.eventType) continue;
      msgs.unshift({
        timestamp: events[i].timestamp,
        sender: moveEvent.fields.sender,
        message: moveEvent.fields.message
      });
    }
  } catch (err) {
    console.log(err)
  }
  return msgs;
}

调用插件钱包发送消息,合约里面写的,发消息是要收费100的,合约 send_msg 第二个参数 是 Sui Coin, 那么在这个web 发送代码里面,就是第二个参数 sui_id, 那么先要调用API 获取钱包用户的 sui coin 列表,在其中选择一个余额大于 100 的使用。

      const resData = await wallet.signAndExecuteTransaction({
        transaction: {
          kind: 'moveCall',
          data: {
            packageObjectId: datalib.ContractInfo.package,
            module: datalib.ContractInfo.module,
            function: 'send_msg',
            typeArguments: [],
            arguments: [
              datalib.ContractInfo.share,
              sui_id,
              msg,
            ],
            gasBudget: 10000,
          }
        }
      });
      console.log('successfully:', resData);

至此演示完成:move 合约开发,web调用合约 的整个过程

 完整源码:GitHub - kf702/suichat: sui chat, Move contract, react sui wallet

 Web Demo URL: SuiChat

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值