使用契约的链上限价订单

news2024/9/22 4:15:31

我们开发了链上限价订单。 它基于一种称为契约的智能合约,只有在花费输出的交易满足特定条件时才可以花费输出。 为了演示其工作原理,我们实施了以比特币支付的 Ordinals 代币买卖限价订单,无需托管人。 它可以运行在任何比特币协议链上,例如Bitcoin SV和MVC。

限价订单

限价单使买方或卖方(通常称为制造商)能够确定他们愿意在市场上买卖资产的特定价格。 随后,另一个交易者可以选择“接受”该报价并进行交易。 这一过程通常在托管交易所中得到促进,交易所暂时持有双方的资金,并采用内部结算机制来相应地分配资金。 然而,这种方法涉及将资金信任给第三方,从而使他们面临因系统黑客或内部盗窃而造成的潜在损失,其中第三方可能会消失或盗用资金。

契约

比特币契约 限制了 UTXO 的使用方式。 它是在 sCrypt 中使用 ScriptContext 实现的。

例如,做市商可以下一个卖出订单,将 10 个 PEPE 代币锁定到契约合约中,允许任何购买者提取最多 10 个 PEPE 代币,只要他们向卖家支付,例如,他们移除的每个 PEPE 1000 聪。

如果买方希望交易的金额低于 10 个 PEPE 限制(例如 7 个),他们可以选择为其余 3 个 PEPE 创建受相同契约约束的代币找零输出。 在这种特殊情况下,卖方被确定为做市商,买方在限价订单的框架内扮演接受者的角色。 该机制有利于部分履行限价订单的过程。

该限价订单可以看作是 RUN 代币的 OrderLock 和 Ordinals 的 OrdinalLock 的扩展,只能进行全额交易。

如果订单未 100% 成交,合同还允许卖方取消订单并拿走剩余的 PEPE。

实现

我们使用 BSV-20 同质化代币 作为创建限价订单的示例,并用比特币进行交易。

限价卖出订单

一定数量的 BSV-20 代币被锁定在契约智能合约中。 买方可以从智能合约中获取部分或全部代币,前提是他在同一合约调用交易中向卖方支付要价。

描述卖出限价订单的交易图

买家可以通过在同一合约调用交易中将聪转移到买家的地址来兑换 BSV-20 代币。 这是在调用合约的“buy”公共方法时完成的。

还有一种“cancel”方法,允许买家在订单未 100% 成交时取回资金。

class BSV20SellLimitOrder extends BSV20V2 {
    // Total amount of tokens we're selling.
    @prop()
    readonly tokenAmt: bigint

    // Amount of tokens already sold.
    @prop(true)
    tokenAmtSold: bigint

    // The seller's public key.
    @prop()
    seller: PubKey

    // Asking price per BSV-20 token unit.
    @prop()
    pricePerUnit: bigint

    ...

    @method()
    public buy(amount: bigint, buyerAddr: Addr) {
        // Check token amount doesn't exceed total.
        assert(
            this.tokenAmtSold + amount < this.tokenAmt,
            'insufficient tokens left in the contract'
        )

        // Update cleared amount.
        this.tokenAmtSold += amount

        // Build transfer inscription.
        const transferInscription = BSV20V2.createTransferInsciption(
            this.id,
            amount
        )
        const transferInscriptionLen = len(transferInscription)

        // Fist output is the contract itself, holding the remaining tokens.
        // If no tokens are remaining, then terminate the contract
        const tokensRemaining = this.tokenAmt - this.tokenAmtSold
        let outputs = toByteString('')
        if (tokensRemaining > 0n) {
            outputs = this.buildStateOutput(1n)
        }

        // Ensure the sold tokens are being payed out to the buyer.
        outputs += BSV20V2.buildTransferOutput(
            pubKey2Addr(this.seller),
            this.id,
            amount
        )

        // Ensure the next output is paying the to the Bitcoin to the seller.
        const satsForSeller = this.pricePerUnit * amount
        outputs += Utils.buildPublicKeyHashOutput(
                        hash160(seller), satsForSeller)

        // Add change output.
        outputs += this.buildChangeOutput()

        // Check outputs.
        assert(hash256(outputs) == this.ctx.hashOutputs, 'hashOutputs mismatch')
    }

    @method()
    public cancel(buyerSig: Sig) {
        assert(this.checkSig(buyerSig, this.seller))
    }
}

BSV20SellLimitOrder

限价买入订单

限价卖出订单非常相似。 只是这一次,智能合约中锁定了一定数量的比特币,而不是 BSV-20 代币。

描述买入限价订单的交易图

由于智能合约本身无法确认 BSV-20 代币的真实性,因此使用了预言机服务。 预言机通过签署其引用以及金额和代币的铭文来保证代币的有效性。 智能合约验证此签名。

class BSV20BuyLimitOrder extends BSV20V2 {
    // Total amount of tokens we're buying.
    @prop()
    readonly tokenAmt: bigint

    // Amount of tokens already cleared.
    @prop(true)
    tokenAmtCleared: bigint

