2023-06-10 Saturday

对于ERC-20代币,大家都不陌生,以太坊 Ethereum诞生之初便支持智能合约 Smart Contract,因此,在以太坊上我们可以部署ERC-20智能合约,从而发布ERC-20代币。可是,我们都知道,比特币Bitcon并不支持智能合约,那么,BRC-20如何实现呢?要弄清楚这个问题,我们就必须了解以下概念

  • Inscribe / Inscription,一般翻译为铭文
  • Ordinal Numbers,一般翻译为序数

铭文 Inscription

首先,我们来看看“铭文”到底是什么意思。如今,如果大家去搜索“铭文”,大概会发现,许多文章说的都是BRC-20相关的内容。实际上,铭文一词表示碑文或者硬币、勋章、奖章、纪念章、印章、器物上的文辞(大多铸成或刻成)。

例如,下图的文字就是铭文。

修建无名英雄广场铭文.jpg

具体到比特币Bitcoin,铭文Inscription是如何实现的呢?我们不妨来看一个具体的案例。

这是一个BRC-20 token ordz的deploy ordinals.com: ordz deploy,对应的json如下。

{ 
  "p": "brc-20",
  "op": "deploy",
  "tick": "ordz",
  "max": "690420"
}

将上述json转为byte array然后以hex string方式表示,那么上述json就可以表示为

7b200d0a20202270223a20226272632d3230222c0d0a2020226f70223a20226465706c6f79222c0d0a2020227469636b223a20226f72647a222c0d0a2020226d6178223a2022363930343230220d0a7d

对应的transaction是mempool: 8e855daa150f57cfa337b19ff5ce103cf41f6258fecc5ed64372910dd4f6664f,这个transaction正好只有1个input和1个output。

我们通过blockchain.info api查看transaction的json,其中的inputs[0].witness部分内容如下。

03401439ae347eb1dde971a2be43655f1057cd94c472f3acc61d9c7e7c720b22eabcb27c8568f79bf4a67b34b973895396528e667b4d135b51f5301340415eddd33497206133809c560ff12d84b5d2638d3ebc4292b4e75aaa838a27277c06e7577d957aac0063036f7264010118746578742f706c61696e3b636861727365743d7574662d38004c507b200d0a20202270223a20226272632d3230222c0d0a2020226f70223a20226465706c6f79222c0d0a2020227469636b223a20226f72647a222c0d0a2020226d6178223a2022363930343230220d0a7d6821c16133809c560ff12d84b5d2638d3ebc4292b4e75aaa838a27277c06e7577d957a

withness部分我们可以找到如下内容

18746578742f706c61696e3b636861727365743d7574662d38

上述内容解析出来如下

18 # bitcoin op_code OP_PUSHBYTES_24
746578742f706c61696e3b636861727365743d7574662d38 # text content 'text/plain;charset=utf-8'

4c507b200d0a20202270223a20226272632d3230222c0d0a2020226f70223a20226465706c6f79222c0d0a2020227469636b223a20226f72647a222c0d0a2020226d6178223a2022363930343230220d0a7d

上述内容解析出来如下

4c # bitcoin op_code OP_PUSHDATA1
50 # 0x50 = 80, there are 80 bytes below 
7b200d0a20202270223a20226272632d3230222c0d0a2020226f70223a20226465706c6f79222c0d0a2020227469636b223a20226f72647a222c0d0a2020226d6178223a2022363930343230220d0a7d

7b200.... is the hex string of 
{ 
  "p": "brc-20",
  "op": "deploy",
  "tick": "ordz",
  "max": "690420"
}

不难发现,对于ordz这个BRC-20 token来说,deploy操作就是在一个transaction之中,添加如下操作

  • OP_PUSHBYTES_24 ‘text/plain;charset=utf-8’
  • OP_PUSHDATA1 80 ‘{上面提到的json内容}’

而PUSHBYTES或者PUSHDATA的内容,就是Bitcoin的铭文。上述操作,即铭文inscribe。

当然,铭文操作并不仅限于上述两个op_code,我们不妨再看看一个BRC-20的mint 1000 1SAT 操作

对应的json如下

{"p":"brc-20","op":"mint","tick":"1Sat","amt":"1000"}

blockchain.info api json

mempool: 08fc2ba4073

OP_PUSHBYTES_32 b28b9bfc5f32cda4d5eafeba9f24ff6d5aa6d63ebdf6613977a65627989809bf
OP_CHECKSIG
OP_0
OP_IF
OP_PUSHBYTES_3 6f7264
OP_PUSHBYTES_1 01
OP_PUSHBYTES_24 746578742f706c61696e3b636861727365743d7574662d38
OP_0
OP_PUSHBYTES_53 7b2270223a226272632d3230222c226f70223a226d696e74222c227469636b223a2231536174222c22616d74223a2231303030227d
OP_ENDIF

