-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e9cea88
Showing
1,921 changed files
with
692,565 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
ethx | ||
ethx.exe | ||
bin | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# ethtx - a microservice to generate Ethereum addressess and sign Ethereum transactions | ||
|
||
## What's the point? | ||
`ethtx` is a small, stateless and portable microservice for generating Ethereum addresses and signing Ethereum transactions without the dedicated Ethereum node. | ||
It comes extremely handy when you need to create Ethereum addresses (private/public key pair) or sign Ethereum transactions using a programming language that doesn't have the required crypto libraries. | ||
|
||
## How it works? | ||
It works as a HTTP service. You POST parameters and get a JSON response. | ||
|
||
## What crypto libraries does ethtx use? Is it safe? | ||
`ethtx` is using `geth`'s implentation directly by importing the corresponding source packages directly from the [go-ethereum](https://github.com/ethereum/go-ethereum) project. | ||
|
||
## How it generates the private keys? Any implementation of such crucial part should be seriously reviewed. | ||
`ethtx` derives key generation directly from [go-ethereum](https://github.com/ethereum/go-ethereum) sources. It doesn't add anything else to it. Please check the sources. | ||
|
||
## Tell me more. | ||
So far the following methods are supported: | ||
|
||
### `generateAddress` | ||
Generates a new Ethereum address (private/public keypair): | ||
|
||
##### Input parameters: | ||
`none` | ||
|
||
##### Curl example: | ||
|
||
``` | ||
curl -X POST \ | ||
http://ethtx-address:8070/generateAddress | ||
``` | ||
|
||
##### Response: | ||
```JSON | ||
{ | ||
"address": "0x2cBD5C1D45DCcCD5147BED0314379c6b50c3e8a5", | ||
"privKey": "0xc3c4a14597d9ca779f730df5716c58321e46bc55d6559d8ba2932f0da04e1dbe", | ||
"pubKey": "0x7cbd2cd558251149285fc379fecbf030a92be3b6f2c793ae5c3a7dfefe4076da, 0xff5365976d4c8cddb531bf9dcb19963d8e03bebfcac713bca7017886ef5be7ab" | ||
} | ||
``` | ||
|
||
##### Output: | ||
|
||
`address` : a new freshly generated Ethereum address. | ||
|
||
`privKey` : the private key for this address. Be careful with it and NEVER save it unencrypted. | ||
|
||
`pubKey` : the public key for this address. Consists of two parts, if you need the public key, just concatenate this two parts. | ||
|
||
### `signTx` | ||
Signs a transaction and returns it in RLP coding, ready to be sent to the Ethereum network via a full node, or a 3rd party service like [Infura](https://infura.io/) or [Etherscan](https://etherscan.io/apis) | ||
|
||
##### Input parameters: | ||
|
||
`chainId` : (integer) your network chain ID. Use 1 for the production network and any other custom one for your own private networks. | ||
|
||
`privKey` : (string), the private key used to sign this transaction. Do not use `0x` prefix for the private key. | ||
|
||
`sendTo` : (string), the Ethereum address to send this transaction to. Use `0x` prefix for the destination address. | ||
|
||
`amount` : (float), the amount of `ETH` to send. For example, 23.33323 | ||
|
||
`amountWei` : (integer), if you don't want to pass the amount in `ETH`, put `0` in `amount` above, and use the amount in `wei` here. For example, 30000000000000000 | ||
|
||
`gasLimit` : (integer), gas limit for this transaction, for example, 21000 | ||
|
||
`gasPrice` : (integer), gas price in `wei` for this transaction, for example, 20000000000 | ||
|
||
`nonce` : (integer), nonce value for this transaction. Use [eth_getTransactionCount](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactioncount) to get the nonce before signing this transaction. Without the valid nonce, your transaction won't be relayed to the network and will be stuck. | ||
|
||
##### Curl example: | ||
|
||
``` | ||
curl -X POST \ | ||
http://ethtx-address:8070/signTx \ | ||
-H 'Content-Type: application/x-www-form-urlencoded' \ | ||
-d 'chainId=88882&privKey=c3c4a14597d9ca779f730df5716c58321e46bc55d6559d8ba2932f0da04e1dbe&sendTo=0x3822e05392f097cf03ba3227cc16b73ceb0ee305&amount=0.1&gasLimit=21000&gasPrice=20000000000&nonce=1' | ||
``` | ||
|
||
##### Output: | ||
|
||
`result` : if it is `ok` then `signedTx` contains the signed transaction. | ||
|
||
`signedTx` : signed transaction ready to be sent to the Ethereum network by any available means. | ||
|
||
##### Response: | ||
```JSON | ||
{ | ||
"result": "ok", | ||
"signedTx": "0xf86f018504a817c800825208943822e05392f097cf03ba3227cc16b73ceb0ee30588016345785d8a000080830300afa0ab96c871bf77e8f2a67b744fbec7138a45f7a706a3cdd758989f3b49da30299ba05eb9343eb000e620e62c31769d6a5e5ac8c191f3afa2f9c934d541520e4340f9" | ||
} | ||
``` | ||
|
||
## What platforms are supported? | ||
Any that Go can compile for. | ||
|
||
## What is required? | ||
Just Go. | ||
|
||
## How do I install goicy? | ||
The `go get` command will automatically fetch all dependencies required, compile the binary and place it in your $GOPATH/bin directory. | ||
|
||
go get github.com/stunndard/ethtx | ||
|
||
## How do I configure it? | ||
Read `ethtx.yml `. Tune it for your needs. | ||
```YAML | ||
--- | ||
Gzip: true | ||
Other: | ||
listen: ":8070" | ||
redactLogs: True | ||
|
||
``` | ||
|
||
`redactLogs` will hide the private keys from the logs. By default `ethtx` will write the logs to the standard output. You can hide that or redirect to files, as usual. | ||
|
||
## How do I run it? | ||
Just run the binary | ||
``` | ||
./ethtx | ||
``` | ||
|
||
You can run it inside `tmux` or `screen` or you can write a systemd config for it to run as daemon. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/stunndard/ethtx/routes" | ||
"gopkg.in/kataras/iris.v6" | ||
"gopkg.in/kataras/iris.v6/adaptors/httprouter" | ||
) | ||
|
||
func startWebApp() { | ||
// load config | ||
app := iris.New(iris.YAML("ethtx.yml")) | ||
|
||
routes.RedactLogs = app.Config.Other["redactLogs"].(bool) == true | ||
|
||
app.Adapt(iris.DevLogger()) | ||
app.Adapt(httprouter.New()) | ||
|
||
// first handlers | ||
app.UseFunc(routes.Log) | ||
app.UseFunc(routes.Headers) | ||
|
||
// 404 handler | ||
app.OnError(iris.StatusNotFound, routes.NotFound) | ||
|
||
// app handlers | ||
app.Get("/health", routes.ApiHealth) | ||
app.Get("/", routes.ApiVersion) | ||
|
||
// sign tx | ||
app.Post("/signTx", routes.CheckTx, routes.SignTx) | ||
// generate address | ||
app.Post("generateAddress", routes.GenerateAddress) | ||
|
||
// start the web app | ||
app.Listen(app.Config.Other["listen"].(string)) | ||
} | ||
|
||
func main() { | ||
|
||
|
||
|
||
startWebApp() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
Gzip: true | ||
Other: | ||
listen: ":8070" | ||
redactLogs: true | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package routes | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"github.com/ethereum/go-ethereum/crypto" | ||
"gopkg.in/kataras/iris.v6" | ||
) | ||
|
||
func GenerateAddress(ctx *iris.Context) { | ||
|
||
privKey, err := crypto.GenerateKey() | ||
if err != nil { | ||
log.Println("error generating private key", err) | ||
renderJSONError(ctx, "101", "error generating key") | ||
return | ||
} | ||
|
||
//pubKey := | ||
address := crypto.PubkeyToAddress(privKey.PublicKey).Hex() | ||
|
||
log.Println("key successfully generated") | ||
|
||
privKey1 := fmt.Sprintf("0x%x", privKey.D) | ||
if RedactLogs { | ||
log.Println("private key: 0x...") | ||
} else { | ||
log.Println("private key:", privKey1) | ||
} | ||
|
||
pubKey1 := fmt.Sprintf("0x%x, 0x%x", privKey.PublicKey.X, privKey.PublicKey.Y) | ||
log.Println("public key:", pubKey1) | ||
log.Println("address :", address) | ||
|
||
ctx.JSON(iris.StatusOK, &iris.Map{ | ||
"privKey": privKey1, | ||
"pubKey": pubKey1, | ||
"address": address, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package routes | ||
|
||
import ( | ||
"time" | ||
|
||
"gopkg.in/kataras/iris.v6" | ||
) | ||
|
||
var ( | ||
Started time.Time | ||
Version string | ||
) | ||
|
||
// show health | ||
func ApiHealth(ctx *iris.Context) { | ||
ctx.JSON(iris.StatusOK, &iris.Map{"health": "OK"}) | ||
} | ||
|
||
// show version | ||
func ApiVersion(ctx *iris.Context) { | ||
ctx.JSON(iris.StatusOK, &iris.Map{ | ||
"success": true, | ||
"status": 200, | ||
"version": Version, | ||
"started": Started, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package routes | ||
|
||
import ( | ||
"log" | ||
"time" | ||
|
||
"gopkg.in/kataras/iris.v6" | ||
) | ||
|
||
var RedactLogs bool = false | ||
|
||
func Headers(ctx *iris.Context) { | ||
ctx.SetHeader("Server", "X-Files") | ||
ctx.Next() | ||
} | ||
|
||
func Log(ctx *iris.Context) { | ||
log.Println("[B]", ctx.RemoteAddr(), ctx.Method(), ctx.Path()) | ||
timeStarted := time.Now() | ||
ctx.Next() | ||
timeElapsed := time.Now().Sub(timeStarted) | ||
|
||
log.Println("[E]", ctx.RemoteAddr(), ctx.Method(), ctx.StatusCode(), ctx.Path(), timeElapsed) | ||
log.Println("---") | ||
} | ||
|
||
func NotFound(ctx *iris.Context ) { | ||
log.Println(ctx.RemoteAddr(), ctx.Method(), ctx.StatusCode(), ctx.Path()) | ||
renderJSONError(ctx, "404", "not found") | ||
} | ||
|
||
func renderJSONError(ctx *iris.Context, code, message string) { | ||
ctx.JSON( | ||
iris.StatusOK, | ||
&iris.Map{ | ||
"error": &iris.Map{ | ||
"code": code, | ||
"message": message, | ||
}, | ||
}, | ||
) | ||
ctx.StopExecution() | ||
} |
Oops, something went wrong.