MRC-20

請注意該協議仍在測試網測試中,我們會在充分測試後在比特幣主網合適的區塊高度啟動該協議

MRC-20 是基於 MetaID 的一個 Fungible Token 發行協議,使用者可以透過 MRC-20 協議發行資產並制定鑄造方式。與其他資產發行協議相比,MRC-20 協議最大的特點是其發行方式能夠與各人鏈數據以及 MetaID 協議緊密結合,從而能夠滿足各種鏈上活動的資產發行方式。簡單來說,MRC-20 是一種為滿足日後各種 Web3 活動而制定的 Fungible Token 發行協議。

協議格式

部署

PIN路徑:/ft/mrc20/deploy

後端索引器應只對符合路徑的 PIN做驗證和索引

該路徑下的 PIN 不接受 modify 和 revoke操作

協議格式:

{
  "tick": "satoshi", // 2-24 字符
  "amtPerMint": "1000", // 每次鑄造獲得的總代幣數量 [1, 1e12]
  "mintCount": "100", // 最大允許鑄造次數 [1, 1e12]
  "tokenName": "SatoshiTheLegend", // 選填,代幣全名,0-48 字符
  "decimals": "8", // 選填,小數位數 0 至 12,默認為 8  
  "premineCount": "60", // 選填,部署時預先鑄造的次數,默認為 0,[0, mintCount]
  "beginHeight": "851235", // 選填,鑄造事件開始的區塊高度
  "endHeight": "851781", // 選填,鑄造事件結束的區塊高度
  "metadata": "Arbitrary Data", // 選填,可以包含額外資料如代幣描述、圖示等,無格式要求
  "payCheck": { // 選填,檢查付款以驗證鑄造資格
    "payTo": "address", // 檢查輸出是否匹配指定地址
    "payAmount": "" // 以 satoshi 為單位,檢查是否支付了指定數量的 satoshi
  },
  "pinCheck": { // 選填,檢查 PIN 以驗證鑄造資格
    "creator": "", // 創建 PIN 的人,使用完整的 MetaID
    "path": "/", // PIN 的路徑
    "count": "1", // 0~n,所需的 PIN 數量
    "lvl": "6" // PIN 的最低等級
  }
}

要點說明:

• 合法的創始交易後,該 tick 將被分配一個唯一的 id,該 id 用於標識該 MRC-20 代幣。該 id 用 pinid 表示

tick 為全局唯一,不可重複,tick 的有效判定採用先見原則。

• 總供應量 = amtPerMint * mintCount

metadata 為自定義數據項目,可綁定代幣相關數據,可以包含簡介、圖片等

beginHeightendHeight 決定了該鑄造時間的有效時間範圍。beginHeight 如未指定有效區塊高度,則為 Deploy 该 PIN確認高度;endHeight 如未指定有效區塊高度,則代表無結束時間限制。

premineCount 說明

• 部署者可設置預挖參數,數值為在 deploy 交易中直接挖取指定次數的代幣

• 預挖的 Token 在 Deploy 交易確認時直接預挖到 Deploy 使用者地址上。

• 預挖總量 = amtPerMint * premineCount

premineCount 為選項,默認值為 0,取值範圍為 0~mintCount,範圍之外的賦值視為無效

• 例子:一個 deploy 中設置為 amtPerMint = 10000, mintCount = 100, premineCount = 60,則視為 100 次的總挖取次數中預挖了 60 次,只有剩餘 40 次為公開的可鑄造次數

payCheck 說明

• 如果部署者設置了 payCheck 項目,則每次鑄造時均會檢查鑄造交易是否向指定地址支付了指定的 satoshi,如不符合要求則鑄造無效

payTo 項目為鑄造時需向指定的地址轉入;payAmount 為鑄造時需向 payTo 地址轉移指定數量的 satoshi

pinCheck 說明

  • 如果部署者設置了 pinCheck 項目,則每次鑄造時均會檢查鑄造交易中是否帶了指定條件的 PIN,如不符合要求則鑄造無效

  • creator 為檢查 PIN 創建者是否為指定 MetaID

  • path 為檢查 PIN 所在路徑是否為指定的路徑

    • path 的格式請詳細查看 MetaID 協議關於 path 的說明

    • path 支持該 path payload 的內容匹配

    • /path[‘payload’] 匹配指定 path 位置下 payload 的全部內容

    • /path[‘key’=’value’] 匹配指定 path 位置下 payload 裡的 key 和 value 值

  • count 為檢查符合條件的 PIN 的數量,默認值為 1

  • lvl 為檢查 PIN 的等級是否符合要求。lvl 由 PIN 的 PoP 值決定,請詳細查看 PoP 值和 lvl 值說明

  • checkPin 裡的 4 個參數可相互組合,形成可適應多場景的鑄造要求

