如何进行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的所有流程。

参考文章

相关推荐
WSY88x9 小时前
重塑支付安全:区块链技术引领下的积分系统革新
安全·区块链
friklogff13 小时前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
SunsPlanter1 天前
02 ETH
区块链
yunteng5211 天前
零知识证明-ZK-SNARKs基础(七)
区块链·零知识证明·zk-snarks·ricp·qap
山师第一深情1 天前
solidity-19-fallback
区块链
zhuqiyua1 天前
TVM和EVM的比较
区块链·智能合约·ton
sino_sound1 天前
伦敦金的交易差价意味着什么?
人工智能·金融·区块链
黑色叉腰丶大魔王2 天前
什么是区块链,以及应用场景
去中心化·区块链·分布式账本
qiquandong2 天前
场外期权或成暴利工具?!应该怎么做场外期权?
区块链
链科天下2 天前
全球国家比特币持有量排名!各国政府合谋能否推翻比特币?数字货币的时代已经来临!
区块链