Compare commits

..

6 Commits

Author SHA1 Message Date
Jim McDonald
0746fa3048 Release 1.5.8 2020-08-25 09:20:45 +01:00
Jim McDonald
94eb3fbca7 Add genesis validators root to chain info 2020-08-23 13:44:17 +01:00
Jim McDonald
48d63398d4 Bump version 2020-08-08 14:25:35 +01:00
Jim McDonald
4e1f47e187 Add ability to create HD accounts with a specific path 2020-08-08 14:25:02 +01:00
Jim McDonald
85c7c7fc55 Bump version 2020-08-02 21:54:43 +01:00
Jim McDonald
05406e8d81 Allow fetching wallet from account variable as well as wallet 2020-08-02 17:02:45 +01:00
13 changed files with 495 additions and 204 deletions

4
CHANGELOG.md Normal file
View File

@@ -0,0 +1,4 @@
1.5.8:
- allow raw deposit transactions to be supplied to "deposit verify"
- move functionality of "account withdrawalcredentials" to be part of "account info"
- add genesis validators root to "chain info"

View File

@@ -17,6 +17,7 @@ import (
"context"
"fmt"
"os"
"regexp"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@@ -62,12 +63,25 @@ In quiet mode this will return 0 if the account is created successfully, otherwi
defer cancel()
account, err = distributedCreator.CreateDistributedAccount(ctx, accountName, viper.GetUint32("participants"), viper.GetUint32("signing-threshold"), []byte(getPassphrase()))
} else {
// Want a standard account.
creator, isCreator := wallet.(e2wtypes.WalletAccountCreator)
assert(isCreator, "Wallet does not support account creation")
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
account, err = creator.CreateAccount(ctx, accountName, []byte(getPassphrase()))
if viper.GetString("path") != "" {
// Want a pathed account
creator, isCreator := wallet.(e2wtypes.WalletPathedAccountCreator)
assert(isCreator, "Wallet does not support account creation with an explicit path")
var match bool
match, err = regexp.Match("^m/[0-9]+/[0-9]+(/[0-9+])+", []byte(viper.GetString("path")))
errCheck(err, "Unable to match path to regular expression")
assert(match, "Path does not match expected format m/...")
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
account, err = creator.CreatePathedAccount(ctx, viper.GetString("path"), accountName, []byte(getPassphrase()))
} else {
// Want a standard account.
creator, isCreator := wallet.(e2wtypes.WalletAccountCreator)
assert(isCreator, "Wallet does not support account creation")
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
account, err = creator.CreateAccount(ctx, accountName, []byte(getPassphrase()))
}
}
errCheck(err, "Failed to create account")
@@ -92,4 +106,8 @@ func init() {
if err := viper.BindPFlag("signing-threshold", accountCreateCmd.Flags().Lookup("signing-threshold")); err != nil {
panic(err)
}
accountCreateCmd.Flags().String("path", "", "path of account (for hierarchical deterministic accounts)")
if err := viper.BindPFlag("path", accountCreateCmd.Flags().Lookup("path")); err != nil {
panic(err)
}
}

View File

@@ -1,73 +0,0 @@
// Copyright © 2019, 2020 Weald Technology Trading
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmd
import (
"context"
"encoding/hex"
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
util "github.com/wealdtech/go-eth2-util"
)
var accountWithdrawalCredentialsCmd = &cobra.Command{
Use: "withdrawalcredentials",
Short: "Provide withdrawal credentials for an account",
Long: `Provide withdrawal credentials for an account. For example:
ethdo account withdrawalcredentials --account="Validators/1"
In quiet mode this will return 0 if the account exists, otherwise 1.`,
Run: func(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
assert(viper.GetString("account") != "" || viper.GetString("pubkey") != "", "account or pubkey is required")
var pubKey []byte
if viper.GetString("pubkey") != "" {
var err error
pubKey, err = hex.DecodeString(strings.TrimPrefix(viper.GetString("pubkey"), "0x"))
errCheck(err, "Failed to decode supplied public key")
} else {
_, account, err := walletAndAccountFromInput(ctx)
errCheck(err, "Failed to obtain account")
key, err := bestPublicKey(account)
errCheck(err, "Account does not provide a public key")
pubKey = key.Marshal()
}
if quiet {
os.Exit(_exitSuccess)
}
withdrawalCredentials := util.SHA256(pubKey)
withdrawalCredentials[0] = byte(0) // BLS_WITHDRAWAL_PREFIX
fmt.Printf("%#x\n", withdrawalCredentials)
},
}
func init() {
accountCmd.AddCommand(accountWithdrawalCredentialsCmd)
accountFlags(accountWithdrawalCredentialsCmd)
accountWithdrawalCredentialsCmd.Flags().String("pubkey", "", "Public key (overrides account)")
if err := viper.BindPFlag("pubkey", accountCreateCmd.Flags().Lookup("pubkey")); err != nil {
panic(err)
}
}

View File

