Proof of PIN (PoP) is an interesting concept in MetaID. We have developed the PoP mechanism with reference to the mining principle of Bitcoin. The PoP value reflects the user's "proof of work" in the MetaID world. In the MetaID world, the minimum "work" of a user is to send a PIN, so each PIN has a hash value that combines the user's PIN with the difficulty of the block it is in. The PoP value reflects the following two dimensions:
Overview of the amount of MetaID data created by the user: The more MetaID PINs created, the higher the probability of obtaining a high-difficulty PoP value.
Hashrate consumption of the user's MetaID data creation: The PoP value is linked to the hashrate of the blockchain where the MetaID data is located. The higher the hashrate, the easier it is to obtain a high-difficulty PoP value.
PIN is similar to SHA256 hashrate, while PoP is similar to difficulty hash. The higher the hashrate, the greater the probability of obtaining a high-difficulty hash value.
By verifying the user's related PoP value, we can quickly evaluate a user's contribution in the MetaID world and give the concept of level and rarity to PINs.
Calculation Method
PoP is calculated by performing a SHA256 joint hash on the MerkleRoot and PINID, and then multiplying it by the BlockHash to generate a new value. The specific formula is:
PoP = hash(PIN_ID + Merkle_Root) * Block_Hash
The resulting original hash value is then converted to octal, and the converted result is the PoP.
Concept of PoP Difficulty
The difficulty level of a PoP value is similar to block hashes, defined by the number of leading zeros ("0"). The more leading zeros, the higher the difficulty level of the PoP. Any valid PoP must contain at least 21 leading zeros.
PoP Difficulty Levels
Regarding the difficulty levels, based on the current hashrate of Bitcoin, MetaID PoP can be divided into 11 levels. Starting from level 1, the PoP value prefix needs to have 22 "0"s to meet level 1, 23 "0"s to reach level 2, and so on. The increase in the number of "0"s directly reflects the improvement in the rarity level of PoP.
Here is the code:
packagepopimport ("crypto/sha256""encoding/hex""fmt""math/big""strconv")funcCalculateHash(pinid string, merkleRoot string) string { h := sha256.New() h.Write([]byte(pinid + merkleRoot))return hex.EncodeToString(h.Sum(nil))}funcCalculateProductToHexStr(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()// Calculate total length: 32+32=64 totalLen :=len(blockhashByte) +len(pinHashByte)// Number of leading zeros needed remainingLen := totalLen -len(popByte)for i :=0; i < remainingLen; i++ { popByte =append([]byte{0}, popByte...) }return hex.EncodeToString(popByte)}funcConvertToOctalHex(productHex string) (string, int64) { productByte, _ := hex.DecodeString(productHex)// Convert to binary 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 } }// Convert binary string to octal string 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}funcGenPop(pinid, merkleRoot, blockHash string) (string, int64) {// Calculate pinHash pinHash :=CalculateHash(pinid, merkleRoot)// Multiply blockhash by pinHash productHexStr :=CalculateProductToHexStr(blockHash, pinHash)// Convert to octal octal, bCount :=ConvertToOctalHex(productHexStr)return octal, bCount}