引介 | FunFair:状态通道合约的参考实现,Part-2
引介 | FunFair:状态通道合约的参考实现,Part-1
推进状态(第一部分)
现在,我们已经有了一条处于初始状态的通道。要想把这条通道利用起来,我们需要具备推进状态的能力,最好不是通过链上交易,为此我们需要一个 Action (操作)功能。
Action(操作)
在这种模式下,我们暂定只能由一位参与者发起 action 。我们目前不会强制两位参与者轮流发起 action(之后会这么做)。不过可以明确的一点是,一个 action 只会有一个签名。我们的 Action 结构如下:
uint256 constant ACTION_TYPE_ADVANCE_STATE = 0x01;
uint256 constant ACTION_TYPE_CLOSE_CHANNEL = 0xff;
struct ActionContents {
bytes32 channelID;
address channelAddress;
uint256 stateNonce;
uint256 participant;
uint256 actionType;
bytes packedActionData;
}
struct Action {
ActionContents contents;
Signature signature;
}
为了识别身份并防止重放攻击,Action 依然需要用到通道 ID 和合约地址,其所应用状态的 nonce 值(这个非常重要),以及执行这个 action 的参与方 (简单地用 0 或 1 表示)。
然后我们还要定义 action 类型——目前只有两类——推进状态(Advance State)和关闭通道(Close Channel)。我们之所以要定义类型,是因为我可以想象得到可用于通道但并不能应用于状态机的其他 action ,尽管现在我们还没实现出来。
最后,我们还要输入状态机所需的数据,即一步棋、一张牌、一次赌注等等,不过状态通道对这些数据一无所知。
推进状态(第二部分)
现在万事俱备。状态通道会公开一个公共的只读函数,将一个状态、一个 action 和状态机地址输入这个函数,会有一个新的状态返回。参与者在链下调用该函数,以确定性的方式推进状态。让我们来看看代码:
function advanceState(StateContents memory stateContents, ActionContents memory actionContents,
IStateMachine stateMachine) public view returns
(FFR memory isValid, StateContents memory newStateContents) {
// advance the state using the state machine
int256 balanceChange;
bytes memory packedNewCustomState;
(isValid, packedNewCustomState, balanceChange) =
stateMachine.advanceState(stateContents.packedStateMachineState,
actionContents.packedActionData,
actionContents.participant,
stateContents.balances);
// was the action valid?
if (!isValid.b) {
return (FFR(false, "Invalid Action"), newStateContents);
}
// check that the balance change is acceptable
// this must *never* trigger
// Does Participant #0 have enough funds?
assert((balanceChange >= 0) || (int256(stateContents.balances[0]) >= (-balanceChange)));
// Does Participant #1 have enough funds?
assert((balanceChange <= 0) || (int256(stateContents.balances[1]) >= ( balanceChange)));
newStateContents.channelID = stateContents.channelID;
newStateContents.channelAddress = stateContents.channelAddress;
newStateContents.nonce = stateContents.nonce + 1;
newStateContents.balances[0] = uint256(int256(stateContents.balances[0]) + balanceChange);
newStateContents.balances[1] = uint256(int256(stateContents.balances[1]) - balanceChange);
newStateContents.packedStateMachineState = packedNewCustomState;
}
显而易见,该代码调用了状态机来更新其状态,然后创建了一个新的最高级状态以及一个新的 nonce 。你会发现,实际的调用比我最初对状态机的定义略复杂一些。实际上,我们的实现是这样进行调用的:
advanceState(state, action, participant, balances) => (isValid, newState, balanceChange)
状态机需要核实 action 是否在特定状态下有效(例如,在下象棋的时候,不能将王下到会被将军的位置;在玩轮盘赌的时候,绝对不能在 37 这个数字上下注)。状态通道需要知道参与者是谁,以便在状态通道存在争议之时,对签名及其它数据进行验证。因此,参与者这一数据是要明确输入状态通道中的,而非被编码到 action 中再输入状态机。也就是说(例如),强制玩家轮流进行操作这一要求是依靠状态机实现的。最后,由于维护参与者余额是状态通道的责任,当前余额需要传入状态机,然后会状态根据 Action 返回一个新的余额作为一个结果。
我们要求所有的 action 必须是有效的, 并且参与者双方的余额都不为负,然后返回新的状态。
关闭通道
若想关闭状态通道,参与者双方必须达成共识——目前有几种可行的方法,不过我们已经选了一个语义上简单的。参与双方根据理想最终状态的 nonce 签署了关闭通道的 action ,然后将这些数据连同双方共同签署过的最终状态一起传到链上。
合约需要对以下几点进行核实:
该状态通道是开启的吗? 被提议的最终状态是否有效? 是否指向该合约 是否指向该状态通道 参与者的余额总量加起来是否是通道开启时的余额总量? 是否所有的 action 都有效? 它们是否都指向该合约? 它们是否都指向该状态通道? 它们是否都指向被提议状态的 nonce ? 状态和 Action 上的签名是否有效? 每个 action 签名是否都来自正确的参与者?
使用状态通道
通过调用 advanceState() ,被提议的 action 确实将前一个状态推进到了被提议的新状态 新状态和 action 的签名都是有效的
协议
如果轮到我进行操作,我必须在合理的时间范围内完成操作 如果我接收到一个新状态,我必须: 验证状态转换是否按照链上代码进行 验证新状态和 action 上的签名是否有效 将我对新状态的签名发送给对手方
争议解决
发起争议
function disputeWithAction(bytes memory packedOpenChannelData, State memory state, Action memory action, State memory proposedNewState)
状态通道是开启且不存在争议的吗? 在状态通道下(根据最终通道(End Channel)调用),状态和 Action 是否有效? 状态是否经过参与双方正确签署? Action 是否经过争议发起方正确签署? Action 是否是推进状态类型的?
新状态是否与争议发起方提交的被提议新状态一致 是否经过参与双方正确签署
解决争议
我必须一直关注这条链的情况
function resolveDispute_WithAction(bytes memory packedOpenChannelData, State memory state,
Action memory action, State memory proposedNewState)
这个状态通道目前存在争议吗? S' 的哈希跟存储在链上的哈希一致吗? 在该状态通道下,Action A' 有效吗?
A' 是否是“推进状态”类型的? A' 是否由争议发起方的对手方发起? A' 是否经过正确签署?
S'' 是否与对手方提交的新状态一致 他们对 S'' 的签名是否有效
(未完)
(文内提供了许多超链接,请点击阅读原文到 EthFans 网站上获取)
原文链接:
https://funfair.io/a-reference-implementation-of-state-channel-contracts/
作者: FunFair
翻译&校对: 闵敏 & 阿剑
你可能还喜欢: