github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/types/contract_verifier.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "github.com/ethereum/go-ethereum/common" 6 "github.com/ethereum/go-ethereum/common/hexutil" 7 "github.com/ethereum/go-ethereum/core/vm" 8 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 9 "math/big" 10 ) 11 12 // ContractVerifier which verify contract method whether blocked 13 type ContractVerifier struct { 14 params Params 15 hook *GuFactorHook 16 } 17 18 // NewContractVerifier return a point of ContractVerifier 19 func NewContractVerifier(params Params) *ContractVerifier { 20 return &ContractVerifier{params: params, hook: &GuFactorHook{}} 21 } 22 23 // Verify check the contract whether is blocked. 24 // It never return error,because in this chain if it blocked, not allow to execute next opCode.In Ethereum call failed,the call err is deal in contract code ether evm. 25 // If current call/delegatecall/callcode contract method is blocked,it will be panic,then it's deal logic at defer{recover}. 26 // If contract all method blocked,it will not be panic in Verify. it will be panic in stateDb.GetCode(). 27 func (cv ContractVerifier) Verify(stateDB vm.StateDB, op vm.OpCode, from, to common.Address, input []byte, value *big.Int) error { 28 csdb, ok := stateDB.(*CommitStateDB) 29 //If stateDB is not native stateDB ,then return error 30 if !ok { 31 panic(ErrContractBlockedVerify{"unknown stateDB expected CommitStateDB"}) 32 } 33 34 cv.hook.UpdateGuFactor(csdb, op, from, to, input, value) 35 36 //check whether contract has been blocked 37 if !cv.params.EnableContractBlockedList { 38 return nil 39 } 40 if op == vm.SELFDESTRUCT { 41 //contract not allowed selfdestruct,check from is blocked 42 bc := csdb.GetContractMethodBlockedByAddress(from.Bytes()) 43 if bc != nil && !bc.IsAllMethodBlocked() { 44 err := ErrContractBlockedVerify{fmt.Sprintf("Contract %s has been blocked. It's not allow to SELFDESTRUCT", from.String())} 45 panic(err) 46 } 47 } else if op == vm.CALL || op == vm.DELEGATECALL || op == vm.CALLCODE { 48 //contract not allowed to call delegateCall and callcode ,check from and input is blocked 。STATICCALL could not check because ,it's readonly. 49 if len(input) > 4 { 50 input = input[:4] 51 } 52 method := hexutil.Encode(input) 53 if csdb.IsContractMethodBlocked(sdk.AccAddress(to.Bytes()), method) { 54 err := ErrContractBlockedVerify{fmt.Sprintf("The method %s of contract %s has been blocked. It's not allow to %s", method, to.String(), op.String())} 55 panic(err) 56 } 57 } 58 return nil 59 }