    // Public key of the oracle, that is used to verify the transfers
    // genesis.
    @prop()
    oraclePubKey: RabinPubKey

    // The buyer's public key.
    @prop()
    buyer: PubKey

    // Offered price per BSV-20 token unit.
    @prop()
    pricePerUnit: bigint

    ...

    @method()
    public sell(oracleMsg: ByteString, oracleSig: RabinSig, sellerAddr: Addr) {
        // Check oracle signature.
        assert(
            RabinVerifier.verifySig(oracleMsg, oracleSig, this.oraclePubKey),
            'oracle sig verify failed'
        )

        // Get token amount held by the UTXO from oracle message.
        const utxoTokenAmt = byteString2Int(slice(oracleMsg, 36n, 44n))

        // Check token amount doesn't exceed total.
        const remainingToClear = this.tokenAmt - this.tokenAmtCleared
        assert(
            utxoTokenAmt <= remainingToClear,
            'UTXO token amount exceeds total'
        )

        // Update cleared amount.
        this.tokenAmtCleared += utxoTokenAmt

        // Build transfer inscription.
        const transferInscription = BSV20V2.createTransferInsciption(
            this.id,
            utxoTokenAmt
        )
        const transferInscriptionLen = len(transferInscription)

        // Check that the ordinal UTXO contains the right inscription.
        assert(
            slice(oracleMsg, 44n, 44n + transferInscriptionLen) ==
                transferInscription,
            'unexpected inscription from oracle'
        )

        // Ensure the tokens are being payed out to the buyer.
        let outputs = BSV20V2.buildTransferOutput(
            pubKey2Addr(this.buyer),
            this.id,
            this.tokenAmt
        )

        // Ensure the second output is paying the Bitcoin to the seller.
        const satsForSeller = this.pricePerUnit * utxoTokenAmt
        outputs += Utils.buildPublicKeyHashOutput(sellerAddr, satsForSeller)

        // If there's tokens left to be cleared, then propagate contract.
        if (this.tokenAmtCleared == this.tokenAmt) {
            outputs += this.buildStateOutput(
                this.ctx.utxo.value - satsForSeller
            )
        }

        // Add change output.
        outputs += this.buildChangeOutput()

        // Check outputs.
        assert(hash256(outputs) == this.ctx.hashOutputs, 'hashOutputs mismatch')
    }

    @method()
    public cancel(buyerSig: Sig) {
        assert(this.checkSig(buyerSig, this.buyer))
    }
}

BSV20BuyLimitOrder

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1229300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

七,vi和vim

Linux系统会内置vi文本编辑器 Vim具有程序编辑的能力&#xff0c;可以看做是Vi的增强版本&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。代码补完、编译及错误跳转等方便编程的功能特别丰富&#xff0c;在程序员中被广泛使用。 vi和vim常用的三…

基因组坐标系统的 0-based 和 1-based(图文详解)

基因组坐标中的 “0-based” 和 “1-based” 是两种不同的规范&#xff0c;用于表示基因组上的位置。 它们在不同的上下文和文件格式中可能会有不同的使用方式。 下面我们聊聊它们间的区别和应用&#xff1a; 一、0-based 也叫做 zero-based half-open 示例 start0&#xf…

Wireshark网络工具

Wireshark是网络包分析工具。网络包分析工具的主要作用是尝试捕获网络包&#xff0c;并尝试显示包的尽可能详细的情况。 Wireshark是一个免费开源软件&#xff0c;不需要付费&#xff0c;免费使用&#xff0c;可以直接登陆到Wireshark的官网下载安装。 在windows环境中&#x…

KylinOSv10修改ulimit值

问题 ulimit 值过小&#xff0c;可能导致压力测试遇到瓶颈&#xff0c;比如通过nginx建立tcp长链接时&#xff0c;链接数量受限。需要修改ulimit值&#xff0c;Linux默认为1024。 解决 使用root或sudo权限&#xff0c;编辑文件/etc/security/limits.conf&#xff0c;新增以下…

龙讯旷腾PWmat发PRL:多k点计算的NAMD方法应用于小型超胞与在等效的大型超胞中进行的单个Γ点模拟之间的一致性

文章信息 作者信息&#xff1a;郑帆&#xff0c;汪林望 通信单位&#xff1a;上海科技大学 中国科学院半导体所 背景导读 固态材料中的超快载流子动力学在能源材料、光电子学、传感器和量子材料等领域起着关键作用。随着超快实验技术在固态系统中载流子动力学研究中的快速发…

(八)、基于 LangChain 实现大模型应用程序开发 | 基于知识库的个性化问答 (检索 Retrieval)

检索增强生成&#xff08;RAG&#xff09;的整体工作流程如下&#xff1a; 在构建检索增强生成 (RAG) 系统时&#xff0c;信息检索是核心环节。检索是指根据用户的问题去向量数据库中搜索与问题相关的文档内容&#xff0c;当我们访问和查询向量数据库时可能会运用到如下几种技术…

简单工程模式

代码实现 //simpleFactory.h #ifndef _SimpleFactory_H_ #define _SimpleFactory_H_#include <iostream> #include <exception> #include <string>using namespace std;class Operation { protected:double _numberA 0;double _numberB 0; public:Operat…

