-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement ecrecover command to fetch public key
- Loading branch information
Showing
9 changed files
with
609 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package ecrecover | ||
|
||
import ( | ||
_ "embed" | ||
"fmt" | ||
|
||
"github.com/maticnetwork/polygon-cli/util" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
//go:embed usage.md | ||
usage string | ||
|
||
rpcUrl string | ||
blockNumber int | ||
extraData string | ||
) | ||
|
||
var EcRecoverCmd = &cobra.Command{ | ||
Use: "ecrecover", | ||
Short: "Recovers and returns the public key of the signature", | ||
Long: usage, | ||
Args: cobra.NoArgs, | ||
PreRunE: func(cmd *cobra.Command, args []string) error { | ||
return checkFlags() | ||
}, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return ecrecover(cmd.Context()) | ||
}, | ||
} | ||
|
||
func init() { | ||
EcRecoverCmd.PersistentFlags().StringVarP(&rpcUrl, "rpc-url", "r", "http://localhost:8545", "The RPC endpoint url") | ||
EcRecoverCmd.PersistentFlags().IntVarP(&blockNumber, "block-number", "b", 0, "Block number to check the extra data for") | ||
EcRecoverCmd.PersistentFlags().StringVarP(&extraData, "extra-data", "e", "", "Raw extra data") | ||
} | ||
|
||
func checkFlags() (err error) { | ||
if err = util.ValidateUrl(rpcUrl); err != nil { | ||
return | ||
} | ||
|
||
if blockNumber <= 0 { | ||
return fmt.Errorf("block-number should be greater than 0") | ||
} | ||
|
||
// if extraData == "" { | ||
// return fmt.Errorf("block-number should be greater than 0") | ||
// } | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package ecrecover | ||
|
||
import ( | ||
"context" | ||
"crypto/ecdsa" | ||
"fmt" | ||
"math/big" | ||
|
||
_ "embed" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
ethcommon "github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
"github.com/ethereum/go-ethereum/ethclient" | ||
ethrpc "github.com/ethereum/go-ethereum/rpc" | ||
"github.com/maticnetwork/polygon-cli/util" | ||
|
||
"github.com/rs/zerolog/log" | ||
) | ||
|
||
func ecrecover(ctx context.Context) (common.Address, error) { | ||
rpc, err := ethrpc.DialContext(ctx, rpcUrl) | ||
if err != nil { | ||
log.Error().Err(err).Msg("Unable to dial rpc") | ||
return common.Address{}, err | ||
} | ||
|
||
ec := ethclient.NewClient(rpc) | ||
if _, err = ec.BlockNumber(ctx); err != nil { | ||
return common.Address{}, err | ||
} | ||
|
||
block, err := ec.BlockByNumber(ctx, big.NewInt(int64(blockNumber))) | ||
if err != nil { | ||
log.Error().Err(err).Msg("Unable to retrieve block") | ||
return common.Address{}, err | ||
} | ||
|
||
if len(block.Transactions()) == 0 { | ||
return common.Address{}, fmt.Errorf("no transaction to derive public key from") | ||
} | ||
|
||
signerBytes, err := util.Ecrecover(block) | ||
if err != nil { | ||
log.Error().Err(err).Msg("Unable to recover signature") | ||
return common.Address{}, err | ||
} | ||
signerAddress := ethcommon.BytesToAddress(signerBytes) | ||
|
||
chainID, err := ec.NetworkID(ctx) | ||
if err != nil { | ||
log.Fatal().Err(err).Msg("Failed to get network ID") | ||
} | ||
|
||
var publicKey *ecdsa.PublicKey | ||
for _, tx := range block.Transactions() { | ||
tx.Value() | ||
if msg, err := tx.AsMessage(types.LatestSignerForChainID(chainID), nil); err == nil { | ||
if msg.From().Hex() == signerAddress { | ||
publicKeyECDSA, err := crypto.SigToPub(signHash(msg), msg.Signature()) | ||
if err != nil { | ||
log.Fatal().Err(err).Msg("Failed to recover public key") | ||
} | ||
publicKey = publicKeyECDSA | ||
break | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
 | ||
|
||
If you're using the terminal UI and you'd like to be able to select text for copying, you might need to use a modifier key. | ||
|
||
If you're experiencing missing blocks, try adjusting the `--batch-size` and `--interval` flags so that you poll for more blocks or more frequently. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.