MetaID
中文
中文
  • 概要
    • 概要
    • 术语
  • 📑MetaID协议规范
    • 协议格式
    • MetaID 树介绍
      • MetaID树
      • Info 节点
      • File 节点
      • FT 节点
      • NFT 节点
      • Protocols 节点
      • Follow节点
    • MetaID 信封格式
    • 隐私模型
    • 关于PIN
    • 关于PoP
    • Host
    • MetaAccess
    • MetaName
    • 一些例子
  • 💻MetaID App Node
    • 简介
    • 编译与运行
    • JSON API
    • 浏览器
    • MetaID PIN规则约定
    • PIN数据结构
  • ⚙️MetaID SDK
    • Get Started
    • Core API
    • Quick Example
  • ⛓️Cross-chain
    • 关于跨链
    • Unified UTXO Chain
  • 🪪About MetaID
    • MetaID历史
    • FAQ
    • MetaID理念
    • MetaID资源
  • 📃资产协议
    • MRC-20
    • MRC-721
Powered by GitBook
On this page
  • 概要
  • 计算方法
  • PoP Level(难度等级)
  • PoP Score(PoP分数)
  1. MetaID协议规范

关于PoP

概要

Proof of PIN(PoP)是 MetaID 中的一个有趣概念,我们参考了比特币的挖矿原理制定了 PoP 机制。PoP值反映的是用户在MetaID 世界的“工作量”证明。在 MetaID 世界中,用户最小的“工作量”是发送一条 PIN,因此每条 PIN 都有一个哈希值,并且该将用户的PIN与其所在的区块难度结合。PoP 值反映了如下两个维度:

  • 用户创建MetaID 数据的数量概况:创建 MetaID PIN越多,获得高难度的 PoP 值的概率越高

  • 用户创建 MetaID 数据的算力消耗:PoP 值和MetaID 数据所在区块链算力情况挂钩,算力越高越容易获得难度高的 PoP 值

PIN 如同 SHA256 算力,PoP 如同难度哈希,算力越高则越大概率获得高难度的哈希值。

通过验证用户相关的PoP值,我们可以快速评价一个用户在 MetaID 世界的贡献度,也让 PIN有了等级和稀有度的概念。

计算方法

PoP 是通过区块的 MerkleRoot 和 PINID 用SHA256联合哈希,然后再与 BlockHash相乘,从而生成一个新的值。具体公式为:

PoP = hash(PIN_ID + Merkle_Root) * Block_Hash

得出的原始的哈希值然后进行8进制转换,转换后的结果即为 PoP。

以下为计算代码:

package pop

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"math/big"
	"strconv"
)

func CalculateHash(pinid string, merkleRoot string) string {
	h := sha256.New()
	h.Write([]byte(pinid + merkleRoot))
	return hex.EncodeToString(h.Sum(nil))
}

func CalculateProductToHexStr(blockhash string, pinHash string) string {
	blockhashByte, _ := hex.DecodeString(blockhash)
	blockhashInt, _ := new(big.Int).SetString(blockhash, 16)
	pinHashByte, _ := hex.DecodeString(pinHash)
	pinHashInt, _ := new(big.Int).SetString(pinHash, 16)
	popByte := new(big.Int).Mul(blockhashInt, pinHashInt).Bytes()
	//计算总位数:32+32=64
	totalLen := len(blockhashByte) + len(pinHashByte)
	//需要补0的位数
	remainingLen := totalLen - len(popByte)
	for i := 0; i < remainingLen; i++ {
		popByte = append([]byte{0}, popByte...)
	}
	return hex.EncodeToString(popByte)
}

func ConvertToOctalHex(productHex string) (string, int64) {
	productByte, _ := hex.DecodeString(productHex)
	
	//转二进制
	bList := make([]string, 0)
	for _, b := range productByte {
		binaryB := fmt.Sprintf("%b", b)
		bList = append(bList, fmt.Sprintf("%08s", binaryB))
	}
	productBinaryStr := ""
	for _, b := range bList {
		productBinaryStr += b
	}
	productBinaryStr = productBinaryStr[:510]

	bCount := int64(0)
	for _, b := range productBinaryStr {
		if b == '0' {
			bCount++
		} else {
			break
		}
	}

	//二进制str转8进制str
	octal := ""
	for i := 0; i < len(productBinaryStr); i += 3 {
		binaryStr := productBinaryStr[i : i+3]
		num, err := strconv.ParseInt(binaryStr, 2, 64)
		if err != nil {
			fmt.Println("ParseInt error:", err)
			return "", 0
		}
		octal += strconv.FormatInt(num, 8)
	}
	return octal, bCount
}

