@bsv/templates

中文文档
2.2.0发布于 2026/10/30SEE LICENSE IN LICENSE.txtTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 2338

BSV 块链脚本模板

中文使用文档
文档目录12 节
  1. 概览
  2. 使用
  3. 当前模板
  4. 签名信任边界
  5. BRC-162 令牌 : Bsv21Binary
  6. 1 颜色有效载荷属性
  7. 严格的 CBOR 有效载荷
  8. R1-K1 硬件钱包
  9. 贡献准则
  10. 支持联系人( C)
  11. 许可证
  12. SDK4 热补丁对等要求

BSV 脚本模板

候选人 2.2.0 添加 1 Color 属性读取器(readOneColorAttributes, (中文(简体) ), reqMatchesDeploy, (中文(简体) ), OneColor.lockRemainder 和36字节的认识 oneColorTokenId* 在已出版文件之上的助手 2.1.1 (单位:千美元) OneColor BRC-162模板和SDK4对等支持. 现有的模板、有线格式和默认仍然得到支持。 添加剂API和迁移指南如下.

BSV BLOCKCHAIN QQ 脚本模板

用于官方 BSV 类型SDK 的脚本模板集

概览

这个寄存器的目标是提供一个位置,让来自生态系统周围的开发者可以发布各种脚本模板,而无需更新核心库. 我们一般对人们的贡献是中立的,没有偏见的,所以可以自由地贡献,看看人们用你的酷点子做什么!

使用

你可以这样写代码:

import { Transaction } from '@bsv/sdk'
import { OpReturn } from '@bsv/templates'

// Then, just use your template with the SDK!
const instance = new OpReturn()
const tx = new Transaction()
tx.addOutput({
  lockingScript: OpReturn.lock(...),
  satoshis: ...
})

当前模板

名称说明
Bsv21 纸币锁定并解码 BRC-162( BSV- 21 二进制) 符号输出
单色锁定、解码并读取 BRC-162 1
选择返回在非消耗性脚本中标记数据
梅达特创建遵循 Metanet 协议的交易
多笔创建多个可信任所有者的数据令牌
P2MSKH (英语)使用M-of-N公用钥匙阈值
R1K1 钱包正常使用 P-256 硬件和 K1 恢复键

签名信任边界

签名模板验证源交易 ID, 输出索引, satoshi 数量、锁定脚本、序列和签名范围,然后请求 钱包签名。 当一个完整的源交易和明确的源 元数据是提供的,它们必须完全一致。 将验证失败视为一种 源验证或交易构建错误; 不丢弃重试 一种相互矛盾的价值观.

MultiPushDrop 仅标出完整的合同形状和支持 最多120个不同的压缩锁键。 其记录的可信任拥有者 模式仍然适用:任何一位拥有者都可以花去或摧毁该令牌.

P2MSKH 只在命令的公用钥匙列表中将承诺排入 源代码锁定脚本和钱包生成的签名密钥属于此 列表中选择一个选项。 在收集递增签名时,保留同样订购的清单; 地址、密钥列表或部分解锁未信任方的脚本 已核实,但本身并不证明打算付款的政策是安全的.

BRC-162 令牌 : Bsv21Binary

OneColor 是 BRC-162 1 Color 模板。 它读和写相同的产出 作为 Bsv21Binary 以及首次部署于 非零输出时的BRC-161(<txid>_<vout>);一个36字节的代号 有vout 0是 拒绝. Bsv21Binary 不变,仍然只接受32字节的id.

Bsv21Binary 构建和阅读 BRC-162号卫星 (BSV-21二进制) 符号输出。 符号输出是普通锁定脚本上的固定前缀 :

<token id | OP_0> <amount> OP_2DROP [<payload> OP_DROP] OP_DUP OP_HASH160 <pkh> OP_EQUALVERIFY OP_CHECKSIG
import { PrivateKey } from '@bsv/sdk'
import { Bsv21Binary, encodeStrictCbor, tokenIdFromString, tokenIdToString } from '@bsv/templates'

const owner = PrivateKey.fromRandom()
const pubKeyHash = owner.toPublicKey().toHash() as number[]

// A deploy output has a null token id; its payload is a strict-CBOR map.
const template = new Bsv21Binary()
const deployScript = template.lock(null, 0n, pubKeyHash, encodeStrictCbor({ sym: 'USD', dec: 2n }))
console.log(Bsv21Binary.decode(deployScript).role) // 'deploy'

// Later outputs name the token by `<deploy txid, 64 lowercase hex>_0`.
const tokenId = `${'ab'.repeat(32)}_0`
const lockingScript = template.lock(tokenId, 1_000_000n, pubKeyHash) // amounts are bigint

const decoded = Bsv21Binary.decode(lockingScript)
console.log(decoded.role) // 'value' ('authority' when the amount is 0n)
console.log(decoded.amount) // 1000000n
console.log(decoded.tokenId !== undefined && tokenIdToString(decoded.tokenId) === tokenId) // true
console.log(tokenIdFromString(tokenId).length) // 32 wire bytes, natural order

每个值都有一个被接受的编码 所以每个读取 相同的字节读取相同的同义输出 :

  • 托肯编号 : 直接推出32个字节(在自然情况下部署 txid) 字节顺序),或 OP_0 在部署. OP_PUSHDATA* 不接受.
  • 数额 : bigint, (中文(简体) ), 0 改为 2^64 - 1。 。 。 . 0 实值 OP_0, (中文(简体) ), 1 改为 16 为: OP_1 改为 OP_16,任何更大的 是一个直接的推动(0x01 改为 0x09页:1 最小的小endian脚本号。 以下政策上限 2^64 - 1总计 各种投入和产出的算术和养护属于呼叫者.
  • 角色 : deploy (无编号), authority (id,数额) 0)或(或) value。 。 。 .
  • 无效的对非符号 : isTokenShaped(script) 告诉剧本 开始 <push> <push> OP_2DROP 从任何其他脚本. Bsv21Binary.decode 掷出 Bsv21BinaryError 对于一个非空想的符号形状的脚本 (例如数额) 5 被推为 01 05因此,它从来没有默默地读作 "不是一个标志".

