# PIN数据结构

MAN索引器會從taproot交易的reveal腳本中獲取MetaID協議數據，具體協議請參照MetaID Specification章節。

## PIN數據結構

```jsx
type PinInscription struct {
	Id                 string `json:"id"`
	Number             int64  `json:"number"`
	RootTxId           string `json:"rootTxId"`
	Address            string `json:"address"`
	Output             string `json:"output"`
	OutputValue        int64  `json:"outputValue"`
	Timestamp          int64  `json:"timestamp"`
	GenesisFee         int64  `json:"genesisFee"`
	GenesisHeight      int64  `json:"genesisHeight"`
	GenesisTransaction string `json:"genesisTransaction"`
	TxInIndex          uint32 `json:"txInIndex"`
	TxInOffset         uint64 `json:"txInOffset"`
	Operation          string `json:"operation"`
	Path               string `json:"path"`
	ParentPath         string `json:"parentPath"`
	Encryption         string `json:"encryption"`
	Version            string `json:"version"`
	ContentType        string `json:"contentType"`
	ContentTypeDetect  string `json:"contentTypeDetect"`
	ContentBody        []byte `json:"contentBody"`
	ContentLength      uint64 `json:"contentLength"`
	ContentSummary     string `json:"contentSummary"`
}
```

## PIN索引規則

**通用**

* 識別Flag：`metaid`
* 大小寫規則：大小寫不敏感，索引器可以全部轉為小寫保存。

**Operation**

1. `init`類型PIN所在的交易的txid為一個`metaid`的`roottxid`。
2. `init`、`create`遵循先到先得原則。
3. 同一區塊內`init`、`create`不區分先後順序，索引器應先處理`init`類型PIN，再處理其他類型PIN，先處理`init`是為了得到`roottxid`/`metaid`。

**Path**

1. 對於相同的`path`，所有`init`和`create`的PIN是看最舊的，只有`modify`/`revoke`才是看最新的。
2. `modify`/`revoke`必須對已入塊的PIN操作，即`modify`/`revoke`只對已經入塊的PIN有效，即使同區塊也是無效的。
3. 非`init`-PIN的`path`一定是在以下`path`內，一個`metaid`默認存在這五個一級`path`：
   * `/info`
   * `/file`
   * `/protocols`
   * `/nft`
   * `/ft`
4. 以`/file`、`/protocols`、`/nft`、`/ft`開始的`path`應該是全路徑的，如`/protocols/simplebuzz/file/my-pfp.jpg`。

## PIN状态码

| 状态码  | 描述                                                                |
| ---- | ----------------------------------------------------------------- |
| 0    | 正常的PIN                                                            |
| -1   | revoke的PIN                                                        |
| 1    | modify的PIN                                                        |
| -101 | 目標PIN所在區塊高度 ≤ 當前PIN所在區塊高度                                         |
| -102 | 目標PIN已經被轉移                                                        |
| -201 | `modify`的PIN，格式正確，但`@+PINID`中的`PINId`不存在（已確認的PIN）                 |
| -202 | `modify`的PIN，格式正確，但發起`modify`的地址不存在                               |
| -203 | `modify`的PIN，格式正確，發起`modify`的地址存在，但目標PIN的地址不等於當前PIN的address       |
| -204 | 目標PIN已經有`modify`（狀態碼為1）                                           |
| -205 | 目標PIN的`Operation`是`init`                                          |
| -301 | `revoke`的PIN，格式正確，但`@+PINID`中的`PINId`不存在                          |
| -302 | `revoke`的PIN，格式正確，但發起`revoke`的地址不存在                               |
| -303 | `revoke`的PIN，格式正確，發起`revoke`的地址存在，但目標PIN的地址不等於當前PIN的地址            |
| -304 | 目標PIN已經被`revoke`過（狀態碼為-1）                                         |
| -305 | `revoke`的PIN，格式正確，但目標PIN的`Operation`是`init`或目標PIN的`Path`是`/info/` |

更多信息，請參考 MAN 源代碼。

{% embed url="<https://github.com/metaid-developers/man-indexer>" %}
