This repository has been archived by the owner on Jan 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pick-winner.go
97 lines (81 loc) · 2.72 KB
/
pick-winner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
. "github.com/Tolsi/vrf-lottery/tools"
"github.com/Tolsi/vrf-lottery/vrf"
"github.com/btcsuite/btcutil/base58"
"io/ioutil"
"os"
)
func main() {
//region Read params
participantsFilename := flag.String("participantsFile", "", "Path to file with participants, it should contains json array of strings")
blockHeight := flag.Uint("blockHeight", 0, "Waves block height, the signature of it will be used in provable message")
privateKeyBase58 := flag.String("privateKey", "", "ed25519 private key in Base58 to prove the message")
pickN := flag.Uint("pickN", 1, "Number of winners to pick, it should be >= 1")
printJson := flag.Bool("json", false, "Output JSON, not plain text")
flag.Parse()
if *participantsFilename == "" {
flag.Usage()
os.Exit(1)
}
if *blockHeight == 0 {
flag.Usage()
os.Exit(1)
}
if *privateKeyBase58 == "" {
flag.Usage()
os.Exit(1)
}
if *pickN < 1 {
flag.Usage()
os.Exit(1)
}
participantsFile, err := ioutil.ReadFile(*participantsFilename)
PrintErrorAndExit(err)
var participants []string
err = json.Unmarshal(participantsFile, &participants)
PrintErrorAndExit(err)
skb := vrf.PrivateKey(base58.Decode(*privateKeyBase58))
//endregion
//region Create proofs
blockSignature, err := GetBlockSignature(*blockHeight)
PrintErrorAndExit(err)
participantsJson, err := json.Marshal(participants)
PrintErrorAndExit(err)
provableMessage := append(participantsJson, []byte("\n"+blockSignature)...)
fileName := fmt.Sprintf("participants_and_%d_block_signature.txt", *blockHeight)
err = ioutil.WriteFile(fileName, provableMessage, 0644)
fmt.Printf("Provable lottery data was saved to file '%s'\n", fileName)
PrintErrorAndExit(err)
vrfBytes, proof := skb.Prove(provableMessage)
pk, _ := skb.Public()
verifyResult, vrfBytes2 := pk.Verify(provableMessage, proof)
if !verifyResult || bytes.Compare(vrfBytes, vrfBytes2) != 0 {
fmt.Printf("Proof verification was failed")
os.Exit(1)
}
PrintErrorAndExit(err)
//endregion
//region Result output
winners := PickUniquePseudorandomParticipants(vrfBytes[:], *pickN, participants)
if *printJson {
type OutputWinners struct {
Winners []string `json:"winners"`
Proof string `json:"proof"`
Vrf string `json:"vrf"`
Message string `json:"message"`
}
err = json.NewEncoder(os.Stdout).Encode(OutputWinners{winners, base58.Encode(proof), base58.Encode(vrfBytes), string(provableMessage)})
PrintErrorAndExit(err)
} else {
fmt.Printf("message: %s\n", string(provableMessage))
fmt.Printf("proof (base58): %s\n", base58.Encode(proof))
fmt.Printf("vrf bytes (base58): %s\n", base58.Encode(vrfBytes))
fmt.Printf("winners are participants: %v\n", winners)
}
//endregion
}