tendermint/vm/precompiled.go
2015-03-18 23:23:56 -07:00

75 lines
1.6 KiB
Go

package vm
import (
"code.google.com/p/go.crypto/ripemd160"
"crypto/sha256"
"math/big"
)
type PrecompiledAccount struct {
Gas func(l int) *big.Int
fn func(in []byte) []byte
}
func (self PrecompiledAccount) Call(in []byte) []byte {
return self.fn(in)
}
var Precompiled = PrecompiledContracts()
// XXX Could set directly. Testing requires resetting and setting of pre compiled contracts.
func PrecompiledContracts() map[string]*PrecompiledAccount {
return map[string]*PrecompiledAccount{
// ECRECOVER
/*
string(LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int {
return GasEcrecover
}, ecrecoverFunc},
*/
// SHA256
string(LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
n := big.NewInt(int64(l+31) / 32)
n.Mul(n, GasSha256Word)
return n.Add(n, GasSha256Base)
}, sha256Func},
// RIPEMD160
string(LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
n := big.NewInt(int64(l+31) / 32)
n.Mul(n, GasRipemdWord)
return n.Add(n, GasRipemdBase)
}, ripemd160Func},
string(LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
n := big.NewInt(int64(l+31) / 32)
n.Mul(n, GasIdentityWord)
return n.Add(n, GasIdentityBase)
}, memCpy},
}
}
func sha256Func(in []byte) []byte {
hasher := sha256.New()
n, err := hasher.Write(in)
if err != nil {
panic(err)
}
return hasher.Sum(nil)
}
func ripemd160Func(in []byte) []byte {
hasher := ripemd160.New()
n, err := hasher.Write(in)
if err != nil {
panic(err)
}
res := hasher.Sum(nil)
return LeftPadBytes(res, 32)
}
func memCpy(in []byte) []byte {
return in
}