将 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.hqwc.cn/news/169404.html

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

相关文章

ENVI IDL:如何将txt文本文件转化为GeoTIFF文件?

01 前言 此处的文本文件形式如下&#xff1a; 里面包含了众多点位信息&#xff08;不是站点数据&#xff09;&#xff0c;我们需要依据上述点的经纬度信息放到对应位置的像素点位置&#xff0c;放置完后如下&#xff1a; 可以发现&#xff0c;还存在部分缺失值&#xff0c;我们…

【强化学习】18 —— SAC( Soft Actor-Critic)

文章目录 前言最大熵强化学习不同动作空间下的最大熵强化学习基于能量的模型软价值函数最大熵策略 Soft Q-learningSoft Q-IterationSoft Q-Learning近似采样与SVGD伪代码 Soft Actor-Critic伪代码代码实践连续动作空间离散动作空间 参考与推荐 前言 之前的章节提到过在线策略…

基于STC12C5A60S2系列1T 8051单片机串口通信信应用

基于STC12C5A60S2系列1T 8051单片机串口通信应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机串口通信介绍STC12C5A60S2系列1T 8051单片机串口通信的结构基于STC12C5A60S2系列1T 8051单片机串口通信的特殊功能寄存器列表基于STC12C5A60S2系列1T 8051单片…

冯·诺依曼结构

一、约翰冯诺依曼---计算机之父 约翰冯诺依曼&#xff08;John von Neumann&#xff0c;1903年12月28日—1957年2月8日&#xff09;&#xff0c;出生于匈牙利布达佩斯&#xff0c;匈牙利裔美籍数学家、计算机科学家、物理学家和化学家&#xff0c;美国国家科学院院士&#xff…

C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发004:游戏核心消息处理 - 玩家类的实现

文章目录 0 代码仓库1 需求2 AOI设计2.1 AOI算法简介2.2 AOI数据结构及实现2.2.1 玩家2.2.2 网格对象2.2.3 游戏世界矩形2.2.4 获取周围玩家的实现2.2.5 代码测试 2.3 GameRole结合AOI创建玩家2.3.1 创建游戏世界全局对象-GameRole继承AOIWorld的Player2.3.2 把玩家到游戏世界的…

C#中基于.NET6的动态编译技术

前几天要解决动态计算问题&#xff0c;尝试着使用了不同的方法。问题是给定一个包含计算的字符串&#xff0c;在程序运行中得到计算结果&#xff0c;当时考虑了动态编译&#xff0c;在网上查了一些资料完成了这项功能&#xff0c;可是基于不同的.NET平台使用的编程代码相差比较…

人工智能基础——图像认知与OpenCV

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

goroutine调度模型 调度策略

文章目录 背景 协程线程与协程的对比线程&#xff08;Thread&#xff09;协程&#xff08;Coroutine&#xff09; 运作线程模型 goroutine调度模型与演进过程G-M模型G-P-M模型抢占式调度器其他优化 调度策略队列轮转系统调用工作量窃取抢占式调度GOMAXPROCS 对性能的影响 Go在语…

MySQL:日志系统

目录 概述错误日志&#xff08;error log&#xff09;慢查询日志&#xff08;slow query log&#xff09;一般查询日志( general log )中继日志&#xff08;relay log&#xff09;Buffer Pool 缓存回滚日志&#xff08;undo log)概述undo log 作用undo log 的存储机制Undo log …

开发者测试2023省赛--Square测试用例

测试结果 官方提交结果 EclEmma PITest 被测文件 [1/7] Square.java /*** This class implements the Square block cipher.** <P>* <b>References</b>** <P>* The Square algorithm was developed by <a href="mailto:Daemen.J@banksys.co…

Linux--vim

一、vim的基础介绍 vim是一个老式的文字处理工具&#xff0c;但是功能很齐全&#xff0c;不仅是文本处理工具&#xff0c;还是一个程序编辑工具&#xff0c;包含了很多额外的功能 为什么Linux使用vim&#xff1f; ①所有类Unix系统都内置vi&#xff0c;而vim相当于是vi的升级版…

MySQL中外键的使用及外键约束策略

一、外键约束的概念 外键约束&#xff08;FOREIGN KEY,缩写FK是数据库设计的一个概念&#xff0c;它确保在两个表之间的关系保持数据的一致性和完整性。 外键是指表中的某个字段的依赖于另一张表中某个字段的值&#xff0c;而被依赖的字段必须具有主键约束或者唯一约束&#…