@@ -39,6 +39,9 @@ In quiet mode this will return 0 if the chain information can be obtained, other
genesisTime, err := grpc.FetchGenesisTime(eth2GRPCConn)
errCheck(err, "Failed to obtain genesis time")
genesisValidatorsRoot, err := grpc.FetchGenesisValidatorsRoot(eth2GRPCConn)
errCheck(err, "Failed to obtain genesis validators root")
if quiet {
os.Exit(_exitSuccess)
}
@@ -49,9 +52,10 @@ In quiet mode this will return 0 if the chain information can be obtained, other
fmt.Printf("Genesis time: %s\n", genesisTime.Format(time.UnixDate))
outputIf(verbose, fmt.Sprintf("Genesis timestamp: %v", genesisTime.Unix()))
}
outputIf(verbose, fmt.Sprintf("Genesis fork version: %0x", config["GenesisForkVersion"].([]byte)))
outputIf(verbose, fmt.Sprintf("Seconds per slot: %v", config["SecondsPerSlot"].(uint64)))
outputIf(verbose, fmt.Sprintf("Slots per epoch: %v", config["SlotsPerEpoch"].(uint64)))
fmt.Printf("Genesis validators root: %#x\n", genesisValidatorsRoot)
fmt.Printf("Genesis fork version: %#x\n", config["GenesisForkVersion"].([]byte))
fmt.Printf("Seconds per slot: %d\n", config["SecondsPerSlot"].(uint64))
fmt.Printf("Slots per epoch: %d\n", config["SlotsPerEpoch"].(uint64))
os.Exit(_exitSuccess)
},

View File

