forked from cerc-io/laconicd-deprecated
f2549a7b76
* build(deps): bump github.com/cosmos/cosmos-sdk from 0.46.6 to 0.46.7 (#1551) Bumps [github.com/cosmos/cosmos-sdk](https://github.com/cosmos/cosmos-sdk) from 0.46.6 to 0.46.7. - [Release notes](https://github.com/cosmos/cosmos-sdk/releases) - [Changelog](https://github.com/cosmos/cosmos-sdk/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/cosmos-sdk/compare/v0.46.6...v0.46.7) --- updated-dependencies: - dependency-name: github.com/cosmos/cosmos-sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/cosmos/ibc-go/v5 from 5.1.0 to 5.2.0 (#1564) Bumps [github.com/cosmos/ibc-go/v5](https://github.com/cosmos/ibc-go) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/v5.2.0/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v5.1.0...v5.2.0) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * make missing key error message during SendTransaction more verbose (#1563) Co-authored-by: 4rgon4ut <59182467+4rgon4ut@users.noreply.github.com> * debug(app): add flag to disable optimized build for remote debugging (#1549) Co-authored-by: MalteHerrmann <42640438+MalteHerrmann@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Problem: personal_newAccount don't work (#1561) fix the internal parameter. * fix(ante): fix reCheckTx gas wanted (#1566) * fix(abci): fix reCheckTx gas wanted' * fix(ante): add changelog entry * fix(cli): fix Ledger signature algorithm verification (#1550) * fix: update Ledger default algorithm to `EthSecp256k1` * fix ledger signing algo validation * changelog Co-authored-by: Freddy Caceres <facs95@gmail.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * update changelog Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: 4rgon4ut <59182467+4rgon4ut@users.noreply.github.com> Co-authored-by: Tomas Guerra <54514587+GAtom22@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> Co-authored-by: yihuang <huang@crypto.com> Co-authored-by: Austin Chandra <austinchandra@berkeley.edu> Co-authored-by: Freddy Caceres <facs95@gmail.com>
153 lines
5.1 KiB
Go
153 lines
5.1 KiB
Go
package backend
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
|
|
errorsmod "cosmossdk.io/errors"
|
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
|
|
|
evmtypes "github.com/evmos/ethermint/x/evm/types"
|
|
)
|
|
|
|
// SendTransaction sends transaction based on received args using Node's key to sign it
|
|
func (b *Backend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) {
|
|
// Look up the wallet containing the requested signer
|
|
_, err := b.clientCtx.Keyring.KeyByAddress(sdk.AccAddress(args.GetFrom().Bytes()))
|
|
if err != nil {
|
|
b.logger.Error("failed to find key in keyring", "address", args.GetFrom(), "error", err.Error())
|
|
return common.Hash{}, fmt.Errorf("failed to find key in the node's keyring; %s; %s", keystore.ErrNoMatch, err.Error())
|
|
}
|
|
|
|
if args.ChainID != nil && (b.chainID).Cmp((*big.Int)(args.ChainID)) != 0 {
|
|
return common.Hash{}, fmt.Errorf("chainId does not match node's (have=%v, want=%v)", args.ChainID, (*hexutil.Big)(b.chainID))
|
|
}
|
|
|
|
args, err = b.SetTxDefaults(args)
|
|
if err != nil {
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
msg := args.ToTransaction()
|
|
if err := msg.ValidateBasic(); err != nil {
|
|
b.logger.Debug("tx failed basic validation", "error", err.Error())
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
bn, err := b.BlockNumber()
|
|
if err != nil {
|
|
b.logger.Debug("failed to fetch latest block number", "error", err.Error())
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
signer := ethtypes.MakeSigner(b.ChainConfig(), new(big.Int).SetUint64(uint64(bn)))
|
|
|
|
// Sign transaction
|
|
if err := msg.Sign(signer, b.clientCtx.Keyring); err != nil {
|
|
b.logger.Debug("failed to sign tx", "error", err.Error())
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
// Query params to use the EVM denomination
|
|
res, err := b.queryClient.QueryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{})
|
|
if err != nil {
|
|
b.logger.Error("failed to query evm params", "error", err.Error())
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
// Assemble transaction from fields
|
|
tx, err := msg.BuildTx(b.clientCtx.TxConfig.NewTxBuilder(), res.Params.EvmDenom)
|
|
if err != nil {
|
|
b.logger.Error("build cosmos tx failed", "error", err.Error())
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
// Encode transaction by default Tx encoder
|
|
txEncoder := b.clientCtx.TxConfig.TxEncoder()
|
|
txBytes, err := txEncoder(tx)
|
|
if err != nil {
|
|
b.logger.Error("failed to encode eth tx using default encoder", "error", err.Error())
|
|
return common.Hash{}, err
|
|
}
|
|
|
|
ethTx := msg.AsTransaction()
|
|
|
|
// check the local node config in case unprotected txs are disabled
|
|
if !b.UnprotectedAllowed() && !ethTx.Protected() {
|
|
// Ensure only eip155 signed transactions are submitted if EIP155Required is set.
|
|
return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC")
|
|
}
|
|
|
|
txHash := ethTx.Hash()
|
|
|
|
// Broadcast transaction in sync mode (default)
|
|
// NOTE: If error is encountered on the node, the broadcast will not return an error
|
|
syncCtx := b.clientCtx.WithBroadcastMode(flags.BroadcastSync)
|
|
rsp, err := syncCtx.BroadcastTx(txBytes)
|
|
if rsp != nil && rsp.Code != 0 {
|
|
err = errorsmod.ABCIError(rsp.Codespace, rsp.Code, rsp.RawLog)
|
|
}
|
|
if err != nil {
|
|
b.logger.Error("failed to broadcast tx", "error", err.Error())
|
|
return txHash, err
|
|
}
|
|
|
|
// Return transaction hash
|
|
return txHash, nil
|
|
}
|
|
|
|
// Sign signs the provided data using the private key of address via Geth's signature standard.
|
|
func (b *Backend) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) {
|
|
from := sdk.AccAddress(address.Bytes())
|
|
|
|
_, err := b.clientCtx.Keyring.KeyByAddress(from)
|
|
if err != nil {
|
|
b.logger.Error("failed to find key in keyring", "address", address.String())
|
|
return nil, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
|
|
}
|
|
|
|
// Sign the requested hash with the wallet
|
|
signature, _, err := b.clientCtx.Keyring.SignByAddress(from, data)
|
|
if err != nil {
|
|
b.logger.Error("keyring.SignByAddress failed", "address", address.Hex())
|
|
return nil, err
|
|
}
|
|
|
|
signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
|
|
return signature, nil
|
|
}
|
|
|
|
// SignTypedData signs EIP-712 conformant typed data
|
|
func (b *Backend) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) {
|
|
from := sdk.AccAddress(address.Bytes())
|
|
|
|
_, err := b.clientCtx.Keyring.KeyByAddress(from)
|
|
if err != nil {
|
|
b.logger.Error("failed to find key in keyring", "address", address.String())
|
|
return nil, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
|
|
}
|
|
|
|
sigHash, _, err := apitypes.TypedDataAndHash(typedData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Sign the requested hash with the wallet
|
|
signature, _, err := b.clientCtx.Keyring.SignByAddress(from, sigHash)
|
|
if err != nil {
|
|
b.logger.Error("keyring.SignByAddress failed", "address", address.Hex())
|
|
return nil, err
|
|
}
|
|
|
|
signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
|
|
return signature, nil
|
|
}
|