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 }