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

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"fmt"
     7  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
     8  	"math/big"
     9  	"math/bits"
    10  	"strings"
    11  	"sync"
    12  
    13  	"github.com/tendermint/go-amino"
    14  
    15  	ethcmn "github.com/ethereum/go-ethereum/common"
    16  	ethtypes "github.com/ethereum/go-ethereum/core/types"
    17  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    18  	"github.com/ethereum/go-ethereum/rlp"
    19  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    20  	"github.com/pkg/errors"
    21  	"golang.org/x/crypto/sha3"
    22  )
    23  
    24  type KV struct {
    25  	Key   []byte `json:"key"`
    26  	Value []byte `json:"value"`
    27  }
    28  
    29  // MarshalToAmino encode KV data to amino bytes
    30  func (k *KV) MarshalToAmino(cdc *amino.Codec) ([]byte, error) {
    31  	var buf bytes.Buffer
    32  	var err error
    33  	fieldKeysType := [2]byte{1<<3 | 2, 2<<3 | 2}
    34  	for pos := 1; pos <= 2; pos++ {
    35  		switch pos {
    36  		case 1:
    37  			if len(k.Key) == 0 {
    38  				break
    39  			}
    40  			err = buf.WriteByte(fieldKeysType[pos-1])
    41  			if err != nil {
    42  				return nil, err
    43  			}
    44  			err = amino.EncodeByteSliceToBuffer(&buf, k.Key)
    45  			if err != nil {
    46  				return nil, err
    47  			}
    48  
    49  		case 2:
    50  			if len(k.Value) == 0 {
    51  				break
    52  			}
    53  			err = buf.WriteByte(fieldKeysType[pos-1])
    54  			if err != nil {
    55  				return nil, err
    56  			}
    57  			err = amino.EncodeByteSliceToBuffer(&buf, k.Value)
    58  			if err != nil {
    59  				return nil, err
    60  			}
    61  
    62  		default:
    63  			panic("unreachable")
    64  		}
    65  	}
    66  	return buf.Bytes(), nil
    67  }
    68  
    69  // UnmarshalFromAmino unmarshal amino bytes to this object
    70  func (k *KV) UnmarshalFromAmino(_ *amino.Codec, data []byte) error {
    71  	var dataLen uint64 = 0
    72  	var subData []byte
    73  
    74  	for {
    75  		data = data[dataLen:]
    76  		if len(data) == 0 {
    77  			break
    78  		}
    79  		pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
    80  		if err != nil {
    81  			return err
    82  		}
    83  		data = data[1:]
    84  
    85  		if pbType == amino.Typ3_ByteLength {
    86  			var n int
    87  			dataLen, n, _ = amino.DecodeUvarint(data)
    88  
    89  			data = data[n:]
    90  			if len(data) < int(dataLen) {
    91  				return errors.New("not enough data")
    92  			}
    93  			subData = data[:dataLen]
    94  		}
    95  
    96  		switch pos {
    97  		case 1:
    98  			k.Key = make([]byte, len(subData))
    99  			copy(k.Key, subData)
   100  
   101  		case 2:
   102  			k.Value = make([]byte, len(subData))
   103  			copy(k.Value, subData)
   104  
   105  		default:
   106  			return fmt.Errorf("unexpect feild num %d", pos)
   107  		}
   108  	}
   109  	return nil
   110  }
   111  
   112  // GenerateEthAddress generates an Ethereum address.
   113  func GenerateEthAddress() ethcmn.Address {
   114  	priv, err := ethsecp256k1.GenerateKey()
   115  	if err != nil {
   116  		panic(err)
   117  	}
   118  
   119  	return ethcrypto.PubkeyToAddress(priv.ToECDSA().PublicKey)
   120  }
   121  
   122  // ValidateSigner attempts to validate a signer for a given slice of bytes over
   123  // which a signature and signer is given. An error is returned if address
   124  // derived from the signature and bytes signed does not match the given signer.
   125  func ValidateSigner(signBytes, sig []byte, signer ethcmn.Address) error {
   126  	pk, err := ethcrypto.SigToPub(signBytes, sig)
   127  
   128  	if err != nil {
   129  		return errors.Wrap(err, "failed to derive public key from signature")
   130  	} else if ethcrypto.PubkeyToAddress(*pk) != signer {
   131  		return fmt.Errorf("invalid signature for signer: %s", signer)
   132  	}
   133  
   134  	return nil
   135  }
   136  
   137  func rlpHash(x interface{}) (hash ethcmn.Hash) {
   138  	hasher := sha3.NewLegacyKeccak256()
   139  	_ = rlp.Encode(hasher, x)
   140  	_ = hasher.Sum(hash[:0])
   141  
   142  	return hash
   143  }
   144  
   145  func rlpHashTo(x interface{}, hash *ethcmn.Hash) {
   146  	hasher := keccakStatePool.Get().(ethcrypto.KeccakState)
   147  	defer keccakStatePool.Put(hasher)
   148  	hasher.Reset()
   149  
   150  	_ = rlp.Encode(hasher, x)
   151  	hasher.Read(hash[:])
   152  	return
   153  }
   154  
   155  // ResultData represents the data returned in an sdk.Result
   156  type ResultData struct {
   157  	ContractAddress ethcmn.Address  `json:"contract_address"`
   158  	Bloom           ethtypes.Bloom  `json:"bloom"`
   159  	Logs            []*ethtypes.Log `json:"logs"`
   160  	Ret             []byte          `json:"ret"`
   161  	TxHash          ethcmn.Hash     `json:"tx_hash"`
   162  }
   163  
   164  func UnmarshalEthLogFromAmino(data []byte) (*ethtypes.Log, error) {
   165  	var dataLen uint64 = 0
   166  	var subData []byte
   167  	log := &ethtypes.Log{}
   168  
   169  	for {
   170  		data = data[dataLen:]
   171  
   172  		if len(data) == 0 {
   173  			break
   174  		}
   175  
   176  		pos, aminoType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
   177  		if err != nil {
   178  			return nil, err
   179  		}
   180  		data = data[1:]
   181  
   182  		if aminoType == amino.Typ3_ByteLength {
   183  			var n int
   184  			dataLen, n, err = amino.DecodeUvarint(data)
   185  			if err != nil {
   186  				return nil, err
   187  			}
   188  
   189  			data = data[n:]
   190  			if len(data) < int(dataLen) {
   191  				return nil, fmt.Errorf("invalid data length: %d", dataLen)
   192  			}
   193  			subData = data[:dataLen]
   194  		}
   195  
   196  		switch pos {
   197  		case 1:
   198  			if int(dataLen) != ethcmn.AddressLength {
   199  				return nil, fmt.Errorf("invalid address length: %d", dataLen)
   200  			}
   201  			copy(log.Address[:], subData)
   202  		case 2:
   203  			if int(dataLen) != ethcmn.HashLength {
   204  				return nil, fmt.Errorf("invalid topic hash length: %d", dataLen)
   205  			}
   206  			var hash ethcmn.Hash
   207  			copy(hash[:], subData)
   208  			log.Topics = append(log.Topics, hash)
   209  		case 3:
   210  			log.Data = make([]byte, dataLen)
   211  			copy(log.Data, subData)
   212  		case 4:
   213  			var n int
   214  			log.BlockNumber, n, err = amino.DecodeUvarint(data)
   215  			if err != nil {
   216  				return nil, err
   217  			}
   218  			dataLen = uint64(n)
   219  		case 5:
   220  			if int(dataLen) != ethcmn.HashLength {
   221  				return nil, fmt.Errorf("invalid topic hash length: %d", dataLen)
   222  			}
   223  			copy(log.TxHash[:], subData)
   224  		case 6:
   225  			var n int
   226  			var uv uint64
   227  			uv, n, err = amino.DecodeUvarint(data)
   228  			log.TxIndex = uint(uv)
   229  			if err != nil {
   230  				return nil, err
   231  			}
   232  			dataLen = uint64(n)
   233  		case 7:
   234  			if int(dataLen) != ethcmn.HashLength {
   235  				return nil, fmt.Errorf("invalid topic hash length: %d", dataLen)
   236  			}
   237  			copy(log.BlockHash[:], subData)
   238  		case 8:
   239  			var n int
   240  			var uv uint64
   241  			uv, n, err = amino.DecodeUvarint(data)
   242  			log.Index = uint(uv)
   243  			if err != nil {
   244  				return nil, err
   245  			}
   246  			dataLen = uint64(n)
   247  		case 9:
   248  			if data[0] == 0 {
   249  				log.Removed = false
   250  			} else if data[0] == 1 {
   251  				log.Removed = true
   252  			} else {
   253  				return nil, fmt.Errorf("invalid removed flag: %d", data[0])
   254  			}
   255  			dataLen = 1
   256  		}
   257  	}
   258  	return log, nil
   259  }
   260  
   261  var ethLogBufferPool = amino.NewBufferPool()
   262  
   263  func MarshalEthLogToAmino(log *ethtypes.Log) ([]byte, error) {
   264  	if log == nil {
   265  		return nil, nil
   266  	}
   267  	var buf = ethLogBufferPool.Get()
   268  	defer ethLogBufferPool.Put(buf)
   269  	fieldKeysType := [9]byte{1<<3 | 2, 2<<3 | 2, 3<<3 | 2, 4 << 3, 5<<3 | 2, 6 << 3, 7<<3 | 2, 8 << 3, 9 << 3}
   270  	for pos := 1; pos < 10; pos++ {
   271  		lBeforeKey := buf.Len()
   272  		var noWrite bool
   273  		err := buf.WriteByte(fieldKeysType[pos-1])
   274  		if err != nil {
   275  			return nil, err
   276  		}
   277  
   278  		switch pos {
   279  		case 1:
   280  			err := buf.WriteByte(byte(ethcmn.AddressLength))
   281  			if err != nil {
   282  				return nil, err
   283  			}
   284  			_, err = buf.Write(log.Address.Bytes())
   285  			if err != nil {
   286  				return nil, err
   287  			}
   288  		case 2:
   289  			topicsLen := len(log.Topics)
   290  			if topicsLen == 0 {
   291  				noWrite = true
   292  				break
   293  			}
   294  			err = buf.WriteByte(byte(ethcmn.HashLength))
   295  			if err != nil {
   296  				return nil, err
   297  			}
   298  			_, err = buf.Write(log.Topics[0].Bytes())
   299  			if err != nil {
   300  				return nil, err
   301  			}
   302  
   303  			for i := 1; i < topicsLen; i++ {
   304  				err = buf.WriteByte(fieldKeysType[pos-1])
   305  				if err != nil {
   306  					return nil, err
   307  				}
   308  
   309  				err = buf.WriteByte(byte(ethcmn.HashLength))
   310  				if err != nil {
   311  					return nil, err
   312  				}
   313  				_, err = buf.Write(log.Topics[i].Bytes())
   314  				if err != nil {
   315  					return nil, err
   316  				}
   317  			}
   318  		case 3:
   319  			dataLen := len(log.Data)
   320  			if dataLen == 0 {
   321  				noWrite = true
   322  				break
   323  			}
   324  			err = amino.EncodeUvarintToBuffer(buf, uint64(dataLen))
   325  			if err != nil {
   326  				return nil, err
   327  			}
   328  			_, err = buf.Write(log.Data)
   329  			if err != nil {
   330  				return nil, err
   331  			}
   332  		case 4:
   333  			if log.BlockNumber == 0 {
   334  				noWrite = true
   335  				break
   336  			}
   337  			err = amino.EncodeUvarintToBuffer(buf, log.BlockNumber)
   338  			if err != nil {
   339  				return nil, err
   340  			}
   341  		case 5:
   342  			err := buf.WriteByte(byte(ethcmn.HashLength))
   343  			if err != nil {
   344  				return nil, err
   345  			}
   346  			_, err = buf.Write(log.TxHash.Bytes())
   347  			if err != nil {
   348  				return nil, err
   349  			}
   350  		case 6:
   351  			if log.TxIndex == 0 {
   352  				noWrite = true
   353  				break
   354  			}
   355  			err := amino.EncodeUvarintToBuffer(buf, uint64(log.TxIndex))
   356  			if err != nil {
   357  				return nil, err
   358  			}
   359  		case 7:
   360  			err := buf.WriteByte(byte(ethcmn.HashLength))
   361  			if err != nil {
   362  				return nil, err
   363  			}
   364  			_, err = buf.Write(log.BlockHash.Bytes())
   365  			if err != nil {
   366  				return nil, err
   367  			}
   368  		case 8:
   369  			if log.Index == 0 {
   370  				noWrite = true
   371  				break
   372  			}
   373  			err := amino.EncodeUvarintToBuffer(buf, uint64(log.Index))
   374  			if err != nil {
   375  				return nil, err
   376  			}
   377  		case 9:
   378  			if log.Removed {
   379  				err = buf.WriteByte(byte(1))
   380  				if err != nil {
   381  					return nil, err
   382  				}
   383  			} else {
   384  				noWrite = true
   385  				break
   386  			}
   387  		default:
   388  			panic("unreachable")
   389  		}
   390  
   391  		if noWrite {
   392  			buf.Truncate(lBeforeKey)
   393  		}
   394  	}
   395  	return amino.GetBytesBufferCopy(buf), nil
   396  }
   397  
   398  func (rd *ResultData) UnmarshalFromAmino(_ *amino.Codec, data []byte) error {
   399  	var dataLen uint64 = 0
   400  	var subData []byte
   401  
   402  	for {
   403  		data = data[dataLen:]
   404  
   405  		if len(data) == 0 {
   406  			break
   407  		}
   408  
   409  		pos, aminoType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
   410  		if err != nil {
   411  			return err
   412  		}
   413  		if aminoType != amino.Typ3_ByteLength {
   414  			return fmt.Errorf("unexpect proto type %d", aminoType)
   415  		}
   416  		data = data[1:]
   417  
   418  		var n int
   419  		dataLen, n, err = amino.DecodeUvarint(data)
   420  		if err != nil {
   421  			return err
   422  		}
   423  
   424  		data = data[n:]
   425  		if len(data) < int(dataLen) {
   426  			return errors.New("invalid data len")
   427  		}
   428  		subData = data[:dataLen]
   429  
   430  		switch pos {
   431  		case 1:
   432  			if int(dataLen) != ethcmn.AddressLength {
   433  				return fmt.Errorf("invalid contract address length: %d", dataLen)
   434  			}
   435  			copy(rd.ContractAddress[:], subData)
   436  		case 2:
   437  			if int(dataLen) != ethtypes.BloomByteLength {
   438  				return fmt.Errorf("invalid bloom length: %d", dataLen)
   439  			}
   440  			copy(rd.Bloom[:], subData)
   441  		case 3:
   442  			var log *ethtypes.Log
   443  			if dataLen == 0 {
   444  				log, err = nil, nil
   445  			} else {
   446  				log, err = UnmarshalEthLogFromAmino(subData)
   447  			}
   448  			if err != nil {
   449  				return err
   450  			}
   451  			rd.Logs = append(rd.Logs, log)
   452  		case 4:
   453  			rd.Ret = make([]byte, dataLen)
   454  			copy(rd.Ret, subData)
   455  		case 5:
   456  			if dataLen != ethcmn.HashLength {
   457  				return fmt.Errorf("invalid tx hash length %d", dataLen)
   458  			}
   459  			copy(rd.TxHash[:], subData)
   460  		}
   461  	}
   462  	return nil
   463  }
   464  
   465  var resultDataBufferPool = amino.NewBufferPool()
   466  
   467  func (rd *ResultData) MarshalToAmino(_ *amino.Codec) ([]byte, error) {
   468  	var buf = resultDataBufferPool.Get()
   469  	defer resultDataBufferPool.Put(buf)
   470  	fieldKeysType := [5]byte{1<<3 | 2, 2<<3 | 2, 3<<3 | 2, 4<<3 | 2, 5<<3 | 2}
   471  	for pos := 1; pos < 6; pos++ {
   472  		lBeforeKey := buf.Len()
   473  		var noWrite bool
   474  		err := buf.WriteByte(fieldKeysType[pos-1])
   475  		if err != nil {
   476  			return nil, err
   477  		}
   478  
   479  		switch pos {
   480  		case 1:
   481  			err := buf.WriteByte(byte(ethcmn.AddressLength))
   482  			if err != nil {
   483  				return nil, err
   484  			}
   485  			_, err = buf.Write(rd.ContractAddress.Bytes())
   486  			if err != nil {
   487  				return nil, err
   488  			}
   489  		case 2:
   490  			_, err := buf.Write([]byte{0b10000000, 0b00000010}) // bloom length 256
   491  			if err != nil {
   492  				return nil, err
   493  			}
   494  			_, err = buf.Write(rd.Bloom.Bytes())
   495  			if err != nil {
   496  				return nil, err
   497  			}
   498  		case 3:
   499  			logsLen := len(rd.Logs)
   500  			if logsLen == 0 {
   501  				noWrite = true
   502  				break
   503  			}
   504  			data, err := MarshalEthLogToAmino(rd.Logs[0])
   505  			if err != nil {
   506  				return nil, err
   507  			}
   508  			err = amino.EncodeUvarintToBuffer(buf, uint64(len(data)))
   509  			if err != nil {
   510  				return nil, err
   511  			}
   512  			_, err = buf.Write(data)
   513  			if err != nil {
   514  				return nil, err
   515  			}
   516  			for i := 1; i < logsLen; i++ {
   517  				err = buf.WriteByte(fieldKeysType[pos-1])
   518  				if err != nil {
   519  					return nil, err
   520  				}
   521  				data, err = MarshalEthLogToAmino(rd.Logs[i])
   522  				if err != nil {
   523  					return nil, err
   524  				}
   525  				err = amino.EncodeUvarintToBuffer(buf, uint64(len(data)))
   526  				if err != nil {
   527  					return nil, err
   528  				}
   529  				_, err = buf.Write(data)
   530  				if err != nil {
   531  					return nil, err
   532  				}
   533  			}
   534  		case 4:
   535  			retLen := len(rd.Ret)
   536  			if retLen == 0 {
   537  				noWrite = true
   538  				break
   539  			}
   540  			err := amino.EncodeUvarintToBuffer(buf, uint64(retLen))
   541  			if err != nil {
   542  				return nil, err
   543  			}
   544  			_, err = buf.Write(rd.Ret)
   545  			if err != nil {
   546  				return nil, err
   547  			}
   548  		case 5:
   549  			err := buf.WriteByte(byte(ethcmn.HashLength))
   550  			if err != nil {
   551  				return nil, err
   552  			}
   553  			_, err = buf.Write(rd.TxHash.Bytes())
   554  			if err != nil {
   555  				return nil, err
   556  			}
   557  		default:
   558  			panic("unreachable")
   559  		}
   560  
   561  		if noWrite {
   562  			buf.Truncate(lBeforeKey)
   563  		}
   564  	}
   565  	return amino.GetBytesBufferCopy(buf), nil
   566  }
   567  
   568  // String implements fmt.Stringer interface.
   569  func (rd ResultData) String() string {
   570  	var logsStr string
   571  	logsLen := len(rd.Logs)
   572  	for i := 0; i < logsLen; i++ {
   573  		logsStr = fmt.Sprintf("%s\t\t%v\n ", logsStr, *rd.Logs[i])
   574  	}
   575  
   576  	return strings.TrimSpace(fmt.Sprintf(`ResultData:
   577  	ContractAddress: %s
   578  	Bloom: %s
   579  	Ret: %v
   580  	TxHash: %s	
   581  	Logs: 
   582  %s`, rd.ContractAddress.String(), rd.Bloom.Big().String(), rd.Ret, rd.TxHash.String(), logsStr))
   583  }
   584  
   585  // EncodeResultData takes all of the necessary data from the EVM execution
   586  // and returns the data as a byte slice encoded with amino
   587  func EncodeResultData(data *ResultData) ([]byte, error) {
   588  	var buf = new(bytes.Buffer)
   589  
   590  	bz, err := data.MarshalToAmino(ModuleCdc)
   591  	if err != nil {
   592  		bz, err = ModuleCdc.MarshalBinaryBare(*data)
   593  		if err != nil {
   594  			return nil, err
   595  		}
   596  	}
   597  
   598  	// Write uvarint(len(bz)).
   599  	err = amino.EncodeUvarintToBuffer(buf, uint64(len(bz)))
   600  	if err != nil {
   601  		return nil, err
   602  	}
   603  
   604  	// Write bz.
   605  	_, err = buf.Write(bz)
   606  	if err != nil {
   607  		return nil, err
   608  	}
   609  
   610  	return buf.Bytes(), nil
   611  }
   612  
   613  func IsEvmEvent(txResult *abci.ResponseDeliverTx) bool {
   614  	for _, event := range txResult.Events {
   615  		if event.Type != "message" {
   616  			continue
   617  		}
   618  
   619  		for _, attr := range event.Attributes {
   620  			if string(attr.Key) == "module" && string(attr.Value) == "evm" {
   621  				return true
   622  			}
   623  		}
   624  	}
   625  
   626  	return false
   627  }
   628  
   629  // DecodeResultData decodes an amino-encoded byte slice into ResultData
   630  func DecodeResultData(in []byte) (ResultData, error) {
   631  	if len(in) > 0 {
   632  		bz, err := amino.GetBinaryBareFromBinaryLengthPrefixed(in)
   633  		if err == nil {
   634  			var data ResultData
   635  			err = data.UnmarshalFromAmino(ModuleCdc, bz)
   636  			if err == nil {
   637  				return data, nil
   638  			}
   639  		}
   640  	}
   641  	var data ResultData
   642  	err := ModuleCdc.UnmarshalBinaryLengthPrefixed(in, &data)
   643  	if err != nil {
   644  		return ResultData{}, err
   645  	}
   646  	return data, nil
   647  }
   648  
   649  type recoverEthSigData struct {
   650  	Buffer  bytes.Buffer
   651  	Sig     [65]byte
   652  	SigHash ethcmn.Hash
   653  }
   654  
   655  var recoverEthSigDataPool = sync.Pool{
   656  	New: func() interface{} {
   657  		return &recoverEthSigData{}
   658  	},
   659  }
   660  
   661  func getZeroPrefixLen(buf []byte) int {
   662  	var i int
   663  	for i < len(buf) && buf[i] == 0 {
   664  		i++
   665  	}
   666  	return i
   667  }
   668  
   669  func getSigRSData(d *big.Int, buffer *bytes.Buffer) []byte {
   670  	const _S = (bits.UintSize / 8)
   671  
   672  	bzLen := len(d.Bits()) * _S
   673  
   674  	buffer.Reset()
   675  	buffer.Grow(bzLen)
   676  	var buf = buffer.Bytes()[:bzLen]
   677  
   678  	d.FillBytes(buf)
   679  	return buf[getZeroPrefixLen(buf):]
   680  }
   681  
   682  // recoverEthSig recovers a signature according to the Ethereum specification and
   683  // returns the sender or an error.
   684  //
   685  // Ref: Ethereum Yellow Paper (BYZANTIUM VERSION 69351d5) Appendix F
   686  // nolint: gocritic
   687  func recoverEthSig(R, S, Vb *big.Int, sigHash *ethcmn.Hash) (ethcmn.Address, error) {
   688  	if Vb.BitLen() > 8 {
   689  		return ethcmn.Address{}, errors.New("invalid signature")
   690  	}
   691  
   692  	V := byte(Vb.Uint64() - 27)
   693  	if !ethcrypto.ValidateSignatureValues(V, R, S, true) {
   694  		return ethcmn.Address{}, errors.New("invalid signature")
   695  	}
   696  
   697  	ethSigData := recoverEthSigDataPool.Get().(*recoverEthSigData)
   698  	defer recoverEthSigDataPool.Put(ethSigData)
   699  	sig := (&ethSigData.Sig)[:]
   700  	for i := range sig {
   701  		sig[i] = 0
   702  	}
   703  
   704  	// encode the signature in uncompressed format
   705  	buffer := &ethSigData.Buffer
   706  	r := getSigRSData(R, buffer)
   707  
   708  	copy(sig[32-len(r):32], r)
   709  
   710  	s := getSigRSData(S, buffer)
   711  
   712  	copy(sig[64-len(s):64], s)
   713  	sig[64] = V
   714  
   715  	ethSigData.SigHash = *sigHash
   716  
   717  	// recover the public key from the signature
   718  	pub, err := ethcrypto.Ecrecover(ethSigData.SigHash[:], sig)
   719  	if err != nil {
   720  		return ethcmn.Address{}, err
   721  	}
   722  
   723  	if len(pub) == 0 || pub[0] != 4 {
   724  		return ethcmn.Address{}, errors.New("invalid public key")
   725  	}
   726  
   727  	var addr ethcmn.Address
   728  	copy(addr[:], keccak256To(sig[:32], pub[1:])[12:])
   729  
   730  	return addr, nil
   731  }
   732  
   733  // keccak256 calculates and returns the Keccak256 hash of the input data.
   734  func keccak256(data ...[]byte) []byte {
   735  	b := make([]byte, 32)
   736  	// d := ethcrypto.NewKeccakState()
   737  	d := keccakStatePool.Get().(ethcrypto.KeccakState)
   738  	d.Reset()
   739  	for _, b := range data {
   740  		d.Write(b)
   741  	}
   742  	d.Read(b)
   743  	keccakStatePool.Put(d)
   744  	return b
   745  }
   746  
   747  func keccak256To(target []byte, data ...[]byte) []byte {
   748  	if len(target) != 32 {
   749  		panic("target size mismatch")
   750  	}
   751  
   752  	d := keccakStatePool.Get().(ethcrypto.KeccakState)
   753  	d.Reset()
   754  	for _, b := range data {
   755  		d.Write(b)
   756  	}
   757  	d.Read(target)
   758  	keccakStatePool.Put(d)
   759  	return target
   760  }
   761  
   762  var ethAddrStringPool = &sync.Pool{
   763  	New: func() interface{} {
   764  		return &[32]byte{}
   765  	},
   766  }
   767  
   768  type EthAddressStringer ethcmn.Address
   769  
   770  func (address EthAddressStringer) String() string {
   771  	p := &address
   772  	return EthAddressToString((*ethcmn.Address)(p))
   773  }
   774  
   775  func EthAddressToString(address *ethcmn.Address) string {
   776  	var buf [len(address)*2 + 2]byte
   777  	buf[0] = '0'
   778  	buf[1] = 'x'
   779  	hex.Encode(buf[2:], address[:])
   780  
   781  	// compute checksum
   782  	sha := keccakStatePool.Get().(ethcrypto.KeccakState)
   783  	sha.Reset()
   784  	sha.Write(buf[2:])
   785  
   786  	hash := ethAddrStringPool.Get().(*[32]byte)
   787  	sha.Read(hash[:])
   788  
   789  	for i := 2; i < len(buf); i++ {
   790  		hashByte := hash[(i-2)/2]
   791  		if i%2 == 0 {
   792  			hashByte = hashByte >> 4
   793  		} else {
   794  			hashByte &= 0xf
   795  		}
   796  		if buf[i] > '9' && hashByte > 7 {
   797  			buf[i] -= 32
   798  		}
   799  	}
   800  	ethAddrStringPool.Put(hash)
   801  	keccakStatePool.Put(sha)
   802  	return amino.BytesToStr(buf[:])
   803  }
   804  
   805  type EthHashStringer ethcmn.Hash
   806  
   807  func (h EthHashStringer) String() string {
   808  	var enc [len(h)*2 + 2]byte
   809  	enc[0] = '0'
   810  	enc[1] = 'x'
   811  	hex.Encode(enc[2:], h[:])
   812  	return amino.BytesToStr(enc[:])
   813  }