github.com/karalabe/go-ethereum@v0.8.5/vm/address.go (about)

     1  package vm
     2  
     3  import (
     4  	"math/big"
     5  
     6  	"github.com/ethereum/go-ethereum/crypto"
     7  	"github.com/ethereum/go-ethereum/ethutil"
     8  )
     9  
    10  type Address interface {
    11  	Call(in []byte) []byte
    12  }
    13  
    14  type PrecompiledAccount struct {
    15  	Gas func(l int) *big.Int
    16  	fn  func(in []byte) []byte
    17  }
    18  
    19  func (self PrecompiledAccount) Call(in []byte) []byte {
    20  	return self.fn(in)
    21  }
    22  
    23  var Precompiled = PrecompiledContracts()
    24  
    25  // XXX Could set directly. Testing requires resetting and setting of pre compiled contracts.
    26  func PrecompiledContracts() map[string]*PrecompiledAccount {
    27  	return map[string]*PrecompiledAccount{
    28  		// ECRECOVER
    29  		string(ethutil.LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int {
    30  			return GasEcrecover
    31  		}, ecrecoverFunc},
    32  
    33  		// SHA256
    34  		string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
    35  			n := big.NewInt(int64(l+31)/32 + 1)
    36  			n.Mul(n, GasSha256)
    37  			return n
    38  		}, sha256Func},
    39  
    40  		// RIPEMD160
    41  		string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
    42  			n := big.NewInt(int64(l+31)/32 + 1)
    43  			n.Mul(n, GasRipemd)
    44  			return n
    45  		}, ripemd160Func},
    46  
    47  		string(ethutil.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
    48  			n := big.NewInt(int64(l+31)/32 + 1)
    49  			n.Mul(n, GasMemCpy)
    50  
    51  			return n
    52  		}, memCpy},
    53  	}
    54  }
    55  
    56  func sha256Func(in []byte) []byte {
    57  	return crypto.Sha256(in)
    58  }
    59  
    60  func ripemd160Func(in []byte) []byte {
    61  	return ethutil.LeftPadBytes(crypto.Ripemd160(in), 32)
    62  }
    63  
    64  func ecrecoverFunc(in []byte) []byte {
    65  	// In case of an invalid sig. Defaults to return nil
    66  	defer func() { recover() }()
    67  
    68  	hash := in[:32]
    69  	v := ethutil.BigD(in[32:64]).Bytes()[0] - 27
    70  	sig := append(in[64:], v)
    71  
    72  	return ethutil.LeftPadBytes(crypto.Sha3(crypto.Ecrecover(append(hash, sig...))[1:])[12:], 32)
    73  }
    74  
    75  func memCpy(in []byte) []byte {
    76  	return in
    77  }