tendermint/vm/native.go

105 lines
2.8 KiB
Go
Raw Normal View History

2015-03-17 21:46:26 -07:00
package vm
import (
"crypto/sha256"
2015-06-09 20:17:19 -07:00
"github.com/tendermint/tendermint/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160"
2015-04-01 17:30:16 -07:00
. "github.com/tendermint/tendermint/common"
2015-03-17 21:46:26 -07:00
)
var registeredNativeContracts = make(map[Word256]NativeContract)
func RegisteredNativeContract(addr Word256) bool {
_, ok := registeredNativeContracts[addr]
return ok
}
2015-03-17 21:46:26 -07:00
2015-08-14 10:59:42 -07:00
func RegisterNativeContract(addr Word256, fn NativeContract) bool {
_, exists := registeredNativeContracts[addr]
if exists {
return false
}
registeredNativeContracts[addr] = fn
return true
}
2015-03-17 21:46:26 -07:00
func init() {
2015-07-21 10:30:24 -07:00
registerNativeContracts()
registerSNativeContracts()
}
func registerNativeContracts() {
2015-08-14 10:59:42 -07:00
// registeredNativeContracts[Int64ToWord256(1)] = ecrecoverFunc
registeredNativeContracts[Int64ToWord256(2)] = sha256Func
registeredNativeContracts[Int64ToWord256(3)] = ripemd160Func
registeredNativeContracts[Int64ToWord256(4)] = identityFunc
2015-03-17 21:46:26 -07:00
}
//-----------------------------------------------------------------------------
type NativeContract func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error)
2015-03-17 21:46:26 -07:00
2015-08-14 10:59:42 -07:00
/* Removed due to C dependency
func ecrecoverFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
2015-03-17 21:46:26 -07:00
// 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:])
2015-04-17 17:39:50 -07:00
return LeftPadBytes(hashed, 32), nil
2015-03-17 21:46:26 -07:00
}
2015-08-14 10:59:42 -07:00
*/
2015-03-17 21:46:26 -07:00
func sha256Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
2015-03-17 21:46:26 -07:00
// Deduct gas
gasRequired := int64((len(input)+31)/32)*GasSha256Word + GasSha256Base
2015-03-17 21:46:26 -07:00
if *gas < gasRequired {
return nil, ErrInsufficientGas
} else {
*gas -= gasRequired
}
// Hash
hasher := sha256.New()
2015-06-25 18:50:31 -07:00
// CONTRACT: this does not err
hasher.Write(input)
2015-03-17 21:46:26 -07:00
return hasher.Sum(nil), nil
}
func ripemd160Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
2015-03-17 21:46:26 -07:00
// Deduct gas
gasRequired := int64((len(input)+31)/32)*GasRipemd160Word + GasRipemd160Base
2015-03-17 21:46:26 -07:00
if *gas < gasRequired {
return nil, ErrInsufficientGas
} else {
*gas -= gasRequired
}
// Hash
hasher := ripemd160.New()
2015-06-25 18:50:31 -07:00
// CONTRACT: this does not err
hasher.Write(input)
2015-04-17 17:39:50 -07:00
return LeftPadBytes(hasher.Sum(nil), 32), nil
2015-03-17 21:46:26 -07:00
}
func identityFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) {
2015-03-17 21:46:26 -07:00
// Deduct gas
gasRequired := int64((len(input)+31)/32)*GasIdentityWord + GasIdentityBase
2015-03-17 21:46:26 -07:00
if *gas < gasRequired {
return nil, ErrInsufficientGas
} else {
*gas -= gasRequired
}
// Return identity
return input, nil
}