Skip to content

Instantly share code, notes, and snippets.

@bydmm
Last active December 8, 2017 08:05
Show Gist options
  • Save bydmm/727e92aa1651a5dd1db41aef50c62568 to your computer and use it in GitHub Desktop.
Save bydmm/727e92aa1651a5dd1db41aef50c62568 to your computer and use it in GitHub Desktop.
用算力工作证明实现抽卡
package main
import (
"encoding/hex"
"math/rand"
"strconv"
"crypto/sha256"
"time"
"fmt"
)
// 时间戳
func timestamp() string {
timestamp := time.Now().UnixNano()
return strconv.Itoa(int(timestamp))
}
// 随机数
func randNumber() string {
s := rand.NewSource(time.Now().UnixNano())
r := rand.New(s)
return strconv.Itoa(r.Intn(1000))
}
// 判定是否为卡的函数
func findCard(hashCard [32]byte) {
// 难度系数
hard := 5
// 获取卡的hash值
card := hex.EncodeToString(hashCard[:])
// 截取这个卡的最后几位
last := string(card[len(card)-(hard + 4):])
// 难度系数就是说,最后几位的开头要有几个0
// 由于这个hash应该是随机分布的,那么0越多自然越难
headZero := ""
for index := 0; index < hard; index++ {
headZero += "0"
}
if last[0:hard] != headZero {
return
}
// 满足hard个0后,还要是个数字,否则匹配不到卡的id
i, err := strconv.ParseInt(last, 10, 32)
if err != nil {
return
}
if i > 0 {
// 那么你的卡的id是?
fmt.Printf("%s %d\n", card, i)
}
}
func main() {
// 用户公钥
user := "1ccfce1ed647ec3b12c398f4791a1adb3285cfff85ce7d382362c321a1a1df2"
// 使用算力工作证明无限抽卡
for true {
// 使用用户公钥,时间戳以及随机数作为种子
key := user + timestamp() + randNumber()
// 去生成一个hash值,这里使用sha256这个比较公允的算法
rawOre := sha256.Sum256([]byte(key))
// 根据规则去判断hash是否是一张卡
findCard(rawOre)
// 交出控制权,不然卡死cpu了。
time.Sleep(1)
}
}
// 用户挖到卡后,展示自己的钥匙,当时挖出的时间戳,以及这个随机数
// 任何人都可以还原这个算法,证明这张卡确实是这个用户挖出来的
// 用户之间也许还可以通过私钥来达成交易(未实现)
{
"pubkey": "1ccfce1ed647ec3b12c398f4791a1adb3285cfff85ce7d382362c321a1a1df2",
"timestamp": 1974545345345,
"randNumber": 6653,
"cardBlock": "15c9c6c3afb2b2ff612c5ea37b563c50dac4e95d7a93695bc5d6800000009004",
"signature": "dsfsdf34515c9c6c3afb2b2ff612c5ea37b563c50dac4e95d7a93695bc5d6800",
"owner": "1ccfce1ed647ec3b12c398f4791a1adb3285cfff85ce7d382362c321a1a1df2"
}
通过这个验证卡是正确的(不挖找不到这个block)
cardBlock = sha256(pubkey + timestamp + randNumber + cardBlock)
通过这个来验证你拥有这个块,用来交易
signature = 签名函数(private_key, cardBlock)
cardBlock = 验证函数(pubkey, signature)
cardBlock
15c9c6c3afb2b2ff612c5ea37b563c50dac4e95d7a93695bc5d68(00000000019999)
0000000 基础难度系数,0越多总体的难度提升
001 卡id,设定为0越多卡越稀有
99 攻击,纯属娱乐
99 防御,纯属娱乐
交易出去的卡:
{
"pubkey": "1ccfce1ed647ec3b12c398f4791a1adb3285cfff85ce7d382362c321a1a1df2",
"timestamp": 1974545345345,
"randNumber": 6653,
"cardBlock": "15c9c6c3afb2b2ff612c5ea37b563c50dac4e95d7a93695bc5d6800000009004",
"signature": "dsfsdf34515c9c6c3afb2b2ff612c5ea37b563c50dac4e95d7a93695bc5d6800",
"ownerPubkey": "1ccfce1ed647ec3b12c398f4791a1adb3285cfff85ce7d382362c321a1a1df2"
}
signature = 签名函数(创造者的private_key, (ownerPubkey + cardBlock))
ownerPubkey + cardBlock = 验证函数(pubkey, signature)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment