mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-21 00:46:32 +00:00
gen_tx for signing transactions
This commit is contained in:
@ -13,12 +13,12 @@ import (
|
|||||||
type PubKey interface {
|
type PubKey interface {
|
||||||
Address() []byte
|
Address() []byte
|
||||||
VerifyBytes(msg []byte, sig Signature) bool
|
VerifyBytes(msg []byte, sig Signature) bool
|
||||||
|
TypeByte() byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types of PubKey implementations
|
// Types of PubKey implementations
|
||||||
const (
|
const (
|
||||||
PubKeyTypeNil = byte(0x00)
|
PubKeyTypeNil = byte(0x00)
|
||||||
PubKeyTypeUnknown = byte(0x01) // For pay-to-pubkey-hash txs.
|
|
||||||
PubKeyTypeEd25519 = byte(0x02)
|
PubKeyTypeEd25519 = byte(0x02)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ func init() {
|
|||||||
log.SetHandler(
|
log.SetHandler(
|
||||||
log15.LvlFilterHandler(
|
log15.LvlFilterHandler(
|
||||||
log15.LvlWarn,
|
log15.LvlWarn,
|
||||||
|
//log15.LvlDebug,
|
||||||
log15.StreamHandler(os.Stderr, log15.LogfmtFormat()),
|
log15.StreamHandler(os.Stderr, log15.LogfmtFormat()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -63,7 +63,7 @@ func RegisterType(info *TypeInfo) *TypeInfo {
|
|||||||
typeInfos[ptrRt] = info
|
typeInfos[ptrRt] = info
|
||||||
|
|
||||||
// See if the type implements HasTypeByte
|
// See if the type implements HasTypeByte
|
||||||
if rt.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) {
|
if rt.Kind() != reflect.Interface && rt.Implements(reflect.TypeOf((*HasTypeByte)(nil)).Elem()) {
|
||||||
zero := reflect.Zero(rt)
|
zero := reflect.Zero(rt)
|
||||||
typeByte := zero.Interface().(HasTypeByte).TypeByte()
|
typeByte := zero.Interface().(HasTypeByte).TypeByte()
|
||||||
if info.HasTypeByte && info.TypeByte != typeByte {
|
if info.HasTypeByte && info.TypeByte != typeByte {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
. "github.com/tendermint/tendermint/account"
|
. "github.com/tendermint/tendermint/account"
|
||||||
@ -15,14 +15,10 @@ func gen_account() {
|
|||||||
privAccount := GenPrivAccount()
|
privAccount := GenPrivAccount()
|
||||||
|
|
||||||
fmt.Printf(`Generated account:
|
fmt.Printf(`Generated account:
|
||||||
Account Public Key: %X
|
Account Public Key: %v
|
||||||
(base64) %v
|
Account Private Key: %v
|
||||||
Account Private Key: %X
|
|
||||||
(base64) %v
|
|
||||||
`,
|
`,
|
||||||
privAccount.PubKey,
|
hex.EncodeToString(BinaryBytes(privAccount.PubKey)),
|
||||||
base64.StdEncoding.EncodeToString(BinaryBytes(privAccount.PubKey)),
|
hex.EncodeToString(BinaryBytes(privAccount.PrivKey)),
|
||||||
privAccount.PrivKey,
|
)
|
||||||
base64.StdEncoding.EncodeToString(BinaryBytes(privAccount.PrivKey)))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
124
cmd/gen_tx.go
Normal file
124
cmd/gen_tx.go
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
account_ "github.com/tendermint/tendermint/account"
|
||||||
|
binary "github.com/tendermint/tendermint/binary"
|
||||||
|
block_ "github.com/tendermint/tendermint/block"
|
||||||
|
. "github.com/tendermint/tendermint/common"
|
||||||
|
db_ "github.com/tendermint/tendermint/db"
|
||||||
|
state_ "github.com/tendermint/tendermint/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getString(prompt string) string {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
fmt.Print(prompt)
|
||||||
|
input, _ := reader.ReadString('\n')
|
||||||
|
return input[:len(input)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getByteSliceFromBase64(prompt string) []byte {
|
||||||
|
input := getString(prompt)
|
||||||
|
bytes, err := hex.DecodeString(input)
|
||||||
|
if err != nil {
|
||||||
|
Exit(Fmt("Not in hexadecimal format: %v\nError: %v\n", input, err))
|
||||||
|
}
|
||||||
|
return bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func getByteSliceFromHex(prompt string) []byte {
|
||||||
|
input := getString(prompt)
|
||||||
|
bytes, err := hex.DecodeString(input)
|
||||||
|
if err != nil {
|
||||||
|
Exit(Fmt("Not in hexadecimal format: %v\nError: %v\n", input, err))
|
||||||
|
}
|
||||||
|
return bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUint64(prompt string) uint64 {
|
||||||
|
input := getString(prompt)
|
||||||
|
i, err := strconv.Atoi(input)
|
||||||
|
if err != nil {
|
||||||
|
Exit(Fmt("Not a valid uint64 amount: %v\nError: %v\n", input, err))
|
||||||
|
}
|
||||||
|
return uint64(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func gen_tx() {
|
||||||
|
|
||||||
|
// Get State, which may be nil.
|
||||||
|
stateDB := db_.GetDB("state")
|
||||||
|
state := state_.LoadState(stateDB)
|
||||||
|
|
||||||
|
// Get source pubkey
|
||||||
|
srcPubKeyBytes := getByteSliceFromBase64("Enter source pubkey: ")
|
||||||
|
r, n, err := bytes.NewReader(srcPubKeyBytes), new(int64), new(error)
|
||||||
|
srcPubKey := account_.PubKeyDecoder(r, n, err).(account_.PubKey)
|
||||||
|
if *err != nil {
|
||||||
|
Exit(Fmt("Invalid PubKey. Error: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the state of the account.
|
||||||
|
var srcAccount *account_.Account
|
||||||
|
var srcAccountAddress = srcPubKey.Address()
|
||||||
|
var srcAccountBalanceStr = "unknown"
|
||||||
|
var srcAccountSequenceStr = "unknown"
|
||||||
|
srcAddress := srcPubKey.Address()
|
||||||
|
if state != nil {
|
||||||
|
srcAccount = state.GetAccount(srcAddress)
|
||||||
|
srcAccountBalanceStr = Fmt("%v", srcAccount.Balance)
|
||||||
|
srcAccountSequenceStr = Fmt("%v", srcAccount.Sequence+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the amount to send from src account
|
||||||
|
srcSendAmount := getUint64(Fmt("Enter amount to send from %X (total: %v): ", srcAccountAddress, srcAccountBalanceStr))
|
||||||
|
|
||||||
|
// Get the next sequence of src account
|
||||||
|
srcSendSequence := uint(getUint64(Fmt("Enter next sequence for %X (guess: %v): ", srcAccountAddress, srcAccountSequenceStr)))
|
||||||
|
|
||||||
|
// Get dest address
|
||||||
|
dstAddress := getByteSliceFromHex("Enter destination address: ")
|
||||||
|
|
||||||
|
// Get the amount to send to dst account
|
||||||
|
dstSendAmount := getUint64(Fmt("Enter amount to send to %X: ", dstAddress))
|
||||||
|
|
||||||
|
// Construct SendTx
|
||||||
|
tx := &block_.SendTx{
|
||||||
|
Inputs: []*block_.TxInput{
|
||||||
|
&block_.TxInput{
|
||||||
|
Address: srcAddress,
|
||||||
|
Amount: srcSendAmount,
|
||||||
|
Sequence: srcSendSequence,
|
||||||
|
Signature: account_.SignatureEd25519{},
|
||||||
|
PubKey: srcPubKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Outputs: []*block_.TxOutput{
|
||||||
|
&block_.TxOutput{
|
||||||
|
Address: dstAddress,
|
||||||
|
Amount: dstSendAmount,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the intermediate form.
|
||||||
|
fmt.Printf("Generated tx: %X\n", binary.BinaryBytes(tx))
|
||||||
|
|
||||||
|
// Get source privkey (for signing)
|
||||||
|
srcPrivKeyBytes := getByteSliceFromBase64("Enter source privkey (for signing): ")
|
||||||
|
r, n, err = bytes.NewReader(srcPrivKeyBytes), new(int64), new(error)
|
||||||
|
srcPrivKey := account_.PrivKeyDecoder(r, n, err).(account_.PrivKey)
|
||||||
|
if *err != nil {
|
||||||
|
Exit(Fmt("Invalid PrivKey. Error: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign
|
||||||
|
tx.Inputs[0].Signature = srcPrivKey.Sign(binary.BinaryBytes(tx))
|
||||||
|
fmt.Printf("Signed tx: %X\n", binary.BinaryBytes(tx))
|
||||||
|
}
|
@ -17,6 +17,7 @@ Commands:
|
|||||||
daemon Run the tendermint node daemon
|
daemon Run the tendermint node daemon
|
||||||
gen_account Generate new account keypair
|
gen_account Generate new account keypair
|
||||||
gen_validator Generate new validator keypair
|
gen_validator Generate new validator keypair
|
||||||
|
gen_tx Generate new transaction
|
||||||
probe_upnp Test UPnP functionality
|
probe_upnp Test UPnP functionality
|
||||||
`)
|
`)
|
||||||
return
|
return
|
||||||
@ -30,6 +31,9 @@ Commands:
|
|||||||
gen_account()
|
gen_account()
|
||||||
case "gen_validator":
|
case "gen_validator":
|
||||||
gen_validator()
|
gen_validator()
|
||||||
|
case "gen_tx":
|
||||||
|
config.ParseFlags(args[1:])
|
||||||
|
gen_tx()
|
||||||
case "probe_upnp":
|
case "probe_upnp":
|
||||||
probe_upnp()
|
probe_upnp()
|
||||||
default:
|
default:
|
||||||
|
@ -125,6 +125,7 @@ func AddrBookFile() string { return rootDir + "/addrbook.json" }
|
|||||||
func PrivValidatorFile() string { return rootDir + "/priv_validator.json" }
|
func PrivValidatorFile() string { return rootDir + "/priv_validator.json" }
|
||||||
func DataDir() string { return rootDir + "/data" }
|
func DataDir() string { return rootDir + "/data" }
|
||||||
|
|
||||||
|
// The actual global config singleton object.
|
||||||
var Config ConfigType
|
var Config ConfigType
|
||||||
|
|
||||||
func parseFlags(flags *flag.FlagSet, args []string) (printHelp bool) {
|
func parseFlags(flags *flag.FlagSet, args []string) (printHelp bool) {
|
||||||
|
2
db/db.go
2
db/db.go
@ -41,6 +41,6 @@ func GetDB(name string) DB {
|
|||||||
dbs.Set(name, db)
|
dbs.Set(name, db)
|
||||||
return db
|
return db
|
||||||
default:
|
default:
|
||||||
panic("Unknown DB backend")
|
panic(Fmt("Unknown DB backend: %v", Config.DB.Backend))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package state
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"time"
|
"time"
|
||||||
@ -61,7 +61,7 @@ func MakeGenesisState(db db_.DB, genDoc *GenesisDoc) *State {
|
|||||||
// Make accounts state tree
|
// Make accounts state tree
|
||||||
accounts := merkle.NewIAVLTree(BasicCodec, AccountCodec, defaultAccountsCacheCapacity, db)
|
accounts := merkle.NewIAVLTree(BasicCodec, AccountCodec, defaultAccountsCacheCapacity, db)
|
||||||
for _, acc := range genDoc.Accounts {
|
for _, acc := range genDoc.Accounts {
|
||||||
address, err := base64.StdEncoding.DecodeString(acc.Address)
|
address, err := hex.DecodeString(acc.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Exit(Fmt("Invalid account address: %v", acc.Address))
|
Exit(Fmt("Invalid account address: %v", acc.Address))
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ func MakeGenesisState(db db_.DB, genDoc *GenesisDoc) *State {
|
|||||||
validatorInfos := merkle.NewIAVLTree(BasicCodec, ValidatorInfoCodec, 0, db)
|
validatorInfos := merkle.NewIAVLTree(BasicCodec, ValidatorInfoCodec, 0, db)
|
||||||
validators := make([]*Validator, len(genDoc.Validators))
|
validators := make([]*Validator, len(genDoc.Validators))
|
||||||
for i, val := range genDoc.Validators {
|
for i, val := range genDoc.Validators {
|
||||||
pubKeyBytes, err := base64.StdEncoding.DecodeString(val.PubKey)
|
pubKeyBytes, err := hex.DecodeString(val.PubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Exit(Fmt("Invalid validator pubkey: %v", val.PubKey))
|
Exit(Fmt("Invalid validator pubkey: %v", val.PubKey))
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ func MakeGenesisState(db db_.DB, genDoc *GenesisDoc) *State {
|
|||||||
FirstBondAmount: val.Amount,
|
FirstBondAmount: val.Amount,
|
||||||
}
|
}
|
||||||
for i, unbondTo := range val.UnbondTo {
|
for i, unbondTo := range val.UnbondTo {
|
||||||
address, err := base64.StdEncoding.DecodeString(unbondTo.Address)
|
address, err := hex.DecodeString(unbondTo.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Exit(Fmt("Invalid unbond-to address: %v", unbondTo.Address))
|
Exit(Fmt("Invalid unbond-to address: %v", unbondTo.Address))
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ package state
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -93,15 +93,15 @@ func LoadPrivValidator(filename string) *PrivValidator {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
address, err := base64.StdEncoding.DecodeString(privValJSON.Address)
|
address, err := hex.DecodeString(privValJSON.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
pubKeyBytes, err := base64.StdEncoding.DecodeString(privValJSON.PubKey)
|
pubKeyBytes, err := hex.DecodeString(privValJSON.PubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
privKeyBytes, err := base64.StdEncoding.DecodeString(privValJSON.PrivKey)
|
privKeyBytes, err := hex.DecodeString(privValJSON.PrivKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -137,9 +137,9 @@ func (privVal *PrivValidator) save() {
|
|||||||
|
|
||||||
func (privVal *PrivValidator) JSONBytes() []byte {
|
func (privVal *PrivValidator) JSONBytes() []byte {
|
||||||
privValJSON := PrivValidatorJSON{
|
privValJSON := PrivValidatorJSON{
|
||||||
Address: base64.StdEncoding.EncodeToString(privVal.Address),
|
Address: hex.EncodeToString(privVal.Address),
|
||||||
PubKey: base64.StdEncoding.EncodeToString(BinaryBytes(privVal.PubKey)),
|
PubKey: hex.EncodeToString(BinaryBytes(privVal.PubKey)),
|
||||||
PrivKey: base64.StdEncoding.EncodeToString(BinaryBytes(privVal.PrivKey)),
|
PrivKey: hex.EncodeToString(BinaryBytes(privVal.PrivKey)),
|
||||||
LastHeight: privVal.LastHeight,
|
LastHeight: privVal.LastHeight,
|
||||||
LastRound: privVal.LastRound,
|
LastRound: privVal.LastRound,
|
||||||
LastStep: privVal.LastStep,
|
LastStep: privVal.LastStep,
|
||||||
|
Reference in New Issue
Block a user