pinCheck示例

// 不限制路徑和難度及創建者,任意一個 PIN 均有鑄造資格
"pinCheck": {
  "count": "1"
}

// 需要一個 simplebuzz 協議的 PIN
"pinCheck": {
  "path": "/protocols/simplebuzz"
}

// 需要關注過特定 metaid 的 PIN
"pinCheck": {
  "path": "/follow['metaid_of_me']"
}

// 需要點贊過某個 PIN 的 PIN
"pinCheck": {
  "path": "/protocols/paylike['liketo'='abcdefgh...']"
}

// /protocols 下的任意協議的 PIN(2 個)均有鑄造資格
"pinCheck": {
  "path": "/protocols/*",
  "count": 2
}

// 需要擁有我的 PIN 才有鑄造資格
"pinCheck": {
  "creator": "abcdef0123457" // 需要 metaid 為“abcdef0123457”所創造的 pin
}

鑄造

PIN 路徑:/ft/mrc20/mint

後端索引器應只對符合路徑的 mint 資料做驗證和索引

該路徑下的 PIN 不接受 modifyrevoke操作

協議格式:

{
  "id": "479f8579e5dcdbef868a61541f0d55efccfee1704c8a03f07fb1d97577104d53i0" // tokenID,這個 tokenID 是 deploy 交易的 PINID
}

要點說明:

• 協議只有一個參數,就是 id,代表了要鑄造的 tokenid,tokenid 為 Deploy PIN對應的 PINID。

• 鑄造的 token 總量由 Deploy 的amtPerMint 參數決定。如成功鑄造,該次鑄造的 token 總量會轉移到 Mint 交易的第一個 output 的第一個 satoshi 上。

• 鑄造有效性由 indexer 服務決定,indexer 根據 Deploy 中的相關條件和約束規則驗證該鑄造交易是否合法。判斷的規則全都是鏈上數據,所以即便不同開發者開發的 indexer 的校驗結果也應該是一致的。

• 如 Deploy 檔有 pinCheck 要求時,Mint 交易 input 需要指向一個或多個有效 PIN 以完成 PIN 校驗。

• 一個 PIN 在同一個 token 的 mint event 中,只能使用一次。

• 如 Deploy PIN有 payCheck 要求時,Mint 交易需有一個 output 符合 payCheck 的地址和金額要求。

• Mint 不支持跨鏈鑄造,也就是說 Mint 交易必須和其對應的 Deploy 交易處於同一鏈中。

Mint 交易構建例子

Transfer 轉帳

轉帳有兩種形式:原生轉帳和數據轉帳

原生轉帳(直接轉帳)

原生轉帳是一種簡易的、Layer 1 的轉帳方式,不需要依靠寫入轉帳數據的方式,以純粹的 utxo 轉移方式完成。

原生轉帳適合於不需要 MRC20 代幣找零 的場景,如

1. Alice 將自己的某種 MRC20 代幣 全部 轉移給 Bob。

2. Alice 需要給 Bob 轉移的某種 MRC20 代幣的 數量剛好是其中一個或幾個 MRC20 UTXO 的數量之和。

原生轉帳交易構造

當 input 中帶有 MRC20 UTXO,且交易中沒有指明轉帳數據(OPRETURN 或 taproot 數據),則所有 MRC 餘額轉入第一個非 OPRETURN 輸出中

數據轉帳 (MRC20 Allocation)

• 數據轉帳指通過 在 MetaID 規範的 Taproot 信封中顯式寫入轉帳說明數據 進行轉帳的方式。使用 JSON 格式。通過指定,規定該交易中傳入的 Input 中的 MRC20 餘額,分別分配到哪些 output 中。

• 數據轉帳適合於所有複雜的、需要有多個 output 分配的,或是需要進行餘額找零的交易類型。

• 數據轉帳使用的 PIN Path 為 /ft/mrc20/transfer

• 數據轉帳使用與 PIN 類似的數據結構,其中 operation 使用 hide 類型,不生成對應的 utxo,不帶有 pinId

