blockchain/gclient.go
2020-07-26 14:08:18 -04:00

285 lines
5.6 KiB
Go

package main
import (
"os"
"fmt"
nt "./network"
bc "./blockchain"
"net/http"
"strconv"
"strings"
"html/template"
"encoding/json"
)
const (
STTC_PATH = "static/"
TMPL_PATH = "templates/"
ADDR_FILE = "addr.json"
)
func init() {
err := json.Unmarshal([]byte(readFile(ADDR_FILE)), &Addresses)
if err != nil {
panic("failed: load addresses")
}
if len(Addresses) == 0 {
panic("failed: len(Addresses) == 0")
}
}
func main() {
fmt.Println("Server is running ...")
http.Handle("/static/", http.StripPrefix(
"/static/",
handleFileServer(http.Dir(STTC_PATH))),
)
http.HandleFunc("/", indexPage)
http.HandleFunc("/login", loginPage)
http.HandleFunc("/signup", signupPage)
http.HandleFunc("/logout", logoutPage)
http.HandleFunc("/account", accountPage)
http.HandleFunc("/transaction", transactionPage)
http.HandleFunc("/blockchain", blockchainPage)
http.HandleFunc("/blockchain/", blockchainXPage)
http.ListenAndServe(":7545", nil)
}
func handleFileServer(fs http.FileSystem) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if _, err := fs.Open(r.URL.Path); os.IsNotExist(err) {
indexPage(w, r)
return
}
http.FileServer(fs).ServeHTTP(w, r)
})
}
func indexPage(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(
TMPL_PATH+"base.html",
TMPL_PATH+"index.html",
)
if err != nil {
panic("can't load hmtl files")
}
var data struct{
User *bc.User
}
data.User = User
t.Execute(w, data)
}
func accountPage(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(
TMPL_PATH+"base.html",
TMPL_PATH+"account.html",
)
if err != nil {
panic("can't load hmtl files")
}
var data struct{
User *bc.User
Address string
Balance string
}
data.User = User
if data.User != nil {
data.Address = User.Address()
res := nt.Send(Addresses[0], &nt.Package{
Option: GET_BLNCE,
Data: data.Address,
})
if res != nil {
data.Balance = res.Data
}
} else {
http.Redirect(w, r, "/", 302)
return
}
t.Execute(w, data)
}
func loginPage(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(
TMPL_PATH+"base.html",
TMPL_PATH+"login.html",
)
if err != nil {
panic("can't load hmtl files")
}
var data struct{
User *bc.User
Error string
}
if r.Method == "POST" {
r.ParseForm()
User = bc.LoadUser(r.FormValue("private"))
if User == nil {
data.Error = "Load Private Key Error"
} else {
http.Redirect(w, r, "/", 302)
return
}
}
data.User = User
t.Execute(w, data)
}
func logoutPage(w http.ResponseWriter, r *http.Request) {
User = nil
http.Redirect(w, r, "/", 302)
}
func signupPage(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(
TMPL_PATH+"base.html",
TMPL_PATH+"signup.html",
)
if err != nil {
panic("can't load hmtl files")
}
var data struct{
User *bc.User
PrivateKey string
}
data.User = User
if r.Method == "POST" {
data.PrivateKey = bc.NewUser().Purse()
}
t.Execute(w, data)
}
func transactionPage(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(
TMPL_PATH+"base.html",
TMPL_PATH+"transaction.html",
)
if err != nil {
panic("can't load hmtl files")
}
var data struct{
User *bc.User
Error string
}
data.User = User
if r.Method == "POST" {
r.ParseForm()
if data.User == nil {
data.Error = "User not authorizated"
t.Execute(w, data)
return
}
receiver := r.FormValue("receiver")
num, err := strconv.Atoi(r.FormValue("value"))
if err != nil {
data.Error = "strconv.Atoi error"
t.Execute(w, data)
return
}
flag := false
for _, addr := range Addresses {
res := nt.Send(addr, &nt.Package{
Option: GET_LHASH,
})
if res == nil {
continue
}
tx := bc.NewTransaction(User, bc.Base64Decode(res.Data), receiver, uint64(num))
res = nt.Send(addr, &nt.Package{
Option: ADD_TRNSX,
Data: bc.SerializeTX(tx),
})
if res == nil || res.Data != "ok" {
continue
}
flag = true
}
if !flag {
data.Error = "TX failed"
} else {
data.Error = "TX success"
}
}
t.Execute(w, data)
}
func blockchainPage(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(
TMPL_PATH+"base.html",
TMPL_PATH+"blockchain.html",
)
if err != nil {
panic("can't load hmtl files")
}
var data struct{
Error string
Size []bool
Address string
Balance string
User *bc.User
}
data.User = User
if r.Method == "POST" {
data.Address = r.FormValue("address")
res := nt.Send(Addresses[0], &nt.Package{
Option: GET_BLNCE,
Data: data.Address,
})
if res != nil {
data.Balance = res.Data
}
}
res := nt.Send(Addresses[0], &nt.Package{
Option: GET_CSIZE,
})
if res == nil || res.Data == "" {
data.Error = "Receive error"
t.Execute(w, data)
return
}
num, err := strconv.Atoi(res.Data)
if err != nil {
data.Error = "strconv.Atoi error"
t.Execute(w, data)
return
}
data.Size = make([]bool, num)
t.Execute(w, data)
}
func blockchainXPage(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(
TMPL_PATH+"base.html",
TMPL_PATH+"blockchainX.html",
)
if err != nil {
panic("can't load hmtl files")
}
var data struct{
Error string
Block *bc.Block
User *bc.User
}
data.User = User
res := nt.Send(Addresses[0], &nt.Package{
Option: GET_BLOCK,
Data: strings.Replace(r.URL.Path, "/blockchain/", "", 1),
})
if res == nil || res.Data == "" {
data.Error = "Receive error"
t.Execute(w, data)
return
}
data.Block = bc.DeserializeBlock(res.Data)
if data.Block == nil {
data.Error = "Block is nil"
t.Execute(w, data)
return
}
t.Execute(w, data)
}