将 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: bigintconstructor(id: ByteString,max: bigint,dec: bigint,supply: bigint,maxMintAmount: bigint,lastUpdate: bigint,timeDelta: bigint) {super(id, max, dec)this.init(...arguments)this.supply = supplythis.maxMintAmount = maxMintAmountthis.lastUpdate = lastUpdatethis.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 -= rewardlet stateOutput = toByteString('')if (this.supply > 0n) {stateOutput = this.buildStateOutput(1n)}const rewardOutput = Utils.buildOutput(this.buildInscription(lock, reward),1n)const outputs: ByteString = stateOutput + rewardOutput + trailingOutputsassert(hash256(outputs) == this.ctx.hashOutputs,`invalid outputs hash ${stateOutput} ${rewardOutput} ${trailingOutputs}`)}@method()calculateReward(): bigint {let reward = this.rewardif (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 varif (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 += amountlet 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.alreadyMintedconst transferInscription = BSV20Mint.getTransferInsciption(this.tokenId,leftover)const stateScript = slice(this.getStateScript(),this.prevInscriptionLen) // Slice prev inscriptionoutputs += 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 * amountoutputs += Utils.buildPublicKeyHashOutput(this.icoAddr, priceTotal)// Build change output.outputs += this.buildChangeOutput()assert(hash256(outputs) == this.ctx.hashOutputs, 'hashOutputs mismatch')}
}

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

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

相关文章

Queue 中 poll()和 remove()的区别(详解)

系列文章目录 1.SpringBoot整合RabbitMQ并实现消息发送与接收 2. 解析JSON格式参数 & 修改对象的key 3. VUE整合Echarts实现简单的数据可视化 4. List&#xff1c;HashMap&#xff1c;String,String&#xff1e;&#xff1e;实现自定义字符串排序&#xff08;key排序、Val…

使用EvoMap/Three.js模拟无人机灯光秀

一、创建地图对象 首先我们需要创建一个EM.Map对象&#xff0c;该对象代表了一个地图实例&#xff0c;并设置id为"map"的文档元素作为地图的容器。 let map new EM.Map("map",{zoom:22.14,center:[8.02528, -29.27638, 0],pitch:71.507,roll:2.01,maxPit…

代码随想录算法训练营Day 47 || 198.打家劫舍、213.打家劫舍II、337.打家劫舍 III

198.打家劫舍 力扣题目链接(opens new window) 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系…

【Cheat Engine7.5】基础教程第三关(步骤4)

文章目录 一、简介二、操作步骤2.1、加载进程2.2、查找健康数据2.2.1、首次扫描(单浮点数100)2.2.2、点击打我&#xff0c;再次扫描数值97.112.2.3、修改数据值为50002.2.4、测试正常 2.3、查找弹药数据2.3.1、双浮点数1002.3.2、点击开火2.3.3、修改数据2.3.4、测试 2.4、通关…

微头条项目实战:通过postman测试登录验证请求

1、CrosFilter package com.csdn.headline.filters; import jakarta.servlet.*; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class CrosFilter implements Filter {/*** 过滤器方法&#xff0c;用于处理HTTP请求* param servletReq…

674. 最长连续递增序列 718. 最长重复子数组 1143.最长公共子序列 1035.不相交的线

674. 最长连续递增序列 题目&#xff1a; 给定一个未经排序的整数数组nums&#xff0c;找到最长且 连续递增的子序列&#xff0c;并返回该序列的长度。 dp数组含义&#xff1a; dp[i]&#xff1a;以下标i为结尾的连续递增的子序列长度为dp[i]。 递推公式&#xff1a; 怎么…

ai 问答时刻

妙啊 这很快 相当棒

希尔排序原理

目录&#xff1a; 一、希尔排序与插入排序 1&#xff09;希尔排序的概念 2&#xff09;插入排序实现 二、希尔排序实现 一、希尔排序与插入排序 1&#xff09;希尔排序的概念 希尔排序(Shells Sort)是插入排序的一种又称“缩小增量排序”&#xff08;Diminishing Incremen…

景区数字化营销怎么做?景区数字化营销优势

随着社会信息化、数字化趋势的不断加强&#xff0c;数字营销逐渐成为景区营销的重要方式之一。借助如蚓链数字化文旅营销系统&#xff0c;能够帮助景区提高知名度&#xff0c;吸引更多游客&#xff0c;同时也能够提高景区管理效率&#xff0c;降低人力成本。景区数字化营销有哪…

Go-服务注册和发现,负载均衡,配置中心

文章目录 什么是服务注册和发现技术选型 Consul 的安装和配置1. 安装2. 访问3. 访问dns Consul 的api接口go操作consulgrpc下的健康检查grpc的健康检查规范动态获取可用端口号 负载均衡策略1. 什么是负载均衡2. 负载均衡策略1. 集中式load balance2. 进程内load balance3. 独立…

图像二值化阈值调整——Triangle算法,Maxentropy方法

一. Triangle方法 算法描述&#xff1a;三角法求分割阈值最早见于Zack的论文《Automatic measurement of sister chromatid exchange frequency》主要是用于染色体的研究&#xff0c;该方法是使用直方图数据&#xff0c;基于纯几何方法来寻找最佳阈值&#xff0c;它的成立条件…

【AI】自回归 (AR) 模型使预测和深度学习变得简单

自回归 (AR) 模型是统计和时间序列模型&#xff0c;用于根据数据点的先前值进行分析和预测。这些模型广泛应用于各个领域&#xff0c;包括经济、金融、信号处理和自然语言处理。 自回归模型假设给定时间变量的值与其过去的值线性相关&#xff0c;这使得它们可用于建模和预测时…

Oracle11g for centos7

准备工作 x86 centos7 oracle11G 环境搭建 配置好虚拟机&#xff0c;网络通畅&#xff0c;建议最少3G内存。 安装依赖 yum install binutils compat-libstdc-33 glibc* ksh gcc gcc-c libgcc libstdc* libaio libaio-devel libXext libX11 libXau libxcb libXi make sy…

蓝桥杯每日一题2023.11.8

题目描述 题目分析 对于输入的abc我们可以以a为年也可以以c为年&#xff0c;将abc,cab,cba这三种情况进行判断合法性即可&#xff0c;注意需要排序去重&#xff0c;所以考虑使用set 此处为纯模拟的写法&#xff0c;但使用循环代码会更加简洁。 方法一&#xff1a; #include&…

【MongoDB-Redis-MySQL-Elasticsearch-Kibana-RabbitMQ-MinIO】Java全栈开发软件一网打尽

“Java全栈开发一网打尽&#xff1a;在Windows环境下探索技术世界的奇妙之旅” 前言 全栈开发是一项复杂而令人兴奋的任务&#xff0c;涵盖了从前端到后端、数据库到可视化层、消息队列到文件存储的广泛领域。本文将带您深入探讨在Windows环境下进行全栈开发的过程&#xff0…

Kafka JNDI 注入分析(CVE-2023-25194)

Apache Kafka Clients Jndi Injection 漏洞描述 Apache Kafka 是一个分布式数据流处理平台&#xff0c;可以实时发布、订阅、存储和处理数据流。Kafka Connect 是一种用于在 kafka 和其他系统之间可扩展、可靠的流式传输数据的工具。攻击者可以利用基于 SASL JAAS 配置和 SAS…

02-PostgreSQL的基本使用

一、数据库操作 ①: 登录到数据库 psql -U postgres -d postgres -h 127.0.0.1②:查看所有数据库 \l③: 创建数据库 # 创建一个名为 mydb 的数据库 create database mydb;④:切换数据库 # \c 数据库名 \c mydb⑤:删除数据库 # 删除前 先确保数据库没有被连接 drop databa…

Linux学习笔记之五(父子进程、孤儿进程、僵尸进程、守护进程)

Linux 1、进程1.1、进程的六种状态1.2、创建子进程1.3、添加子进程任务1.4、孤儿进程、僵尸进程、守护进程1.4.1、避免僵尸进程1.4.2、创建守护进程1.4.3、杀死守护进程 1.5、综合练习 1、进程 进程可以简单的理解为一个正在执行的程序&#xff0c;它是计算机系统中拥有资源和…

小红书母婴博主投放技巧是什么,怎么避免无用功

如今&#xff0c;随着互联网的发展&#xff0c;母婴博主和社交媒体成为了很多妈妈们&#xff0c;获取育儿知识和建立社交圈的重要途径。今天为大家分享下小红书母婴博主投放技巧是什么&#xff0c;怎么避免无用功&#xff01; 一、优质的母婴博主在哪里 我们都知道&#xff0c;…

数据中台之数据分析

效果界面 技术方案 Notebook集成 在您的数据平台上,创建一个能够与Jupyter Notebook通讯的服务。通过Jupyter Notebook的HTTP API与Notebook实例进行交互,执行代码、获取输出等。用户界面 在数据开发/数据分析的代码框右上方,添加一个机器人样式的图标,用户点击后可以调起…