忆往昔
发布于

根据difficulty计算 算力

package main

import (
    "encoding/hex"
    "fmt"
    "math/big"
)

// ParseBig256 parses s as a 256 bit integer in decimal or hexadecimal syntax.
// Leading zeros are accepted. The empty string parses as zero.
func ParseBig256(s string) (*big.Int, bool) {
    if s == "" {
        return new(big.Int), true
    }
    var bigint *big.Int
    var ok bool
    if len(s) >= 2 && (s[:2] == "0x" || s[:2] == "0X") {
        bigint, ok = new(big.Int).SetString(s[2:], 16)
    } else {
        bigint, ok = new(big.Int).SetString(s, 10)
    }
    if ok && bigint.BitLen() > 256 {
        bigint, ok = nil, false
    }
    return bigint, ok
}

// has0xPrefix validates str begins with '0x' or '0X'.
func has0xPrefix(str string) bool {
    return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
}

// Hex2Bytes returns the bytes represented by the hexadecimal string str.
func Hex2Bytes(str string) []byte {
    h, _ := hex.DecodeString(str)
    return h
}

func BytesToInt(b []byte) *big.Int {
    bigNum := new(big.Int).SetBytes(b)
    return bigNum
}

func IntToBytes(i *big.Int, numBytes int) []byte {
    if i == nil {
        return []byte("0x0")
    }
    return []byte(fmt.Sprintf("%#x", (*big.Int)(i)))
}

func HexStrToInt(strHex string) *big.Int {
    return BytesToInt(strToBytes(strHex))
}

func strToBytes(s string) []byte {
    if has0xPrefix(s) {
        s = s[2:]
    }
    if len(s)%2 == 1 {
        s = "0" + s
    }
    return Hex2Bytes(s)
}

const (
    N_DIVIDED       = 8
    N_DIVIDED_START = 32
)

var ZERO_MASK = []byte{0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01}

func calcZeroBytes(diffiLevel int) []byte {
    boundry := []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
    nBytesToZero, nBitsToZero := diffiLevel/N_DIVIDED, diffiLevel%N_DIVIDED

    for i := 0; i < nBytesToZero; i++ {
        boundry[i] = 0x00
    }
    boundry[nBytesToZero] = ZERO_MASK[nBitsToZero]
    return boundry
}
func DifficultyToBoundary(difficult int) *big.Int {
    var difficultyLevel int
    m := 0
    n := (difficult - N_DIVIDED_START) / N_DIVIDED
    m = (difficult - N_DIVIDED_START) % N_DIVIDED
    difficultyLevel = N_DIVIDED_START + n
    intBoundry := BytesToInt(calcZeroBytes(difficultyLevel))

    rsh := big.NewInt(0).Rsh(intBoundry, 1)
    mod := new(big.Int)
    step, mod := rsh.DivMod(rsh, big.NewInt(N_DIVIDED), mod)

    boundry := intBoundry.Sub(intBoundry, step.Mul(step, big.NewInt(int64(m))))
    return boundry
}
func boundryTohashPower(boundry *big.Int) string {
    a, ok := new(big.Int).SetString("ffff000000000000000000000000000000000000000000000000000000000000", 16)
    if !ok {
        return "0"
    }
    mod, _ := a.DivMod(a, boundry, big.NewInt(0))
    return mod.String()
}
func DifficultToHashPower(difficult int) string {
    return boundryTohashPower(DifficultyToBoundary(difficult))
}

func main() {
    fmt.Println(DifficultToHashPower(101))
    fmt.Println(DifficultToHashPower(158))
    fmt.Println(DifficultToHashPower(159))
}

import math
import os
import sys

import matplotlib.pyplot as plt

N_DIVIDED = 8
TOKEN_NUM_BYTES = 32

ZERO_MASK = [0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01]

def hex_str_to_bytes(str_hex: str) -> bytes:
    if isinstance(str_hex, bytes):
        return str_hex
    str_hex = str_hex.lower()
    if str_hex.startswith("0x"):
        str_hex = str_hex[2:]
    if len(str_hex) & 1:
        str_hex = "0" + str_hex
    return bytes.fromhex(str_hex)