1 颜色有效载荷属性

readOneColorAttributes(payload) 读取 1Color 输出在 bRC-207钱包规则。 是纯净而从来所出所出所出所出所出所出所出所出所出所出所出所出所出所出. payload 表示输出包含的内容:

  • 'absent':不推进有效载荷;
  • 'empty': 零字节有效载荷(OP_0 OP_DROP(三);
  • 'opaque': 非零字节为非严格有效的 DAG- CBOR 映射 (行走字节,不排序或重复键,非映射字节外出) 0.255) (中文(简体) ). 没有从中恢复任何东西;
  • 'map': 严格有效的 DAG- CBOR 地图, 也作为 map。 。 。 .

每个保留栏(dec, (中文(简体) ), sym, (中文(简体) ), icon, (中文(简体) ), req, (中文(简体) ), ext)为 { status: 'absent' }, (中文(简体) ), { status: 'valid', value } 或者说 { status: 'malformed', reason }每个字段 'absent' 除非 payload 实值 'map'。在地图中,存在但形状不好的保留键是 'malformed'永远 'absent'数字 :

  • dec: 无符号的 CBOR 整数 0 改为 18一个浮点,甚至 2.0,为畸形;
  • sym: 文本;
  • icon: 准确无误 [mediaType text, bytes]。显示会处理格式错误的图标 缺席;
  • req: 一张来自 process- profile ids (isProfileId确切地说 { params, version }, (中文(简体) ), version a 未签名的 CBOR 整数 1 改为 2^32 - 1 财务报告和审定财务报表 params 任何数值,包括 null。 。 。 . reqBytes 准确的线段 会 议 日 程 和 议 程 req 值,仅在 req 有效;
  • ext: 从处理- profile ids 到任意值的地图 .

reqMatchesDeploy(deploy, later) 检查后期输出是否重复 部署 req失败关闭,按此顺序:部署不当 req 给 false 用于后期输出; 后期输出不包含 req 给 true页:1 后经畸形 req 给 false; 否则, Canonial DAG- CBOR 字节 必须平等,部署时没有 req 计数为空地图 a0字节 以文字作比较,故 params: 1.0 永远不匹配 params: 1。 。 。 .

OneColor.lockRemainder(tokenId, amount, remainder, payload?) 将一彩色 任何锁定脚本前的前缀。 没有有效载荷和剩余 开始于 <push> OP_DROP,它写着空负载标记 OP_0 OP_DROP 首先(BRC-162),所以其余的首个推力从不读作: 有效载荷。 这里的推力是 OP_0, (中文(简体) ), OP_1NEGATE, (中文(简体) ), OP_1 改为 OP_16 或任何数据 推动. needsEmptyPayloadMarker(remainder.chunks) 告诉它会不会.

新的 1 Color 代码应该更可取 oneColorTokenIdFromString 财务报告和审定财务报表 oneColorTokenIdToString,它接受32和36字节的id. tokenIdFromString 财务报告和审定财务报表 tokenIdToString 接受32字节_0仅限身份证.

import { PrivateKey } from '@bsv/sdk'
import {
  OneColor,
  encodeStrictCbor,
  oneColorTokenIdFromString,
  readOneColorAttributes,
  reqMatchesDeploy
} from '@bsv/templates'

const pubKeyHash = PrivateKey.fromRandom().toPublicKey().toHash() as number[]
const template = new OneColor()

const deployScript = template.lock(null, 0n, pubKeyHash, encodeStrictCbor({ sym: 'USD', dec: 2n }))
const deploy = readOneColorAttributes(OneColor.decode(deployScript).payload)
if (deploy.dec.status === 'valid') console.log(deploy.dec.value) // 2

const tokenId = `${'ab'.repeat(32)}_1` // a BRC-161 asset deployed at output 1
console.log(oneColorTokenIdFromString(tokenId).length) // 36
const later = readOneColorAttributes(
  OneColor.decode(template.lock(tokenId, 5n, pubKeyHash)).payload
)
console.log(later.payload) // 'absent'
console.log(reqMatchesDeploy(deploy, later)) // true: the later output omits req

严格的 CBOR 有效载荷

有效载荷属性从一个小的无依赖子集读取 DAG- 边境保护局,因此两个解码器不能 从同一个字节读取不同的属性. encodeStrictCbor 写下来, decodeStrictCbor 掷出 StrictCborError 财务报告和审定财务报表 tryDecodeStrictCbor 返回时 undefined 对于它之外的一切:

  • 顶级是带有文本密钥的地图,严格通过编码字节增加 (无重复);
  • 值是无符号整数,最多为 2^64 - 1 (单位:千美元)bigint),字节字符串 (单位:千美元)Uint8Array),严格的UTF-8文本, null、布林图和嵌入图;
  • 信头有确定和最小长度;
  • 筑巢深度最多 STRICT_CBOR_MAX_DEPTH (4) 编码最多 STRICT_CBOR_MAX_BYTES (4096年),没有后行字节.

