Parse Ethereum private key in string in Go - ethereum

I am trying really hard to convert Ethereum private keys BIP44 in string format to a type that can (*ecdsa.PrivateKey) be used by rest of the code.
import (
"crypto/x509"
"fmt"
"log"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
const (
privateKey2 string = "0xbacd06016aea4280e14efd7182ba18cd98bf11701943d3d47d76b04bb7baad19"
)
func main() {
_, err = x509.ParsePKCS8PrivateKey(firstKey)
if err != nil {
fmt.Println("Cannot parse private key")
}
}

Here is how a private key can be converted to Ethereum address
You need to import one additional package "crypto/ecdsa" and also remove "0x" from the private key.
privateKey, err := crypto.HexToECDSA(privateKey2)
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("error casting public key to ECDSA")
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)

Related

How can I clean up this return type for neoism go-lang?

This model I am trying to make with neoism is working now but I can't figure out how to make the return type shorter and or cleaner looking.
There must be a way to make this:
[]struct { UserId string "json:\"account.UserId\""; FirstName string "json:\"account.firstName\""; LastName string "json:\"account.lastName\"" }
Into:
[]Account or something
package models
import (
"errors"
"strconv"
"time"
// "fmt"
"github.com/jmcvetta/neoism"
)
var (
Accounts map[string]*Account
)
var (
db *neoism.Database
)
func panicErr(err error) {
if err != nil {
panic(err)
}
}
type Account struct {
UserId string `json:"account.UserId"`
FirstName string `json:"account.firstName"`
LastName string `json:"account.lastName"`
}
func init() {
var err error
db, err = neoism.Connect("http://neo4j:password#localhost:7474/db/data")
if err != nil {
panic(err)
}
}
// map[lastName:PATRUS UserId:7f7014f9-bd59-4739-8e1b-5aebfa00f4c5 firstName:LARISSA]
func GetAccounts() []struct { UserId string "json:\"account.UserId\""; FirstName string "json:\"account.firstName\""; LastName string "json:\"account.lastName\"" } {
stmt := `
MATCH (account:Account) RETURN account.UserId, account.firstName, account.lastName
`
res := []struct {
UserId string `json:"account.UserId"`
FirstName string `json:"account.firstName"`
LastName string `json:"account.lastName"`
}{}
// construct query
cq := neoism.CypherQuery{
Statement: stmt,
Result: &res,
}
// execute query
err := db.Cypher(&cq)
panicErr(err)
return res
}
Here is another copy:
http://play.golang.org/p/14gzc0a_89
I am new to go and I am going off of these examples for neoism:
https://gist.github.com/verdverm/b43444063995a7f5b913
There are many examples, but verdverm is always just outputting and not returning.
I have a controller as well where I would like to output the json.
package controllers
import (
"github.com/astaxie/beego"
"social/models"
)
type AccountsController struct {
beego.Controller
}
func (c *AccountsController) Get() {
c.Data["json"] = models.GetAccounts()
// c.Data["json"] = "hello world"
c.ServeJson()
}
Thanks for any help/tips for go newbie!
Can getAccounts return an array of account pointers?
func GetAccounts() []*Account {}
package models
import (
"errors"
"strconv"
"time"
// "fmt"
"github.com/jmcvetta/neoism"
)
var (
Accounts map[string]*Account
)
var (
db *neoism.Database
)
func panicErr(err error) {
if err != nil {
panic(err)
}
}
type Account struct {
UserId string `json:"account.UserId"`
FirstName string `json:"account.firstName"`
LastName string `json:"account.lastName"`
}
func init() {
var err error
db, err = neoism.Connect("http://neo4j:password#localhost:7474/db/data")
if err != nil {
panic(err)
}
}
// map[lastName:PATRUS UserId:7f7014f9-bd59-4739-8e1b-5aebfa00f4c5 firstName:LARISSA]
func GetAccounts() []Account {
stmt := `
MATCH (account:Account) RETURN account.UserId, account.firstName, account.lastName
`
var accounts []Account
// construct query
cq := neoism.CypherQuery{
Statement: stmt,
Result: &accounts,
}
// execute query
err := db.Cypher(&cq)
panicErr(err)
return accounts
}
need to use the Account struct above the function and then make a variable inside and use pointer to var for the response of neoism db.

Create public key from modulus and exponent in Golang