func GenPop(pinid, merkleRoot, blockHash string) (string, int64) {
	//计算pinHash
	pinHash := CalculateHash(pinid, merkleRoot)
	//blockhash * pinHash
	productHexStr := CalculateProductToHexStr(blockHash, pinHash)
	//转8进制
	octal, bCount := ConvertToOctalHex(productHexStr)
	
	return octal, bCount
}

以下为计算实例:

func Test_pop(t *testing.T) {
	pinid := "77aac2ae323748dee3b8b1ae6b7c33c1c4466f568c572ea488f584f041f0de4ei0"    // 64 char hash
	merkleRoot := "e56011a241cb196fc4efbeafef051ca901761ffb569a43146582f9133bfd41d2" // 64 char hash
	blockhash := "000000000000000004c2db0441a47fd3574992d508b8d9d866a789d371aa5060"  // real block hash
	pop, bCountZero := GenPop(mockPinId, merkleRoot, blockHash)

	fmt.Println("POP:", octal)
	fmt.Println("POP-0:", bCountZero)
}

PoP Level(难度等级)

在MetaID系统中,PoP值的难度级别采用类似区块哈希的前缀 "0" 位数进行定义。具体而言,PoP值前缀中 "0" 的数量越多,其对应的难度等级(PoP Level)越高。系统规定,任何有效的PoP值至少应包含21位前缀 "0" ,作为最低标准。

为了高效评估和表达PoP的稀有性与难度,MetaID提出了PoP Level的设定。PoP Level为整数,目前体系中共有1至13级,主要应用于PIN稀有度的快速判定、MRC20等场景的资产铸造等。在不同主链环境下,PoP Level的起始标准有所区别,例如MVC常以1级为初始门槛,BTC则通常从6级起步。

具体难度划分为:PoP Level为1时,需满足PoP值前缀有22个 "0" ;PoP Level为2时,需要23个 "0" ;此后每提升一级,"0" 的数量相应增加1位。前缀 "0" 的数量越多,反映出PoP值的稀有性和算法挑战难度越高。

此外,PoP Level难度等级间为指数递增关系,即每提升一个等级,PoP值挖掘的难度为前一等级的8倍,极大增强了高等级PoP的安全性和稀缺性。

PoP Score(PoP分数)

PoPScore的定义与应用场景

PoP Score是为比PoP Level更加精细评估PIN稀有度而设立的数值。尤其在诸如MetaSo系统下的PEV值、MDV值等需细致区分PoP难度的场景下,PoP Score能够为每条PIN精准地评分和排序。每一条PIN都对应一个PoP Score,并会记录在MetaID系统中。

PoPScore的计算方法

a. 确定PoP Level整数部分

以某PIN对应的PoP值为例:

0000000000000000000000215206653161113226643512614250403542335511435340330664252463510373257440244542222437344512355773452022004517474440724217350505346711227665150775715
  • 先统计前缀连续“0”的数量。假设上例有22个“0”,则对应的PoP Level为1,则整数部分为1。

b. 计算PoP Sub Octal

  • 将前缀“0”全部去除后,取其后非0部分的前4位数字,作为小数点后的部分。例如,例中的4位为“2152”,并将其记录为PoP Sub Octal。则此步骤得到PoPSubOctal = 0.2152。

  • 需要注意,PoP Sub Octal是特殊的8进制小数。

c. 8进制均匀化转换

  • 为便于数值分布的均匀性,将8进制小数PoPSubOctal转换为[0,1]范围内均匀分布的十进制小数。此计算采用Octal Fraction To Uniform Decimal方法进行转换。

d. 求取PoP Sub Decimal

  • 记最终的均匀化十进制小数为PoP Sub Decimal,并采用如下公式修正:

    PoPSubDecimal = 1 - octalFractionToUniformDecimal(PoPSubOctal)

    这样能保证小数值越接近0,对应的PoP Level Decimal越大,契合难度设计初衷。

e. 计算PoP Level Decimal

  • 将整数等级和小数等级相加:

    PoP Level Decimal = PoP Level + PoP Sub Decimal

    例如,本例得到PoP Level Decimal约等于1.72。

f. 求取PoPScore

  • 以8为底数,取PoP Level Decimal为指数,得到最终PoP Score值:

    PoP Score = 8 ^ PoP Level Decimal

    举例,8的1.72次方约等于35.7531(结果取小数点后4位)

计算结果

根据以上计算步骤,在本例中:

0000000000000000000000215206653161113226643512614250403542335511435340330664252463510373257440244542222437344512355773452022004517474440724217350505346711227665150775715

其PoP Level为:Lv.1

其PoP Score为:35.7531

Previous关于PINNextHost

Last updated 17 days ago

📑