【解读】Filecoin中的支付通道是什么?检索交易是如何完成的?
引言 ·
Filecoin是一个高效、安全的分布式存储网络,为用户提供存储和检索两大服务。不同于传统云存储商的会员制,用户需要支付一定的费用来向Filecoin网络存储或检索数据。由于存储提供者受到各种激励和惩罚机制,存储一般是一次性付清费用,而检索及下载服务,基于区块链的支付功能一般存在以下两个问题:
· 如果用户一次性支付了所有费用,存储提供者可能拿钱走人,拒绝提供数据
· 如果数据分段进行多次支付,一方面需要额外支付大量的Gas费,另一方面由于每笔交易上链的确认时间较长,整个过程会变得十分漫长
为了解决这些问题,Filecoin中的支付通道功能应运而生。下文将详细分析Lotus代码中支付通道功能的设计。
概述
支付通道是一种提高区块链可扩展性的机制,减少交易双方与链的交互,提高了系统的负载量,同时减少了交互产生的gas费。
在Filecoin中,交易双方通过智能合约使用支付通道,一般由支付通道发起者创建支付通道,并向其中质押部分资金,通过相互发送凭证进行交易,交易完成后接收方兑换凭证取出资金,剩余的金额返还给发起方。
假设凭证格式为(Nonce,FIL),发起方发送三个凭证(1,10),(2,20),(3,30)给对方。首先Nonce值是依次递增的,代表凭证的编号。兑换凭证2后接收方可获得20FIL,与此同时凭证1会作废,接着兑换凭证3可获得10FIL,总共获得30FIL,所以一般情况下直接兑换凭证3(Nonce值最高的凭证)即可。
此外,该通道中资金的流向是单向的。如果接收方发送一张凭证(4,25)给发起方,发起方兑换这张凭证后,之前的凭证全部作废,接收方最终可以收到25FIL。这种方式一般在接收者出于善意,想退还部分钱给用户时使用。
源码分析
1、术语
· payment channel sender
支付通道发起者,是创建支付通道并向支付通道添加资金的一方,支付通道发起者接受支付通道接收者提供的服务。
· payment channel recipient
支付通道接收者,接收从支付通道来的资金并向支付通道发起者提供相应的服务。
· voucher
支付凭证,由支付通道任意一方创建的签名消息,用于更新支付通道支付资金。
· lane
支付航道,多个服务可以共享一个支付通道,通过支付航道区别不同的服务。每个支付凭证必须指定一个支付航道,
· Redeeming a voucher
兑现凭证, 凭证必须由凭证的接收方在链上提交。兑换凭证不会触发资金从渠道转移到接收者的账户,但它会产生gas费。凭证可以在任何时间兑换,直到归集为止。
· UpdateChannelState
更新支付通道状态, 兑付凭证的过程,即在链上提交(但不兑现)凭证。
· Settle
结算, 此过程开始关闭支付通道。它可以由通道的创建者(发送方)或通道接收方调用,这个过程会产生gas费。
· Collect
领取, 通过此过程,资金最终从支付通道发送方转移到支付通道接收方,这个过程会产生gas费。
2、执行逻辑
1. 双方在链下协商好交易的具体内容,约定进行一系列交易。
2. 支付通道发起者通过PayChActor创建一个支付通道并质押一些资金。(合约并没有限制创建支付通道的地址,任何账户地址都可以为任意两个交易双方创建支付通道。但是创建支付通道需要支付一定的费用,所以正常情况下是由支付通道发起者创建)
3. 交易双方创建并相互发送支付凭证给对方
4. 双方暂时将支付凭证保存在本地,支付凭证只能被接收者兑换
5. 接收凭证的一方可以立即或在之后将凭证提交到链上
6. 任意一方调用Settle,会于12小时后关闭支付通道(为了防止有一方过早的关闭支付通道,可以通过MinSettleHeight值限制支付通道最早的截止日期)
7. 如果双方还有更高Nonce值的支付凭证没有兑换,则需要及时将该凭证提交到链上,否则12小时到期后,凭证失效
8. 任意一方调用Collect领取资金,资金转入到支付通道接收者账户,剩余的资金返回给支付通道发起者
3、具体实现
支付通道状态
支付通道发起者通过智能合约创建一个支付通道,发起者需要提供发起者地址和接收者地址。支付通道创建后生成一个PayChActor,以下是PayChActor状态:
type State struct {
// 支付通道发起者,必须和创建支付通道的地址一致
From addr.Address
// 支付通道接收者
To addr.Address
// 支付通道可成功兑换的金额,结算后,ToSend资金支付给支付通道接收者,余额归还支付通道发起者
ToSend abi.TokenAmount
// 支付通道停止兑换支付凭证的时间,高度达到SettlingAt后,未兑换的支付凭证失效
SettlingAt abi.ChainEpoch
// 最晚的兑换支付凭证时间,SettlingAt不可以小于MinSettleHeight
MinSettleHeight abi.ChainEpoch
// 航道状态集合
LaneStates cid.Cid // AMT<LaneState>
}
Voucher(凭证)
为了使用支付通道进行交易,双方会互相发送签名消息更新支付通道内的资金动向。在Filecoin网络,这个签名消息称作支付凭证。支付凭证用于更新支付通道状态。
type SignedVoucher struct {
// ChannelAddr is the address of the payment channel this signed voucher is valid for
ChannelAddr addr.Address
// TimeLockMin sets a min epoch before which the voucher cannot be redeemed
TimeLockMin abi.ChainEpoch
// TimeLockMax sets a max epoch beyond which the voucher cannot be redeemed
// TimeLockMax set to 0 means no timeout
TimeLockMax abi.ChainEpoch
// (optional) The SecretPreImage is used by `To` to validate
SecretPreimage []byte
// (optional) Extra can be specified by `From` to add a verification method to the voucher
Extra *ModVerifyParams
// Specifies which lane the Voucher merges into (will be created if does not exist)
Lane uint64
// Nonce is set by `From` to prevent redemption of stale vouchers on a lane
Nonce uint64
// Amount voucher can be redeemed for
Amount big.Int
// (optional) MinSettleHeight can extend channel MinSettleHeight if needed
MinSettleHeight abi.ChainEpoch
// (optional) Set of lanes to be merged into `Lane`
Merges []Merge
// Sender's signature over the voucher
Signature *crypto.Signature
}
介绍一些重点字段:
TimeLockMin字段限制了兑换支付凭证的最小高度
TimeLockMax字段限制了兑换支付凭证的最大高度,如果字段非0,当超过TimeLockMax高度后凭证过期
SecretPreimage和Secret共同验证支付凭证的合法性。支付者向接收者发送凭证时,会额外提供Secret,凭证在链上兑换时,会检查SecretPreimage是和Secret是否一致。SecretPreimage等于hash(Secret),目前filecoin实际暂时未使用这个功能。
if len(sv.SecretPreimage) > 0 {
hashedSecret := rt.HashBlake2b(params.Secret)
if !bytes.Equal(hashedSecret[:], sv.SecretPreimage) {
rt.Abortf(exitcode.ErrIllegalArgument, "incorrect secret!")
}
}
Extra比较有意思,在凭证兑换时,支付者可以要求验证某种条件是否满足。
if sv.Extra != nil {
code := rt.Send(
sv.Extra.Actor,
sv.Extra.Method,
builtin.CBORBytes(sv.Extra.Data),
abi.NewTokenAmount(0),
&builtin.Discard{},
)
builtin.RequireSuccess(rt, code, "spend voucher verification failed")
}
Merges用于将多个支付航道(lane)合并。
创建支付通道
支付通道创建者通过智能合约创建一个支付通道,发起者需要提供支付通道发起者地址和支付通道接收者地址参数,具体如下:
type ConstructorParams struct {
From addr.Address // Payer
To addr.Address // Payee
}
创建完成后链上生成支付通道状态,返回支付通道的地址,交易双方通过支付通道进行交易。
注意:支付通道的创建者不一定是发起者。任何人都可以为一对交易者创建支付通道,只需要向智能合约提供通道发起者地址、接收者地址和一笔手续费。但一般情况下支付通道发起者是支付通道创建者。
UpdateChannelState(更新通道状态)
UpdateChannelState用于兑换凭证,更新支付通道状态,只有接收方才可以兑换凭证。UpdateChannelState方法除了更新支付金额外,还可以更新支付通道状态的MinSettleHeight,以更新兑换支付凭证的截止时间。
type UpdateChannelStateParams struct {
Sv SignedVoucher
Secret []byte
}
合约UpdateChannelState验证凭证和更新支付通道状态,逻辑主要有以下部分:
1. 验证调用者是否是支付者或者接收者,只有支付通道的双方才可以创建凭证
2. 验证签名是否是凭证创建者
3. 验证凭证的时间是否可以接受
4. 验证SecretPreimage和Secret是否匹配
5. Extra验证凭证创建者要求的额外条件是否满足
6. 凭证对应的lane的nonce是否大于支付通道最大的nonce
7. 处理合并凭证
8. 检查余额是否足够支付合并后的金额
9. 更新状态
注意:Nonce最高的支付凭证会刷新掉其他支付凭证,例如以下情况:
当前支付通道有余额100FIL,支付资金为0。有某航道的三个支付凭证(Nonce,FIL):(1,10),(2,20),(3,30),如果接收者兑换了(2,20),则支付资金为20,(1,10)支付凭证作废。如果接着兑换(3,30),支付资金更新为30。
支付凭证是一种无状态的凭证。支付通道发起者根据接收者提供的服务发送支付凭证,接收到支付凭证的一方可以进行兑换。兑换凭证的过程需要和链交互,会产生gas费,所以只需要在服务结束时将Nonce最高的支付凭证兑换即可。在支付凭证兑换之前可以在链上检查支付通道是否有足够的余额来兑换支付凭证,这个过程不需要消耗gas费
Settle(结算)
交易双方都可以调用Settle方法,用于设置允许兑换凭证的截止兑换高度,Settle方法不需要参数,
主要逻辑如下:
1. 验证调用者是否是支付者或者接收者,只有支付通道的双方才可以调用Settle
2. 验证截止兑换高度是否已经被设置
3. Settle方法设置截止日期为12小时后但不可以小于支付通道MinSettleHeight值
注意:除了Settle方法,在截止高度之前,还可通过设置支付凭证中的minSettleHeight再次更改截止兑换高度
Collect(领取)
交易双方都可以调用Collect方法,用于领取资金,主要逻辑如下:
1. 验证调用者是否是支付者或者接收者,只有支付通道的双方才可以调用Collect
2. 验证是否到达截止兑换高度
3. 将ToSend资金转给支付通道接收者,销毁支付通道并将剩余资金归还支付通道发起者
总结·
支付通道的使用主要解决了支付双方在一次服务中多次交易存在的问题,这些交易不需要事实上链,只需要在最终状态上链进行结算。对交易双方有以下几个好处:
1. 减少等待时间,由于区块链的特性,如果和链进行交互,相较于普通的计算机操作,会有巨大的延迟,以检索市场为例,如果检索一个30G文件,存在频繁的支付交易,当交易必须上链确认时,等待消息上链几乎占据了检索的整个耗时。
2. 减少gas费,与链交互会产生gas费,降低与链的交互会降低服务的成本。
3. 提高网络容量,支付通道将多次频繁的交易简化为只需在最终状态时上链进行结算,大大减少了频繁交易占据的网络容量。
支付凭证总是指当前支付的支付总数,支付凭证虽然不是绝对递增的,但是由于兑换的权利在于另一方。nonce值更大的支付凭证会刷新掉以前的支付凭证,所以支付通道接收者肯定不会乐意兑换一个资金更少的凭证。
支付通道发起者,由于是支付资金的一方,如果发送的支付凭证少于上一个支付凭证支付的金额。作为支付凭证的兑换者-支付通道接收者不会乐意接收这个支付凭证,可以用上一个金额更大的支付凭证作为兑换的凭证并停止提供服务。所以,支付通道发起者为了继续接受来自支付通道接收者提供的服务,应当提供越来越大的支付凭证。
支付通道接收者,是获取支付通道资金的一方,如果支付通道接收者随意发起一个更高金额的支付凭证,作为支付凭证的兑换者——一个理性的支付通道发起者肯定不会接收这个支付凭证,所以这个支付凭证也就毫无意义。当然,如果接收者由于提供的服务没有完成,出于人性的善意,可以退回部分资金给支付通道发起者,此时接收者可能会发送一个较低金额的支付凭证,作为支付的一方,用户肯定也会欣喜的接受,并对检索提供者以及Filecoin网络的检索服务好感备至。
- END-
星际联盟官网:
https://www.ipfsunion.cn
飞驰浏览器:
https://www.filscout.com
微博:IPFS星际联盟
推特:@IPFSUnion_CN
抖音:IPFS星际联盟