# 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

* **init** 类型 PIN 所在的交易的 `txid` 为一个 `metaid` 的 `roottxid`。
* **init**、**create** 遵循先到先得原则。
* 同一区块内 **init**、**create** 不区分先后顺序，索引器应先处理 **init** 类型 PIN，再处理其他类型 PIN。
  * 先处理 **init** 是为了得到 `roottxid/metaid`。

### Path

* 对于相同的 `path`，所有 **init** 和 **create** 的 PIN 是看最旧的，只有 **modify/revoke** 才是看最新的。
* **modify/revoke** 必须对已入块的 PIN 操作，即 **modify/revoke** 只对已经入块的 PIN 有效，即使同区块也是无效的。
* 非 **init-PIN** 的 `path` 一定是在以下 `path` 内，一个 `metaid` 默认存在这五个一级 `path`：
  * `/info`
  * `/file`
  * `/protocols`
  * `/nft`
  * `/ft`

#### Path 规则

* 以 `/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的address不存在                                |
| -203 | modify的PIN，格式正确，发起modify的address存在，但目标PIN的address不等于当前PIN的address   |
| -204 | 目标PIN已经有modify（状态码为1）                                               |
| -205 | 目标PIN的Operation是init                                                |
| -301 | revoke的PIN，格式正确，但@+PINID 中的PINId不存在                                 |
| -302 | revoke的PIN，格式正确，但发起modify的address不存在                                |
| -303 | revoke的PIN，格式正确，发起revoke的address存在，但目标PIN的address不等于当前PIN的address   |
| -304 | 目标PIN已经被revoke过，（状态码为-1）                                            |
| -305 | revoke的PIN，格式正确，但目标PIN的Operation是init 或目标PIN的Path&#x662F;**/info/** |

更多信息，请参考 MAN 源代码：

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