github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/evm/precompiles_test.go (about)

     1  // Copyright Monax Industries Limited
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package evm
     5  
     6  import (
     7  	"math/big"
     8  	"testing"
     9  
    10  	"github.com/hyperledger/burrow/execution/evm/abi"
    11  
    12  	"github.com/btcsuite/btcd/btcec"
    13  	"github.com/hyperledger/burrow/binary"
    14  	"github.com/hyperledger/burrow/execution/native"
    15  	"github.com/hyperledger/burrow/execution/solidity"
    16  
    17  	"github.com/hyperledger/burrow/acm/acmstate"
    18  	"github.com/hyperledger/burrow/execution/engine"
    19  	"github.com/hyperledger/burrow/execution/exec"
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/hyperledger/burrow/acm"
    23  	"github.com/hyperledger/burrow/crypto"
    24  
    25  	"github.com/hyperledger/burrow/execution/evm/asm/bc"
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  func TestECRecover(t *testing.T) {
    30  	message := []byte("THIS MESSAGE IS NOT SIGNED")
    31  	digest := crypto.Keccak256(message)
    32  	privateKey, err := btcec.NewPrivateKey(btcec.S256())
    33  	require.NoError(t, err)
    34  
    35  	sig, err := btcec.SignCompact(btcec.S256(), privateKey, digest, false)
    36  	require.NoError(t, err)
    37  
    38  	st := native.NewState(native.MustDefaultNatives(), acmstate.NewMemoryState())
    39  	caller := &acm.Account{
    40  		Address: crypto.Address{1, 1, 1},
    41  	}
    42  	function := native.Precompiles.GetByName("ecrecover").(*native.Function)
    43  	require.NotNil(t, function, "Could not get function: %s")
    44  	require.NoError(t, st.UpdateAccount(caller))
    45  
    46  	state := engine.State{
    47  		CallFrame: engine.NewCallFrame(st),
    48  		EventSink: exec.NewNoopEventSink(),
    49  	}
    50  
    51  	spec, err := abi.ReadSpec(solidity.Abi_ECRecover)
    52  	require.NoError(t, err)
    53  	funcId := spec.Functions["recoverSigningAddress"].FunctionID
    54  	input := bc.MustSplice(funcId, digest, binary.Int64ToWord256(int64(sig[2*binary.Word256Bytes])), sig[:2*binary.Word256Bytes])
    55  
    56  	params := engine.CallParams{
    57  		Caller: caller.Address,
    58  		Input:  input,
    59  		Gas:    big.NewInt(10000),
    60  	}
    61  
    62  	vm := New(engine.Options{
    63  		Natives: native.MustDefaultNatives(),
    64  	})
    65  	returnValue, err := vm.Contract(solidity.DeployedBytecode_ECRecover).Call(state, params)
    66  	require.NoError(t, err)
    67  	priv, err := crypto.PrivateKeyFromRawBytes(privateKey.Serialize(), crypto.CurveTypeSecp256k1)
    68  	require.NoError(t, err)
    69  	address := priv.GetPublicKey().GetAddress()
    70  	addressOut := crypto.AddressFromWord256(binary.LeftPadWord256(returnValue))
    71  	require.NoError(t, err)
    72  	assert.Equal(t, address, addressOut)
    73  }