如何进行brc20铭文的创建

什么是p2tr

想要创建一个铭文,首先得了解下什么是p2tr ?

P2tr: 即Pay-to-Taproot

是比特币的一种新的交易类型,由比特币的升级提案BIP341提出。

一个P2TR类型的交易,资金不再是锁到固定的地址上,而是锁到一个Taproot上。

什么是Taproot呢?

Taproot和merkle root类似,是一颗merkle树的根。 如下图所示,这个merkle上的所有节点都是一个witness script。

上面说到,p2tr的交易,是将btc锁定在Taproot的地址上的。想要将这个地址上的比特币花费出去,需要提供一份merkle证明。

如下图所示,你可以提供任意一条的merkle证明路径,只要能最终得到这个merkle root hash,就证明了你有资格去解锁。

铭文是怎么被创建出来的

btc的铭文创建需要用到上面的p2tr交易。

  • 首先,我们随机生成一个btc的私钥;
  • 将这个私钥转化成符合p2tr格式的私钥;
  • 然后构建一个witness script, 这个witness script其实很简单,代码如下。其实生效的就是10~11行,验证用户的签名是否和公钥一致;
ts 复制代码
   // 拿到p2tr类型的公钥
   const tweakedPublicKey = toXOnly(keypair.publicKey)
   const json = `{ "p": "brc-20", "op": "mint", "tick": "cccc", "amt": "100" }`;
 ​
   // 构建铭文的script
   const inscriptionWitnessScript = bitcoin.script.compile([
     tweakedPublicKey,
     opcodes.OP_CHECKSIG, // 验证公钥
 ​
     opcodes.OP_FALSE, // referred to as an ENVELOPE
     opcodes.OP_IF, // adding false enables prunable content
     opPush("ord"), // specifies its an ordinal inscription
     1,
     1,
     opPush("text/plain;charset=utf-8"), // defines media type
     opcodes.OP_0,
     opPush(json), // media content
     bitcoin.opcodes.OP_ENDIF // end of ENVELOPE
   ]);
 ​
 ​
   // 构建一个tap leaf
   const scriptTree: Tapleaf = { output: inscriptionWitnessScript }
 ​
   const redeemScript = {
     output: inscriptionWitnessScript,
     redeemVersion: 192
   }
 ​
   const inscriptionPayment = bitcoin.payments.p2tr({ // 这个就是一个包含了铭文的p2tr对象
     internalPubkey: tweakedPublicKey,
     network: network,
     scriptTree: scriptTree,
     redeem: redeemScript
   });
 ​
   const commitAndRevealAddress = inscriptionPayment.address; // 返回铭文的地址
   console.log(`commit_and_reveal_address = `, commitAndRevealAddress)
  • 然后生成一个包含了铭文的p2tr对象。
  • 我们将这个p2tr的地址打印出来,然后向里构建一笔utxo,向这个地址里发送一些btc,用来reveal铭文;
  • 接下来我们用redeem_script将p2tr里的btc再花费掉,转给某一个地址,这样铭文就被reveal这个地址上了;

代码片段:花p2tr地址上的钱,revel铭文

ts 复制代码
 // PSBT 是 Partially Signed Bitcoin Transaction 的缩写,即部分签名的比特币交易
   // 构建PSBT去花这个inscriptionPayment.address上的钱
   const psbt = new Psbt({ network });
   const tapLeafScript = {
     leafVersion: 192,
     script: inscriptionWitnessScript,
     controlBlock: inscriptionPayment.witness![inscriptionPayment.witness!.length - 1]
   };
 ​
 ​
   // 添加输入 
   psbt.addInput({
     hash: utxos[utxos.length - 1].txid,
     index: utxos[utxos.length - 1].vout,
     tapInternalKey: tweakedPublicKey,
     witnessUtxo: {
       value: utxos[utxos.length - 1].value,
       script: inscriptionPayment.output!
     },
     tapLeafScript: [
       tapLeafScript,
     ]
   });
   // 添加输出
   psbt.addOutputs([{
     // 往这个地址发铭文
     address: "tb1plf84y3ak54k6m3kr9rzka9skynkn5mhfjmaenn70epdzamtgpadqu8uxx9",
     value: 1000
   }, {
     // 找零地址
     address: "tb1pjjq4snuntgja3ggyluncdlkvhxw26gm8pkfgjc8jvhh3asyaj6as4uctjg",
     value: utxos[utxos.length - 1].value - 1000 - 1000 // 扣除上面的1000, 再扣除1000给gas
   }]);
 ​
   // 签名
   psbt.signInput(0, keypair);
   // 验证所有的input都被正确签名了,
   psbt.finalizeAllInputs();
   // 拿到tx数据
   const tx = psbt.extractTransaction().toHex();
   console.log(`Broadcasting Transaction Hex: ${tx}`);
   // 广播交易
   const txid = await broadcast(tx);
   console.log(`Success! Txid is ${txid}`);

截图举例

铭文的详情:testnet.unisat.io/brc20/coda

交易地址:mempool.space/testnet/add...

如下图所示,1个deploy铭文,实际上有2笔关联的交易,一笔是向taproot地址转账,我们称为commit阶段 另一笔taproot地址向其他地址转账,我们称为reveal阶段

仓库地址

github.com/6gunner/ord...

运行这个repo里的examples/unisat-web3-demo,并且安装上unista钱包插件,可以完整体验brc20铭文deploy、mint、transfer的所有流程。

参考文章

相关推荐
天晟科技8 小时前
GameFi的前景:游戏与金融的未来交汇点
游戏·金融·区块链
Roun38 小时前
Web3和区块链如何促进数据透明与隐私保护的平衡
web3·区块链·隐私保护
The_Ticker15 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
程序猿阿伟15 小时前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链
TechubNews15 小时前
Helius:从数据出发,衡量 Solana 的真实去中心化程度
去中心化·区块链
dingzd9517 小时前
Web3的核心技术:区块链如何确保信息安全与共享
web3·去中心化·区块链
清 晨17 小时前
Web3与智能合约:区块链技术下的数字信任体系
web3·区块链·智能合约
CertiK18 小时前
Web3.0安全开发实践:Clarity最佳实践总结
web3·区块链·clarity
加密新世界18 小时前
Move on Sui入门 004-在sui链上发布Coin合约和Faucet Coin合约
区块链
YSGZJJ1 天前
股指期货的套保策略如何精准选择和规避风险?
人工智能·区块链