@@ -16,48 +16,60 @@ package cmd
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/spf13/cobra"
"github.com/wealdtech/ethdo/util"
e2types "github.com/wealdtech/go-eth2-types/v2"
util "github.com/wealdtech/go-eth2-util"
eth2util "github.com/wealdtech/go-eth2-util"
string2eth "github.com/wealdtech/go-string2eth"
)
type depositData struct {
Name string `json:"name,omitempty"`
Account string `json:"account,omitempty"`
PublicKey string `json:"pubkey"`
WithdrawalCredentials string `json:"withdrawal_credentials"`
Signature string `json:"signature"`
DepositDataRoot string `json:"deposit_data_root"`
Value uint64 `json:"value"`
Version uint64 `json:"version"`
}
var depositVerifyData string
var depositVerifyWithdrawalPubKey string
var depositVerifyValidatorPubKey string
var depositVerifyDepositValue string
var depositVerifyDepositAmount string
var depositVerifyCmd = &cobra.Command{
Use: "verify",
Short: "Verify deposit data matches requirements",
Long: `Verify deposit data matches requirements. For example:
Short: "Verify deposit data matches the provided data",
Long: `Verify deposit data matches the provided input data. For example:
ethdo deposit verify --data=depositdata.json --withdrawalaccount=primary/current --value="32 Ether"
The information generated can be passed to ethereal to create a deposit from the Ethereum 1 chain.
The deposit data is compared to the supplied withdrawal account/public key, validator public key, and value to ensure they match.
In quiet mode this will return 0 if the the data can be generated correctly, otherwise 1.`,
In quiet mode this will return 0 if the the data is verified correctly, otherwise 1.`,
Run: func(cmd *cobra.Command, args []string) {
assert(depositVerifyData != "", "--data is required")
deposits, err := depositDataFromJSON(depositVerifyData)
var data []byte
var err error
// Input could be JSON or a path to JSON.
switch {
case strings.HasPrefix(depositVerifyData, "0x"):
// Looks like raw binary.
data = []byte(depositVerifyData)
case strings.HasPrefix(depositVerifyData, "{"):
// Looks like JSON.
data = []byte("[" + depositVerifyData + "]")
case strings.HasPrefix(depositVerifyData, "["):
// Looks like JSON array.
data = []byte(depositVerifyData)
default:
// Assume it's a path to JSON.
data, err = ioutil.ReadFile(depositVerifyData)
errCheck(err, "Failed to read deposit data file")
if data[0] == '{' {
data = []byte("[" + string(data) + "]")
}
}
deposits, err := util.DepositInfoFromJSON(data)
errCheck(err, "Failed to fetch deposit data")
var withdrawalCredentials []byte
@@ -67,17 +79,16 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth
assert(len(withdrawalPubKeyBytes) == 48, "Public key should be 48 bytes")
withdrawalPubKey, err := e2types.BLSPublicKeyFromBytes(withdrawalPubKeyBytes)
errCheck(err, "Value supplied with --withdrawalpubkey is not a valid public key")
withdrawalCredentials = util.SHA256(withdrawalPubKey.Marshal())
withdrawalCredentials = eth2util.SHA256(withdrawalPubKey.Marshal())
withdrawalCredentials[0] = 0 // BLS_WITHDRAWAL_PREFIX
}
outputIf(debug, fmt.Sprintf("Withdrawal credentials are %#x", withdrawalCredentials))
depositValue := uint64(0)
if depositVerifyDepositValue != "" {
depositValue, err = string2eth.StringToGWei(depositVerifyDepositValue)
depositAmount := uint64(0)
if depositVerifyDepositAmount != "" {
depositAmount, err = string2eth.StringToGWei(depositVerifyDepositAmount)
errCheck(err, "Invalid value")
// This is hard-coded, to allow deposit data to be generated without a connection to the beacon node.
assert(depositValue >= 1000000000, "deposit value must be at least 1 Ether") // MIN_DEPOSIT_AMOUNT
assert(depositAmount >= 1000000000, "deposit amount must be at least 1 Ether") // MIN_DEPOSIT_AMOUNT
}
validatorPubKeys := make(map[[48]byte]bool)
@@ -88,31 +99,17 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth
failures := false
for i, deposit := range deposits {
if withdrawalCredentials != nil {
depositWithdrawalCredentials, err := hex.DecodeString(strings.TrimPrefix(deposit.WithdrawalCredentials, "0x"))
errCheck(err, fmt.Sprintf("Invalid withdrawal public key for deposit %d", i))
if !bytes.Equal(depositWithdrawalCredentials, withdrawalCredentials) {
outputIf(!quiet, fmt.Sprintf("Invalid withdrawal credentials for deposit %d", i))
failures = true
}
if deposit.Amount == 0 {
deposit.Amount = depositAmount
}
if depositValue != 0 {
if deposit.Value != depositValue {
outputIf(!quiet, fmt.Sprintf("Invalid deposit value for deposit %d", i))
failures = true
}
verified, err := verifyDeposit(deposit, withdrawalCredentials, validatorPubKeys, depositAmount)
errCheck(err, fmt.Sprintf("Error attempting to verify deposit %d", i))
if !verified {
failures = true
outputIf(!quiet, fmt.Sprintf("Deposit %q failed verification", deposit.Name))
} else {
outputIf(quiet, fmt.Sprintf("Deposit %q verified", deposit.Name))
}
if len(validatorPubKeys) != 0 {
depositValidatorPubKey, err := hex.DecodeString(strings.TrimPrefix(deposit.PublicKey, "0x"))
errCheck(err, fmt.Sprintf("Invalid validator public key for deposit %d", i))
var key [48]byte
copy(key[:], depositValidatorPubKey)
if _, exists := validatorPubKeys[key]; !exists {
outputIf(!quiet, fmt.Sprintf("Unknown validator public key for deposit %d", i))
failures = true
}
}
outputIf(!quiet, fmt.Sprintf("Deposit %q verified", deposit.Name))
}
if failures {
@@ -177,61 +174,47 @@ func validatorPubKeysFromInput(input string) (map[[48]byte]bool, error) {
return pubKeys, nil
}
func depositDataFromJSON(input string) ([]*depositData, error) {
var err error
var data []byte
// Input could be JSON or a path to JSON
switch {
case strings.HasPrefix(input, "{"):
// Looks like JSON
data = []byte("[" + input + "]")
case strings.HasPrefix(input, "["):
// Looks like JSON array
data = []byte(input)
default:
// Assume it's a path to JSON
data, err = ioutil.ReadFile(input)
if err != nil {
return nil, errors.Wrap(err, "failed to find deposit data file")
}
if data[0] == '{' {
data = []byte("[" + string(data) + "]")
func verifyDeposit(deposit *util.DepositInfo, withdrawalCredentials []byte, validatorPubKeys map[[48]byte]bool, amount uint64) (bool, error) {
if withdrawalCredentials != nil {
if !bytes.Equal(deposit.WithdrawalCredentials, withdrawalCredentials) {
return false, errors.New("withdrawal credentials incorrect")
}
outputIf(verbose, "Withdrawal credentials verified")
}
var depositData []*depositData
err = json.Unmarshal(data, &depositData)
if amount != 0 {
if deposit.Amount != amount {
return false, errors.New("deposit value incorrect")
}
outputIf(verbose, "Amount verified")
}
if len(validatorPubKeys) != 0 {
var key [48]byte
copy(key[:], deposit.PublicKey)
if _, exists := validatorPubKeys[key]; !exists {
return false, errors.New("validator public key incorrect")
}
outputIf(verbose, "Validator public key verified")
}
depositData := &ethpb.Deposit_Data{
PublicKey: deposit.PublicKey,
WithdrawalCredentials: deposit.WithdrawalCredentials,
Amount: deposit.Amount,
Signature: deposit.Signature,
}
depositDataRoot, err := depositData.HashTreeRoot()
if err != nil {
return nil, errors.Wrap(err, "data is not valid JSON")
return false, errors.Wrap(err, "failed to generate deposit data root")
}
if len(depositData) == 0 {
return nil, errors.New("no deposits supplied")
if !bytes.Equal(deposit.DepositDataRoot, depositDataRoot[:]) {
return false, errors.New("deposit data root incorrect")
}
minVersion := depositData[0].Version
maxVersion := depositData[0].Version
for i := range depositData {
if depositData[i].PublicKey == "" {
return nil, fmt.Errorf("no public key for deposit %d", i)
}
if depositData[i].DepositDataRoot == "" {
return nil, fmt.Errorf("no data root for deposit %d", i)
}
if depositData[i].Signature == "" {
return nil, fmt.Errorf("no signature for deposit %d", i)
}
if depositData[i].WithdrawalCredentials == "" {
return nil, fmt.Errorf("no withdrawal credentials for deposit %d", i)
}
if depositData[i].Value < 1000000000 {
return nil, fmt.Errorf("Deposit amount too small for deposit %d", i)
}
if depositData[i].Version > maxVersion {
maxVersion = depositData[i].Version
}
if depositData[i].Version < minVersion {
minVersion = depositData[i].Version
}
}
return depositData, nil
outputIf(debug, "Deposit data root verified")
outputIf(verbose, "Deposit verified")
return true, nil
}
func init() {
@@ -239,6 +222,6 @@ func init() {
depositFlags(depositVerifyCmd)
depositVerifyCmd.Flags().StringVar(&depositVerifyData, "data", "", "JSON data, or path to JSON data")
depositVerifyCmd.Flags().StringVar(&depositVerifyWithdrawalPubKey, "withdrawalpubkey", "", "Public key of the account to which the validator funds will be withdrawn")
depositVerifyCmd.Flags().StringVar(&depositVerifyDepositValue, "depositvalue", "", "Value of the amount to be deposited")
depositVerifyCmd.Flags().StringVar(&depositVerifyDepositAmount, "depositvalue", "", "Value of the amount to be deposited")
depositVerifyCmd.Flags().StringVar(&depositVerifyValidatorPubKey, "validatorpubkey", "", "Public key(s) of the account(s) that will be carrying out validation")
}

View File

@@ -36,14 +36,12 @@ var exitVerifyPubKey string
var exitVerifyCmd = &cobra.Command{
Use: "verify",
Short: "Verify deposit data matches requirements",
Long: `Verify deposit data matches requirements. For example:
Short: "Verify exit data is valid",
Long: `Verify that exit data generated by "ethdo validator exit" is correct for a given account. For example:
ethdo deposit verify --data=depositdata.json --withdrawalaccount=primary/current --value="32 Ether"
ethdo exit verify --data=exitdata.json --account=primary/current
The information generated can be passed to ethereal to create a deposit from the Ethereum 1 chain.
In quiet mode this will return 0 if the the data can be generated correctly, otherwise 1.`,
In quiet mode this will return 0 if the the exit is verified correctly, otherwise 1.`,
Run: func(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
defer cancel()
@@ -60,7 +58,7 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth
err = connect()
errCheck(err, "Failed to obtain connection to Ethereum 2 beacon chain node")
genesisValidatorsRoot, err := grpc.FetchGenesisValidatorsRoot(eth2GRPCConn)
outputIf(debug, fmt.Sprintf("Genesis validators root is %x", genesisValidatorsRoot))
outputIf(debug, fmt.Sprintf("Genesis validators root is %#x", genesisValidatorsRoot))
errCheck(err, "Failed to obtain genesis validators root")
domain := e2types.Domain(e2types.DomainVoluntaryExit, data.ForkVersion, genesisValidatorsRoot)
exit := &ethpb.VoluntaryExit{

View File

@@ -233,8 +233,12 @@ func outputIf(condition bool, msg string) {
}
}
// walletFromInput obtains a wallet given the information in the viper variable "wallet".
// walletFromInput obtains a wallet given the information in the viper variable
// "account", or if not present the viper variable "wallet".
func walletFromInput(ctx context.Context) (e2wtypes.Wallet, error) {
if viper.GetString("account") != "" {
return walletFromPath(ctx, viper.GetString("account"))
}
return walletFromPath(ctx, viper.GetString("wallet"))
}

View File

@@ -22,7 +22,7 @@ import (
"github.com/spf13/viper"
)
var ReleaseVersion = "local build from v1.5.5"
var ReleaseVersion = "local build from v1.5.8"
// versionCmd represents the version command
var versionCmd = &cobra.Command{

View File

@@ -65,3 +65,21 @@ ethdo wallet info --verbose --wallet="My wallet"
```
This will provide, amongst other information, a `Location` line giving the directory where the wallet information resides.
## Recreate launchpad wallet and accounts
Recreating launchpad accounts requires two steps: recreating the wallet, and recreating the individual accounts. All that is required is the mnemonic from the launchpad process.
To recreate the wallet with the given mnemonic run the following command (changing the wallet name, passphrase and mnemonic as required):
```sh
ethdo wallet create --wallet="Launchpad" --type=hd --walletpassphrase=walletsecret --mnemonic="faculty key lamp panel appear choose express off absent dance strike twenty elephant expect swift that resist bicycle kind sun favorite evoke engage thumb"
```
Launchpad accounts are identified by their path. The path can be seen in the filename of the keystore, for example the filename `keystore-m_12381_3600_1_0_0-1596891358.json` relates to a path of `m/12381/3600/1/0/0`. It is also present directly in the keystore under the `path` key.
To create an account corresponding to this key you would use the command:
```sh
ethdo account create --wallet="Launchpad" --walletpassphrase=walletsecret --passphrase=secret --path=m/12381/3600/1/0/0
```

View File

@@ -112,9 +112,12 @@ Account commands focus on information about local accounts, generally those used
`ethdo account create` creates a new account with the given parameters. Options for creating an account include:
- `account`: the name of the account to create
- `passphrase`: the passphrase for the account
- `path`: the HD path for the account (only for hierarchical deterministic accounts)
Note that for hierarchical deterministic wallets you will also need to supply `--walletpassphrase` to unlock the wallet seed.
For distributed accounts you will also need to supply `--participants` and `--signing-threshold`.
```sh
$ ethdo account create --account="Personal wallet/Operations" --walletpassphrase="my wallet secret" --passphrase="my account secret"
```
@@ -314,7 +317,7 @@ Deposit commands focus on information about deposit data information in a JSON f
#### `verify`
`ethdo deposit verify` verifies one or more deposit data information in a JSON file generated by the `ethdo validator depositdata` command. Options include:
- `data`: either a path to the JSON file or the JSON itself
- `data`: either a path to the JSON file, the JSON itself, or a hex string representing a deposit transaction
- `withdrawalpubkey`: the public key of the withdrawal for the deposit. If no value is supplied then withdrawal credentials for deposits will not be checked
- `validatorpubkey`: the public key of the validator for the deposit. If no value is supplied then validator public keys will not be checked
- `depositvalue`: the value of the Ether being deposited. If no value is supplied then deposit values will not be checked.

29
go.mod
View File

@@ -4,45 +4,48 @@ go 1.13
require (
github.com/OneOfOne/xxhash v1.2.5 // indirect
github.com/aws/aws-sdk-go v1.33.11 // indirect
github.com/aws/aws-sdk-go v1.34.9 // indirect
github.com/ferranbt/fastssz v0.0.0-20200818222714-826c7ef45b30 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gogo/protobuf v1.3.1
github.com/google/uuid v1.1.1
github.com/grpc-ecosystem/grpc-gateway v1.14.6 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.14.7 // indirect
github.com/herumi/bls-eth-go-binary v0.0.0-20200722032157-41fc56eba7b4
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/pelletier/go-toml v1.8.0 // indirect
github.com/pkg/errors v0.9.1
github.com/prysmaticlabs/ethereumapis v0.0.0-20200709024211-e8095222f77b
github.com/prysmaticlabs/ethereumapis v0.0.0-20200812153649-a842fc47c2c3
github.com/prysmaticlabs/go-bitfield v0.0.0-20200618145306-2ae0807bef65
github.com/prysmaticlabs/go-ssz v0.0.0-20200612203617-6d5c9aa213ae
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/afero v1.3.2 // indirect
github.com/spf13/afero v1.3.4 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.0.0
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.7.0
github.com/spf13/viper v1.7.1
github.com/tyler-smith/go-bip39 v1.0.2
github.com/wealdtech/eth2-signer-api v1.5.2
github.com/wealdtech/go-bytesutil v1.1.1
github.com/wealdtech/go-ecodec v1.1.0
github.com/wealdtech/go-eth2-types/v2 v2.5.0
github.com/wealdtech/go-eth2-util v1.5.0
github.com/wealdtech/go-eth2-wallet v1.12.0
github.com/wealdtech/go-eth2-wallet-dirk v1.0.1
github.com/wealdtech/go-eth2-wallet v1.13.0
github.com/wealdtech/go-eth2-wallet-dirk v1.0.2
github.com/wealdtech/go-eth2-wallet-distributed v1.1.0
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.0
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.3.0
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.4.0
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.3.0
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.16.1
github.com/wealdtech/go-eth2-wallet-store-s3 v1.8.0
github.com/wealdtech/go-eth2-wallet-types/v2 v2.6.0
github.com/wealdtech/go-eth2-wallet-types/v2 v2.7.0
github.com/wealdtech/go-string2eth v1.1.0
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 // indirect
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a // indirect
golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
golang.org/x/sys v0.0.0-20200821140526-fda516888d29 // indirect
golang.org/x/text v0.3.3 // indirect
google.golang.org/genproto v0.0.0-20200722002428-88e341933a54 // indirect
google.golang.org/grpc v1.30.0
gopkg.in/ini.v1 v1.57.0 // indirect
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70 // indirect
google.golang.org/grpc v1.31.0
gopkg.in/ini.v1 v1.60.1 // indirect
)

47
go.sum
View File

@@ -31,6 +31,10 @@ github.com/aws/aws-sdk-go v1.33.5 h1:p2fr1ryvNTU6avUWLI+/H7FGv0TBIjzVM5WDgXBBv4U
github.com/aws/aws-sdk-go v1.33.5/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.33.11 h1:A7b3mNKbh/0zrhnNN/KxWD0YZJw2RImnjFXWOquYKB4=
github.com/aws/aws-sdk-go v1.33.11/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.5 h1:FwubVVX9u+kW9qDCjVzyWOdsL+W5wPq683wMk2R2GXk=
github.com/aws/aws-sdk-go v1.34.5/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.9 h1:cUGBW9CVdi0mS7K1hDzxIqTpfeWhpoQiguq81M1tjK0=
github.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
@@ -67,6 +71,11 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/ferranbt/fastssz v0.0.0-20200514094935-99fccaf93472 h1:maoKvILdMk6CSWHanFcUdxXIZGKD9YpWIaVbUQ/4kfg=
github.com/ferranbt/fastssz v0.0.0-20200514094935-99fccaf93472/go.mod h1:LlFXPmgrgVYsuoFDwV8rDJ9tvt1pLQdjKvU1b5IRES0=
github.com/ferranbt/fastssz v0.0.0-20200728110133-0b6e349af87a/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
github.com/ferranbt/fastssz v0.0.0-20200803113354-a18be873a4b6 h1:P440pnxSHIQI8gg7lQNNo+/F88EzUzS3Os0Xkhta7OQ=
github.com/ferranbt/fastssz v0.0.0-20200803113354-a18be873a4b6/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
github.com/ferranbt/fastssz v0.0.0-20200818222714-826c7ef45b30 h1:Sbm5yhPObRc+RCZa9fAR/Px/j1qYwuqawF0X8dR2gAw=
github.com/ferranbt/fastssz v0.0.0-20200818222714-826c7ef45b30/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
@@ -126,6 +135,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
github.com/grpc-ecosystem/grpc-gateway v1.14.6 h1:8ERzHx8aj1Sc47mu9n/AksaKCSWrMchFtkdrS4BIj5o=
github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
github.com/grpc-ecosystem/grpc-gateway v1.14.7 h1:Nk5kuHrnWUTf/0GL1a/vchH/om9Ap2/HnVna+jYZgTY=
github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -243,6 +254,8 @@ github.com/prysmaticlabs/ethereumapis v0.0.0-20200619200018-174e3b90d786 h1:bJiO
github.com/prysmaticlabs/ethereumapis v0.0.0-20200619200018-174e3b90d786/go.mod h1:rs05kpTfWKl0KflsBWzBQFstoyPFMTWQTbxSAyGHe78=
github.com/prysmaticlabs/ethereumapis v0.0.0-20200709024211-e8095222f77b h1:GjYix8Y4VpQhlsjA2ickr3HxjIns4bI36zOmC+lwaNw=
github.com/prysmaticlabs/ethereumapis v0.0.0-20200709024211-e8095222f77b/go.mod h1:rs05kpTfWKl0KflsBWzBQFstoyPFMTWQTbxSAyGHe78=
github.com/prysmaticlabs/ethereumapis v0.0.0-20200812153649-a842fc47c2c3 h1:0f++UXRfp4/Mrmlfj3UaCnYj2lPr6El0gWWTBb9MD2Y=
github.com/prysmaticlabs/ethereumapis v0.0.0-20200812153649-a842fc47c2c3/go.mod h1:k7b2dxy6RppCG6kmOJkNOXzRpEoTdsPygc2aQhsUsZk=
github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
github.com/prysmaticlabs/go-bitfield v0.0.0-20200322041314-62c2aee71669/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
github.com/prysmaticlabs/go-bitfield v0.0.0-20200618145306-2ae0807bef65 h1:hJfAWrlxx7SKpn4S/h2JGl2HHwA1a2wSS3HAzzZ0F+U=
@@ -275,6 +288,8 @@ github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk=
github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.3.2 h1:GDarE4TJQI52kYSbSAmLiId1Elfj+xgSDqrUZxFhxlU=
github.com/spf13/afero v1.3.2/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.3.4 h1:8q6vk3hthlpb2SouZcnBVKboxWQWMDNF38bwholZrJc=
github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -289,6 +304,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -334,10 +351,14 @@ github.com/wealdtech/go-eth2-wallet v1.11.0 h1:2KfrWDqF4sWGgk4N5+DaYmh0hOnqiCl0P
github.com/wealdtech/go-eth2-wallet v1.11.0/go.mod h1:E9ZRNO4JNdi27ys7oc+xWWucXu4IGfV5q1vWC9X3oqg=
github.com/wealdtech/go-eth2-wallet v1.12.0 h1:nrwI3jPhehUhJGlBtNv/UmIo/57llvuVZZavLnfdQHI=
github.com/wealdtech/go-eth2-wallet v1.12.0/go.mod h1:ouV+YSMbzk2dyecmofm8jhaMKdSigdIPMSnSqmWEfW8=
github.com/wealdtech/go-eth2-wallet v1.13.0 h1:ayy/jBcKVZhqU4OMlZDieRzhwSiF3Ozmc3e3LrdpWro=
github.com/wealdtech/go-eth2-wallet v1.13.0/go.mod h1:O4efkfrSBRRa7Q8vZQ8usUCBRki+/zE531b3JqScIII=
github.com/wealdtech/go-eth2-wallet-dirk v1.0.0 h1:1QUcWILF3h4OLCgTPpWklvRSuPu0fqrt15jwSm7CSC4=
github.com/wealdtech/go-eth2-wallet-dirk v1.0.0/go.mod h1:VTzjJ51dedvYPr4huI7g7KXZVTpGR6ZrCDQwBxJpLck=
github.com/wealdtech/go-eth2-wallet-dirk v1.0.1 h1:YUE1QlJPun8b+xbz0JM71/3t1i9zp9KjcZdJvtJQL+E=
github.com/wealdtech/go-eth2-wallet-dirk v1.0.1/go.mod h1:5jK/aEAjYAVRBKKjYAvJWSmOWxiECs4asYXHwloNI+w=
github.com/wealdtech/go-eth2-wallet-dirk v1.0.2 h1:ZxAdF6iTOzYHtQlWd1nzVevZ+HtXS/LLn580t+NXT3A=
github.com/wealdtech/go-eth2-wallet-dirk v1.0.2/go.mod h1:5jK/aEAjYAVRBKKjYAvJWSmOWxiECs4asYXHwloNI+w=
github.com/wealdtech/go-eth2-wallet-distributed v1.0.1 h1:3BxMII8T6t16g6lWcYWXjfdvaw8rXuwMQx9h0TG5wRg=
github.com/wealdtech/go-eth2-wallet-distributed v1.0.1/go.mod h1:Ha/8S+SCLEuSfXHdvhTLwnKaEF47o6gzQ+FURKwftvU=
github.com/wealdtech/go-eth2-wallet-distributed v1.1.0 h1:OZjjuxcIYo+EhAfph7lYP1z+VeNs9ruOI32kqtYe1Jg=
@@ -351,6 +372,8 @@ github.com/wealdtech/go-eth2-wallet-hd/v2 v2.2.0 h1:L+yrAn8TC9DQUw+S7moOJxQTp2jr
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.2.0/go.mod h1:lhSwtkIO/Pfg5kz8k50yrDgj7ZQaElCPsXnixlrQn/I=
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.3.0 h1:UORXUYRoUYgYF96Y+QiBq33OKQVtn/nEjnSoQbe1UOA=
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.3.0/go.mod h1:Kc/8WcqMTczfH2xy5mDfCRd0NI/ca/j2jXmqJ7gz8yk=
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.4.0 h1:bqG/i1fpDpnQFgJ+NBLgOLdmGhXiinwlrFVD1OAgZlo=
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.4.0/go.mod h1:xBbzc+aRD06dTL5phnMshpM4sryyWYM8m86sjQKG5u0=
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.2/go.mod h1:IssxoHII0ewO1VysMfCmdJP1D00tRhRhXIhhaEXIOVE=
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.2.0 h1:h4eePfG0ANOJYMonmIYOvxJ9uLmBEX4APb2O8Vhtv6k=
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.2.0/go.mod h1:Un2EtseZWSObmTBjgkt7Qz2am54S/0115jrF83lto1U=
@@ -380,6 +403,8 @@ github.com/wealdtech/go-eth2-wallet-types/v2 v2.5.0 h1:J29mbkSCUMl2xdu8Lg6U+JptF
github.com/wealdtech/go-eth2-wallet-types/v2 v2.5.0/go.mod h1:X9kYUH/E5YMqFMZ4xL6MJanABUkJGaH/yPZRT2o+yYA=
github.com/wealdtech/go-eth2-wallet-types/v2 v2.6.0 h1:vBrH5icPPSeb14cdShA7/P2PBZOgZscJ2IhBlTIaFrA=
github.com/wealdtech/go-eth2-wallet-types/v2 v2.6.0/go.mod h1:X9kYUH/E5YMqFMZ4xL6MJanABUkJGaH/yPZRT2o+yYA=
github.com/wealdtech/go-eth2-wallet-types/v2 v2.7.0 h1:pquFQdIWEiSYrpIpFuvsRuialI8t9KhFsPvbIBPnzic=
github.com/wealdtech/go-eth2-wallet-types/v2 v2.7.0/go.mod h1:X9kYUH/E5YMqFMZ4xL6MJanABUkJGaH/yPZRT2o+yYA=
github.com/wealdtech/go-indexer v1.0.0 h1:/S4rfWQbSOnnYmwnvuTVatDibZ8o1s9bmTCHO16XINg=
github.com/wealdtech/go-indexer v1.0.0/go.mod h1:u1cjsbsOXsm5jzJDyLmZY7GsrdX8KYXKBXkZcAmk3Zg=
github.com/wealdtech/go-string2eth v1.1.0 h1:USJQmysUrBYYmZs7d45pMb90hRSyEwizP7lZaOZLDAw=
@@ -406,6 +431,10 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnk
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -446,6 +475,10 @@ golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYc
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -478,6 +511,10 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORK
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 h1:X9xIZ1YU8bLZA3l6gqDUHSFiD0GFI9S548h6C8nDtOY=
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed h1:J22ig1FUekjjkmZUM7pTKixYm8DvrYsvrBZdunYeIuQ=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200821140526-fda516888d29 h1:mNuhGagCf3lDDm5C0376C/sxh6V7fy9WbdEu/YDNA04=
golang.org/x/sys v0.0.0-20200821140526-fda516888d29/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -540,6 +577,10 @@ google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c h1:6DWnZZ6EY/59QRR
google.golang.org/genproto v0.0.0-20200715011427-11fb19a81f2c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200722002428-88e341933a54 h1:ASrBgpl9XvkNTP0m39/j18mid7aoF21npu2ioIBxYnY=
google.golang.org/genproto v0.0.0-20200722002428-88e341933a54/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200814021100-8c09557e8a18 h1:hjnc4GP1IeBnHi+u3sp8be4ELyIHmFSO5p8DUdJUVt4=
google.golang.org/genproto v0.0.0-20200814021100-8c09557e8a18/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70 h1:wboULUXGF3c5qdUnKp+6gLAccE6PRpa/czkYvQ4UXv8=
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -553,6 +594,8 @@ google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -574,6 +617,10 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.58.0 h1:VdDvTzv/005R8vEFyQ56bpEnOKTNPbpJhL0VCohxlQw=
gopkg.in/ini.v1 v1.58.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.60.1 h1:P5y5shSkb0CFe44qEeMBgn8JLow09MP17jlJHanke5g=
gopkg.in/ini.v1 v1.60.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

282
util/depositinfo.go Normal file
View File

@@ -0,0 +1,282 @@
// Copyright © 2019, 2020 Weald Technology Trading
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package util
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"strings"
"github.com/pkg/errors"
)
// DepositInfo is a generic deposit structure.
type DepositInfo struct {
Name string
Account string
PublicKey []byte
WithdrawalCredentials []byte
Signature []byte
DepositDataRoot []byte
DepositMessageRoot []byte
ForkVersion []byte
Amount uint64
Version uint64
}
// depositInfoV1 is an ethdo V1 deposit structure.
type depositInfoV1 struct {
Name string `json:"name,omitempty"`
Account string `json:"account,omitempty"`
PublicKey string `json:"pubkey"`
WithdrawalCredentials string `json:"withdrawal_credentials"`
Signature string `json:"signature"`
DepositDataRoot string `json:"deposit_data_root"`
Value uint64 `json:"value"`
Version uint64 `json:"version"`
}
// depositInfoV3 is an ethdo V3 deposit structure.
type depositInfoV3 struct {
Name string `json:"name,omitempty"`
Account string `json:"account,omitempty"`
PublicKey string `json:"pubkey"`
WithdrawalCredentials string `json:"withdrawal_credentials"`
Signature string `json:"signature"`
DepositDataRoot string `json:"deposit_data_root"`
DepositMessageRoot string `json:"deposit_message_root"`
ForkVersion string `json:"fork_version"`
Amount uint64 `json:"amount"`
Version uint64 `json:"version"`
}
// depositInfoCLI is a deposit structure from the eth2 deposit CLI.
type depositInfoCLI struct {
PublicKey string `json:"pubkey"`
WithdrawalCredentials string `json:"withdrawal_credentials"`
Signature string `json:"signature"`
DepositDataRoot string `json:"deposit_data_root"`
DepositMessageRoot string `json:"deposit_message_root"`
ForkVersion string `json:"fork_version"`
Amount uint64 `json:"amount"`
}
func DepositInfoFromJSON(input []byte) ([]*DepositInfo, error) {
// Work out the type of data that we're dealing with, and decode it appropriately.
depositInfo, err := tryRawTxData(input)
if err != nil {
depositInfo, err = tryV3DepositInfoFromJSON(input)
if err != nil {
depositInfo, err = tryV1DepositInfoFromJSON(input)
if err != nil {
depositInfo, err = tryCLIDepositInfoFromJSON(input)
if err != nil {
// Give up
return nil, errors.New("unknown deposit data format")
}
}
}
}
if len(depositInfo) == 0 {
return nil, errors.New("no deposits supplied")
}
for i := range depositInfo {
if len(depositInfo[i].PublicKey) == 0 {
return nil, fmt.Errorf("no public key for deposit %d", i)
}
if len(depositInfo[i].DepositDataRoot) == 0 {
return nil, fmt.Errorf("no data root for deposit %d", i)
}
if len(depositInfo[i].Signature) == 0 {
return nil, fmt.Errorf("no signature for deposit %d", i)
}
if len(depositInfo[i].WithdrawalCredentials) == 0 {
return nil, fmt.Errorf("no withdrawal credentials for deposit %d", i)
}
}
return depositInfo, nil
}
func tryV3DepositInfoFromJSON(data []byte) ([]*DepositInfo, error) {
var depositData []*depositInfoV3
err := json.Unmarshal(data, &depositData)
if err != nil {
return nil, err
}
depositInfos := make([]*DepositInfo, len(depositData))
for i, deposit := range depositData {
if deposit.Version != 3 {
return nil, errors.New("incorrect V3 deposit version")
}
publicKey, err := hex.DecodeString(strings.TrimPrefix(deposit.PublicKey, "0x"))
if err != nil {
return nil, errors.New("public key invalid")
}
withdrawalCredentials, err := hex.DecodeString(strings.TrimPrefix(deposit.WithdrawalCredentials, "0x"))
if err != nil {
return nil, errors.New("withdrawal credentials invalid")
}
signature, err := hex.DecodeString(strings.TrimPrefix(deposit.Signature, "0x"))
if err != nil {
return nil, errors.New("signature invalid")
}
depositDataRoot, err := hex.DecodeString(strings.TrimPrefix(deposit.DepositDataRoot, "0x"))
if err != nil {
return nil, errors.New("deposit data root invalid")
}
depositMessageRoot, err := hex.DecodeString(strings.TrimPrefix(deposit.DepositMessageRoot, "0x"))
if err != nil {
return nil, errors.New("deposit message root invalid")
}
forkVersion, err := hex.DecodeString(strings.TrimPrefix(deposit.ForkVersion, "0x"))
if err != nil {
return nil, errors.New("fork version invalid")
}
depositInfos[i] = &DepositInfo{
Name: deposit.Name,
Account: deposit.Account,
PublicKey: publicKey,
WithdrawalCredentials: withdrawalCredentials,
Signature: signature,
DepositDataRoot: depositDataRoot,
DepositMessageRoot: depositMessageRoot,
ForkVersion: forkVersion,
Amount: deposit.Amount,
Version: 3,
}
}
return depositInfos, nil
}
func tryCLIDepositInfoFromJSON(data []byte) ([]*DepositInfo, error) {
var depositData []*depositInfoCLI
err := json.Unmarshal(data, &depositData)
if err != nil {
return nil, err
}
depositInfos := make([]*DepositInfo, len(depositData))
for i, deposit := range depositData {
publicKey, err := hex.DecodeString(strings.TrimPrefix(deposit.PublicKey, "0x"))
if err != nil {
return nil, errors.New("public key invalid")
}
withdrawalCredentials, err := hex.DecodeString(strings.TrimPrefix(deposit.WithdrawalCredentials, "0x"))
if err != nil {
return nil, errors.New("withdrawal credentials invalid")
}
signature, err := hex.DecodeString(strings.TrimPrefix(deposit.Signature, "0x"))
if err != nil {
return nil, errors.New("signature invalid")
}
depositDataRoot, err := hex.DecodeString(strings.TrimPrefix(deposit.DepositDataRoot, "0x"))
if err != nil {
return nil, errors.New("deposit data root invalid")
}
depositMessageRoot, err := hex.DecodeString(strings.TrimPrefix(deposit.DepositMessageRoot, "0x"))
if err != nil {
return nil, errors.New("deposit message root invalid")
}
forkVersion, err := hex.DecodeString(strings.TrimPrefix(deposit.ForkVersion, "0x"))
if err != nil {
return nil, errors.New("fork version invalid")
}
depositInfos[i] = &DepositInfo{
PublicKey: publicKey,
WithdrawalCredentials: withdrawalCredentials,
Signature: signature,
DepositDataRoot: depositDataRoot,
DepositMessageRoot: depositMessageRoot,
ForkVersion: forkVersion,
Amount: deposit.Amount,
Version: 3,
}
}
return depositInfos, nil
}
func tryV1DepositInfoFromJSON(data []byte) ([]*DepositInfo, error) {
var depositData []*depositInfoV1
err := json.Unmarshal(data, &depositData)
if err != nil {
return nil, err
}
depositInfos := make([]*DepositInfo, len(depositData))
for i, deposit := range depositData {
if deposit.Version < 1 || deposit.Version > 2 {
return nil, errors.New("incorrect deposit version")
}
publicKey, err := hex.DecodeString(strings.TrimPrefix(deposit.PublicKey, "0x"))
if err != nil {
return nil, errors.New("public key invalid")
}
withdrawalCredentials, err := hex.DecodeString(strings.TrimPrefix(deposit.WithdrawalCredentials, "0x"))
if err != nil {
return nil, errors.New("withdrawal credentials invalid")
}
signature, err := hex.DecodeString(strings.TrimPrefix(deposit.Signature, "0x"))
if err != nil {
return nil, errors.New("signature invalid")
}
depositDataRoot, err := hex.DecodeString(strings.TrimPrefix(deposit.DepositDataRoot, "0x"))
if err != nil {
return nil, errors.New("deposit data root invalid")
}
depositInfos[i] = &DepositInfo{
Name: deposit.Name,
Account: deposit.Account,
PublicKey: publicKey,
WithdrawalCredentials: withdrawalCredentials,
Signature: signature,
DepositDataRoot: depositDataRoot,
Amount: deposit.Value,
Version: 3,
}
}
return depositInfos, nil
}
func tryRawTxData(data []byte) ([]*DepositInfo, error) {
txData, err := hex.DecodeString(strings.TrimPrefix(string(data), "0x"))
if err != nil {
return nil, errors.New("public key invalid")
}
depositInfos := make([]*DepositInfo, 1)
if len(txData) != 420 {
return nil, errors.New("invalid transaction length")
}
if !bytes.Equal(txData[0:4], []byte{0x22, 0x89, 0x51, 0x18}) {
return nil, errors.New("invalid function signature")
}
depositInfos[0] = &DepositInfo{
PublicKey: txData[164:212],
WithdrawalCredentials: txData[260:292],
Signature: txData[324:420],
DepositDataRoot: txData[100:132],
}
return depositInfos, nil
}