链下订单簿
链下订单簿是一种混合型的去中心化交易平台(DEX)模式,它将订单簿管理和撮合流程在链下进行,而交易结算在链上进行。
链下订单簿的原理是:
- 用户(Maker)通过自己的钱包向一个中继节点(Relayer)发送一个订单请求,并用私钥签名。
Relayer是一种在链下提供订单簿服务的节点,它可以收集和广播用户的订单,以及将匹配的订单提交到链上进行结算 。
Relayer的作用是:
- **提高交易效率**,因为它可以在链下进行订单管理和撮合,避免区块链的限制和拥堵 。
- **增加交易灵活性**,因为它可以根据不同的市场需求和策略来设计和优化订单簿和撮合引擎 。
- **扩大交易范围**,因为它可以连接不同的链上协议和资产,实现跨链和跨平台的交易 。
Relayer的特点是:
- **无需信任**,因为它只负责订单的传输和提交,不涉及资产的转移和结算,用户仍然通过自己的钱包控制资产 。
- **开放式**,因为它可以基于开源的协议来创建和运行,任何人都可以成为Relayer或使用Relayer的服务 。
- **竞争式**,因为它可以通过提供更好的服务、更低的费用、更多的激励等方式来吸引更多的用户和流动性 。
Relayer如何赚钱,取决于它使用的协议和模式。
一种常见的方式是,Relayer可以从用户的交易中收取一定比例的费用,作为提供订单簿和撮合服务的报酬。这种费用可以直接支付给Relayer,也可以通过智能合约分配给Relayer。
另一种方式是,Relayer可以发行自己的代币,作为平台的治理和激励机制。Relayer可以通过代币销售、空投、流动性挖矿等方式来筹集资金和吸引用户。Relayer的代币持有者可以享受平台的收益分红、投票权利、优惠费率等权益。
- Relayer收到订单请求后,将其添加到自己维护的链下订单簿中,并向其他用户(Taker)广播。
- Taker从Relayer的订单簿中选择一个或多个想要交易的订单,并用自己的私钥签名。
- Taker将签名后的订单发送给Relayer,Relayer将其提交到链上的智能合约进行验证和结算。
- 智能合约根据订单的参数和签名,从Maker和Taker的钱包中划转相应的资产,并支付给对方和Relayer。
链下订单簿的优势是:
- 提高了交易速度和效率,因为在链下进行订单管理和撮合,可以避免区块链的吞吐量和拥堵限制,实现更快的响应和匹配。
- 降低了交易费用,因为只有在交易结算时才需要在链上执行智能合约,可以减少区块链网络费用(gas费)的支出。
- 保留了去中心化和安全性,因为用户仍然通过自己的钱包控制资产,不需要将资产存入中心化的交易平台,而且交易结算仍然在链上进行,可以防止欺诈和操纵。
但是,换个角度看,链下订单簿的缺陷仍然有:
- 仍然牺牲了部分去中心化和安全性,因为它依赖于Relayer来提供订单簿和撮合服务,而Relayer可能是中心化的或者不可靠的,可能会出现故障、停机、操纵、审查等问题 。
- 受限于链上结算的速度和成本,因为它仍然需要在链上进行交易的验证和结算,而链上的网络状况可能会影响交易的速度和费用,导致用户体验不佳 。
- 缺乏跨链和跨平台的互操作性,因为它仍然需要遵循链上协议的规则和标准,而不同的链上协议可能不兼容或不互通,导致用户无法在不同的链和平台之间进行交易 。
目前使用链下订单簿的产品有:
- 0x:一种基于以太坊的开放式协议,可以让任何人创建和运行自己的Relayer,并支持ERC20代币之间的点对点交易。
- dYdX:一种基于以太坊的去中心化衍生品交易平台,可以让用户进行杠杆交易、借贷和做空ERC20代币。
- Loopring DEX:一种基于以太坊的去中心化交易平台,使用ZK-rollup技术来提高吞吐量和降低成本,并支持ERC20代币之间的点对点交易。
- Serum:一种基于Solana区块链的去中心化交易平台,利用Solana的高速度和低成本来实现完全链上的订单簿和撮合引擎,并支持Solana生态系统中的SPL代币之间的点对点交易。
为了更好地理解链下订单簿的工作原理,我们可以用数学公式和代码来表示一个简单的例子:
假设Alice想要用100个ETH换取200个DAI,Bob想要用200个DAI换取100个ETH,他们都通过自己的钱包向Relayer发送订单请求,并用私钥签名。
Alice的订单请求可以表示为:
其中:
是Alice的钱包地址 是Bob的钱包地址 是Alice想要卖出的ETH数量 是Alice想要买入的DAI数量 是Alice的订单过期时间 是Alice用私钥对订单哈希值进行的签名
Bob的订单请求可以表示为:
其中:
是Bob的钱包地址 是Alice的钱包地址 是Bob想要卖出的DAI数量 是Bob想要买入的ETH数量 是Bob的订单过期时间 是Bob用私钥对订单哈希值进行的签名
Relayer收到两个订单后,发现它们可以完全匹配,于是将它们提交到链上的智能合约进行验证和结算。
智能合约的伪代码可以表示为:
// 定义一个结构体来存储订单信息
struct Order {
address maker; // 订单发起方地址
address taker; // 订单接收方地址
uint256 amountA; // 订单中卖出代币的数量
uint256 amountB; // 订单中买入代币的数量
uint256 expiry; // 订单过期时间
bytes signature; // 订单签名
}
// 定义一个函数来验证和执行两个匹配的订单
function executeOrders(Order memory orderA, Order memory orderB) public {
// 验证两个订单是否匹配,即卖出代币和买入代币互换,数量相等,过期时间未到,接收方地址正确
require(orderA.amountA == orderB.amountB && orderA.amountB == orderB.amountA, "Orders do not match");
require(orderA.expiry > block.timestamp && orderB.expiry > block.timestamp, "Orders are expired");
require(orderA.taker == orderB.maker && orderB.taker == orderA.maker, "Orders have wrong takers");
// 验证两个订单的签名是否有效,即签名者地址与订单发起方地址一致
require(recoverSigner(orderA) == orderA.maker, "Invalid signature for order A");
require(recoverSigner(orderB) == orderB.maker, "Invalid signature for order B");
// 从订单发起方的钱包中划转卖出代币,并支付给订单接收方
tokenA.transferFrom(orderA.maker, orderB.maker, orderA.amountA);
tokenB.transferFrom(orderB.maker, orderA.maker, orderB.amountA);
// 触发订单执行事件
emit ExecuteOrders(orderA, orderB);
}
// 定义一个辅助函数来恢复签名者的地址
function recoverSigner(Order memory order) internal pure returns (address) {
bytes32 r;
bytes32 s;
uint8 v;
// 检查签名长度
if (order.signature.length != 65) {
return address(0);
}
// 分离r,s,v值
assembly {
r := mload(add(order.signature, 32))
s := mload(add(order.signature, 64))
v := byte(0, mload(add(order.signature, 96)))
}
// 如果v值不在有效范围内,返回空地址
if (v < 27) {
return address(0);
}
// 使用ecrecover函数恢复签名者的地址,并返回
return ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hashOrder(order))), v, r, s);
}
// 定义一个辅助函数来计算订单的哈希值
function hashOrder(Order memory order) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(order.maker, order.taker, order.amountA, order.amountB, order.expiry));
}
这样,智能合约就可以根据Alice和Bob的订单和签名,从他们的钱包中划转100个ETH和200个DAI,并支付给对方,完成交易结算。
链下订单簿如何做到杠杆交易,主要取决于它与链上协议的结合方式。
一种方式是,链下订单簿可以直接与链上的借贷协议进行交互,从而实现用户在下单时自动借入或还款所需的资产,以达到杠杆的效果。例如,dYdX就是采用这种方式,它的链下订单簿可以与其自己开发的链上借贷协议进行对接,让用户在进行现货交易、杠杆交易或合约交易时,自动从资金池中借入或还款资产,并支付相应的利息。
另一种方式是,链下订单簿可以利用链上的合成资产协议来创建和交易具有杠杆效果的资产,从而实现用户在下单时无需借入或还款任何资产,只需抵押一定比例的保证金即可。例如,Lever Network就是采用这种方式,它的链下订单簿可以与其自己开发的链上合成资产协议进行对接,让用户在进行现货交易时,自动创建和销毁具有2倍杠杆效果的合成资产,并支付相应的费用。
顺带一提,杠杆交易的收益和风险,可以用以下公式来计算:
- 收益率 = (卖出价格 - 买入价格) / 买入价格
- 杠杆率 = 总头寸 / 保证金
- 风险率 = (清算价格 - 买入价格) / 买入价格
其中:
- 卖出价格是指用户平仓时的资产价格
- 买入价格是指用户开仓时的资产价格
- 总头寸是指用户开仓时的资产总价值
- 保证金是指用户开仓时需要抵押的资产价值
- 清算价格是指用户被强制平仓的资产价格
举个例子:
假设用户想要用100 USDT做多 ETH,ETH 的当前价格是2000 USDT,杠杆率是2倍,清算价格是1800 USDT。
那么,用户可以用100 USDT作为保证金,借入100 USDT,买入0.1 ETH,总头寸为200 USDT。
如果 ETH 的价格上涨到2200 USDT,用户平仓卖出0.1 ETH,还回借入的100 USDT,剩余的120 USDT作为收益。
那么,用户的收益率为:
- 收益率 = (2200 - 2000) / 2000 = 10%
用户的杠杆率为:
- 杠杆率 = 200 / 100 = 2
用户的风险率为:
- 风险率 = (1800 - 2000) / 2000 = -10%
这意味着,如果 ETH 的价格下跌到1800 USDT,用户就会被强制平仓,损失所有的保证金。