将hex参数解析成文本就是

OP_CHECKSIG
OP_0
OP_IF
OP_PUSHBYTES_3 ord
OP_PUSHBYTES_1 01
OP_PUSHBYTES_24 text/plain;charset=utf-8
OP_0
OP_PUSHBYTES_53 {"p":"brc-20","op":"mint","tick":"1Sat","amt":"1000"}

如果我们在看这个BRC-20的transfer

OP_PUSHBYTES_32 703ad641174c7746d0dd7408fea5332d9156043dfb6b6155ca2a4538d60df474
OP_CHECKSIG
OP_0
OP_IF
OP_PUSHBYTES_3 6f7264
OP_PUSHBYTES_1 01
OP_PUSHBYTES_10 746578742f706c61696e
OP_0
OP_PUSHBYTES_57 7b2270223a226272632d3230222c226f70223a227472616e73666572222c227469636b223a224f584254222c22616d74223a2231303030227d
OP_ENDIF

翻译成文本就是

OP_PUSHBYTES_32 703ad641174c7746d0dd7408fea5332d9156043dfb6b6155ca2a4538d60df474
OP_CHECKSIG
OP_0
OP_IF
OP_PUSHBYTES_3 ord
OP_PUSHBYTES_1 01
OP_PUSHBYTES_10 text/plain
OP_0
OP_PUSHBYTES_57 {"p":"brc-20","op":"transfer","tick":"OXBT","amt":"1000"}
OP_ENDIF

总结,铭文Inscription就是将信息,如上面提到的json字符串,附加到Bitcoin的transaction上。我们不难看到,Bitcoin本身并不阻止我们重复执行BRC-20的deploy操作,不会判断BRC-20的mint是否超出限制,不会判断transfer操作是否有效,Bitcoin仅仅是记录上述操作而已,那么,BRC-20显然不能只靠inscription来实现。

Ordinal Numbers 序数

我们上面提到了,即便有人事先已经执行了deploy,如

{ 
  "p": "brc-20",
  "op": "deploy",
  "tick": "ordz",
  "max": "690420"
}

这也并不能阻止我继续在Bitcoin上写入如下信息

{ 
  "p": "brc-20",
  "op": "deploy",
  "tick": "ordz",
  "max": "69042000000"
}

那么,对于BRC-20来说,该协议如何确定,哪一个deploy才是真正的ordz toekn呢?这就涉及到Ordinal Numbers了。

首先,我们来看看到底如何定义Ordinal。根据比特币的规范,比特币的总量上限为2100万BTC,而 1 BTC = 100,000,000 Satoshi。理论上,Satoshi之间是相同的,可是,正如纸币可以有编号,我们是否能给Satoshi也编号呢?这就是Ordinal Numbers。

Ordinal Number的定义在 Sats are numbered and transferred with the following algorithm,本文就不详细赘述了。例如,比特币的第一个Block,coinbase transaction会给minder 50个比特币的奖励,那么这50个比特币对应的Satoshi就对应了Ordinal 0到50*100,000,000 - 1,以此类推。

如果发生交易,例如,第一个block的coinbase产生了一个UTXO,对应50个BTC,而这50个BTC需要转账给3个人,每人16,剩余的2 BTC作为miner fee,那么,这个交易就是

inputs = [UXTO (50 BTC)] 对应  ordinal=[0, 50*100,000,000 - 1]
outputs = [A(16 BTC), B(16 BTC), C(16 BTC)] fee = 2BTC
A的output在outputs位于index = 0
所以A得到的16个BTC对应的ordinal numbers为[0, 16*100,000,000 - 1]

B的output在outputs位于index = 1
所以B得到的16个BTC对应的ordinal numbers为[16*100,000,000, 16*2*100,000,000 - 1]

C的output在outputs位于index = 2
所以C得到的16个BTC对应的ordinal numbers为[16*2*100,000,000, 16*3*100,000,000 - 1]

将2 BTC的fee看作coinbase的input,则miner获得在一个50 BTC subsidy以及2 BTC的fee,
miner获得的的52 BTC对应的ordinal则是
[16*3*100,000,000, 50*100,000,000] + [50*100,000,000,50*2*100,000,000-1] 

当我们可以为每一个Satoshi分配一个唯一的Ordinal Number以后,所有的BRC-20 deploy,mint和transfer操作都可以对应某一个Satoshi的inscription了。这样的话,整个BRC-20系统就可以根据Ordinal Numbers和Inscription运行了。

其中一个BRC-20 transfer的例子如下

我们可以在e94edfbc…4bf8bcf1之中找到

OP_PUSHBYTES_57 7b2270223a226272632d3230222c226f70223a227472616e73666572222c227469636b223a2270657065222c22616d74223a2231303030227d

OP_PUSHBYTES_57 {"p":"brc-20","op":"transfer","tick":"pepe","amt":"1000"}