def bytes_to_int(bytes_hex: bytes, byteorder="big"):
    return int.from_bytes(bytes_hex, byteorder=byteorder)


def int_to_bytes(i: int, n_bytes=TOKEN_NUM_BYTES, byteorder="big") -> bytes:
    if n_bytes is None:
        n_bytes = (i.bit_length() + 7) // 8 or 1
    return i.to_bytes(length=n_bytes, byteorder=byteorder)


def hex_str_to_int(str_hex: str, byteorder: str = "big") -> int:
    return bytes_to_int(hex_str_to_bytes(str_hex), byteorder=byteorder)


def calc_zero_bytes(difficulty_level):
    boundary = bytearray(b"\xFF" * 32)

    n_bytes_to_zero = difficulty_level // 8
    n_bits_to_zero = difficulty_level % 8

    boundary[0:n_bytes_to_zero] = b"\x00" * n_bytes_to_zero
    boundary[n_bytes_to_zero] = ZERO_MASK[n_bits_to_zero]

    return bytes(boundary)


def new_difficulty_to_boundary(difficulty: int) -> bytes:
    if difficulty < 32:
        difficulty_level = difficulty
        return calc_zero_bytes(difficulty_level)
    else:
        n = (difficulty - 32) // N_DIVIDED
        m = (difficulty - 32) % N_DIVIDED
        difficulty_level = 32 + n
    tmp = calc_zero_bytes(difficulty_level)
    print(tmp)
    int_boundary = bytes_to_int(tmp)
    boundary_change_step = (int_boundary >> 1) // N_DIVIDED
# // 822752278660603021077484591278675252491367932816789931674304511
    boundary = int_boundary - boundary_change_step * m

    return int_to_bytes(boundary, n_bytes=32)


dividend = 0xffff000000000000000000000000000000000000000000000000000000000000  # 2^256


def boundary_to_hashpower(boundary) -> int:
    if isinstance(boundary, str):
        return dividend // hex_str_to_int(boundary)
    elif isinstance(boundary, bytes):
        return dividend // bytes_to_int(boundary)
    raise TypeError("Type of boundary should be str or bytes")


def new_difficulty_to_hashpower(difficulty: int) -> int:
    return boundary_to_hashpower(new_difficulty_to_boundary(difficulty))



def plot_new_diff(diff_list, n_divided=4):
    global N_DIVIDED
    N_DIVIDED = n_divided
    new_hash_list = [new_difficulty_to_hashpower(d) for d in diff_list]
    plt.scatter(diff_list, new_hash_list, label=f"Divided 1/{n_divided}")
    plt.legend()
    return new_hash_list


def convert_hashrate(hashrate, k=1000):
    if hashrate <= 0:
        return "0 Mh"

    rates = ['h', 'Kh', 'Mh', 'Gh', 'Th', 'Ph', 'Eh', 'Zh', 'Yh']
    i = math.floor(math.log(hashrate) / math.log(k))

    return f"{hashrate / pow(k, i):.2f} {rates[i]}"

print(convert_hashrate(new_difficulty_to_hashpower(100)))
sys.exit()

diff_list = list(range(158, 160))

plt.figure(figsize=(16, 10))
plt.yscale("log")

# new_hash_list_2 = plot_new_diff(diff_list, n_divided=2)
# new_hash_list_4 = plot_new_diff(diff_list, n_divided=4)
# new_hash_list_6 = plot_new_diff(diff_list, n_divided=6)
new_hash_list_8 = plot_new_diff(diff_list, n_divided=8)

print(f"Level",
      "    ", f"{'1/8':15s}",
      )

# for diff, hashpower4, hashpower6, hashpower8 in zip(diff_list,
#                                                     new_hash_list_4, new_hash_list_6,
#                                                     new_hash_list_8):
for diff, hashpower8 in zip(diff_list,    new_hash_list_8):
    print(f"{diff:03}",
          " -- ", f"{convert_hashrate(hashpower8):15s}",
          )

浏览 (52)
点赞
收藏
评论