10.5. Signing a message with go¶
The following file should give you a quick introduction into how the messages are signed with go
10.5.1. Create files¶
package main
import (
"crypto/ecdsa"
"encoding/hex"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"golang.org/x/crypto/sha3"
"os"
"strconv"
"strings"
)
// ---- Utility functions ----
// strip0x remove the 0x prefix, which is not important to us
func strip0x(s string) string {
if strings.HasPrefix(s, "0x") {
s = s[2:]
}
return s
}
// ---- Main functions ----
func Sign(hash []byte, privateKey string) (string, error) {
var key *ecdsa.PrivateKey
var bytes []byte
if b, err := hex.DecodeString(strip0x(privateKey)); err != nil {
return "", err
} else {
bytes = b
}
if pk, err := crypto.ToECDSA(bytes); err != nil {
return "", err
} else {
key = pk
}
if sig, err := crypto.Sign(hash, key); err != nil {
return "", err
} else {
return "0x" + hex.EncodeToString(sig), nil
}
}
func SignHash(message []byte, privateKey string) (string, error) {
msglen := []byte(strconv.Itoa(len(message)))
hash := sha3.NewLegacyKeccak256()
hash.Write([]byte{0x19})
hash.Write([]byte("Ethereum Signed Message:"))
hash.Write([]byte{0x0A})
hash.Write(msglen)
hash.Write(message)
buf := hash.Sum([]byte{})
return Sign(buf, privateKey)
}
func SignChallenge(challenge, privateKey string) (string, error) {
hash := sha3.NewLegacyKeccak256()
hash.Write([]byte(challenge))
buf := hash.Sum([]byte{})
return SignHash(buf, privateKey)
}
func main() {
// Remove executable name from arguments
args := os.Args[1:]
// Just take the parameters. In real-live scenario, you would probably want to read the
// private key from stdin and do some parameter validation.
challenge := args[0]
privateKey := args[1]
// Quick and dirty way of doing it. You probably don't want to call panic in your code, though.
if result, err := SignChallenge(challenge, privateKey); err != nil {
panic(err)
} else {
if _, err := fmt.Fprintf(os.Stdout, "%v", result); err != nil {
panic(err)
}
}
}
10.5.3. Test signing¶
Execute the following command:
go run sign.go u3Z5LUDVp31tMtKtwCGr1FCs3kw a0f0e1232dae3ce8a0bf968c452602663975005537e37e79d28c23af52b3114e
Example output:
0x2a2785be5d38ba773765df2232d749b01c4ebc97721f9d033a696b7f893ba45d20bccf4341ae6b01a8f697e22e1e4b4697e02e04352363bee1eeaa9494e096cb01