Purchase
* 本文由Starcoin社区原创
Purchase是首届Starcoin & Move黑客松的一个参赛项目,由TopYD团队提交。Purchase是在完全没有信任的场景下,双方通过链上质押的方式进行安全的交易。如果一方欺诈,将罚没其质押的Token,以此来保证双方的交易顺利、安全的进行下去。
这里我们通过对合约源码进行分析,来学习一下Move如何实现一个简单的交易协议。我们先来看一 下Purchase项目的整体设计图:
从上图我们可以看到Purchase的数据结构和主要流程:
- 数据结构
- Market
- Goods
- 核心流程
- publish函数
- order函数
- done函数
Purchase的实现上,可以在Market里面买卖各种各样的Goods,通过publish、order、done完成一次顺利的交易。
数据结构
我们来看一下Purchase核心的数据结构:
- Market市场
struct Market<Info: copy + drop + store> has key, store {
goods_center: vector<Goods<Info>>,//商品列表
}
- Goods商品
struct Goods<Info: copy + drop + store> has store {
state: u8,// 状态
info: Info,//商品信息
seller: address,//卖方地址
price: u128,//价格
s_deposit: Option<Token<STC>>,//买方质押
buyer: Option<address>,//买方
b_deposit: Option<Token<STC>>,//卖方质押+支付
}
Market和Goods的定义有以下优点:
- 没有drop的ability,Market的instance不能被丢弃或者凭空消失
- 没有copy的ability,Market不能通过instance拷贝成多个instance,不会增发
- Market可以被存储和检索,Goods只能被存储
- Info是泛型,可以接收任何有copy + drop + store的ability的Struct
核心函数
Purchase主要的流程包括3个核心的函数:
publish函数
public fun publish<Info: copy + drop + store>(account: &signer, market_address: address, s_deposit: Token<STC>, info:Info): u64 acquires Market
publish是用于发布商品信息的函数,任何人都能发布商品。
order函数
public fun order<Info: copy + drop + store>(account: &signer, market_address: address, goods_id: u64, b_deposit: Token<STC>) acquires Market
order函数用于用户下单。
done函数
public fun done<Info: copy + drop + store>(account: &signer, market_address: address, goods_id: u64):Token<STC> acquires Market
订单完成,进行结算,这步会把双方质押的Token退还。
上面这3个函数,设计上基本相同:
- public函数可见性
- 泛型编程,实现通用的协议
- acquires表示当前函数使用了当前合约定义的Struct
总结&思考
合约功能相对比较简单,我们从代码的⻆度来分析一下优缺点。
- 优点:
- Struct的定义安全可靠,既不会凭空消失,也不能被拷贝
- 泛型编程,实现通用的协议
- 功能上通过双方质押的方式,保障非信任的场景下顺利交易
- 可以改进的地方:
- Market使用了vector,容易引发大数组的安全问题
- 将数据分散到每个用户自己的账号下
- 支持形式化验证,通过数学方式证明合约的安全性
- 如果交易不顺利,应该提供一种Proof的方式避免损失
Purchase在设计上比较简洁通用,感兴趣的可以通过这里查看完整代码。