I fetched from the first certificate on: https://www.googleapis.com/oauth2/v2/certs the 'n' and 'e' key values. Is there a package in Go that can build a public key with 'n' and 'e'? I don't know how it's done using the crypto/rsa package. Some code would be precious. Thank You.
The rsa package has a PublicKey type with fields N and E. It should be pretty straightforward to decode the parts as described in the JWA draft.
Here is some quickly hacked code (Playground):
package main
import (
"bytes"
"crypto/rsa"
"encoding/base64"
"encoding/binary"
"fmt"
"math/big"
)
func main() {
nStr := "AN+7p8kw1A3LXfAJi+Ui4o8F8G0EeB4B5RuufglWa4AkadDaLTxGLNtY/NtyRZBfwhdAmRjKQJTVgn5j3y0s+j/bvpzMktoVeHB7irOhxDnZJdIxNNMY3nUKBgQB81jg8lNTeBrJqELSJiRXQIe5PyWJWwQJ1XrtfQNcwGkICM1L"
decN, err := base64.StdEncoding.DecodeString(nStr)
if err != nil {
fmt.Println(err)
return
}
n := big.NewInt(0)
n.SetBytes(decN)
eStr := "AQAB"
decE, err := base64.StdEncoding.DecodeString(eStr)
if err != nil {
fmt.Println(err)
return
}
var eBytes []byte
if len(decE) < 8 {
eBytes = make([]byte, 8-len(decE), 8)
eBytes = append(eBytes, decE...)
} else {
eBytes = decE
}
eReader := bytes.NewReader(eBytes)
var e uint64
err = binary.Read(eReader, binary.BigEndian, &e)
if err != nil {
fmt.Println(err)
return
}
pKey := rsa.PublicKey{N: n, E: int(e)}
}

Getting json dynamic key name as string?

For example:
{"id":
{"12345678901234":
{"Account":"asdf",
"Password":"qwerty"
"LastSeen":"1397621470",
}
}
}
A program I've been trying to make needs to get the id as a string and then later use it to check the time in LastSeen.
I've tried using simplejson and jsonq,but still cant figure out how to do that.
You can use RawMessage and make it much simpiler (play with it) :
package main
import (
"encoding/json"
"fmt"
)
var data []byte = []byte(`{"id": {"12345678901234": {"Account":"asdf", "Password":"qwerty", "LastSeen":"1397621470"}}}`)
type Message struct {
Id string
Info struct {
Account string
Password string
LastSeen string
}
}
func main() {
var (
tmpmsg struct {
Data map[string]json.RawMessage `json:"id"`
}
msg Message
)
if err := json.Unmarshal(data, &tmpmsg); err != nil {
panic(err) //you probably wanna use or something instead
}
for id, raw := range tmpmsg.Data {
msg.Id = id
if err := json.Unmarshal(raw, &msg.Info); err != nil {
panic(err)
}
}
fmt.Printf("%+v\n", msg)
}
Looking at the Golang blog post on JSON here it can be done using the encoding/json package. I created a small program to do this as follows:
package main
import (
"encoding/json"
"fmt"
)
var data []byte = []byte(`{"id": {"12345678901234": {"Account":"asdf", "Password":"qwerty", "LastSeen":"1397621470"}}}`)
type Message struct {
id string
LastSeen int64
}
var m Message
func main() {
var i interface {}
err := json.Unmarshal(data, &i)
if err != nil {
println("Error decoding data")
fmt.Printf("%s", err.Error())
return
}
m := i.(map[string]interface{})
for k, v := range m {
println(k)
im := v.(map[string]interface{})
for ik, iv := range im {
println("\t", ik)
jm := iv.(map[string]interface{})
for jk, jv := range jm {
println("\t\t", jk, ": ", jv.(string))
}
}
}
}
I apologise if this is poor in terms of Go best practices and such, I am new to the language. And I know that some elements of this aren't entirely necessary like the Message type definition but this works, at least on your data.

Golang Converting JSON

