mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-19 08:01:22 +00:00
vm makeover
This commit is contained in:
90
vm/native.go
Normal file
90
vm/native.go
Normal file
@ -0,0 +1,90 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.crypto/ripemd160"
|
||||
"crypto/sha256"
|
||||
"github.com/tendermint/tendermint/vm/secp256k1"
|
||||
"github.com/tendermint/tendermint/vm/sha3"
|
||||
|
||||
. "github.com/tendermint/tendermint/common"
|
||||
)
|
||||
|
||||
var nativeContracts = make(map[Word]NativeContract)
|
||||
|
||||
func init() {
|
||||
nativeContracts[Uint64ToWord(1)] = ecrecoverFunc
|
||||
nativeContracts[Uint64ToWord(2)] = sha256Func
|
||||
nativeContracts[Uint64ToWord(3)] = ripemd160Func
|
||||
nativeContracts[Uint64ToWord(4)] = identityFunc
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
type NativeContract func(input []byte, gas *uint64) (output []byte, err error)
|
||||
|
||||
func ecrecoverFunc(input []byte, gas *uint64) (output []byte, err error) {
|
||||
// Deduct gas
|
||||
gasRequired := GasEcRecover
|
||||
if *gas < gasRequired {
|
||||
return nil, ErrInsufficientGas
|
||||
} else {
|
||||
*gas -= gasRequired
|
||||
}
|
||||
// Recover
|
||||
hash := input[:32]
|
||||
v := byte(input[32] - 27) // ignore input[33:64], v is small.
|
||||
sig := append(input[64:], v)
|
||||
|
||||
recovered, err := secp256k1.RecoverPubkey(hash, sig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hashed := sha3.Sha3(recovered[1:])
|
||||
return RightPadBytes(hashed, 32), nil
|
||||
}
|
||||
|
||||
func sha256Func(input []byte, gas *uint64) (output []byte, err error) {
|
||||
// Deduct gas
|
||||
gasRequired := uint64((len(input)+31)/32)*GasSha256Word + GasSha256Base
|
||||
if *gas < gasRequired {
|
||||
return nil, ErrInsufficientGas
|
||||
} else {
|
||||
*gas -= gasRequired
|
||||
}
|
||||
// Hash
|
||||
hasher := sha256.New()
|
||||
_, err = hasher.Write(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return hasher.Sum(nil), nil
|
||||
}
|
||||
|
||||
func ripemd160Func(input []byte, gas *uint64) (output []byte, err error) {
|
||||
// Deduct gas
|
||||
gasRequired := uint64((len(input)+31)/32)*GasRipemd160Word + GasRipemd160Base
|
||||
if *gas < gasRequired {
|
||||
return nil, ErrInsufficientGas
|
||||
} else {
|
||||
*gas -= gasRequired
|
||||
}
|
||||
// Hash
|
||||
hasher := ripemd160.New()
|
||||
_, err = hasher.Write(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return RightPadBytes(hasher.Sum(nil), 32), nil
|
||||
}
|
||||
|
||||
func identityFunc(input []byte, gas *uint64) (output []byte, err error) {
|
||||
// Deduct gas
|
||||
gasRequired := uint64((len(input)+31)/32)*GasIdentityWord + GasIdentityBase
|
||||
if *gas < gasRequired {
|
||||
return nil, ErrInsufficientGas
|
||||
} else {
|
||||
*gas -= gasRequired
|
||||
}
|
||||
// Return identity
|
||||
return input, nil
|
||||
}
|
Reference in New Issue
Block a user