add hashcash cli

This commit is contained in:
AJ ONeal 2020-08-15 05:36:17 -06:00
parent badaa411f2
commit 8ff4270901
3 changed files with 180 additions and 0 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
cmd/hashcash/hashcash
# ---> Go
# Binaries for programs and plugins
*.exe

View File

@ -5,3 +5,37 @@ HTTP Hashcash implemented in Go.
Explanation at https://therootcompany.com/blog/http-hashcash/
Go docs at https://godoc.org/git.rootprojects.org/root/hashcash
# CLI Usage
Install:
```bash
go get git.rootprojects.org/root/hashcash/cmd/hashcash
```
Usage:
```txt
Usage:
hashcash new [subject *] [expires in 5m] [difficulty 10]
hashcash parse <hashcash>
hashcash solve <hashcash>
hashcash verify <hashcash> [subject *]
```
Example:
```bash
my_hc=$(hashcash new)
echo New: $my_hc
hashcash parse "$my_hc"
echo ""
my_hc=$(hashcash solve "$my_hc")
echo Solved: $my_hc
hashcash parse "$my_hc"
echo ""
hashcash verify "$my_hc"
```

144
cmd/hashcash/hashcash.go Normal file
View File

@ -0,0 +1,144 @@
package main
import (
"encoding/json"
"fmt"
"os"
"strconv"
"time"
"git.rootprojects.org/root/hashcash"
)
func help() {
fmt.Println("Usage:")
fmt.Println("\thashcash new [subject *] [expires in 5m] [difficulty 10]")
fmt.Println("\thashcash parse <hashcash>")
fmt.Println("\thashcash solve <hashcash>")
fmt.Println("\thashcash verify <hashcash> [subject *]")
}
func main() {
args := os.Args[:]
if len(args) < 2 {
help()
os.Exit(1)
return
}
switch args[1] {
case "new":
var subject string
if len(args) > 3 {
subject = args[2]
}
var difficulty int
if len(args) > 4 {
var err error
difficulty, err = strconv.Atoi(args[3])
if nil != err {
help()
os.Exit(1)
}
}
var expIn time.Duration
if len(args) > 5 {
var err error
expIn, err = time.ParseDuration(args[4])
if nil != err {
help()
os.Exit(1)
}
} 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 != len(args) {
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 != len(args) {
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 "verify":
var token string
if len(args) < 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 len(args) > 3 {
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)
}
}