github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/evm2cm.go (about)

     1  package evm
     2  
     3  import (
     4  	"encoding/hex"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/ethereum/go-ethereum/common"
     9  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/baseapp"
    10  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    11  	"github.com/fibonacci-chain/fbc/x/evm/types"
    12  )
    13  
    14  var (
    15  	ErrNoMatchParam = errors.New("no match the abi param")
    16  	sysABIParser    *types.ABI
    17  )
    18  
    19  const (
    20  	sysContractABI            = `[{"inputs":[{"internalType":"string","name":"data","type":"string"}],"name":"invoke","outputs":[],"stateMutability":"nonpayable","type":"function"}]`
    21  	sysContractInvokeFunction = "invoke"
    22  )
    23  
    24  func init() {
    25  	RegisterHandle()
    26  	var err error
    27  	sysABIParser, err = types.NewABI(sysContractABI)
    28  	if err != nil {
    29  		panic(fmt.Sprintln("init system abi fail", err.Error()))
    30  	}
    31  }
    32  
    33  func RegisterHandle() {
    34  	baseapp.RegisterEvmResultConverter(EncodeResultData)
    35  	baseapp.RegisterEvmConvertJudge(EvmConvertJudge)
    36  	baseapp.RegisterEvmParamParse(EvmParamParse)
    37  }
    38  
    39  func EvmParamParse(msg sdk.Msg) ([]byte, error) {
    40  	evmTx, ok := msg.(*types.MsgEthereumTx)
    41  	if !ok {
    42  		return nil, fmt.Errorf("msg type is not a MsgEthereumTx")
    43  	}
    44  	value, err := ParseContractParam(evmTx.Data.Payload)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  	return value, nil
    49  }
    50  
    51  func EvmConvertJudge(msg sdk.Msg) ([]byte, bool) {
    52  	if msg.Route() != types.ModuleName {
    53  		return nil, false
    54  	}
    55  	evmTx, ok := msg.(*types.MsgEthereumTx)
    56  	if !ok || evmTx.Data.Recipient == nil {
    57  		return nil, false
    58  	}
    59  	if !sysABIParser.IsMatchFunction(sysContractInvokeFunction, evmTx.Data.Payload) {
    60  		return nil, false
    61  	}
    62  	return evmTx.Data.Recipient[:], true
    63  }
    64  
    65  func ParseContractParam(input []byte) ([]byte, error) {
    66  	res, err := sysABIParser.DecodeInputParam(sysContractInvokeFunction, input)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	if len(res) != 1 {
    71  		return nil, ErrNoMatchParam
    72  	}
    73  	v, ok := res[0].(string)
    74  	if !ok {
    75  		return nil, ErrNoMatchParam
    76  	}
    77  	return DecodeParam([]byte(v))
    78  }
    79  
    80  func DecodeParam(data []byte) ([]byte, error) {
    81  	value, err := hex.DecodeString(string(data)) // this is json fmt
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	return value, nil
    86  }
    87  
    88  func EncodeResultData(txHash, data []byte) ([]byte, error) {
    89  	ethHash := common.BytesToHash(txHash)
    90  	return types.EncodeResultData(&types.ResultData{Ret: data, TxHash: ethHash})
    91  }
    92  
    93  func IsMatchSystemContractFunction(data []byte) bool {
    94  	return sysABIParser.IsMatchFunction(sysContractInvokeFunction, data)
    95  }