mirror of
https://github.com/wealdtech/ethdo.git
synced 2026-01-10 14:37:57 -05:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2bb5e0d51 | ||
|
|
f5fc8b363d | ||
|
|
a31509f7d6 | ||
|
|
4b451ec2fa | ||
|
|
a8fee14b89 | ||
|
|
9cfb1b5637 | ||
|
|
df1724f763 | ||
|
|
f1a586ca56 | ||
|
|
b9cb926662 | ||
|
|
220cc21356 | ||
|
|
5bc7c1a26c | ||
|
|
4c3237cd0d | ||
|
|
7215e04a69 | ||
|
|
71e9c0471b | ||
|
|
1a6f402fb8 |
14
README.md
14
README.md
@@ -5,7 +5,7 @@
|
||||
|
||||
A command-line tool for managing common tasks in Ethereum 2.
|
||||
|
||||
** Please note that this library uses standards that are not yet final, and as such may result in changes that alter public and private keys. Do not use this library for production use just yet **
|
||||
**Please note that this tool and its underlying libraries have not yet undergone a security audit; use at your own risk.**
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -118,6 +118,18 @@ If set, the `--debug` argument will output additional information about the oper
|
||||
|
||||
Commands will have an exit status of 0 on success and 1 on failure. The specific definition of success is specified in the help for each command.
|
||||
|
||||
## Rules for account passphrases
|
||||
|
||||
Account passphrases are used in various places in `ethdo`. Where they are used, the following rules apply:
|
||||
|
||||
- commands that require passphrases to operate, for example unlocking an account, can be supplied with multiple passphrases. If they are, then each passphrase is tried until one succeeds or they all fail
|
||||
- commands that require passphrases to create, for example creating an account, must be supplied with a single passphrase. If more than one passphrase is supplied the command will fail
|
||||
|
||||
In addition, the following rules apply to passphrases supplied on the command line:
|
||||
|
||||
- passphrases **must not** start with `0x`
|
||||
- passphrases **must not** contain the comma (,) character
|
||||
|
||||
# Commands
|
||||
|
||||
Command information, along with sample outputs and optional arguments, is available in [the usage section](https://github.com/wealdtech/ethdo/blob/master/docs/usage.md).
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
e2wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
var accountCreateCmd = &cobra.Command{
|
||||
@@ -31,24 +33,26 @@ In quiet mode this will return 0 if the account is created successfully, otherwi
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
assert(!remote, "account create not available with remote wallets")
|
||||
assert(rootAccount != "", "--account is required")
|
||||
assert(rootAccountPassphrase != "", "--passphrase is required")
|
||||
|
||||
w, err := walletFromPath(rootAccount)
|
||||
wallet, err := walletFromPath(rootAccount)
|
||||
errCheck(err, "Failed to access wallet")
|
||||
|
||||
if w.Type() == "hierarchical deterministic" {
|
||||
assert(rootWalletPassphrase != "", "--walletpassphrase is required to create new accounts with hierarchical deterministic wallets")
|
||||
if wallet.Type() == "hierarchical deterministic" {
|
||||
assert(getWalletPassphrase() != "", "--walletpassphrase is required to create new accounts with hierarchical deterministic wallets")
|
||||
}
|
||||
_, err = accountFromPath(rootAccount)
|
||||
assert(err != nil, "Account already exists")
|
||||
|
||||
err = w.Unlock([]byte(rootWalletPassphrase))
|
||||
err = wallet.Unlock([]byte(getWalletPassphrase()))
|
||||
errCheck(err, "Failed to unlock wallet")
|
||||
|
||||
_, accountName, err := walletAndAccountNamesFromPath(rootAccount)
|
||||
errCheck(err, "Failed to obtain accout name")
|
||||
_, accountName, err := e2wallet.WalletAndAccountNames(rootAccount)
|
||||
errCheck(err, "Failed to obtain account name")
|
||||
|
||||
account, err := w.CreateAccount(accountName, []byte(rootAccountPassphrase))
|
||||
walletAccountCreator, ok := wallet.(e2wtypes.WalletAccountCreator)
|
||||
assert(ok, "wallet does not allow account creation")
|
||||
|
||||
account, err := walletAccountCreator.CreateAccount(accountName, []byte(getPassphrase()))
|
||||
errCheck(err, "Failed to create account")
|
||||
|
||||
outputIf(verbose, fmt.Sprintf("0x%048x", account.PublicKey().Marshal()))
|
||||
|
||||
@@ -19,7 +19,8 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wealdtech/go-bytesutil"
|
||||
types "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
e2wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
var accountImportKey string
|
||||
@@ -35,7 +36,7 @@ In quiet mode this will return 0 if the account is imported successfully, otherw
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
assert(!remote, "account import not available with remote wallets")
|
||||
assert(rootAccount != "", "--account is required")
|
||||
assert(rootAccountPassphrase != "", "--passphrase is required")
|
||||
passphrase := getPassphrase()
|
||||
assert(accountImportKey != "", "--key is required")
|
||||
|
||||
key, err := bytesutil.FromHexString(accountImportKey)
|
||||
@@ -44,19 +45,19 @@ In quiet mode this will return 0 if the account is imported successfully, otherw
|
||||
w, err := walletFromPath(rootAccount)
|
||||
errCheck(err, "Failed to access wallet")
|
||||
|
||||
_, ok := w.(types.WalletAccountImporter)
|
||||
_, ok := w.(e2wtypes.WalletAccountImporter)
|
||||
assert(ok, fmt.Sprintf("wallets of type %q do not allow importing accounts", w.Type()))
|
||||
|
||||
_, err = accountFromPath(rootAccount)
|
||||
assert(err != nil, "Account already exists")
|
||||
|
||||
err = w.Unlock([]byte(rootWalletPassphrase))
|
||||
err = w.Unlock([]byte(getWalletPassphrase()))
|
||||
errCheck(err, "Failed to unlock wallet")
|
||||
|
||||
_, accountName, err := walletAndAccountNamesFromPath(rootAccount)
|
||||
_, accountName, err := e2wallet.WalletAndAccountNames(rootAccount)
|
||||
errCheck(err, "Failed to obtain account name")
|
||||
|
||||
account, err := w.(types.WalletAccountImporter).ImportAccount(accountName, key, []byte(rootAccountPassphrase))
|
||||
account, err := w.(e2wtypes.WalletAccountImporter).ImportAccount(accountName, key, []byte(passphrase))
|
||||
errCheck(err, "Failed to create account")
|
||||
|
||||
outputIf(verbose, fmt.Sprintf("0x%048x", account.PublicKey().Marshal()))
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
pb "github.com/wealdtech/eth2-signer-api/pb/v1"
|
||||
util "github.com/wealdtech/go-eth2-util"
|
||||
)
|
||||
|
||||
var accountInfoCmd = &cobra.Command{
|
||||
@@ -33,6 +34,7 @@ In quiet mode this will return 0 if the account exists, otherwise 1.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
assert(rootAccount != "", "--account is required")
|
||||
|
||||
var withdrawalCredentials []byte
|
||||
if remote {
|
||||
listerClient := pb.NewListerClient(remoteGRPCConn)
|
||||
listAccountsReq := &pb.ListAccountsRequest{
|
||||
@@ -44,13 +46,18 @@ In quiet mode this will return 0 if the account exists, otherwise 1.`,
|
||||
errCheck(err, "Failed to access account")
|
||||
assert(resp.State == pb.ResponseState_SUCCEEDED, "No such account")
|
||||
assert(len(resp.Accounts) == 1, "No such account")
|
||||
fmt.Printf("Public key: %#048x\n", resp.Accounts[0].PublicKey)
|
||||
|
||||
fmt.Printf("Public key: %#x\n", resp.Accounts[0].PublicKey)
|
||||
withdrawalCredentials = util.SHA256(resp.Accounts[0].PublicKey)
|
||||
withdrawalCredentials[0] = byte(0) // BLS_WITHDRAWAL_PREFIX
|
||||
outputIf(verbose, fmt.Sprintf("Withdrawal credentials: %#x", withdrawalCredentials))
|
||||
} else {
|
||||
account, err := accountFromPath(rootAccount)
|
||||
errCheck(err, "Failed to access wallet")
|
||||
outputIf(verbose, fmt.Sprintf("UUID: %v", account.ID()))
|
||||
outputIf(!quiet, fmt.Sprintf("Public key: %#048x", account.PublicKey().Marshal()))
|
||||
outputIf(!quiet, fmt.Sprintf("Public key: %#x", account.PublicKey().Marshal()))
|
||||
withdrawalCredentials = util.SHA256(account.PublicKey().Marshal())
|
||||
withdrawalCredentials[0] = byte(0) // BLS_WITHDRAWAL_PREFIX
|
||||
outputIf(verbose, fmt.Sprintf("Withdrawal credentials: %#x", withdrawalCredentials))
|
||||
outputIf(verbose && account.Path() != "", fmt.Sprintf("Path: %s", account.Path()))
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,15 @@ In quiet mode this will return 0 if the key can be obtained, otherwise 1.`,
|
||||
_, ok := account.(types.AccountPrivateKeyProvider)
|
||||
assert(ok, fmt.Sprintf("account %q does not provide its private key", rootAccount))
|
||||
|
||||
assert(rootAccountPassphrase != "", "--passphrase is required")
|
||||
err = account.Unlock([]byte(rootAccountPassphrase))
|
||||
errCheck(err, "Failed to unlock account to obtain private key")
|
||||
unlocked := false
|
||||
for _, passphrase := range getPassphrases() {
|
||||
err = account.Unlock([]byte(passphrase))
|
||||
if err == nil {
|
||||
unlocked = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert(unlocked, "Failed to unlock account to obtain private key")
|
||||
defer account.Lock()
|
||||
privateKey, err := account.(types.AccountPrivateKeyProvider).PrivateKey()
|
||||
errCheck(err, "Failed to obtain private key")
|
||||
|
||||
@@ -35,23 +35,23 @@ In quiet mode this will return 0 if the account is unlocked, otherwise 1.`,
|
||||
assert(rootAccount != "", "--account is required")
|
||||
|
||||
client := pb.NewAccountManagerClient(remoteGRPCConn)
|
||||
unlockReq := &pb.UnlockAccountRequest{
|
||||
Account: rootAccount,
|
||||
Passphrase: []byte(rootAccountPassphrase),
|
||||
}
|
||||
unlocked := false
|
||||
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
|
||||
defer cancel()
|
||||
resp, err := client.Unlock(ctx, unlockReq)
|
||||
errCheck(err, "Failed in attempt to unlock account")
|
||||
switch resp.State {
|
||||
case pb.ResponseState_DENIED:
|
||||
die("Unlock request denied")
|
||||
case pb.ResponseState_FAILED:
|
||||
die("Unlock request failed")
|
||||
case pb.ResponseState_SUCCEEDED:
|
||||
outputIf(!quiet, "Unlock request succeeded")
|
||||
os.Exit(_exitSuccess)
|
||||
for _, passphrase := range getPassphrases() {
|
||||
unlockReq := &pb.UnlockAccountRequest{
|
||||
Account: rootAccount,
|
||||
Passphrase: []byte(passphrase),
|
||||
}
|
||||
resp, err := client.Unlock(ctx, unlockReq)
|
||||
errCheck(err, "Failed in attempt to unlock account")
|
||||
if resp.State == pb.ResponseState_SUCCEEDED {
|
||||
unlocked = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert(unlocked, "Failed to unlock account")
|
||||
os.Exit(_exitSuccess)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ In quiet mode this will return 0 if the block information is present and not ski
|
||||
err := connect()
|
||||
errCheck(err, "Failed to obtain connection to Ethereum 2 beacon chain block")
|
||||
|
||||
config, err := grpc.FetchChainConfig(eth2GRPCConn)
|
||||
errCheck(err, "Failed to obtain beacon chain configuration")
|
||||
slotsPerEpoch := config["SlotsPerEpoch"].(uint64)
|
||||
|
||||
if blockInfoStream {
|
||||
stream, err := grpc.StreamBlocks(eth2GRPCConn)
|
||||
errCheck(err, "Failed to obtain block stream")
|
||||
@@ -53,7 +57,7 @@ In quiet mode this will return 0 if the block information is present and not ski
|
||||
errCheck(err, "Failed to obtain block")
|
||||
if signedBlock != nil {
|
||||
fmt.Println("")
|
||||
outputBlock(signedBlock)
|
||||
outputBlock(signedBlock, slotsPerEpoch)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +66,7 @@ In quiet mode this will return 0 if the block information is present and not ski
|
||||
var slot uint64
|
||||
if blockInfoSlot < 0 {
|
||||
slot, err = grpc.FetchLatestFilledSlot(eth2GRPCConn)
|
||||
errCheck(err, "Failed to obtain slot of latest block")
|
||||
} else {
|
||||
slot = uint64(blockInfoSlot)
|
||||
}
|
||||
@@ -73,14 +78,14 @@ In quiet mode this will return 0 if the block information is present and not ski
|
||||
outputIf(!quiet, "No block at that slot")
|
||||
os.Exit(_exitFailure)
|
||||
}
|
||||
outputBlock(signedBlock)
|
||||
outputBlock(signedBlock, slotsPerEpoch)
|
||||
}
|
||||
|
||||
os.Exit(_exitSuccess)
|
||||
},
|
||||
}
|
||||
|
||||
func outputBlock(signedBlock *ethpb.SignedBeaconBlock) {
|
||||
func outputBlock(signedBlock *ethpb.SignedBeaconBlock, slotsPerEpoch uint64) {
|
||||
block := signedBlock.Block
|
||||
body := block.Body
|
||||
|
||||
@@ -88,6 +93,7 @@ func outputBlock(signedBlock *ethpb.SignedBeaconBlock) {
|
||||
bodyRoot, err := ssz.HashTreeRoot(block)
|
||||
errCheck(err, "Failed to calculate block body root")
|
||||
fmt.Printf("Slot: %d\n", block.Slot)
|
||||
fmt.Printf("Epoch: %d\n", block.Slot/slotsPerEpoch)
|
||||
fmt.Printf("Block root: %#x\n", bodyRoot)
|
||||
outputIf(verbose, fmt.Sprintf("Parent root: %#x", block.ParentRoot))
|
||||
outputIf(verbose, fmt.Sprintf("State root: %#x", block.StateRoot))
|
||||
@@ -105,15 +111,30 @@ func outputBlock(signedBlock *ethpb.SignedBeaconBlock) {
|
||||
outputIf(verbose, fmt.Sprintf("Ethereum 1 deposit root: %#x", eth1Data.DepositRoot))
|
||||
outputIf(verbose, fmt.Sprintf("Ethereum 1 block hash: %#x", eth1Data.BlockHash))
|
||||
|
||||
validatorCommittees := make(map[uint64][][]uint64)
|
||||
|
||||
// Attestations.
|
||||
fmt.Printf("Attestations: %d\n", len(body.Attestations))
|
||||
if verbose {
|
||||
for i, att := range body.Attestations {
|
||||
fmt.Printf("\t%d:\n", i)
|
||||
|
||||
// Fetch committees for this epoch if not already obtained.
|
||||
committees, exists := validatorCommittees[att.Data.Slot]
|
||||
if !exists {
|
||||
attestationEpoch := att.Data.Slot / slotsPerEpoch
|
||||
epochCommittees, err := grpc.FetchValidatorCommittees(eth2GRPCConn, attestationEpoch)
|
||||
errCheck(err, "Failed to obtain committees")
|
||||
for k, v := range epochCommittees {
|
||||
validatorCommittees[k] = v
|
||||
}
|
||||
committees = validatorCommittees[att.Data.Slot]
|
||||
}
|
||||
|
||||
fmt.Printf("\t\tCommittee index: %d\n", att.Data.CommitteeIndex)
|
||||
fmt.Printf("\t\tAttesters: %d/%d\n", att.AggregationBits.Count(), att.AggregationBits.Len())
|
||||
fmt.Printf("\t\tAggregation bits: %s\n", bitsToString(att.AggregationBits))
|
||||
fmt.Printf("\t\tAttesting indices: %s\n", attestingIndices(att.AggregationBits, committees[att.Data.CommitteeIndex]))
|
||||
fmt.Printf("\t\tSlot: %d\n", att.Data.Slot)
|
||||
fmt.Printf("\t\tBeacon block root: %#x\n", att.Data.BeaconBlockRoot)
|
||||
fmt.Printf("\t\tSource epoch: %d\n", att.Data.Source.Epoch)
|
||||
@@ -157,18 +178,17 @@ func outputBlock(signedBlock *ethpb.SignedBeaconBlock) {
|
||||
fmt.Printf("\t\t\tAttestation 1 beacon block root: %#x\n", att1.Data.BeaconBlockRoot)
|
||||
fmt.Printf("\t\t\tAttestation 2 beacon block root: %#x\n", att2.Data.BeaconBlockRoot)
|
||||
}
|
||||
} else {
|
||||
if att1.Data.Source.Epoch < att2.Data.Source.Epoch &&
|
||||
att1.Data.Target.Epoch > att2.Data.Target.Epoch {
|
||||
fmt.Printf("\t\tSurround voted:\n")
|
||||
fmt.Printf("\t\t\tAttestation 1 vote: %d->%d\n", att1.Data.Source.Epoch, att1.Data.Target.Epoch)
|
||||
fmt.Printf("\t\t\tAttestation 2 vote: %d->%d\n", att2.Data.Source.Epoch, att2.Data.Target.Epoch)
|
||||
}
|
||||
} else if att1.Data.Source.Epoch < att2.Data.Source.Epoch &&
|
||||
att1.Data.Target.Epoch > att2.Data.Target.Epoch {
|
||||
fmt.Printf("\t\tSurround voted:\n")
|
||||
fmt.Printf("\t\t\tAttestation 1 vote: %d->%d\n", att1.Data.Source.Epoch, att1.Data.Target.Epoch)
|
||||
fmt.Printf("\t\t\tAttestation 2 vote: %d->%d\n", att2.Data.Source.Epoch, att2.Data.Target.Epoch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Proposer slashings once proposer slashings exist.
|
||||
fmt.Printf("Proposer slashings: %d\n", len(body.ProposerSlashings))
|
||||
// TODO verbose proposer slashings.
|
||||
|
||||
// Deposits.
|
||||
fmt.Printf("Deposits: %d\n", len(body.Deposits))
|
||||
@@ -237,6 +257,17 @@ func bitsToString(input bitfield.Bitlist) string {
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
|
||||
func attestingIndices(input bitfield.Bitlist, indices []uint64) string {
|
||||
bits := int(input.Len())
|
||||
res := ""
|
||||
for i := 0; i < bits; i++ {
|
||||
if input.BitAt(uint64(i)) {
|
||||
res = fmt.Sprintf("%s%d ", res, indices[i])
|
||||
}
|
||||
}
|
||||
return strings.TrimSpace(res)
|
||||
}
|
||||
|
||||
func init() {
|
||||
blockCmd.AddCommand(blockInfoCmd)
|
||||
blockFlags(blockInfoCmd)
|
||||
|
||||
@@ -70,12 +70,12 @@ In quiet mode this will return 0 if the chain status can be obtained, otherwise
|
||||
slotsPerEpoch := config["SlotsPerEpoch"].(uint64)
|
||||
epoch := slot / slotsPerEpoch
|
||||
fmt.Printf("Current epoch: %d\n", epoch)
|
||||
fmt.Printf("Justified epoch: %d\n", info.GetJustifiedSlot()/slotsPerEpoch)
|
||||
fmt.Printf("Justified epoch: %d\n", info.GetJustifiedEpoch())
|
||||
if verbose {
|
||||
distance := (slot - info.GetJustifiedSlot()) / slotsPerEpoch
|
||||
fmt.Printf("Justified epoch distance %d\n", distance)
|
||||
fmt.Printf("Justified epoch distance: %d\n", distance)
|
||||
}
|
||||
fmt.Printf("Finalized epoch: %d\n", info.GetFinalizedSlot()/slotsPerEpoch)
|
||||
fmt.Printf("Finalized epoch: %d\n", info.GetFinalizedEpoch())
|
||||
if verbose {
|
||||
distance := (slot - info.GetFinalizedSlot()) / slotsPerEpoch
|
||||
fmt.Printf("Finalized epoch distance: %d\n", distance)
|
||||
|
||||
32
cmd/deposit.go
Normal file
32
cmd/deposit.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright © 2019 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 (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// depositCmd represents the deposit command
|
||||
var depositCmd = &cobra.Command{
|
||||
Use: "deposit",
|
||||
Short: "Manage Ethereum 2 deposits",
|
||||
Long: `Manage Ethereum 2 deposits.`,
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.AddCommand(depositCmd)
|
||||
}
|
||||
|
||||
func depositFlags(cmd *cobra.Command) {
|
||||
}
|
||||
235
cmd/depositverify.go
Normal file
235
cmd/depositverify.go
Normal file
@@ -0,0 +1,235 @@
|
||||
// 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 (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
e2types "github.com/wealdtech/go-eth2-types/v2"
|
||||
util "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 depositVerifyCmd = &cobra.Command{
|
||||
Use: "verify",
|
||||
Short: "Verify deposit data matches requirements",
|
||||
Long: `Verify deposit data matches requirements. 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.
|
||||
|
||||
In quiet mode this will return 0 if the the data can be generated correctly, otherwise 1.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
assert(depositVerifyData != "", "--data is required")
|
||||
deposits, err := depositDataFromJSON(depositVerifyData)
|
||||
errCheck(err, "Failed to fetch deposit data")
|
||||
|
||||
withdrawalCredentials := ""
|
||||
if depositVerifyWithdrawalPubKey != "" {
|
||||
withdrawalPubKeyBytes, err := hex.DecodeString(strings.TrimPrefix(depositVerifyWithdrawalPubKey, "0x"))
|
||||
errCheck(err, "Invalid withdrawal public key")
|
||||
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")
|
||||
withdrawalBytes := util.SHA256(withdrawalPubKey.Marshal())
|
||||
withdrawalBytes[0] = 0 // BLS_WITHDRAWAL_PREFIX
|
||||
withdrawalCredentials = fmt.Sprintf("%x", withdrawalBytes)
|
||||
}
|
||||
outputIf(debug, fmt.Sprintf("Withdrawal credentials are %s", withdrawalCredentials))
|
||||
|
||||
depositValue := uint64(0)
|
||||
if depositVerifyDepositValue != "" {
|
||||
depositValue, err = string2eth.StringToGWei(depositVerifyDepositValue)
|
||||
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
|
||||
}
|
||||
|
||||
validatorPubKeys := make(map[string]bool)
|
||||
if depositVerifyValidatorPubKey != "" {
|
||||
validatorPubKeys, err = validatorPubKeysFromInput(depositVerifyValidatorPubKey)
|
||||
errCheck(err, "Failed to obtain validator public key(s))")
|
||||
}
|
||||
|
||||
failures := false
|
||||
for i, deposit := range deposits {
|
||||
if withdrawalCredentials != "" {
|
||||
if deposit.WithdrawalCredentials != withdrawalCredentials {
|
||||
outputIf(!quiet, fmt.Sprintf("Invalid withdrawal credentials for deposit %d", i))
|
||||
failures = true
|
||||
}
|
||||
}
|
||||
if depositValue != 0 {
|
||||
if deposit.Value != depositValue {
|
||||
outputIf(!quiet, fmt.Sprintf("Invalid deposit value for deposit %d", i))
|
||||
failures = true
|
||||
}
|
||||
}
|
||||
if len(validatorPubKeys) != 0 {
|
||||
if _, exists := validatorPubKeys[deposit.PublicKey]; !exists {
|
||||
outputIf(!quiet, fmt.Sprintf("Unknown validator public key for deposit %d", i))
|
||||
failures = true
|
||||
}
|
||||
}
|
||||
outputIf(!quiet, fmt.Sprintf("Deposit for %q verified", deposit.Name))
|
||||
}
|
||||
|
||||
if failures {
|
||||
os.Exit(_exitFailure)
|
||||
}
|
||||
os.Exit(_exitSuccess)
|
||||
},
|
||||
}
|
||||
|
||||
func validatorPubKeysFromInput(input string) (map[string]bool, error) {
|
||||
pubKeys := make(map[string]bool)
|
||||
var err error
|
||||
var data []byte
|
||||
// Input could be a public key or a path to public keys.
|
||||
if strings.HasPrefix(input, "0x") {
|
||||
// Looks like a public key.
|
||||
pubKeyBytes, err := hex.DecodeString(strings.TrimPrefix(input, "0x"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "public key is not a hex string")
|
||||
}
|
||||
if len(pubKeyBytes) != 48 {
|
||||
return nil, errors.New("public key should be 48 bytes")
|
||||
}
|
||||
pubKey, err := e2types.BLSPublicKeyFromBytes(pubKeyBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "invalid public key")
|
||||
}
|
||||
pubKeys[fmt.Sprintf("%x", pubKey.Marshal())] = true
|
||||
} else {
|
||||
// Assume it's a path to a file of public keys.
|
||||
data, err = ioutil.ReadFile(input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to find public key file")
|
||||
}
|
||||
lines := bytes.Split(bytes.Replace(data, []byte("\r\n"), []byte("\n"), -1), []byte("\n"))
|
||||
if len(lines) == 0 {
|
||||
return nil, errors.New("file has no public keys")
|
||||
}
|
||||
for _, line := range lines {
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
pubKeyBytes, err := hex.DecodeString(strings.TrimPrefix(string(line), "0x"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "public key is not a hex string")
|
||||
}
|
||||
if len(pubKeyBytes) != 48 {
|
||||
return nil, errors.New("public key should be 48 bytes")
|
||||
}
|
||||
pubKey, err := e2types.BLSPublicKeyFromBytes(pubKeyBytes)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "invalid public key")
|
||||
}
|
||||
pubKeys[fmt.Sprintf("%x", pubKey.Marshal())] = true
|
||||
}
|
||||
}
|
||||
|
||||
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) + "]")
|
||||
}
|
||||
}
|
||||
var depositData []*depositData
|
||||
err = json.Unmarshal(data, &depositData)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "data is not valid JSON")
|
||||
}
|
||||
if len(depositData) == 0 {
|
||||
return nil, errors.New("no deposits supplied")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
func init() {
|
||||
depositCmd.AddCommand(depositVerifyCmd)
|
||||
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(&depositVerifyValidatorPubKey, "validatorpubkey", "", "Public key(s) of the account(s) that will be carrying out validation")
|
||||
}
|
||||
39
cmd/passphrases.go
Normal file
39
cmd/passphrases.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright © 2019 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 "github.com/spf13/viper"
|
||||
|
||||
// getStorePassphrases() fetches the store passphrase supplied by the user.
|
||||
func getStorePassphrase() string {
|
||||
return viper.GetString("store-passphrase")
|
||||
}
|
||||
|
||||
// getWalletPassphrases() fetches the wallet passphrase supplied by the user.
|
||||
func getWalletPassphrase() string {
|
||||
return viper.GetString("wallet-passphrase")
|
||||
}
|
||||
|
||||
// getPassphrases() fetches the passphrases supplied by the user.
|
||||
func getPassphrases() []string {
|
||||
return viper.GetStringSlice("passphrase")
|
||||
}
|
||||
|
||||
// getPassphrase fetches the passphrase supplied by the user.
|
||||
func getPassphrase() string {
|
||||
passphrases := getPassphrases()
|
||||
assert(len(passphrases) != 0, "passphrase is required")
|
||||
assert(len(passphrases) == 1, "multiple passphrases supplied; cannot continue")
|
||||
return passphrases[0]
|
||||
}
|
||||
58
cmd/root.go
58
cmd/root.go
@@ -31,13 +31,12 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
e2types "github.com/wealdtech/go-eth2-types/v2"
|
||||
e2wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
filesystem "github.com/wealdtech/go-eth2-wallet-store-filesystem"
|
||||
s3 "github.com/wealdtech/go-eth2-wallet-store-s3"
|
||||
wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
var cfgFile string
|
||||
@@ -49,9 +48,6 @@ var debug bool
|
||||
var rootStore string
|
||||
var rootAccount string
|
||||
var rootBaseDir string
|
||||
var rootStorePassphrase string
|
||||
var rootWalletPassphrase string
|
||||
var rootAccountPassphrase string
|
||||
|
||||
// Store for wallet actions.
|
||||
var store wtypes.Store
|
||||
@@ -93,9 +89,6 @@ func persistentPreRun(cmd *cobra.Command, args []string) {
|
||||
rootStore = viper.GetString("store")
|
||||
rootAccount = viper.GetString("account")
|
||||
rootBaseDir = viper.GetString("basedir")
|
||||
rootStorePassphrase = viper.GetString("storepassphrase")
|
||||
rootWalletPassphrase = viper.GetString("walletpassphrase")
|
||||
rootAccountPassphrase = viper.GetString("passphrase")
|
||||
|
||||
if quiet && verbose {
|
||||
fmt.Println("Cannot supply both quiet and verbose flags")
|
||||
@@ -110,12 +103,12 @@ func persistentPreRun(cmd *cobra.Command, args []string) {
|
||||
case "s3":
|
||||
assert(rootBaseDir == "", "--basedir does not apply for the s3 store")
|
||||
var err error
|
||||
store, err = s3.New(s3.WithPassphrase([]byte(rootStorePassphrase)))
|
||||
store, err = s3.New(s3.WithPassphrase([]byte(getStorePassphrase())))
|
||||
errCheck(err, "Failed to access Amazon S3 wallet store")
|
||||
case "filesystem":
|
||||
opts := make([]filesystem.Option, 0)
|
||||
if rootStorePassphrase != "" {
|
||||
opts = append(opts, filesystem.WithPassphrase([]byte(rootStorePassphrase)))
|
||||
if getStorePassphrase() != "" {
|
||||
opts = append(opts, filesystem.WithPassphrase([]byte(getStorePassphrase())))
|
||||
}
|
||||
if rootBaseDir != "" {
|
||||
opts = append(opts, filesystem.WithLocation(rootBaseDir))
|
||||
@@ -124,7 +117,7 @@ func persistentPreRun(cmd *cobra.Command, args []string) {
|
||||
default:
|
||||
die(fmt.Sprintf("Unsupported wallet store %s", rootStore))
|
||||
}
|
||||
err := wallet.UseStore(store)
|
||||
err := e2wallet.UseStore(store)
|
||||
errCheck(err, "Failed to use defined wallet store")
|
||||
} else {
|
||||
err := initRemote()
|
||||
@@ -164,18 +157,18 @@ func init() {
|
||||
panic(err)
|
||||
}
|
||||
RootCmd.PersistentFlags().String("basedir", "", "Base directory for filesystem wallets")
|
||||
if err := viper.BindPFlag("basedir", RootCmd.PersistentFlags().Lookup("basedir")); err != nil {
|
||||
if err := viper.BindPFlag("base-dir", RootCmd.PersistentFlags().Lookup("basedir")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
RootCmd.PersistentFlags().String("storepassphrase", "", "Passphrase for store (if applicable)")
|
||||
if err := viper.BindPFlag("storepassphrase", RootCmd.PersistentFlags().Lookup("storepassphrase")); err != nil {
|
||||
if err := viper.BindPFlag("store-passphrase", RootCmd.PersistentFlags().Lookup("storepassphrase")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
RootCmd.PersistentFlags().String("walletpassphrase", "", "Passphrase for wallet (if applicable)")
|
||||
if err := viper.BindPFlag("walletpassphrase", RootCmd.PersistentFlags().Lookup("walletpassphrase")); err != nil {
|
||||
if err := viper.BindPFlag("wallet-passphrase", RootCmd.PersistentFlags().Lookup("walletpassphrase")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
RootCmd.PersistentFlags().String("passphrase", "", "Passphrase for account (if applicable)")
|
||||
RootCmd.PersistentFlags().StringSlice("passphrase", nil, "Passphrase for account (if applicable)")
|
||||
if err := viper.BindPFlag("passphrase", RootCmd.PersistentFlags().Lookup("passphrase")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -252,37 +245,20 @@ func outputIf(condition bool, msg string) {
|
||||
}
|
||||
}
|
||||
|
||||
// walletAndAccountNamesFromPath breaks a path in to wallet and account names.
|
||||
func walletAndAccountNamesFromPath(path string) (string, string, error) {
|
||||
if len(path) == 0 {
|
||||
return "", "", errors.New("invalid account format")
|
||||
}
|
||||
index := strings.Index(path, "/")
|
||||
if index == -1 {
|
||||
// Just the wallet
|
||||
return path, "", nil
|
||||
}
|
||||
if index == len(path)-1 {
|
||||
// Trailing /
|
||||
return path[:index], "", nil
|
||||
}
|
||||
return path[:index], path[index+1:], nil
|
||||
}
|
||||
|
||||
// walletFromPath obtains a wallet given a path specification.
|
||||
func walletFromPath(path string) (wtypes.Wallet, error) {
|
||||
walletName, _, err := walletAndAccountNamesFromPath(path)
|
||||
walletName, _, err := e2wallet.WalletAndAccountNames(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w, err := wallet.OpenWallet(walletName)
|
||||
wallet, err := e2wallet.OpenWallet(walletName)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "failed to decrypt wallet") {
|
||||
return nil, errors.New("Incorrect store passphrase")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return w, nil
|
||||
return wallet, nil
|
||||
}
|
||||
|
||||
// accountFromPath obtains an account given a path specification.
|
||||
@@ -291,7 +267,7 @@ func accountFromPath(path string) (wtypes.Account, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, accountName, err := walletAndAccountNamesFromPath(path)
|
||||
_, accountName, err := e2wallet.WalletAndAccountNames(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -300,8 +276,8 @@ func accountFromPath(path string) (wtypes.Account, error) {
|
||||
}
|
||||
|
||||
if wallet.Type() == "hierarchical deterministic" && strings.HasPrefix(accountName, "m/") {
|
||||
assert(rootWalletPassphrase != "", "--walletpassphrase is required for direct path derivations")
|
||||
err = wallet.Unlock([]byte(rootWalletPassphrase))
|
||||
assert(getWalletPassphrase() != "", "--walletpassphrase is required for direct path derivations")
|
||||
err = wallet.Unlock([]byte(viper.GetString("wallet-passphrase")))
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid wallet passphrase")
|
||||
}
|
||||
@@ -325,7 +301,7 @@ func accountsFromPath(path string) ([]wtypes.Account, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, accountSpec, err := walletAndAccountNamesFromPath(path)
|
||||
_, accountSpec, err := e2wallet.WalletAndAccountNames(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ In quiet mode this will return 0 if the data can be signed, otherwise 1.`,
|
||||
} else {
|
||||
account, err := accountFromPath(rootAccount)
|
||||
errCheck(err, "Failed to access account for signing")
|
||||
err = account.Unlock([]byte(rootAccountPassphrase))
|
||||
err = account.Unlock([]byte(getPassphrase()))
|
||||
errCheck(err, "Failed to unlock account for signing")
|
||||
var fixedSizeData [32]byte
|
||||
copy(fixedSizeData[:], data)
|
||||
|
||||
@@ -112,7 +112,10 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth
|
||||
err := connect()
|
||||
errCheck(err, "Failed to connect to beacon node")
|
||||
config, err := grpc.FetchChainConfig(eth2GRPCConn)
|
||||
errCheck(err, "Failed to obtain chain configuration")
|
||||
if err != nil {
|
||||
outputIf(!quiet, "Could not connect to beacon node; supply a connection with --connection or provide a fork version with --forkversion to generate a deposit")
|
||||
os.Exit(_exitFailure)
|
||||
}
|
||||
genesisForkVersion, exists := config["GenesisForkVersion"]
|
||||
assert(exists, "Failed to obtain genesis fork version")
|
||||
forkVersion = genesisForkVersion.([]byte)
|
||||
@@ -121,8 +124,15 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth
|
||||
|
||||
domain := e2types.Domain(e2types.DomainDeposit, forkVersion, e2types.ZeroGenesisValidatorsRoot)
|
||||
outputIf(debug, fmt.Sprintf("Domain is %x", domain))
|
||||
err = validatorAccount.Unlock([]byte(rootAccountPassphrase))
|
||||
errCheck(err, "Failed to unlock validator account")
|
||||
unlocked := false
|
||||
for _, passphrase := range getPassphrases() {
|
||||
err = validatorAccount.Unlock([]byte(passphrase))
|
||||
if err == nil {
|
||||
unlocked = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert(unlocked, "Failed to unlock validator account")
|
||||
signature, err := signStruct(validatorAccount, depositData, domain)
|
||||
validatorAccount.Lock()
|
||||
errCheck(err, "Failed to generate deposit data signature")
|
||||
@@ -167,7 +177,7 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth
|
||||
txData = append(txData, signedDepositData.Signature...)
|
||||
outputs = append(outputs, fmt.Sprintf("%#x", txData))
|
||||
} else {
|
||||
outputs = append(outputs, fmt.Sprintf(`{"account":"%s","pubkey":"%048x","withdrawal_credentials":"%032x","signature":"%096x","value":%d,"deposit_data_root":"%032x","version":1}`, fmt.Sprintf("%s/%s", validatorWallet.Name(), validatorAccount.Name()), signedDepositData.PubKey, signedDepositData.WithdrawalCredentials, signedDepositData.Signature, val, depositDataRoot))
|
||||
outputs = append(outputs, fmt.Sprintf(`{"account":"%s","pubkey":"%048x","withdrawal_credentials":"%032x","signature":"%096x","value":%d,"deposit_data_root":"%032x","version":2}`, fmt.Sprintf("%s/%s", validatorWallet.Name(), validatorAccount.Name()), signedDepositData.PubKey, signedDepositData.WithdrawalCredentials, signedDepositData.Signature, val, depositDataRoot))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,11 @@ func validatorExitHandleAccountInput(account e2wtypes.Account) (*ethpb.Voluntary
|
||||
// Beacon chain config required for later work.
|
||||
config, err := grpc.FetchChainConfig(eth2GRPCConn)
|
||||
errCheck(err, "Failed to obtain beacon chain configuration")
|
||||
secondsPerEpoch := config["SecondsPerSlot"].(uint64) * config["SlotsPerEpoch"].(uint64)
|
||||
secondsPerSlot, ok := config["SecondsPerSlot"].(uint64)
|
||||
assert(ok, "Failed to obtain seconds per slot from chain")
|
||||
slotsPerEpoch, ok := config["SlotsPerEpoch"].(uint64)
|
||||
assert(ok, "Failed to obtain slots per epoch from chain")
|
||||
secondsPerEpoch := secondsPerSlot * slotsPerEpoch
|
||||
|
||||
// Fetch the validator's index.
|
||||
index, err := grpc.FetchValidatorIndex(eth2GRPCConn, account)
|
||||
@@ -113,7 +117,9 @@ func validatorExitHandleAccountInput(account e2wtypes.Account) (*ethpb.Voluntary
|
||||
validator, err := grpc.FetchValidator(eth2GRPCConn, account)
|
||||
errCheck(err, "Failed to obtain validator information")
|
||||
outputIf(debug, fmt.Sprintf("Activation epoch is %v", validator.ActivationEpoch))
|
||||
earliestExitEpoch := validator.ActivationEpoch + config["PersistentCommitteePeriod"].(uint64)
|
||||
shardCommitteePeriod, ok := config["ShardCommitteePeriod"].(uint64)
|
||||
assert(ok, "Failed to obtain shard committee period from chain")
|
||||
earliestExitEpoch := validator.ActivationEpoch + shardCommitteePeriod
|
||||
|
||||
genesisTime, err := grpc.FetchGenesisTime(eth2GRPCConn)
|
||||
errCheck(err, "Failed to obtain genesis time")
|
||||
@@ -135,8 +141,15 @@ func validatorExitHandleAccountInput(account e2wtypes.Account) (*ethpb.Voluntary
|
||||
errCheck(err, "Failed to obtain genesis validators root")
|
||||
domain := e2types.Domain(e2types.DomainVoluntaryExit, currentForkVersion, genesisValidatorsRoot)
|
||||
|
||||
err = account.Unlock([]byte(rootAccountPassphrase))
|
||||
errCheck(err, "Failed to unlock account; please confirm passphrase is correct")
|
||||
unlocked := false
|
||||
for _, passphrase := range getPassphrases() {
|
||||
err = account.Unlock([]byte(passphrase))
|
||||
if err == nil {
|
||||
unlocked = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert(unlocked, "Failed to unlock account; please confirm passphrase is correct")
|
||||
signature, err := signStruct(account, exit, domain)
|
||||
errCheck(err, "Failed to sign exit proposal")
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ var versionCmd = &cobra.Command{
|
||||
|
||||
ethdo version.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("1.4.17")
|
||||
fmt.Println("1.4.21")
|
||||
if viper.GetBool("verbose") {
|
||||
buildInfo, ok := dbg.ReadBuildInfo()
|
||||
if ok {
|
||||
|
||||
@@ -45,8 +45,8 @@ In quiet mode this will return 0 if the wallet is created successfully, otherwis
|
||||
assert(walletCreateSeed == "", "--seed is not allowed with non-deterministic wallets")
|
||||
err = walletCreateND(walletWallet)
|
||||
case "hierarchical deterministic", "hd":
|
||||
assert(rootWalletPassphrase != "", "--walletpassphrase is required for hierarchical deterministic wallets")
|
||||
err = walletCreateHD(walletWallet, rootWalletPassphrase, walletCreateSeed)
|
||||
assert(getWalletPassphrase() != "", "--walletpassphrase is required for hierarchical deterministic wallets")
|
||||
err = walletCreateHD(walletWallet, getWalletPassphrase(), walletCreateSeed)
|
||||
default:
|
||||
die("unknown wallet type")
|
||||
}
|
||||
|
||||
@@ -14,18 +14,22 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/wealdtech/go-bytesutil"
|
||||
wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
"github.com/wealdtech/go-ecodec"
|
||||
e2wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
)
|
||||
|
||||
var walletImportData string
|
||||
var walletImportPassphrase string
|
||||
var walletImportVerify bool
|
||||
|
||||
var walletImportCmd = &cobra.Command{
|
||||
Use: "import",
|
||||
@@ -52,8 +56,42 @@ In quiet mode this will return 0 if the wallet is imported successfully, otherwi
|
||||
importData, err := bytesutil.FromHexString(walletImportData)
|
||||
errCheck(err, "Failed to decode wallet data")
|
||||
|
||||
_, err = wallet.ImportWallet(importData, []byte(walletImportPassphrase))
|
||||
errCheck(err, "Failed to import wallet")
|
||||
if walletImportVerify {
|
||||
type accountInfo struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
type walletInfo struct {
|
||||
ID uuid.UUID `json:"uuid"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
type export struct {
|
||||
Wallet *walletInfo `json:"wallet"`
|
||||
Accounts []*accountInfo `json:"accounts"`
|
||||
}
|
||||
|
||||
data, err := ecodec.Decrypt(importData, []byte(walletImportPassphrase))
|
||||
errCheck(err, "Failed to decrypt wallet")
|
||||
ext := &export{}
|
||||
err = json.Unmarshal(data, ext)
|
||||
errCheck(err, "Failed to read wallet")
|
||||
|
||||
outputIf(!quiet, fmt.Sprintf("Wallet name: %s", ext.Wallet.Name))
|
||||
outputIf(!quiet, fmt.Sprintf("Wallet type: %s", ext.Wallet.Type))
|
||||
outputIf(verbose, fmt.Sprintf("Wallet UUID: %s", ext.Wallet.ID))
|
||||
if verbose {
|
||||
fmt.Printf("Wallet accounts:\n")
|
||||
for _, account := range ext.Accounts {
|
||||
outputIf(verbose, fmt.Sprintf(" %s", account.Name))
|
||||
}
|
||||
} else {
|
||||
outputIf(!quiet, fmt.Sprintf("Wallet accounts: %d", len(ext.Accounts)))
|
||||
}
|
||||
|
||||
} else {
|
||||
_, err = e2wallet.ImportWallet(importData, []byte(walletImportPassphrase))
|
||||
errCheck(err, "Failed to import wallet")
|
||||
}
|
||||
|
||||
os.Exit(_exitSuccess)
|
||||
},
|
||||
@@ -64,4 +102,5 @@ func init() {
|
||||
walletFlags(walletImportCmd)
|
||||
walletImportCmd.Flags().StringVar(&walletImportData, "importdata", "", "The data to import, or the name of a file to read")
|
||||
walletImportCmd.Flags().StringVar(&walletImportPassphrase, "importpassphrase", "", "Passphrase protecting the data to import")
|
||||
walletImportCmd.Flags().BoolVar(&walletImportVerify, "verify", false, "Verify the wallet can be imported, but do not import it")
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
e2wallet "github.com/wealdtech/go-eth2-wallet"
|
||||
)
|
||||
|
||||
var walletListCmd = &cobra.Command{
|
||||
@@ -36,7 +36,7 @@ In quiet mode this will return 0 if any wallets are found, otherwise 1.`,
|
||||
if remote {
|
||||
die("Remote wallets cannot be listed")
|
||||
} else {
|
||||
for w := range wallet.Wallets() {
|
||||
for w := range e2wallet.Wallets() {
|
||||
walletsFound = true
|
||||
outputIf(!quiet && !verbose, w.Name())
|
||||
outputIf(verbose, fmt.Sprintf("%s\n\tUUID:\t\t%s", w.Name(), w.ID().String()))
|
||||
|
||||
@@ -34,14 +34,14 @@ In quiet mode this will return 0 if the wallet is a hierarchical deterministic w
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
assert(!remote, "wallet seed not available with remote wallets")
|
||||
assert(walletWallet != "", "--wallet is required")
|
||||
assert(rootWalletPassphrase != "", "--walletpassphrase is required")
|
||||
assert(getWalletPassphrase() != "", "--walletpassphrase is required")
|
||||
|
||||
wallet, err := walletFromPath(walletWallet)
|
||||
errCheck(err, "Failed to access wallet")
|
||||
_, ok := wallet.(types.WalletKeyProvider)
|
||||
assert(ok, fmt.Sprintf("wallets of type %q do not have a seed", wallet.Type()))
|
||||
|
||||
err = wallet.Unlock([]byte(rootWalletPassphrase))
|
||||
err = wallet.Unlock([]byte(getWalletPassphrase()))
|
||||
errCheck(err, "Failed to unlock wallet")
|
||||
seed, err := wallet.(types.WalletKeyProvider).Key()
|
||||
errCheck(err, "Failed to obtain wallet key")
|
||||
|
||||
@@ -13,3 +13,21 @@ sudo apt install build-essential libstdc++6
|
||||
|
||||
and then try to install `ethdo` again.
|
||||
|
||||
## ethdo not found after installing
|
||||
|
||||
This is usually due to an incorrectly set path. Go installs its binaries (such as `ethdo`) in a particular location. The defaults are:
|
||||
|
||||
- Linux, Mac: `$HOME/go/bin`
|
||||
- Windows: `%USERPROFILE%\go\bin`
|
||||
|
||||
You must add these paths to be able to access `ethdo`. To add the path on linux or OSX type:
|
||||
|
||||
```sh
|
||||
export PATH=$PATH:$(go env GOPATH)/bin
|
||||
```
|
||||
|
||||
and on Windows type:
|
||||
|
||||
```sh
|
||||
setx /M path "%PATH%;%USERPROFILE%\go\bin"
|
||||
```
|
||||
|
||||
@@ -69,6 +69,7 @@ $ ethdo wallet export --wallet="Personal wallet" --exportpassphrase="my export s
|
||||
`ethdo wallet import` imports a wallet and all of its accounts exported by `ethdo wallet export`. Options for importing a wallet include:
|
||||
- `importdata`: the data exported by `ethdo wallet export`
|
||||
- `importpassphrase`: the passphrase that was provided to `ethdo wallet export` to encrypt the data
|
||||
- `verify`: confirm information about the wallet import without importing it
|
||||
|
||||
```sh
|
||||
$ ethdo wallet import --importdata="0x01c7a27ad40d45b4ae5be5f..." --importpassphrase="my export secret"
|
||||
|
||||
35
go.mod
35
go.mod
@@ -4,40 +4,41 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
||||
github.com/ferranbt/fastssz v0.0.0-20200514094935-99fccaf93472 // 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/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/mapstructure v1.3.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.3.2 // indirect
|
||||
github.com/pelletier/go-toml v1.8.0 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200528232825-cf963636d24e
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200322041314-62c2aee71669
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200619200018-174e3b90d786
|
||||
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.2.2 // indirect
|
||||
github.com/spf13/afero v1.3.0 // 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 // indirect
|
||||
github.com/spf13/viper v1.7.0
|
||||
github.com/tyler-smith/go-bip39 v1.0.2
|
||||
github.com/wealdtech/eth2-signer-api v1.3.0
|
||||
github.com/wealdtech/eth2-signer-api v1.4.0
|
||||
github.com/wealdtech/go-bytesutil v1.1.1
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.0
|
||||
github.com/wealdtech/go-eth2-util v1.2.0
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.0
|
||||
github.com/wealdtech/go-ecodec v1.1.0
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.2
|
||||
github.com/wealdtech/go-eth2-util v1.2.2
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.2
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.0.0
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.0
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.0
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.0
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.0
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.1.0
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.3
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.2
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.2
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.2
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.2.0
|
||||
github.com/wealdtech/go-string2eth v1.1.0
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 // indirect
|
||||
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b // indirect
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200620020550-bd6e04640131 // indirect
|
||||
google.golang.org/grpc v1.29.1
|
||||
gopkg.in/ini.v1 v1.57.0 // indirect
|
||||
)
|
||||
|
||||
163
go.sum
163
go.sum
@@ -26,12 +26,10 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aws/aws-sdk-go v1.30.15 h1:Sd8QDVzzE8Sl+xNccmdj0HwMrFowv6uVUx9tGsCE1ZE=
|
||||
github.com/aws/aws-sdk-go v1.30.15/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.30.25 h1:89NXJkfpjnMEnsxkP8MVX+LDsoiLCSqevraLb5y4Mjk=
|
||||
github.com/aws/aws-sdk-go v1.30.25/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.31.7 h1:TCA+pXKvzDMA3vVqhK21cCy5GarC8pTQb/DrVOWI3iY=
|
||||
github.com/aws/aws-sdk-go v1.31.7/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.32.6 h1:HoswAabUWgnrUF7X/9dr4WRgrr8DyscxXvTDm7Qw/5c=
|
||||
github.com/aws/aws-sdk-go v1.32.6/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=
|
||||
@@ -64,8 +62,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/ferranbt/fastssz v0.0.0-20200415074633-b062b680417b h1:CxaMtGnKgr9Ar2xLMVddPhnMwYLDsY56w/LxQ/wnsKA=
|
||||
github.com/ferranbt/fastssz v0.0.0-20200415074633-b062b680417b/go.mod h1:LlFXPmgrgVYsuoFDwV8rDJ9tvt1pLQdjKvU1b5IRES0=
|
||||
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/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
@@ -101,8 +97,6 @@ github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaW
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4 h1:+EOh4OY6tjM6ZueeUKinl1f0U2820HzQOuf1iqMnsks=
|
||||
github.com/golang/protobuf v1.4.0-rc.4/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
@@ -136,10 +130,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.12.2/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.5 h1:aiLxiiVzAXb7wb3lAmubA69IokWOoUNe+E7TdGKh8yw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.5/go.mod h1:UJ0EZAp832vCd54Wev9N1BMKEyvcZ5+IM0AwDrnlkEc=
|
||||
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/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
@@ -163,12 +154,10 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200428020417-6dd0e5634b87 h1:23l9wMlu3iMRg5PwI4wuA7sbR77GSF+rnwI0Z/Y4IPc=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200428020417-6dd0e5634b87/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200508110836-07e8f416e478 h1:UMIHMlIgtPmh96SmXdDiEDRbQ2NSroxBQzpEknueoG4=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200508110836-07e8f416e478/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200522010937-01d282b5380b h1:mu+F5uA3Y68oB6KXZqWlASKMetbNufhQx2stMI+sD+Y=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200522010937-01d282b5380b/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200618063237-4d3c66ab099d h1:ZLYUT27mOTH+ogU6Sov6xs1zqYi9cRJ6ksBEELXC8R4=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200618063237-4d3c66ab099d/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200621110855-298ffb6847bc h1:1ANh6XSZu8Quo4d03TDFhqiFjgUicMdavTtPm6B+RfE=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200621110855-298ffb6847bc/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||
@@ -183,6 +172,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@@ -210,18 +200,14 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.3.0 h1:iDwIio/3gk2QtLLEsqU5lInaMzos0hDTz8a6lazSFVw=
|
||||
github.com/mitchellh/mapstructure v1.3.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
|
||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=
|
||||
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -229,6 +215,7 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
@@ -245,15 +232,21 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
|
||||
github.com/protolambda/zssz v0.1.3/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag=
|
||||
github.com/protolambda/zssz v0.1.4 h1:4jkt8sqwhOVR8B1JebREU/gVX0Ply4GypsV8+RWrDuw=
|
||||
github.com/protolambda/zssz v0.1.4/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200511212457-3444ffb75440 h1:plalLbsEdAKKURjR7u+JUsgD2tyxSa/yitdMyqaWY4E=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200511212457-3444ffb75440/go.mod h1:5OkRN6UmvgtP+kIewitcEKC7S5KOzLOGtya/Tz+HBns=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200528232825-cf963636d24e h1:AvUpoH1sezZmue9NKyHxk7HpD6ajzLVh9m6YCyFwgSw=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200528232825-cf963636d24e/go.mod h1:UQrDJAnxOPXPxvzECD1fmiKAw84LIYcoX2Op7KEUfGk=
|
||||
github.com/protolambda/zssz v0.1.5 h1:7fjJjissZIIaa2QcvmhS/pZISMX21zVITt49sW1ouek=
|
||||
github.com/protolambda/zssz v0.1.5/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200619200018-174e3b90d786 h1:bJiOTV2sYykacsxViyRltztQY0DyjT/uFoVRZkEaxsY=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200619200018-174e3b90d786/go.mod h1:rs05kpTfWKl0KflsBWzBQFstoyPFMTWQTbxSAyGHe78=
|
||||
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 h1:cX6YRZnZ9sgMqM5U14llxUiXVNJ3u07Res1IIjTOgtI=
|
||||
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-20200617184054-d57b8c55ea83 h1:HujNkiChDhXhDOlpYtwJu42VFn5Vp1yt+QAEJy03RjU=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200617184054-d57b8c55ea83/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200618145306-2ae0807bef65 h1:hJfAWrlxx7SKpn4S/h2JGl2HHwA1a2wSS3HAzzZ0F+U=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200618145306-2ae0807bef65/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963 h1:Th5ufPIaL5s/7i3gXHTgiTwfsUhWDP/PwFRiI6qV6v0=
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963/go.mod h1:VecIJZrewdAuhVckySLFt2wAAHRME934bSDurP8ftkc=
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200612203617-6d5c9aa213ae h1:7qd0Af1ozWKBU3c93YW2RH+/09hJns9+ftqWUZyts9c=
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200612203617-6d5c9aa213ae/go.mod h1:VecIJZrewdAuhVckySLFt2wAAHRME934bSDurP8ftkc=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@@ -274,8 +267,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk=
|
||||
github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
@@ -306,52 +299,54 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/wealdtech/eth2-signer-api v1.3.0 h1:Fs0GfrdhboBKW7zaMvIvUHJaOB1ibpAmRG3lkB53in4=
|
||||
github.com/wealdtech/eth2-signer-api v1.3.0/go.mod h1:H8OpAoTBl6CaBvZEnhxWDjjWXNc3kwVFKWMAZd6sHlk=
|
||||
github.com/wealdtech/eth2-signer-api v1.4.0 h1:y/Bg2SfTT5nGfwyIz7mILWE+BokeDOUE1eZ0jVqPBeA=
|
||||
github.com/wealdtech/eth2-signer-api v1.4.0/go.mod h1:5wlLQ7NO7nbXo3znJOwIWHN8S4C3xHcZ0uOg9Ue4mvg=
|
||||
github.com/wealdtech/go-bytesutil v1.0.1 h1:6xzMM+VEHf5WNh1PsIFcRwScgcno+CP8Rw1rGvT6Cew=
|
||||
github.com/wealdtech/go-bytesutil v1.0.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s=
|
||||
github.com/wealdtech/go-bytesutil v1.1.1 h1:ocEg3Ke2GkZ4vQw5lp46rmO+pfqCCTgq35gqOy8JKVc=
|
||||
github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s=
|
||||
github.com/wealdtech/go-ecodec v1.1.0 h1:yggrTSckcPJRaxxOxQF7FPm21kgE8WA6+f5jdq5Kr8o=
|
||||
github.com/wealdtech/go-ecodec v1.1.0/go.mod h1:PSdBFEB6cltdT7V4E1jbboufMZTZXcQOKG/2PeEjKK4=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.3.1 h1:2KSUzducArOynCL2prRf4vWU5GjwaPSnSN9oqNgf+dQ=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.3.1/go.mod h1:FubkGSavaa+rvmHDMTUVoPdFh00wKg0k5QPW6G52mhw=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.0 h1:1sFuNENHka/BYHY9F6f1gQqE3dCCQxKODEHc+3RK8fI=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.0/go.mod h1:azyBA/qeMC5sa3BuNm3spje96rHMmW0dyZkJzog8NIk=
|
||||
github.com/wealdtech/go-eth2-util v1.1.5 h1:4OPbf2yaEQmqDmOIU6UKBfhKTPNZ7skU4lPhueBLx8o=
|
||||
github.com/wealdtech/go-eth2-util v1.1.5/go.mod h1:wYYmtc9KpQQAaAzWjXSPLgtsJMkoDAmTNN0h6uj3RCA=
|
||||
github.com/wealdtech/go-eth2-util v1.2.0 h1:ineLDTrFN8zpb7+R2lWrm1HMmTFxlirtcCsppKoVix0=
|
||||
github.com/wealdtech/go-eth2-util v1.2.0/go.mod h1:UNDR21GfVCq429DP+RyFVl2iKkHaMI8B8r7F44NECkU=
|
||||
github.com/wealdtech/go-eth2-wallet v1.9.4 h1:9XFM1Y7dsyrgNFFCnE3Gd00PAsrpob70SAQqHSPmsBU=
|
||||
github.com/wealdtech/go-eth2-wallet v1.9.4/go.mod h1:UGd1bAPDEtP+UrFjj3HCbip7jggFGDIQoeGw8/XHMvo=
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.0 h1:WX6wZQvGwXtu3+L9d9HCW7WWrw6522ur2XiPI6W1lYg=
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.0/go.mod h1:vqB02WIpP0SL+Ug8p4Q8BqVkwPyO1SEarOHAqppjqHE=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.1 h1:8Brj7MvJk3EUkYBQ8A5bWLleIc3/W1Jr1tApzTXtW1A=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.1/go.mod h1:gqvLvmdw5CaDJUmClvmLRp653Ugf0VlGO9ZoWdi7mLY=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.2 h1:EkOvP8Ma0Ru7WIh0haoST97rc0PYm2AJpuWG1HzgfCI=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.4.2/go.mod h1:hhKa4ZFaNU2fwUjEh8GYr8wKg5D1W4QyxZ3xpsb/2hw=
|
||||
github.com/wealdtech/go-eth2-util v1.2.1 h1:ReY7XWgTgXf1Fi9MoRLodD1H7rCVMFHMHJKHXoHYNQE=
|
||||
github.com/wealdtech/go-eth2-util v1.2.1/go.mod h1:PPhVwXc9gv1omyf/Ik4h97jL77HdCEzlEUX4P5wDqQw=
|
||||
github.com/wealdtech/go-eth2-util v1.2.2 h1:LALunpMSJFvu89RHS1zl6RjZ52805utRvd12RtquB54=
|
||||
github.com/wealdtech/go-eth2-util v1.2.2/go.mod h1:R3VlTd69B2Jf58s62ChcyXt11ZK1/36CTplTuyR/6dE=
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.1 h1:Inp0Mk8noUoJIMSBc+W+Si+WhPvs04pcTJrcMuYrNzM=
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.1/go.mod h1:nB3aarecFrhJLXjKhl+N6jhnbtymb/yAQQ9n1AankR8=
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.2 h1:oUgi6Ih5fA9thhIipzXMSaLkiwDQXwT8q3bCOLpCr7s=
|
||||
github.com/wealdtech/go-eth2-wallet v1.10.2/go.mod h1:8H9pgp5K7X1kU1cJMS/B3DrMZF74ZlwBThownrcRYgk=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.0.0 h1:IcpS4VpXhYz+TVupB5n6C6IQzaKwG+Rc8nvgCa/da4c=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.0.0/go.mod h1:X8WRO5hEwbjx8ZOqoRmtS1ngyflKs25GkP7qGv7yOqE=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.0.3/go.mod h1:nNNZNXCP1BrJCu1hLlFUCAQBvCInD4zwE7eslf2U5XQ=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.0.4 h1:/nBbza+ZPY1dn455AnZRRpIEjeUmTRQCS5QdKf6nhrg=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.0.4/go.mod h1:nNNZNXCP1BrJCu1hLlFUCAQBvCInD4zwE7eslf2U5XQ=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.0 h1:gB3wFIovLgS7GVNU81mpCgekfUmGm8H/f6WtG6xqEJw=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.0/go.mod h1:6voi4JG8G7inZ1bGx41xL2z+YJZc6rr6echT0AUtUdw=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.0.3 h1:NfeWHtyjtZt3hmVA7kysNf2w+cB9Y82w6Cv4zWbFRSk=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.0.3/go.mod h1:RDXAfay+PL+apCVLnVtWBUb183m4uug93FBZ0c2cVaw=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.0 h1:d8JOfWRd39c7w3BLud3eErJH4xSa3tdrMOZjeFXXg0c=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.0/go.mod h1:DTnJWJ5/O56pxqXAR53H4t8K80Rrtop5pmTSOc5tCFA=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.7.3 h1:2nMDDRULzSSa6LCk3044d5J4rXi2HX61nRLyGLXGI3M=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.7.3/go.mod h1:HE1JcXUhWUtJ7F/APzSI/ZTfXjdxbQ15CDe6L0mjtaQ=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.0 h1:iNwHjCj9zGpybEO9URx7AmHWET1PrnkfKcpLYUyFFxw=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.0/go.mod h1:qjU0CZ12duEMCTGORb4bjeUncvy5vUSTVOtwI+/A4A8=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.6.3 h1:SD5tsdj9pRdsfWbhpL09X6gDGO9rJvlI6lz2cxpdfA4=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.6.3/go.mod h1:wS8sqBuIcn9QuLR1VlV7JaSKrFiNOMSPDDBYtWWe98c=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.0 h1:aYMCj2WMCLPbXcITrXx22+P5vhfRW0I1Y1NuJxp5XK0=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.0/go.mod h1:dT5tX+uTFI16qdt4On7KCmxx96V7xYn+vdUJUzPDdyo=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.3.3 h1:0cKttlJ5QONJ2ZndVLUVv3RhbEaSU0TKvOI2BIB9j60=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.3.3/go.mod h1:/tvALCsQ07lvqlU+IKKAdwYFYyjIO628bu/Ssv0JRv4=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.4.0/go.mod h1:F+CGazuwGZpxa+2nmr8T1zC3rC0mTTZyO3UFmimNwSs=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.0.2 h1:Lhwne1gRUp961fD+eoWrgDbZF5rHwosI2LS5pIdX4Yc=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.0.2/go.mod h1:d7WZ9WvtL3vGSHtSh/jnVh4YO93verLL1dRW2NK5sN4=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.1.0 h1:Zl36EPHI/4SYgjnx+mmYRVKLDdrFpWkT39ClRKYiL7U=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.1.0/go.mod h1:6mlZXBwEeyeAKj22OF+b3E0RFnwoOBM/BXIdAo5QG2M=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.1 h1:L4L445Uvd1Uw+Af4I9Bu29e8OCJOhYgN9lKmzjRhNwQ=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.1/go.mod h1:1IC4wOz0SIySMld5tRi4Vb0cpe7tOwqP0hS2LsrGJ34=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.2 h1:Rrpit3nuxKOUKE7poDcs2x9MZOaodd+mact+KL+/S98=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.2/go.mod h1:STigKib4ZSefVvJjx88V2QpUGaoyUE1TiupcpsHpvKE=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.3 h1:JJwCr0NfMnS0xI7gSE+GqENXBxNIfySoC3NtxK8dG1o=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.1.3/go.mod h1:STigKib4ZSefVvJjx88V2QpUGaoyUE1TiupcpsHpvKE=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.1 h1:ziEpwVutiAdP0+LsVsC+nlfhgc4kwQAaUNpPz/rJ+CM=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.1/go.mod h1:IEWuITdIQTImjHju0crCJkvGus05n1HmoMZmO+EDil8=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.2 h1:j3cKJ02Js83ygvZOmbb+GA2iSCAQDYhY5nNdm7anzjQ=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.1.2/go.mod h1:IssxoHII0ewO1VysMfCmdJP1D00tRhRhXIhhaEXIOVE=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.1 h1:HlJZp6xyJ14nd+IFPV8TvtJyumKe0RbHIG+PKEeqxTk=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.1/go.mod h1:C4m7Xv0gCgb7XUwCxxJp+45YX8Qfn1vrE0UOSHD/QfE=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.2 h1:Z4Pw7/Mlp6jJLoJnhgov8M1011HP/Pb3YYqcdYGCy6Q=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.15.2/go.mod h1:GSMbVCewjbxRrw32m6YCd9DOzCRjAXB3qUOQnr58JEs=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.1 h1:EFX2SfWQ9zi7lJ/Jy1WsVBHQuTdGp8Z/Q+uuxNFpBQA=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.1/go.mod h1:LDmyvkgcaY4rGnGBQwf1uc02m0dMSebm9nRHx7feVHU=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.2 h1:a7GWfFd139CODvvkuTbRIuRwAAjb55sFDGRh177KXGk=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.7.2/go.mod h1:VWvXScZKUWHbhQpadLX8Yj+mc8U/i4zGthQJee+o3xg=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.4.1 h1:uw2Kqqfcr7NMBHM0x/JpKkr1XpKr+zeASOXhOV6xobk=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.4.1/go.mod h1:psrxFO0Df0R+2iGD8Wdvb5AAYBY7zx+4/qtULaJ57IY=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.4.2 h1:GvG3ZuzxbqFjGUaGoa8Tz7XbPlDA33G6nHQbSZInC3g=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.4.2/go.mod h1:+TbqLmJuT98PWi/xW1bp5nwZbKz+SIJYVh/+NUkmnb4=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.1.1 h1:RGvhM7C85ptEdVsCDQNt+fJrF0SrMnUb0gkgtU75ifI=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.1.1/go.mod h1:608wNFKrwPzwjWeQVRE/rHnHkrRmmTCUhFg2/Bgkbvs=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.2.0 h1:SfoBlW2LYjW05uHhnTZaezX37gbRsp+VYtxWT6SeAME=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.2.0/go.mod h1:XEvrlKFnHLbg1tj4Dep76XKASeS13TBpvdeXmvLiH+k=
|
||||
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=
|
||||
@@ -369,14 +364,13 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59 h1:PyXRxSVbvzDGuqYXjHndV7xDzJ7w2K8KD9Ef8GB7KOE=
|
||||
golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc h1:ZGI/fILM2+ueot/UixBSoj9188jCAxVHEZEGhqq67I4=
|
||||
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/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=
|
||||
@@ -413,10 +407,10 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f h1:QBjCr1Fz5kw158VqdE9JfI9cJnl/ymnJWAdMuinqL7Y=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b h1:IYiJPiJfzktmDAO1HQiwjMjwjlYKHAL7KzeD544RJPs=
|
||||
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
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=
|
||||
@@ -443,16 +437,18 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200427175716-29b57079015a h1:08u6b1caTT9MQY4wSbmsd4Ulm6DmgNYnbImBuZjGJow=
|
||||
golang.org/x/sys v0.0.0-20200427175716-29b57079015a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25 h1:OKbAoGs4fGM5cPLlVQLZGYkFC8OnOfgo6tt0Smf9XhM=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200620081246-981b61492c35 h1:wb/9mP8eUAmHfkM8RmpeLq6nUA7c2i5+bQOtcDftjaE=
|
||||
golang.org/x/sys v0.0.0-20200620081246-981b61492c35/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 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -498,12 +494,12 @@ google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBr
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380 h1:xriR1EgvKfkKxIoU2uUvrMVl+H26359loFFUleSMXFo=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200528191852-705c0b31589b h1:nl5tymnV+50ACFZUDAP+xFCe3Zh3SWdMDx+ernZSKNA=
|
||||
google.golang.org/genproto v0.0.0-20200528191852-705c0b31589b/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200620020550-bd6e04640131 h1:IXNofpkLhv80L3TJQvj2YQLnMHZgAktycswvtXwQiRk=
|
||||
google.golang.org/genproto v0.0.0-20200620020550-bd6e04640131/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
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 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0=
|
||||
@@ -515,16 +511,12 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
|
||||
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
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/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=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.20.1 h1:ESRXHgpUBG5D2I5mmsQIyYxB/tQIZfSZ8wLyFDf/N/U=
|
||||
google.golang.org/protobuf v1.20.1/go.mod h1:KqelGeouBkcbcuB3HCk4/YH2tmNLk6YSWA5LIWeI/lY=
|
||||
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
|
||||
@@ -541,8 +533,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.56.0 h1:DPMeDvGTM54DXbPkVIZsp19fp/I2K7zwA/itHYHKo8Y=
|
||||
gopkg.in/ini.v1 v1.56.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/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
@@ -552,10 +542,9 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -91,6 +91,39 @@ func FetchLatestFilledSlot(conn *grpc.ClientConn) (uint64, error) {
|
||||
return chainHead.HeadSlot, nil
|
||||
}
|
||||
|
||||
// FetchValidatorCommittees fetches the validator committees for a given epoch.
|
||||
func FetchValidatorCommittees(conn *grpc.ClientConn, epoch uint64) (map[uint64][][]uint64, error) {
|
||||
if conn == nil {
|
||||
return nil, errors.New("no connection to beacon node")
|
||||
}
|
||||
beaconClient := ethpb.NewBeaconChainClient(conn)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
|
||||
defer cancel()
|
||||
|
||||
req := ðpb.ListCommitteesRequest{
|
||||
QueryFilter: ðpb.ListCommitteesRequest_Epoch{
|
||||
Epoch: epoch,
|
||||
},
|
||||
}
|
||||
resp, err := beaconClient.ListBeaconCommittees(ctx, req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain committees")
|
||||
}
|
||||
|
||||
res := make(map[uint64][][]uint64)
|
||||
for slot, committees := range resp.Committees {
|
||||
res[slot] = make([][]uint64, len(resp.Committees))
|
||||
for i, committee := range committees.Committees {
|
||||
res[slot][uint64(i)] = make([]uint64, len(committee.ValidatorIndices))
|
||||
indices := make([]uint64, len(committee.ValidatorIndices))
|
||||
copy(indices, committee.ValidatorIndices)
|
||||
res[slot][uint64(i)] = indices
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// FetchValidator fetches the validator definition from the beacon node.
|
||||
func FetchValidator(conn *grpc.ClientConn, account wtypes.Account) (*ethpb.Validator, error) {
|
||||
if conn == nil {
|
||||
@@ -125,6 +158,54 @@ func FetchValidatorByIndex(conn *grpc.ClientConn, index uint64) (*ethpb.Validato
|
||||
return beaconClient.GetValidator(ctx, req)
|
||||
}
|
||||
|
||||
// FetchValidatorBalance fetches the validator balance from the beacon node.
|
||||
func FetchValidatorBalance(conn *grpc.ClientConn, account wtypes.Account) (uint64, error) {
|
||||
if conn == nil {
|
||||
return 0, errors.New("no connection to beacon node")
|
||||
}
|
||||
beaconClient := ethpb.NewBeaconChainClient(conn)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
|
||||
defer cancel()
|
||||
|
||||
res, err := beaconClient.ListValidatorBalances(ctx, ðpb.ListValidatorBalancesRequest{
|
||||
PublicKeys: [][]byte{account.PublicKey().Marshal()},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(res.Balances) == 0 {
|
||||
return 0, errors.New("unknown validator")
|
||||
}
|
||||
return res.Balances[0].Balance, nil
|
||||
}
|
||||
|
||||
// FetchValidatorPerformance fetches the validator performance from the beacon node.
|
||||
func FetchValidatorPerformance(conn *grpc.ClientConn, account wtypes.Account) (bool, bool, bool, uint64, int64, error) {
|
||||
if conn == nil {
|
||||
return false, false, false, 0, 0, errors.New("no connection to beacon node")
|
||||
}
|
||||
beaconClient := ethpb.NewBeaconChainClient(conn)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout"))
|
||||
defer cancel()
|
||||
|
||||
req := ðpb.ValidatorPerformanceRequest{
|
||||
PublicKeys: [][]byte{account.PublicKey().Marshal()},
|
||||
}
|
||||
res, err := beaconClient.GetValidatorPerformance(ctx, req)
|
||||
if err != nil {
|
||||
return false, false, false, 0, 0, err
|
||||
}
|
||||
if len(res.InclusionDistances) == 0 {
|
||||
return false, false, false, 0, 0, errors.New("unknown validator")
|
||||
}
|
||||
return res.CorrectlyVotedHead[0],
|
||||
res.CorrectlyVotedSource[0],
|
||||
res.CorrectlyVotedTarget[0],
|
||||
res.InclusionDistances[0],
|
||||
int64(res.BalancesAfterEpochTransition[0]) - int64(res.BalancesBeforeEpochTransition[0]),
|
||||
err
|
||||
}
|
||||
|
||||
// FetchValidatorInfo fetches current validator info from the beacon node.
|
||||
func FetchValidatorInfo(conn *grpc.ClientConn, account wtypes.Account) (*ethpb.ValidatorInfo, error) {
|
||||
if conn == nil {
|
||||
|
||||
Reference in New Issue
Block a user