Last active
December 8, 2017 08:05
-
-
Save bydmm/727e92aa1651a5dd1db41aef50c62568 to your computer and use it in GitHub Desktop.
用算力工作证明实现抽卡
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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