• 如果分配方案超過了 input 中蘊含的 MRC20 數量的總額,則該分配視為無效 invalid,退回到缺省的直接轉帳機制,即當前交易中所有 MRC 餘額轉入第一個非 OPRETURN 輸出。

• input 中未被分配完的餘額,使用缺省的直接轉帳機制,自動賦予第一個非 OP_RETURN 的輸出。可將該機制看作自動找零的行為,默認將未分配的餘額部份找零到第一個 output。

• 其他未被認可的數據轉帳寫法被視為非法,使用缺省的直接轉帳機制,此交易中的 MRC20 餘額將轉入第一個輸出。

數據轉帳格式

數據轉帳寫在 MetaID 信封的 payload 中,以數組的形式存在。

type MRC20AllocationItem = {
	id: string
	amount: string
	type?: 'transfer' | 'teleport' = 'transfer'
	vout?: number
	coord?: string
}

type MRC20Allocation = MRC20AllocationItem[]

數據轉帳字段說明

  • id: 分配的 MRC20 的 MRC20ID

  • amount: 分配的 MRC20 數量

  • type: 操作類型。有兩種類型:

    • transfer: (默認)轉帳,指該部份餘額轉到當前交易的某個輸出中。當類型為 transfer 時,需指定 vout

    • teleport:躍遷,指該部份餘額轉到非本鏈的某個 已存在 的 UTXO 中。當類型為 teleport 時,需指定 coord。躍遷的詳情請參考下一部份。

  • vout: MRC20 分配到的 output index。

  • coord:躍遷時 MRC20 分配到的非本鏈的 UTXO 的位置,以 ${txid}i${vout} 的形式表達。

數據轉帳示例

  • 以下 JSON 實例為 MetaID 協議規範中的 payload 項,外層需遵循 MetaID 信封規範。

const allocation: MRC20Allocation = [
  {
    "amount": "100",
    "vout": 0,
    "id": "479f8579e5dcdbef868a61541f0d55efccfee1704c8a03f07fb1d97577104d53i0", // 'token1'
  },
  {
    "amount": "256",
    "vout": 3,
    "id": "bcccd98a7a1250f26b57d47cfdd36a95866d4bee59c32c9d4e71a6cc1f3429a5i0", // 'token2'
  },
  {
    "amount": "300",
    "vout": 3,
    "id": "479f8579e5dcdbef868a61541f0d55efccfee1704c8a03f07fb1d97577104d53i0", // 'token1'
  },
];

const pinData = {
	metaidFlag: 'metaid',
	operation: 'hide',
	path: '/ft/mrc20/transfer',
	contentType: 'application/json',
	payload: JSON.stringify(allocation) // 將分配數據進行 JSON 序列化放入 payload 字段
}

以上的轉帳交易中,100 個 token1 賦予給 index:0 輸出;256 個 token2 賦予給 index:3 輸出;300 個 token1 賦予給 index:3 輸出。

Teleport 躍遷(跨鏈)

躍遷示例

const allocation: MRC20Allocation = [
  {
    amount: '100',
    id: '479f8579e5dcdbef868a61541f0d55efccfee1704c8a03f07fb1d97577104d53i0', // 'token1'
    coord: 'bcccd98a7a1250f26b57d47cfdd36a95866d4bee59c32c9d4e71a6cc1f3429a5i2', // 躍遷坐標,使用 pinId 結構定位 utxo
    type: 'teleport',
  },
]

const pinData = {
	metaidFlag: 'metaid',
	operation: 'hide',
	path: '/ft/mrc20/transfer',
	contentType: 'application/json',
	payload: JSON.stringify(allocation) // 將分配數據進行 JSON 序列化放入 payload 字段
}
  • 躍遷實現了 MRC-20 的跨鏈功能;可以視為是 transfer 的擴維版本。transfer 將 MRC-20 餘額分配到本交易的 output 中,teleport 將餘額分配到其他鏈的 output 中。

  • coord(坐標)使用另外鏈中的 ${txid}i${vout} 格式來定位目標 utxo

  • coord 指向的 utxo 由 indexer 來識別所在的鏈,無需在數據中表達

  • 如果 coord 指向的 utxo 不存在(indexer 無法尋得),此交易依然視為有效,而 teleport 分配的餘額部份視為燃燒。

  • teleport 可以同 transfer 並列於一個交易內,分配優先級高於 transfer

Teleport 同 Transfer 可以同層

Last updated