将 Ordinals 与比特币智能合约集成:第 4 部分

控制 BSV-20 代币的分配

在上一篇文章中,我们展示了智能合约可以在铸造后控制 BSV-20 代币的转移。 今天,我们演示如何控制此类代币的分发/发行。

无Tick模式

BSV-20 在 V2 中引入了无Tick模式,并采用了与 V1 不同的方法。

部署 (Deploy)

要部署和铸造供应量为 21000000 的代币,请写入以下 JSON(ContentType:application/bsv-20):


{ 
  "p": "bsv-20",
  "op": "deploy+mint",
  "amt": "21000000",
  "sym": "sCrypt",
  "dec": "10"
}

请注意,与 V1 不同,没有指定的 tick 字段(因此无 tick)。

sym 字段仅代表代币名称,不用于建立代币的索引。

发行 (Issue)

要发行上述 10000 个代币,您可以使用以下 JSON 创建转移铭文:

{ 
  "p": "bsv-20",
  "op": "transfer",
  "id": "3b313338fa0555aebeaf91d8db1ffebd74773c67c8ad5181ff3d3f51e21e0000_1"
  "amt": "10000",
}

代币不是通过 tick 来标识,而是通过 id 字段来标识,该字段由交易 ID 和部署代币的输出索引组成,格式为 _。

此外,第一个发行交易必须从部署交易中支出,因为整个供应量是立即铸造的,而铸造交易不会从中支出,并且它们在 V1 中是分开的。 这意味着代币的每笔交易都可以追溯到该代币的创世部署,并且每笔交易都位于植根于创世交易的 DAG(有向无环图)中。 这使得 BSV-20 索引器能够更有效地扩展,因为它不必扫描整个区块链并排序铸币交易,以强制“first is first”铸币。

有关 BSV-20 代币 V2 工作原理的更多详细信息,请阅读官方文档。

公平发布

与 ERC-20 代币相比,BSV-20 V1 代币的一个显着特点是公平发行。 具体来说,一旦有人在 BSV-20 上部署代币交易,每个人都有相同的机会领取代币。 发行人不能免费预留一部分,即没有预挖。

如果在 V2 无代码模式下部署时一次性铸造出总供应量,是否可以保持公平发布?

答案是肯定的。 我们在部署时没有将整个供应锁定在标准发行人地址(P2PKH 脚本)中,而是将其锁定在智能合约中。 任何人都可以调用智能合约,并且可以在其中执行任何分配策略。
在这里插入图片描述
在上图中,每个方框代表一个代币 UTXO,堆叠的 UTXO 位于同一笔交易中。 第二笔交易花费了第一笔部署交易的 UTXO(如第一个箭头所示),并创建了两个 UTXO:

  • 创世时相同合约的衍生副本,但剩余供应量减少
  • 新发行的代币。

交易链一直持续到整个代币供应被发行为止。 请注意,任何人都可以调用该合约。

我们列出了一些分发策略作为示例。

速率限制

根据这项策略,任何人都可以领取代币,只要距离最后一次领取的时间超过 5 分钟即可。 合约如下。

export class BSV20Mint extends BSV20V2 {
    @prop(true)
    supply: bigint

    @prop()
    maxMintAmount: bigint

    @prop(true)
    lastUpdate: bigint

    @prop()
    timeDelta: bigint

    constructor(
        id: ByteString,
        max: bigint,
        dec: bigint,
        supply: bigint,
        maxMintAmount: bigint,
        lastUpdate: bigint,
        timeDelta: bigint
    ) {
        super(id, max, dec)
        this.init(...arguments)

        this.supply = supply
        this.maxMintAmount = maxMintAmount
        this.lastUpdate = lastUpdate
        this.timeDelta = timeDelta
    }

