mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
100 lines
3.4 KiB
Go
100 lines
3.4 KiB
Go
package vm
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"os"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
)
|
|
|
|
var (
|
|
StateManagerAddress = common.HexToAddress(os.Getenv("STATE_MANAGER_ADDRESS"))
|
|
)
|
|
|
|
type stateManagerFunction func(*EVM, *Contract, []byte) ([]byte, error)
|
|
type methodId [4]byte
|
|
|
|
var funcs = map[string]stateManagerFunction{
|
|
"getStorage(address,bytes32)": getStorage,
|
|
"setStorage(address,bytes32,bytes32)": setStorage,
|
|
"deployContract(address,bytes,bool,address)": deployContract,
|
|
"getOvmContractNonce(address)": getOvmContractNonce,
|
|
"getCodeContractBytecode(address)": getCodeContractBytecode,
|
|
"getCodeContractHash(address)": getCodeContractHash,
|
|
"incrementOvmContractNonce(address)": incrementOvmContractNonce,
|
|
}
|
|
var methodIds map[[4]byte]stateManagerFunction
|
|
var executionMangerBytecode []byte
|
|
|
|
func init() {
|
|
methodIds = make(map[[4]byte]stateManagerFunction, len(funcs))
|
|
for methodSignature, f := range funcs {
|
|
methodIds[MethodSignatureToMethodId(methodSignature)] = f
|
|
}
|
|
}
|
|
|
|
func MethodSignatureToMethodId(methodSignature string) [4]byte {
|
|
var methodId [4]byte
|
|
copy(methodId[:], crypto.Keccak256([]byte(methodSignature)))
|
|
return methodId
|
|
}
|
|
|
|
func callStateManager(input []byte, evm *EVM, contract *Contract) (ret []byte, err error) {
|
|
var methodId [4]byte
|
|
copy(methodId[:], input[:4])
|
|
ret, err = methodIds[methodId](evm, contract, input)
|
|
return ret, err
|
|
}
|
|
|
|
func setStorage(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
|
|
address := common.BytesToAddress(input[4:36])
|
|
key := common.BytesToHash(input[36:68])
|
|
val := common.BytesToHash(input[68:100])
|
|
evm.StateDB.SetState(address, key, val)
|
|
return nil, nil
|
|
}
|
|
|
|
func getStorage(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
|
|
address := common.BytesToAddress(input[4:36])
|
|
key := common.BytesToHash(input[36:68])
|
|
val := evm.StateDB.GetState(address, key)
|
|
return val.Bytes(), nil
|
|
}
|
|
|
|
func getCodeContractBytecode(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
|
|
address := common.BytesToAddress(input[4:36])
|
|
code := evm.StateDB.GetCode(address)
|
|
return code, nil
|
|
}
|
|
|
|
func getCodeContractHash(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
|
|
address := common.BytesToAddress(input[4:36])
|
|
codeHash := evm.StateDB.GetCodeHash(address)
|
|
return codeHash.Bytes(), nil
|
|
}
|
|
|
|
func getOvmContractNonce(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
|
|
address := common.BytesToAddress(input[4:36])
|
|
b := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(b, evm.StateDB.GetNonce(address))
|
|
val := append(make([]byte, 24), b[:]...)
|
|
return val, nil
|
|
}
|
|
|
|
func incrementOvmContractNonce(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
|
|
address := common.BytesToAddress(input[4:36])
|
|
oldNonce := evm.StateDB.GetNonce(address)
|
|
evm.StateDB.SetNonce(address, oldNonce+1)
|
|
return nil, nil
|
|
}
|
|
|
|
func deployContract(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
|
|
address := common.BytesToAddress(input[4:36])
|
|
callerAddress := common.BytesToAddress(input[100:132])
|
|
initCodeLength := binary.BigEndian.Uint32(input[160:164])
|
|
initCode := input[164 : 164+initCodeLength]
|
|
callerContractRef := &Contract{self: AccountRef(callerAddress)}
|
|
returnVal, _, _, err := evm.OvmCreate(callerContractRef, address, initCode, contract.Gas, bigZero)
|
|
return returnVal, nil
|
|
}
|