浮点、标记(包括42个)、负整数、阵列和无限期长度 拒绝.

2.0.0版本删除 MandalaToken, (中文(简体) ), MandalaAdmin 财务报告和审定财务报表 ADMIN_PROTOCOL· ; BRC-162号卫星 Bsv21Binary 产出取而代之,与电线兼容.

R1-K1 硬件钱包

R1K1Wallet 承诺 HASH160(compressedR1PublicKey || privateSalt) (单位:千美元) 分离的secp256k1公用钥匙散列。 盐会隐藏 PIV 公钥的再利用 直至R1支出显示两种值。 保持每32字节盐的备份 钱包元数据; 丢失它会禁用输出的 R1 路径而不是 K1 复原.

import { Hash, type PrivateKey, Utils } from '@bsv/sdk'
import { R1K1Wallet } from '@bsv/templates'

declare const compressedP256PublicKeyHex: string
declare const k1RecoveryPrivateKey: PrivateKey
declare const signWithYubiKeyPiv: (digest: Uint8Array) => Promise<Uint8Array>

const template = new R1K1Wallet()
const r1PublicKey = Utils.toArray(compressedP256PublicKeyHex, 'hex')
const salt = crypto.getRandomValues(new Uint8Array(32))
const lockingScript = await template.lock(
  Hash.hash160([...r1PublicKey, ...salt]),
  Hash.hash160(k1RecoveryPrivateKey.toPublicKey().encode(true) as number[])
)