Python的requests库:解决文档缺失问题的策略与实践

在Python的requests库中&#xff0c;有一个名为ALL_PROXY的参数&#xff0c;但是该参数的文档并未进行详细的描述。这使得用户在使用该参数时可能会遇到一些问题&#xff0c;例如不知道如何正确地配置和使用该参数。 解决方案 针对这个问题&#xff0c;我们可以采取以下几种解…

单片微机原理与接口技术期末复习

第二章&#xff1a; STC15F2K60S2 参数含义 &#xff08;1&#xff09;“STC”代表的含义是不能在应用中访问程序存储器&#xff0c;但设置了可单独访问的数据 Flash 区域。 &#xff08;2&#xff09;F &#xff1a;工作电源为5V。 &#xff08;3&#xff09;2k&#xff1a;片…

PPT基础:表格

目录 表格基本功能底纹框线单元格表格美化 表格基本功能 底纹 所在位置&#xff1a;插入图表>>>表设计>>>底纹 底纹&#xff1a;相当于每个单元格的“颜色填充”如何用表格拆分图片 &#xff08;1&#xff09;生成一个表格>>>插入一张图片>>…

C#开发的OpenRA游戏之属性QuantizeFacingsFromSequence(7)

C#开发的OpenRA游戏之属性QuantizeFacingsFromSequence(7) 前面分析了身体的方向,在这里继续QuantizeFacingsFromSequence属性,这个属性就是通过序列定义文件里获取身体的方向。 根据前面分析可知,同样有一个信息类QuantizeFacingsFromSequenceInfo: [Desc("Deriv…

分布式与微服务 —— 初始

前言 距今微服务的提出已经过去快十个春秋&#xff0c;网络上的博文讲微服务也是一抓一大把&#xff0c;但是荔枝仍然觉得还是有必要自己梳理一下整个知识体系。在这篇文章中&#xff0c;荔枝将会以一个初学者的角度来切入&#xff0c;从分布式系统和微服务架构引入&#xff0c…

如何使用 WPF 应用程序连接 FastReport报表

随着期待已久的FastReport WPF的发布&#xff0c;您不再需要使用 FastReport .NET 来处理基于 WPF 的项目。 不久前&#xff0c;在 FastReport .NET 中使用 WPF 还相当不方便。并非一切都进展顺利&#xff1b;连接 FastReport.dll 和许多其他问题存在问题。我们重新思考了该方…

(十二)Flask重点之session

session 自我介绍&基本使用&#xff1a; 在Flask中&#xff0c;Session是一种用于在客户端和服务器之间存储和传输数据的机制。它允许您在用户与应用程序之间保持状态&#xff0c;并且可以存储和检索有关特定用户的信息。 Flask使用Werkzeug库提供的SecureCookie来实现S…

[黑马程序员SpringBoot2]——开发实用篇2

目录&#xff1a; Mongodb简介Mongodb下载与安装Mongodb基础操作Sprintboot整合MongodbES简介ES下载与安装ES索引操作ES文档操作SpringBoot整合ES客户端操作添加文档查询文档缓存的作用Spring缓存使用方式手机验证码案例-生成验证码手机验证码案例-验证码校验变更缓存供应商Eh…

逐字节讲解 Redis 持久化(RDB 和 AOF)的文件格式(一)

前言 相信各位对 Redis 的这两种持久化机制都不陌生&#xff0c;简单来说&#xff0c;RDB 就是对数据的全量备份&#xff0c;AOF 则是增量备份&#xff0c;而从 4.0 版本开始引入了混合方式&#xff0c;以 7.2.3 版本为例&#xff0c;会生成三类文件&#xff1a;RDB、AOF 和记…

6.10二叉树的所有路径(LC257-E,不太会)

算法&#xff1a; 前序遍历&#xff1a; 因为要让父节点指向孩子节点&#xff0c;才能输出路径。 递归与回溯相辅相成&#xff0c;只要有递归&#xff0c;就一定有回溯。 举个例子理解一下&#xff1a; 中&#xff1a;先push入1 左&#xff1a;再Push入2 右&#xff1a;再…

Linux系统编程 day03 Makefile、gdb、文件IO

Linux系统编程 day03 Makefile、gdb、文件IO 1. Makefile2. gdb3. 文件IO 1. Makefile Makefile文件中定义了一系列规则来指定哪些文件需要先编译&#xff0c;哪些文件需要后编译&#xff0c;哪些文件需要重新编译&#xff0c;甚至更加复杂的功能操作。Makefile就像一个shell脚…

详解“协方差”与“相关系数”

引言 PCA的目标对象是矩阵&#xff0c;例如&#xff0c;有m个样本&#xff0c;每个样本有n个特征&#xff0c;那么就可以构造成一个样本矩阵&#xff0c;并转换成矩阵的形式。 PCA的最终目的是减少特征的个数&#xff0c;去掉那些不重要的特征&#xff0c;也就是减小矩阵列向量…

【LeetCode:689. 三个无重叠子数组的最大和 | 序列dp+前缀和】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…