From 7c773b4c3ea7e23f83c0f9e9099e57108d7b7e38 Mon Sep 17 00:00:00 2001 From: arnaucode Date: Fri, 27 Jul 2018 00:23:16 +0200 Subject: [PATCH] first commit --- .gitignore | 2 ++ README.md | 11 +++++++ config.go | 23 ++++++++++++++ config.yaml | 2 ++ configEXAMPLE.yaml | 2 ++ eth.go | 32 +++++++++++++++++++ main.go | 51 ++++++++++++++++++++++++++++++ rest.go | 19 ++++++++++++ utils.go | 23 ++++++++++++++ www/index.html | 71 ++++++++++++++++++++++++++++++++++++++++++ www/index.js | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 313 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 config.go create mode 100644 config.yaml create mode 100644 configEXAMPLE.yaml create mode 100644 eth.go create mode 100644 main.go create mode 100644 rest.go create mode 100644 utils.go create mode 100644 www/index.html create mode 100644 www/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f00cf94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +data-dir* +config.yaml diff --git a/README.md b/README.md new file mode 100644 index 0000000..17ff3f7 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# tor-eth-online-shop + +Online shop through Tor hidden service, that allows payments in Ethereum. + + +## Run +First edit configEXAMPLE.yaml to config.yaml, and edit the content. +Then, run: +``` +go run *.go +``` diff --git a/config.go b/config.go new file mode 100644 index 0000000..078fdbb --- /dev/null +++ b/config.go @@ -0,0 +1,23 @@ +package main + +import "github.com/spf13/viper" + +type Config struct { + GethURL string + PrivK string +} + +var config Config + +func ReadConfig(path, filename string) { + viper.SetConfigName(filename) + viper.AddConfigPath(path) + viper.SetConfigType("yaml") + if err := viper.ReadInConfig(); err != nil { + panic(err) + } + err := viper.Unmarshal(&config) + if err != nil { + panic(err) + } +} diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..8cb49b4 --- /dev/null +++ b/config.yaml @@ -0,0 +1,2 @@ +privK: "da7079f082a1ced80c5dee3bf00752fd67f75321a637e5d5073ce1489af062d8" +gethurl: "https://ropsten.infura.io/TFnR8BWJlqZOKxHHZNcs" diff --git a/configEXAMPLE.yaml b/configEXAMPLE.yaml new file mode 100644 index 0000000..528206d --- /dev/null +++ b/configEXAMPLE.yaml @@ -0,0 +1,2 @@ +privK: "here the private key" +gethurl: "here the Geth URL" diff --git a/eth.go b/eth.go new file mode 100644 index 0000000..e89ad20 --- /dev/null +++ b/eth.go @@ -0,0 +1,32 @@ +package main + +import ( + "crypto/ecdsa" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" +) + +var ( + client *ethclient.Client + key *ecdsa.PrivateKey + address common.Address +) + +func Web3Open() error { + // geth set up + var err error + + client, err = ethclient.Dial(config.GethURL) + if err != nil { + return err + } + key, err = crypto.HexToECDSA(config.PrivK) + if err != nil { + return err + } + address = crypto.PubkeyToAddress(key.PublicKey) + + return nil +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..744fba7 --- /dev/null +++ b/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "context" + "fmt" + "log" + "net/http" + "os" + "time" + + "github.com/cretz/bine/tor" + "github.com/ipsn/go-libtor" +) + +func main() { + ReadConfig(".", "config") + + // Start tor with some defaults + elevated verbosity + fmt.Println("Starting and registering onion service, please wait a bit...") + t, err := tor.Start(nil, &tor.StartConf{ProcessCreator: libtor.Creator, DebugWriter: os.Stderr}) + if err != nil { + log.Panicf("Failed to start tor: %v", err) + } + defer t.Close() + + // Wait at most a few minutes to publish the service + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) + defer cancel() + + // Create an onion service to listen on any port but show as 80 + onion, err := t.Listen(ctx, &tor.ListenConf{RemotePorts: []int{80}}) + if err != nil { + log.Panicf("Failed to create onion service: %v", err) + } + defer onion.Close() + + fmt.Printf("Please open a Tor capable browser and navigate to http://%v.onion\n", onion.ID) + + // connect to eth + // Ethereum + err = Web3Open() + if err != nil { + log.Fatal(err) + } + + // Run a Hello-World HTTP service until terminated + http.Handle("/", http.FileServer(http.Dir("./www"))) + http.HandleFunc("/api/purchase", handlePurchase) + http.HandleFunc("/api/txid", handleTxId) + http.Serve(onion, nil) +} diff --git a/rest.go b/rest.go new file mode 100644 index 0000000..a2eb9df --- /dev/null +++ b/rest.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "net/http" +) + +func handlePurchase(w http.ResponseWriter, r *http.Request) { + challenge, err := generateChallenge(20) + if err != nil { + panic(err) + return + } + fmt.Fprintf(w, challenge) +} +func handleTxId(w http.ResponseWriter, r *http.Request) { + + fmt.Fprintf(w, "ack") +} diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..afa2914 --- /dev/null +++ b/utils.go @@ -0,0 +1,23 @@ +package main + +import ( + "crypto/rand" + "math/big" +) + +func generateChallenge(length int) (string, error) { + result := "" + for { + if len(result) >= length { + return result, nil + } + num, err := rand.Int(rand.Reader, big.NewInt(int64(127))) + if err != nil { + return "", err + } + n := num.Int64() + if n > 32 && n < 127 { + result += string(n) + } + } +} diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..dff3812 --- /dev/null +++ b/www/index.html @@ -0,0 +1,71 @@ + + + + + + + + + tor-eth-online-shop + + +
+

tor-eth-online-shop

+
+
+
+
+
+ Card image cap +
+
Product 1
+

Description.

+ Add to card +
+
+
+
+
+ Card image cap +
+
Product 2
+

Description.

+ Add to card +
+
+
+
+
+ Card image cap +
+
Product 3
+

Description.

+ Add to card +
+
+
+
+
+
+
+
+

Selected products

+

+ Purchase +
+
+
+
+
+ + + + + + + + + + + + diff --git a/www/index.js b/www/index.js new file mode 100644 index 0000000..aa9700e --- /dev/null +++ b/www/index.js @@ -0,0 +1,77 @@ +var products = [ + { + id: 'id1', + title: 'beer1', + price: '0.1' + }, + { + id: 'id2', + title: 'beer2', + price: '0.1' + }, + { + id: 'id3', + title: 'beer3', + price: '0.1' + } +]; +var list = {}; +function getProduct(id) { + for(var i=0; i"; + html += ""; + html += "
"; + document.getElementById("list").innerHTML = html; +} + +function purchase() { + var total = 0; + for (var property in list) { + if (list.hasOwnProperty(property)) { + total = (+(total) + +(getProduct(property).price * list[property])).toFixed(4); + } + } + var answ = confirm("total to pay: " + total + " eth"); + if (!answ) { + return; + } + axios.post('/api/purchase', { + list: list + }) + .then(function (response) { + console.log(response); + }) + .catch(function (error) { + console.log(error); + }); +}