const normalSpend = template.unlock({
  path: 'r1',
  publicKey: r1PublicKey,
  salt,
  // Submit this 32-byte digest unchanged to PIV GENERAL AUTHENTICATE.
  // Return the YubiKey DER ECDSA signature (or raw 64-byte r || s).
  signDigest: digest => signWithYubiKeyPiv(digest)
})

const recoverySpend = template.unlock({
  path: 'k1',
  privateKey: k1RecoveryPrivateKey
})

被合成的P-256验证器在959,632字节后生成了959,632字节锁定脚本 建筑师的承诺被烤熟。 这超过了普通的500KB矿工政策; 在为某项产出提供资金之前确认目标矿工的限额.

R1解锁脚本也会推出BIP-143的预告片,其出品人: scriptCode 合同中约960 KB OP_CODESEPARATOR。R1路径 因此,涉及大约2 MB的锁定加解锁脚本材料,以及 仅证人一人就为支出交易增加了大约960 KB。 账户 由此产生的费用,并确认任何最大交易政策; estimateLength 包括这个预想推. K1 解锁脚本仍然很小.

PIV证明硬件密钥在所供应的文摘上签了名,但有一个YubiKey 不显示或独立验证比特币交易。 一个PIN或 触摸策略保护关键用途,而不是交易意图;审查交易 在批准之前,他是受信任的东道主.

贡献准则

我们总是寻找贡献者 添加最酷的新模板。 不管你想出什么样的剧本 - 所有的贡献都是受欢迎的.

  1. 叉和克隆( C):叉出此寄存器并克隆到您的本地机器上.
  2. 设置运行 npm i 以安装所有依赖.
  3. 更改: 创建新的分支并进行修改.
  4. 测试: 确保所有测试通过运行 npm test。 。 。 .
  5. 提交: 提交修改并按到叉上.
  6. 拉请求: 打开从您叉到此寄存器的拉取请求 . 详情请查看 储存库贡献准则。 。 。 .

关于过去释放的信息,请查看 更改日志对于今后的计划,请检查 路线图来啊!

支持联系人( C)

项目所有人: Ty Everett

发展小组组长:蒂·埃弗雷特

对于问题,错误报告或特性请求,请在 GitHub 上打开一个问题或直接与我们联系.

许可证

当前 TS Stack 更改根据 Open BSV 许可证版本 6 获得许可; 参见 LICENSE.txt (英语)。该软件包还保留了统一前代码 在开放BSV许可证版本4下. 补给者必须保留 第三次议会 NoTICES.md 和适用的文本在 LICENSES/。 。 。 .

感谢您参与BSV Blockchain脚本模板项目. 让我们一起打造BSV区块链的未来!

SDK4 热补丁对等要求

SDK4 对等替代开始于 @bsv/sdk ^4.0.1,恢复数字 钱包结果和遗留线条相容性。 现有的SDK2/3替代品和 下限不变。 SDK4 用户应安装 4. 0.1 个热补丁; 不 需要应用程序-wallet线或数据迁移.

版本与发布记录

@bsv/templates 共发布 28 个版本,首次发布于 2024/05/30;过去 12 个月发布了 21 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.2.0latest2026/10/309 天前
2.1.12026/10/2811 天前
2.1.02026/10/2416 天前
2.0.02026/10/031 个月前
1.10.32026/09/241 个月前
1.10.22026/09/231 个月前

关于 @bsv/templates 的常见问题

@bsv/templates 是什么?

BSV 块链脚本模板

如何安装 @bsv/templates?

在项目目录运行 npm install @bsv/templates,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@bsv/sdk(^2.1.6 || ^3.0.0 || ^4.0.1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@bsv/templates 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bsv/templates 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@bsv/templates 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@bsv/templates 可以商用吗?

@bsv/templates 使用 SEE LICENSE IN LICENSE.txt 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@bsv/templates 的下载量有多少?

根据 npm 官方下载统计,@bsv/templates 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,338 次,日均约 78 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bsv/templates 还在维护吗?

最新版本 2.2.0 发布于 2026/10/30(9 天前);至今共发布 28 个版本,其中过去 12 个月发布了 21 个;首次发布于 2024/05/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。