map[key:2073933158088]
I need to grab the key out of this data structure as a string, but I can't seem to figure out how!
Help with this overly simple question very much appreciated.
The value above is encapsulated in the variable named data.
I have tried: data.key, data[key], data["key"], data[0] and none of these seem to be appropriate calls.
To define data I sent up a JSON packet to a queue on IronMQ. I then pulled the message from the queue and manipulated it like this:
payloadIndex := 0
for index, arg := range(os.Args) {
if arg == "-payload" {
payloadIndex = index + 1
}
}
if payloadIndex >= len(os.Args) {
panic("No payload value.")
}
payload := os.Args[payloadIndex]
var data interface{}
raw, err := ioutil.ReadFile(payload)
if err != nil {
panic(err.Error())
}
err = json.Unmarshal(raw, &data)
Design your data type to match json structure. This is how can you achieve this:
package main
import (
"fmt"
"encoding/json"
)
type Data struct {
Key string `json:"key"`
}
func main() {
data := new(Data)
text := `{ "key": "2073933158088" }`
raw := []byte(text)
err := json.Unmarshal(raw, data)
if err != nil {
panic(err.Error())
}
fmt.Println(data.Key)
}
Since the number in the json is unquoted, it's not a string, Go will panic if you try to just handle it as a string (playground: http://play.golang.org/p/i-NUwchJc1).
Here's a working alternative:
package main
import (
"fmt"
"encoding/json"
"strconv"
)
type Data struct {
Key string `json:"key"`
}
func (d *Data) UnmarshalJSON(content []byte) error {
var m map[string]interface{}
err := json.Unmarshal(content, &m)
if err != nil {
return err
}
d.Key = strconv.FormatFloat(m["key"].(float64), 'f', -1, 64)
return nil
}
func main() {
data := new(Data)
text := `{"key":2073933158088}`
raw := []byte(text)
err := json.Unmarshal(raw, data)
if err != nil {
panic(err.Error())
}
fmt.Println(data.Key)
}
You can see the result in the playground: http://play.golang.org/p/5hU3hdV3kK

Unmarshal CSV record into struct in Go

The problem how to automatically deserialize/unmarshal record from CSV file into Go struct.
For example, I have
type Test struct {
Name string
Surname string
Age int
}
And CSV file contains records
John;Smith;42
Piter;Abel;50
Is there an easy way to unmarshal those records into struct except by using "encoding/csv" package for reading record and then doing something like
record, _ := reader.Read()
test := Test{record[0],record[1],atoi(record[2])}
There is gocarina/gocsv which handles custom struct in the same way encoding/json does.
You can also write custom marshaller and unmarshaller for specific types.
Example:
type Client struct {
Id string `csv:"client_id"` // .csv column headers
Name string `csv:"client_name"`
Age string `csv:"client_age"`
}
func main() {
in, err := os.Open("clients.csv")
if err != nil {
panic(err)
}
defer in.Close()
clients := []*Client{}
if err := gocsv.UnmarshalFile(in, &clients); err != nil {
panic(err)
}
for _, client := range clients {
fmt.Println("Hello, ", client.Name)
}
}
Seems I've done with automatic marshaling of CSV records into structs (limited to string and int). Hope this would be useful.
Here is a link to playground: http://play.golang.org/p/kwc32A5mJf
func Unmarshal(reader *csv.Reader, v interface{}) error {
record, err := reader.Read()
if err != nil {
return err
}
s := reflect.ValueOf(v).Elem()
if s.NumField() != len(record) {
return &FieldMismatch{s.NumField(), len(record)}
}
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
switch f.Type().String() {
case "string":
f.SetString(record[i])
case "int":
ival, err := strconv.ParseInt(record[i], 10, 0)
if err != nil {
return err
}
f.SetInt(ival)
default:
return &UnsupportedType{f.Type().String()}
}
}
return nil
}
I'll try to create github package is someone needs this implementation.
You could bake your own. Perhaps something like this:
package main
import (
"fmt"
"strconv"
"strings"
)
type Test struct {
Name string
Surname string
Age int
}
func (t Test) String() string {
return fmt.Sprintf("%s;%s;%d", t.Name, t.Surname, t.Age)
}
func (t *Test) Parse(in string) {
tmp := strings.Split(in, ";")
t.Name = tmp[0]
t.Surname = tmp[1]
t.Age, _ = strconv.Atoi(tmp[2])
}
func main() {
john := Test{"John", "Smith", 42}
fmt.Printf("john:%v\n", john)
johnString := john.String()
fmt.Printf("johnString:%s\n", johnString)
var rebornJohn Test
rebornJohn.Parse(johnString)
fmt.Printf("rebornJohn:%v\n", rebornJohn)
}
Using csvutil it is possible to give column header see example.
In your case, this could be :
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
"github.com/jszwec/csvutil"
)
type Test struct {
Name string
Surname string
Age int
}
func main() {
csv_file, _ := os.Open("test.csv")
reader := csv.NewReader(csv_file)
reader.Comma = ';'
userHeader, _ := csvutil.Header(Test{}, "csv")
dec, _ := csvutil.NewDecoder(reader, userHeader...)
var users []Test
for {
var u Test
if err := dec.Decode(&u); err == io.EOF {
break
}
users = append(users, u)
}
fmt.Println(users)
}