    @method()
    public mint(dest: Addr, amount: bigint) {
        // Check time passed since last mint.
        assert(
            this.timeLock(this.lastUpdate + this.timeDelta),
            'time lock not yet expired'
        )

        // Update last mint timestamp.
        this.lastUpdate = this.ctx.locktime

        // Check mint amount doesn't exceed maximum.
        assert(amount <= this.maxMintAmount, 'mint amount exceeds maximum')

        // Update supply.
        this.supply -= amount

        // If there are still tokens left, then
        // build state output inscribed with leftover tokens.
        let outputs = toByteString('')
        if (this.supply > 0n) {
            outputs += this.buildStateOutputFT(this.supply)
        }

        // Build FT P2PKH output to dest paying specified amount of tokens.
        outputs += BSV20V2.buildTransferOutput(dest, this.id, amount)

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

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

合约源代码

第 6-12 行强制执行速率限制。 第 26-30 行确保不超过供应量。 如果是,第 38-52 行将创建一个包含相同合约但具有更新状态的输出:剩余供应量。 第 55-58 行向目标地址发出令牌。

迷你工作量证明

该策略确保任何人都可以领取代币,只要她发现随机数满足某些特定的难度要求,就像比特币的工作量证明(PoW)一样。

export class Pow20 extends SmartContract {
    // ...

    @method(SigHash.ANYONECANPAY_ALL)
    public mint(
        nonce: ByteString,
        lock: ByteString,
        trailingOutputs: ByteString
    ) {
        if (len(this.id) == 0n) {
            this.id =
                this.ctx.utxo.outpoint.txid +
                int2ByteString(this.ctx.utxo.outpoint.outputIndex, 4n)
  }
        this.pow = this.validatePOW(nonce)
        const reward = this.calculateReward()
        this.supply -= reward
        let stateOutput = toByteString('')
        if (this.supply > 0n) {
            stateOutput = this.buildStateOutput(1n)
        }
        const rewardOutput = Utils.buildOutput(
            this.buildInscription(lock, reward),
            1n
        )

        const outputs: ByteString = stateOutput + rewardOutput + trailingOutputs
        assert(
            hash256(outputs) == this.ctx.hashOutputs,
            `invalid outputs hash ${stateOutput} ${rewardOutput} ${trailingOutputs}`
        )
    }

    @method()
    calculateReward(): bigint {
        let reward = this.reward
        if (this.supply < this.reward) {
            reward = this.supply
        }
        return reward
    }

    @method()
    validatePOW(nonce: ByteString): ByteString {
        const pow = hash256(this.pow + nonce)
        const test = rshift(Utils.fromLEUnsigned(pow), 256n - this.difficulty)
        assert(test == 0n, pow + ' invalid pow')
        return pow
    }
}
归功于: David Case

ICO

可以实施一项策略,以便任何人都可以通过以无需信任的方式将比特币发送到特定地址来接收代币,类似于首次代币发行(ICO)。 在上图中,添加了第三个输出用于比特币支付,该输出在合约中进行验证。

export class BSV20Mint extends SmartContract {
    // ...

    @method()
    public mint(dest: Addr, amount: bigint) {
        // If first mint, parse token id and store it in a state var
        if (this.isFirstMint) {
            this.tokenId =
                BSV20Mint.txId2Ascii(this.ctx.utxo.outpoint.txid) +
                toByteString('_', true) +
                BSV20Mint.int2Ascii(this.ctx.utxo.outpoint.outputIndex)
            this.isFirstMint = false
        }

        // Check if tokens still available.
        assert(
            this.totalSupply - this.alreadyMinted >= amount,
            'not enough tokens left to mint'
        )

        // Update already minted amount.
        this.alreadyMinted += amount

        let outputs = toByteString('')

        if (this.alreadyMinted != this.totalSupply) {
            // If there are still tokens left, then
            // build state output inscribed with leftover tokens.
            const leftover = this.totalSupply - this.alreadyMinted
            const transferInscription = BSV20Mint.getTransferInsciption(
                this.tokenId,
                leftover
            )
            const stateScript = slice(
                this.getStateScript(),
                this.prevInscriptionLen
            ) // Slice prev inscription
            outputs += Utils.buildOutput(transferInscription + stateScript, 1n)

            // Store next inscription length, so we know how much to slice in the next iteration.
            this.prevInscriptionLen = len(transferInscription)
        }

        // Build P2PKH output to dest paying specified amount of tokens.
        const script1 =
            BSV20Mint.getTransferInsciption(this.tokenId, amount) +
            Utils.buildPublicKeyHashScript(dest)
        outputs += Utils.buildOutput(script1, 1n)

        // Calculate total price for minted amount and enforce payment to ICO address.
        const priceTotal = this.icoPrice * amount
        outputs += Utils.buildPublicKeyHashOutput(this.icoAddr, priceTotal)

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

openinstall携手途虎养车,赋能汽车服务数字化

近日&#xff0c;openinstall与中国领先的一站式汽车服务平台途虎养车再次续约&#xff0c;双方将开启第三年合作。过去两年&#xff0c;途虎在建设线上线下一体化数字平台的过程中&#xff0c;深度结合openinstall传参归因与渠道统计技术&#xff0c;打造出了一套高效的渠道来…

聚焦千兆光模块和万兆光模块的测试技术及设备

千兆光模块和万兆光模块的测试技术涉及多个方面&#xff0c;如光学性能测试、电气性能测试、动态性能测试、温度测试、环境和耐久性测试等。不同的测试技术可以验证不同的光模块的性能和稳定性&#xff0c;从而确保光模块在各种应用场景下的可靠性&#xff0c;下面将介绍一些常…

PSP - 蛋白质复合物结构预测 模版配对(Template Pair) 逻辑的特征分析

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/134328447 在 蛋白质复合物结构预测 的过程中&#xff0c;模版 (Template) 起到重要作用&#xff0c;提供预测结果的关于三维结构的先验信息&…

Ubuntu2004字体不清晰,排查流程

昨天一早来发现平时用的Ubuntu2004物理机的字体变得很模糊&#xff0c;之前还是好好的&#xff0c;这里记录一下解决方案。 解决方案 通过显示器物理按键设置“自适应”解决&#xff0c;我的显示器是长城的&#xff0c;“自适应”按钮是右边从下往上数第二个。 排查流程 我先…

WordPress Modown 6.2付费下载资源/付费查看内容 wp主题模板+erphpdown11.7

模板简介&#xff1a; 自适应响应式设计&#xff0c;兼容主流浏览器 网格样式与瀑布流样式任意切换 内置SEO优化 自带与主题UI完美兼容搭配的erphpdown前端用户中心页面&#xff08;此功能若单独找我们定制也需要几百&#xff09; 收费付费下载资源、付费查看内容、付费观看…

GoLong的学习之路(二十一)进阶,语法之并发(go最重要的特点)(协程的主要用法)

并发编程在当前软件领域是一个非常重要的概念&#xff0c;随着CPU等硬件的发展&#xff0c;我们无一例外的想让我们的程序运行的快一点、再快一点。Go语言在语言层面天生支持并发&#xff0c;充分利用现代CPU的多核优势&#xff0c;这也是Go语言能够大范围流行的一个很重要的原…

【Delphi】Android 开发HTTP请求出错解决方案

目录 一、故障现象 二、原因及解决方案 一、故障现象 在android内建的WebBrowser浏览器中通过http访问一个网站&#xff08;注意不是https&#xff09;&#xff0c;出现如下错误提示&#xff1a; 在使用ntfy的时候&#xff0c;访问http定义的服务器地址&#xff08;注意不是…

MySQL模糊查询/模式匹配(Pattern Match)

使用SQL查询数据时&#xff0c;时常会遇到这种情况&#xff0c;我们并不需要精确的匹配&#xff0c;而是要查找具有某类特点的数据。这种场景我们就要用到模糊查询。MySQL中常用的模糊查询方法有2种&#xff1a; like语句模糊查询regexp正则表达式模式匹配 目录 一、使用like模…

大厂面试题-为什么索引要用B+树来实现呢,而不是B树?

首先&#xff0c;常规的数据库存储引擎&#xff0c;一般都是采用B树或者B树来实现索引的存储。 (如图)因为B树是一种多路平衡树&#xff0c;用这种存储结构来存储大量数据&#xff0c;它的整个高度会相比二叉树来说&#xff0c;会矮很多。 而对于数据库来说&#xff0c;所有的…

【191】Java8在大比例尺小范围地图上,根据wgs84坐标系的经纬度计算两个点之间的方向和距离

场景 本文代码在大比例迟、小范围的地图上测试过。这些地图一般是县、区、镇、街道等范围的&#xff0c;其测试效果较好。由于地图范围较小&#xff0c;可以把经纬度近似看作直线。 问题分析 方向一共分东、南、西、北、东北、西北、西南、东南共八个方向。一周是 360 度&am…

最新GitHub学生认证,可以愉快的使用Copilot了(保姆级教程)

&#x1f388;博客主页&#xff1a;&#x1f308;我的主页&#x1f308; &#x1f388;欢迎点赞 &#x1f44d; 收藏 &#x1f31f;留言 &#x1f4dd; 欢迎讨论&#xff01;&#x1f44f; &#x1f388;本文由 【泠青沼~】 原创&#xff0c;首发于 CSDN&#x1f6a9;&#x1f…

“深入理解机器学习性能评估指标:TP、TN、FP、FN、精确率、召回率、准确率、F1-score和mAP”

目录 引言 分类标准 示例&#xff1a;癌症检测 1. 精确率&#xff08;Precision&#xff09; 2. 召回率&#xff08;Recall&#xff09; 3. 准确率&#xff08;Accuracy&#xff09; 4. F1-score 5. mAP&#xff08;均值平均精度&#xff09; 总结与通俗解释 引言 机器…

电销行业获客的精准客源从哪里来的?

在电话营销行业中找到精确的客户资源对电话营销的成功至关重要。 这里有几种方法可以找到准确的客户资源&#xff1a; 1、自身数据库&#xff1a;首先&#xff0c;使用现有的客户信息数据库&#xff0c;如客户电话号码、电子邮件和地址&#xff0c;来推广和营销现有客户。 2…

django 批量 serializers listserializers

Django drf 序列化器 序列化器 扩展serializers的有用性是我们想要解决的问题。但是&#xff0c;这不是一个微不足道的问题&#xff0c;而是需要一些严肃的设计工作。— Russell Keith-Magee, Django用户组 序列化器允许把像查询集和模型实例这样的复杂数据转换为可以轻松渲染…

基于element-plus定义表单配置化

文章目录 前言一、配置化的前提二、配置的相关组件1、新建form.vue组件2、新建input.vue组件3、新建select.vue组件4、新建v-html.vue组件5、新建upload.vue组件6、新建switch.vue组件7、新建radio.vue组件8、新建checkbox.vue组件9、新建date.vue组件10、新建time-picker.vue组…

泄露35TB数据,医疗巨头Henry Schein遭受黑猫勒索组织攻击

近日&#xff0c;据Bleeping Computer 网站消息&#xff0c;BlackCat&#xff08;黑猫&#xff09;勒索软件团伙将医疗保健巨头Henry Schein 添加到了其暗网泄露网站&#xff0c;并声称其破坏了该公司的网络&#xff0c;窃取了35 TB的敏感文件&#xff0c;这些文件包括了Henry …

【算法】道路与航线(保姆级题解)

题目 农夫约翰正在一个新的销售区域对他的牛奶销售方案进行调查。 他想把牛奶送到 T 个城镇&#xff0c;编号为 1∼T。 &#xff08;存在T个点&#xff09; 这些城镇之间通过 R 条道路 (编号为 1 到 R) 和 P 条航线 (编号为 1 到 P) 连接。 &#xff08;存在R条道路&#…

Bytebase 2.11.0 - 支持 OceanBase Oracle 模式

&#x1f680; 新功能 支持 OceanBase Oracle 模式。支持设置 MySQL 在线变更参数。新增项目数据库查看者的角色。 &#x1f384; 改进 支持在项目中直接选择所有用户并为之添加角色。 调整了项目页面的布局。在 SQL 编辑器中通过悬浮面板展示表和列的详情。 &#x1faa6; …

全局后置路由守卫(afterEach)

全局后置路由守卫&#xff08;afterEach&#xff09; 功能&#xff1a;每一次切换任意路由组件之后都会被调用&#xff0c;相当于在进入下一个路由组件之后设置一个权限。 使用原理 代码创建的位置&#xff1a; 在创建router之后&#xff08;const router new VueRouter&…

基于自然语言处理的结构化数据库问答机器人系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 Wechat / QQ 名片 :) 1. 项目简介 知识库&#xff0c;就是人们总结出的一些历史知识的集合&#xff0c;存储、索引以后&#xff0c;可以被方便的检索出来供后人查询/学习。QnA Maker是用于建立知识库的工具&#xff0c;使用…