package main import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "os" "strconv" "time" "git.rootprojects.org/root/hashcash" ) func help() { fmt.Println("Usage:") fmt.Println("\thashcash new [subject *] [difficulty 10] [expires in 5m]") fmt.Println("\thashcash parse ") fmt.Println("\thashcash solve ") fmt.Println("\thashcash hash ") fmt.Println("\thashcash verify [subject *]") } func main() { args := os.Args[:] nargs := len(args) if nargs < 2 { help() os.Exit(1) return } switch args[1] { case "new": var subject string if nargs >= 3 { subject = args[2] } var difficulty int if nargs >= 4 { var err error difficulty, err = strconv.Atoi(args[3]) if nil != err { help() os.Exit(1) return } } var expIn time.Duration if nargs >= 5 { var err error expIn, err = time.ParseDuration(args[4]) if nil != err { fmt.Println(err) help() os.Exit(1) return } } else { expIn = 5 * time.Minute } h := hashcash.New(hashcash.Hashcash{ Subject: subject, Difficulty: difficulty, ExpiresAt: time.Now().Add(expIn), }) fmt.Println(h.String()) return case "parse": var token string if 3 != nargs { help() os.Exit(1) return } token = args[2] h, err := hashcash.Parse(token) if nil != err { fmt.Fprintf(os.Stderr, "%s\n", err) return } b, _ := json.MarshalIndent(h, "", " ") fmt.Println(string(b)) return case "solve": var token string if 3 != nargs { help() os.Exit(1) return } token = args[2] h, err := hashcash.Parse(token) if nil != err { fmt.Fprintf(os.Stderr, "%s\n", err) os.Exit(1) return } err = h.Solve(22) if nil != err { fmt.Fprintf(os.Stderr, "%s\n", err) os.Exit(1) return } fmt.Println(h.String()) return case "hash": var token string if 3 != nargs { help() os.Exit(1) return } token = args[2] hash := sha256.Sum256([]byte(token)) fmt.Println(hex.EncodeToString(hash[:])) return case "verify": var token string if nargs < 3 { help() os.Exit(1) return } token = args[2] h, err := hashcash.Parse(token) if nil != err { fmt.Fprintf(os.Stderr, "%s\n", err) return } subject := "*" if nargs >= 4 { subject = args[3] } err = h.Verify(subject) if nil != err { fmt.Fprintf(os.Stderr, "%s\n", err) return } var duration string dur := h.ExpiresAt.Sub(time.Now()) if dur > 365*24*time.Hour { duration = "...a long, long time" } else { duration = dur.Truncate(time.Second).String() } fmt.Println("valid for", duration) return default: help() os.Exit(1) } }