Commit bddeb9d6 authored by hezhengjun's avatar hezhengjun Committed by vipwzw

sync evm to 1.10

parent 612a211c
...@@ -145,6 +145,13 @@ chain33_SignAndSendTx() { ...@@ -145,6 +145,13 @@ chain33_SignAndSendTx() {
fi fi
local req='"method":"Chain33.SignRawTx","params":[{"privkey":"'"$priKey"'","txHex":"'"$txHex"'","expire":"'"$expire"'"}]' local req='"method":"Chain33.SignRawTx","params":[{"privkey":"'"$priKey"'","txHex":"'"$txHex"'","expire":"'"$expire"'"}]'
if [ -n "$5" ]; then
fee=$5
req='"method":"Chain33.SignRawTx","params":[{"privkey":"'"$priKey"'","txHex":"'"$txHex"'","expire":"'"$expire"'","fee":'$fee'}]'
else
req='"method":"Chain33.SignRawTx","params":[{"privkey":"'"$priKey"'","txHex":"'"$txHex"'","expire":"'"$expire"'"}]'
fi
signedTx=$(curl -ksd "{$req}" "${MAIN_HTTP}" | jq -r ".result") signedTx=$(curl -ksd "{$req}" "${MAIN_HTTP}" | jq -r ".result")
if [ "$signedTx" != null ]; then if [ "$signedTx" != null ]; then
......
This diff is collapsed.
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package compiler wraps the Solidity compiler executable (solc).
package compiler
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os/exec"
"regexp"
"strconv"
"strings"
)
var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`)
// Contract contains information about a compiled contract, alongside its code and runtime code.
type Contract struct {
Code string `json:"code"`
RuntimeCode string `json:"runtime-code"`
Info ContractInfo `json:"info"`
}
// ContractInfo contains information about a compiled contract, including access
// to the ABI definition, source mapping, user and developer docs, and metadata.
//
// Depending on the source, language version, compiler version, and compiler
// options will provide information about how the contract was compiled.
type ContractInfo struct {
Source string `json:"source"`
Language string `json:"language"`
LanguageVersion string `json:"languageVersion"`
CompilerVersion string `json:"compilerVersion"`
CompilerOptions string `json:"compilerOptions"`
SrcMap string `json:"srcMap"`
SrcMapRuntime string `json:"srcMapRuntime"`
AbiDefinition interface{} `json:"abiDefinition"`
UserDoc interface{} `json:"userDoc"`
DeveloperDoc interface{} `json:"developerDoc"`
Metadata string `json:"metadata"`
}
// Solidity contains information about the solidity compiler.
type Solidity struct {
Path, Version, FullVersion string
Major, Minor, Patch int
}
// --combined-output format
type solcOutput struct {
Contracts map[string]struct {
BinRuntime string `json:"bin-runtime"`
SrcMapRuntime string `json:"srcmap-runtime"`
Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string
}
Version string
}
func (s *Solidity) makeArgs() []string {
p := []string{
"--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc",
"--optimize", // code optimizer switched on
}
if s.Major > 0 || s.Minor > 4 || s.Patch > 6 {
p[1] += ",metadata"
}
return p
}
// SolidityVersion runs solc and parses its version output.
func SolidityVersion(solc string) (*Solidity, error) {
if solc == "" {
solc = "solc"
}
var out bytes.Buffer
cmd := exec.Command(solc, "--version")
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return nil, err
}
matches := versionRegexp.FindStringSubmatch(out.String())
if len(matches) != 4 {
return nil, fmt.Errorf("can't parse solc version %q", out.String())
}
s := &Solidity{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]}
if s.Major, err = strconv.Atoi(matches[1]); err != nil {
return nil, err
}
if s.Minor, err = strconv.Atoi(matches[2]); err != nil {
return nil, err
}
if s.Patch, err = strconv.Atoi(matches[3]); err != nil {
return nil, err
}
return s, nil
}
// CompileSolidityString builds and returns all the contracts contained within a source string.
func CompileSolidityString(solc, source string) (map[string]*Contract, error) {
if len(source) == 0 {
return nil, errors.New("solc: empty source string")
}
s, err := SolidityVersion(solc)
if err != nil {
return nil, err
}
args := append(s.makeArgs(), "--")
cmd := exec.Command(s.Path, append(args, "-")...)
cmd.Stdin = strings.NewReader(source)
return s.run(cmd, source)
}
// CompileSolidity compiles all given Solidity source files.
func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract, error) {
if len(sourcefiles) == 0 {
return nil, errors.New("solc: no source files")
}
source, err := slurpFiles(sourcefiles)
if err != nil {
return nil, err
}
s, err := SolidityVersion(solc)
if err != nil {
return nil, err
}
args := append(s.makeArgs(), "--")
cmd := exec.Command(s.Path, append(args, sourcefiles...)...)
return s.run(cmd, source)
}
func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) {
var stderr, stdout bytes.Buffer
cmd.Stderr = &stderr
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes())
}
return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " "))
}
// ParseCombinedJSON takes the direct output of a solc --combined-output run and
// parses it into a map of string contract name to Contract structs. The
// provided source, language and compiler version, and compiler options are all
// passed through into the Contract structs.
//
// The solc output is expected to contain ABI, source mapping, user docs, and dev docs.
//
// Returns an error if the JSON is malformed or missing data, or if the JSON
// embedded within the JSON is malformed.
func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) {
var output solcOutput
if err := json.Unmarshal(combinedJSON, &output); err != nil {
return nil, err
}
// Compilation succeeded, assemble and return the contracts.
contracts := make(map[string]*Contract)
for name, info := range output.Contracts {
// Parse the individual compilation results.
var abi interface{}
if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil {
return nil, fmt.Errorf("solc: error reading abi definition (%v)", err)
}
var userdoc interface{}
if err := json.Unmarshal([]byte(info.Userdoc), &userdoc); err != nil {
return nil, fmt.Errorf("solc: error reading user doc: %v", err)
}
var devdoc interface{}
if err := json.Unmarshal([]byte(info.Devdoc), &devdoc); err != nil {
return nil, fmt.Errorf("solc: error reading dev doc: %v", err)
}
contracts[name] = &Contract{
Code: "0x" + info.Bin,
RuntimeCode: "0x" + info.BinRuntime,
Info: ContractInfo{
Source: source,
Language: "Solidity",
LanguageVersion: languageVersion,
CompilerVersion: compilerVersion,
CompilerOptions: compilerOptions,
SrcMap: info.SrcMap,
SrcMapRuntime: info.SrcMapRuntime,
AbiDefinition: abi,
UserDoc: userdoc,
DeveloperDoc: devdoc,
Metadata: info.Metadata,
},
}
}
return contracts, nil
}
func slurpFiles(files []string) (string, error) {
var concat bytes.Buffer
for _, file := range files {
content, err := ioutil.ReadFile(file)
if err != nil {
return "", err
}
concat.Write(content)
}
return concat.String(), nil
}
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package compiler
import (
"os/exec"
"testing"
)
const (
testSource = `
pragma solidity >= 0.4.18;
contract test {
/// @notice Will multiply ` + "`a`" + ` by 7.
function multiply(uint a) public returns(uint d) {
return a * 7;
}
}
`
)
func skipWithoutSolc(t *testing.T) {
if _, err := exec.LookPath("solc"); err != nil {
t.Skip(err)
}
}
func TestCompiler(t *testing.T) {
skipWithoutSolc(t)
contracts, err := CompileSolidityString("", testSource)
if err != nil {
t.Fatalf("error compiling source. result is %v: %v", contracts, err)
}
if len(contracts) != 1 {
t.Errorf("one contract expected, got %d", len(contracts))
}
c, ok := contracts["test"]
if !ok {
c, ok = contracts["<stdin>:test"]
if !ok {
t.Fatal("info for contract 'test' not present in result")
}
}
if c.Code == "" {
t.Error("empty code")
}
if c.Info.Source != testSource {
t.Error("wrong source")
}
if c.Info.CompilerVersion == "" {
t.Error("empty version")
}
}
func TestCompileError(t *testing.T) {
skipWithoutSolc(t)
contracts, err := CompileSolidityString("", testSource[4:])
if err == nil {
t.Errorf("error expected compiling source. got none. result %v", contracts)
}
t.Logf("error: %v", err)
}
This diff is collapsed.
package abi package abi
import ( import (
"encoding/json" "errors"
"fmt" "fmt"
"math/big" "math/big"
"os"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"errors" log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/golang-collections/collections/stack" "github.com/golang-collections/collections/stack"
) )
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
func Pack(param, abiData string, readOnly bool) (methodName string, packData []byte, err error) { func Pack(param, abiData string, readOnly bool) (methodName string, packData []byte, err error) {
// 首先解析参数字符串,分析出方法名以及个参数取值 // 首先解析参数字符串,分析出方法名以及个参数取值
methodName, params, err := procFuncCall(param) methodName, params, err := procFuncCall(param)
if err != nil { if err != nil {
return methodName, packData, err return methodName, packData, err
} }
...@@ -69,11 +70,50 @@ func Pack(param, abiData string, readOnly bool) (methodName string, packData []b ...@@ -69,11 +70,50 @@ func Pack(param, abiData string, readOnly bool) (methodName string, packData []b
return methodName, packData, err return methodName, packData, err
} }
func PackContructorPara(param, abiStr string) (packData []byte, err error) {
_, params, err := procFuncCall(param)
if err != nil {
return nil, err
}
parsedAbi, err := JSON(strings.NewReader(abiStr))
if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err)
return
}
method := parsedAbi.Constructor
paramVals := []interface{}{}
if len(params) != 0 {
// 首先检查参数个数和ABI中定义的是否一致
if method.Inputs.LengthNonIndexed() != len(params) {
err = fmt.Errorf("function Params count error: %v", param)
return nil, err
}
for i, v := range method.Inputs.NonIndexed() {
paramVal, err := str2GoValue(v.Type, params[i])
if err != nil {
return nil, err
}
paramVals = append(paramVals, paramVal)
}
}
packData, err = parsedAbi.Constructor.Inputs.Pack(paramVals...)
if err != nil {
return nil, err
}
return packData, nil
}
// Unpack 将调用返回结果按照ABI的格式序列化为json // Unpack 将调用返回结果按照ABI的格式序列化为json
// data 合约方法返回值 // data 合约方法返回值
// abiData 完整的ABI定义 // abiData 完整的ABI定义
func Unpack(data []byte, methodName, abiData string) (output string, err error) { func Unpack(data []byte, methodName, abiData string) (output []*Param, err error) {
if len(data) == 0 { if len(data) == 0 {
log.Info("Unpack", "Data len", 0, "methodName", methodName)
return output, err return output, err
} }
// 解析ABI数据结构,获取本次调用的方法对象 // 解析ABI数据结构,获取本次调用的方法对象
...@@ -97,19 +137,20 @@ func Unpack(data []byte, methodName, abiData string) (output string, err error) ...@@ -97,19 +137,20 @@ func Unpack(data []byte, methodName, abiData string) (output string, err error)
return output, err return output, err
} }
outputs := []*Param{} output = []*Param{}
for i, v := range values { for i, v := range values {
arg := method.Outputs[i] arg := method.Outputs[i]
pval := &Param{Name: arg.Name, Type: arg.Type.String(), Value: v} pval := &Param{Name: arg.Name, Type: arg.Type.String(), Value: v}
outputs = append(outputs, pval) if arg.Type.String() == "address" {
} pval.Value = v.(common.Hash160Address).ToAddress().String()
log.Info("Unpack address", "address", pval.Value)
}
jsondata, err := json.Marshal(outputs) output = append(output, pval)
if err != nil {
return output, err
} }
return string(jsondata), err
return
} }
// Param 返回值参数结构定义 // Param 返回值参数结构定义
...@@ -196,7 +237,37 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) { ...@@ -196,7 +237,37 @@ func str2GoValue(typ Type, val string) (res interface{}, err error) {
for idx, sub := range subs { for idx, sub := range subs {
subVal, er := str2GoValue(*typ.Elem, sub) subVal, er := str2GoValue(*typ.Elem, sub)
if er != nil { if er != nil {
return res, er //return res, er
subparams, err := procArrayItem(sub) //解析复合类型中的多个元素
if err != nil {
return res, er
}
fmt.Println("subparams len", len(subparams), "subparams", subparams)
//获取符合类型对应的参数类型(address,bytes)
abityps := strings.Split(typ.Elem.stringKind[1:len(typ.Elem.stringKind)-1], ",") //解析为[address, bytes]
fmt.Println("abityps", abityps)
//复合类型,继续解析参数
for i := 0; i < len(subparams); i++ {
tp, err := NewType(abityps[i], "", nil)
if err != nil {
fmt.Println("NewType", err.Error())
continue
}
fmt.Println("tp", tp.stringKind, "types", tp.T)
subVal, err = str2GoValue(tp, subparams[i]) //处理对应的元素
if err != nil {
fmt.Println("str2GoValue err ", err.Error())
continue
}
fmt.Println("subVal", subVal)
rval.Index(idx).Field(i).Set(reflect.ValueOf(subVal))
}
return rval.Interface(), nil
} }
rval.Index(idx).Set(reflect.ValueOf(subVal)) rval.Index(idx).Set(reflect.ValueOf(subVal))
} }
......
...@@ -7,7 +7,6 @@ package executor ...@@ -7,7 +7,6 @@ package executor
import ( import (
"bytes" "bytes"
"math/big" "math/big"
"os" "os"
"reflect" "reflect"
...@@ -22,7 +21,7 @@ import ( ...@@ -22,7 +21,7 @@ import (
) )
var ( var (
evmDebug = false evmDebug = true
// EvmAddress 本合约地址 // EvmAddress 本合约地址
EvmAddress = "" EvmAddress = ""
...@@ -69,9 +68,21 @@ func NewEVMExecutor() *EVMExecutor { ...@@ -69,9 +68,21 @@ func NewEVMExecutor() *EVMExecutor {
exec := &EVMExecutor{} exec := &EVMExecutor{}
exec.vmCfg = &runtime.Config{} exec.vmCfg = &runtime.Config{}
exec.vmCfg.Tracer = runtime.NewJSONLogger(os.Stdout) //exec.vmCfg.Tracer = runtime.NewJSONLogger(os.Stdout)
exec.vmCfg.Tracer = runtime.NewMarkdownLogger(
&runtime.LogConfig{
DisableMemory: false,
DisableStack: false,
DisableStorage: false,
DisableReturnData: false,
Debug: true,
Limit: 0,
},
os.Stdout,
)
exec.SetChild(exec) exec.SetChild(exec)
exec.SetExecutorType(types.LoadExecutorType(driverName))
return exec return exec
} }
...@@ -141,6 +152,11 @@ func (evm *EVMExecutor) getNewAddr(txHash []byte) common.Address { ...@@ -141,6 +152,11 @@ func (evm *EVMExecutor) getNewAddr(txHash []byte) common.Address {
return common.NewAddress(cfg, txHash) return common.NewAddress(cfg, txHash)
} }
// createContractAddress creates an ethereum address given the bytes and the nonce
func (evm *EVMExecutor) createContractAddress(b common.Address, txHash []byte) common.Address {
return common.NewContractAddress(b, txHash)
}
// CheckTx 校验交易 // CheckTx 校验交易
func (evm *EVMExecutor) CheckTx(tx *types.Transaction, index int) error { func (evm *EVMExecutor) CheckTx(tx *types.Transaction, index int) error {
return nil return nil
......
...@@ -6,17 +6,20 @@ package executor ...@@ -6,17 +6,20 @@ package executor
import ( import (
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"strings" "strings"
"github.com/33cn/chain33/account"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/runtime" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/runtime"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/state" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/state"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types" evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
) )
// Exec 本合约执行逻辑 // Exec 本合约执行逻辑
...@@ -39,66 +42,74 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int, ...@@ -39,66 +42,74 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int,
cfg := evm.GetAPI().GetConfig() cfg := evm.GetAPI().GetConfig()
// 创建EVM运行时对象 // 创建EVM运行时对象
env := runtime.NewEVM(context, evm.mStateDB, *evm.vmCfg, cfg) env := runtime.NewEVM(context, evm.mStateDB, *evm.vmCfg, cfg)
isCreate := strings.Compare(msg.To().String(), EvmAddress) == 0 isCreate := strings.Compare(msg.To().String(), EvmAddress) == 0 && len(msg.Data()) > 0
isTransferOnly := strings.Compare(msg.To().String(), EvmAddress) == 0 && 0 == len(msg.Data())
var ( var (
ret []byte ret []byte
vmerr error vmerr error
leftOverGas uint64 leftOverGas uint64
contractAddr common.Address contractAddr common.Address
snapshot int snapshot int
execName string execName string
methodName string contractAddrStr string
) )
// 为了方便计费,即使合约为新生成,也将地址的初始化放到外面操作 if isTransferOnly {
if isCreate { caller := msg.From()
receiver := common.BytesToAddress(msg.Para())
if !evm.mStateDB.CanTransfer(caller.String(), msg.Value()) {
log.Error("innerExec", "Not enough balance to be transferred from", caller.String(), "amout", msg.Value())
return nil, types.ErrNoBalance
}
env.StateDB.Snapshot()
env.Transfer(env.StateDB, caller, receiver, msg.Value())
curVer := evm.mStateDB.GetLastSnapshot()
kvSet, logs := evm.mStateDB.GetChangedData(curVer.GetID())
receipt = &types.Receipt{Ty: types.ExecOk, KV: kvSet, Logs: logs}
return receipt, nil
} else if isCreate {
// 使用随机生成的地址作为合约地址(这个可以保证每次创建的合约地址不会重复,不存在冲突的情况) // 使用随机生成的地址作为合约地址(这个可以保证每次创建的合约地址不会重复,不存在冲突的情况)
contractAddr = evm.getNewAddr(txHash) contractAddr = evm.createContractAddress(msg.From(), txHash)
if !env.StateDB.Empty(contractAddr.String()) { contractAddrStr = contractAddr.String()
if !env.StateDB.Empty(contractAddrStr) {
return receipt, model.ErrContractAddressCollision return receipt, model.ErrContractAddressCollision
} }
// 只有新创建的合约才能生成合约名称 // 只有新创建的合约才能生成合约名称
execName = fmt.Sprintf("%s%s", cfg.ExecName(evmtypes.EvmPrefix), common.BytesToHash(txHash).Hex()) execName = fmt.Sprintf("%s%s", cfg.ExecName(evmtypes.EvmPrefix), common.BytesToHash(txHash).Hex())
} else { } else {
contractAddr = *msg.To() contractAddr = *msg.To()
contractAddrStr = contractAddr.String()
if !env.StateDB.Exist(contractAddrStr) {
log.Error("innerExec", "Contract not exist for address", contractAddrStr)
return receipt, model.ErrContractNotExist
}
log.Info("innerExec", "Contract exist for address", contractAddrStr)
} }
// 状态机中设置当前交易状态 // 状态机中设置当前交易状态
evm.mStateDB.Prepare(common.BytesToHash(txHash), index) evm.mStateDB.Prepare(common.BytesToHash(txHash), index)
if isCreate { if isCreate {
// 如果携带ABI数据,则对数据合法性进行检查 ret, snapshot, leftOverGas, vmerr = env.Create(runtime.AccountRef(msg.From()), contractAddr, msg.Data(), context.GasLimit, execName, msg.Alias(), msg.Value())
if len(msg.ABI()) > 0 && cfg.IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEVMABI) {
_, err = abi.JSON(strings.NewReader(msg.ABI()))
if err != nil {
return receipt, err
}
}
ret, snapshot, leftOverGas, vmerr = env.Create(runtime.AccountRef(msg.From()), contractAddr, msg.Data(), context.GasLimit, execName, msg.Alias(), msg.ABI())
} else { } else {
inData := msg.Data() callPara := msg.Para()
// 在这里进行ABI和十六进制的调用参数转换 log.Debug("call contract ", "callPara", common.Bytes2Hex(callPara))
if len(msg.ABI()) > 0 && cfg.IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEVMABI) { ret, snapshot, leftOverGas, vmerr = env.Call(runtime.AccountRef(msg.From()), *msg.To(), callPara, context.GasLimit, msg.Value())
funcName, packData, err := abi.Pack(msg.ABI(), evm.mStateDB.GetAbi(msg.To().String()), readOnly)
if err != nil {
return receipt, err
}
inData = packData
methodName = funcName
log.Debug("call contract ", "abi funcName", funcName, "packData", common.Bytes2Hex(inData))
}
ret, snapshot, leftOverGas, vmerr = env.Call(runtime.AccountRef(msg.From()), *msg.To(), inData, context.GasLimit, msg.Value())
log.Debug("call(create) contract ", "input", common.Bytes2Hex(inData))
} }
// 打印合约中生成的日志
evm.mStateDB.PrintLogs()
usedGas := msg.GasLimit() - leftOverGas usedGas := msg.GasLimit() - leftOverGas
logMsg := "call contract details:" logMsg := "call contract details:"
if isCreate { if isCreate {
logMsg = "create contract details:" logMsg = "create contract details:"
} }
log.Debug(logMsg, "caller address", msg.From().String(), "contract address", contractAddr.String(), "exec name", execName, "alias name", msg.Alias(), "usedGas", usedGas, "return data", common.Bytes2Hex(ret)) log.Debug(logMsg, "caller address", msg.From().String(), "contract address", contractAddrStr, "exec name", execName, "alias name", msg.Alias(), "usedGas", usedGas, "return data", common.Bytes2Hex(ret))
curVer := evm.mStateDB.GetLastSnapshot() curVer := evm.mStateDB.GetLastSnapshot()
if vmerr != nil { if vmerr != nil {
log.Error("evm contract exec error", "error info", vmerr) log.Error("evm contract exec error", "error info", vmerr, "ret", string(ret))
vmerr = errors.New(fmt.Sprintf("%s,detail: %s", vmerr.Error(), string(ret)))
return receipt, vmerr return receipt, vmerr
} }
...@@ -113,28 +124,24 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int, ...@@ -113,28 +124,24 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int,
return receipt, model.ErrOutOfGas return receipt, model.ErrOutOfGas
} }
// 打印合约中生成的日志
evm.mStateDB.PrintLogs()
// 没有任何数据变更 // 没有任何数据变更
if curVer == nil { if curVer == nil {
return receipt, nil return receipt, nil
} }
// 从状态机中获取数据变更和变更日志 // 从状态机中获取数据变更和变更日志
kvSet, logs := evm.mStateDB.GetChangedData(curVer.GetID()) kvSet, logs := evm.mStateDB.GetChangedData(curVer.GetID())
contractReceipt := &evmtypes.ReceiptEVMContract{Caller: msg.From().String(), ContractName: execName, ContractAddr: contractAddr.String(), UsedGas: usedGas, Ret: ret} contractReceipt := &evmtypes.ReceiptEVMContract{Caller: msg.From().String(), ContractName: execName, ContractAddr: contractAddrStr, UsedGas: usedGas, Ret: ret}
// 这里进行ABI调用结果格式化 //// 这里进行ABI调用结果格式化
if len(methodName) > 0 && len(msg.ABI()) > 0 && cfg.IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEVMABI) { //if len(methodName) > 0 && len(msg.Para()) > 0 && cfg.IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEVMABI) {
jsonRet, err := abi.Unpack(ret, methodName, evm.mStateDB.GetAbi(msg.To().String())) // jsonRet, err := abi.Unpack(ret, methodName, evm.mStateDB.GetAbi(msg.To().String()))
if err != nil { // if err != nil {
// 这里出错不影响整体执行,只打印错误信息 // // 这里出错不影响整体执行,只打印错误信息
log.Error("unpack evm return error", "error", err) // log.Error("unpack evm return error", "error", err)
} // }
contractReceipt.JsonRet = jsonRet // contractReceipt.JsonRet = jsonRet
} //}
logs = append(logs, &types.ReceiptLog{Ty: evmtypes.TyLogCallContract, Log: types.Encode(contractReceipt)}) logs = append(logs, &types.ReceiptLog{Ty: evmtypes.TyLogCallContract, Log: types.Encode(contractReceipt)})
logs = append(logs, evm.mStateDB.GetReceiptLogs(contractAddr.String())...) logs = append(logs, evm.mStateDB.GetReceiptLogs(contractAddrStr)...)
if cfg.IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEVMKVHash) { if cfg.IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEVMKVHash) {
// 将执行时生成的合约状态数据变更信息也计算哈希并保存 // 将执行时生成的合约状态数据变更信息也计算哈希并保存
...@@ -156,14 +163,25 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int, ...@@ -156,14 +163,25 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int,
evm.collectEvmTxLog(txHash, contractReceipt, receipt) evm.collectEvmTxLog(txHash, contractReceipt, receipt)
if isCreate {
log.Info("innerExec", "Succeed to created new contract with name", msg.Alias(),
"created contract address", contractAddrStr)
}
return receipt, nil return receipt, nil
} }
// CheckInit 检查是否初始化数据库 // CheckInit 检查是否初始化数据库
func (evm *EVMExecutor) CheckInit() { func (evm *EVMExecutor) CheckInit() {
if evm.mStateDB == nil { cfg := evm.GetAPI().GetConfig()
if !cfg.IsPara() {
//主链
evm.mStateDB = state.NewMemoryStateDB(evm.GetStateDB(), evm.GetLocalDB(), evm.GetCoinsAccount(), evm.GetHeight(), evm.GetAPI()) evm.mStateDB = state.NewMemoryStateDB(evm.GetStateDB(), evm.GetLocalDB(), evm.GetCoinsAccount(), evm.GetHeight(), evm.GetAPI())
return
} }
//平行链
accountDB, _ := account.NewAccountDB(evm.GetAPI().GetConfig(), pt.ParaX, "coins.bty", evm.GetStateDB())
evm.mStateDB = state.NewMemoryStateDB(evm.GetStateDB(), evm.GetLocalDB(), accountDB, evm.GetHeight(), evm.GetAPI())
} }
// GetMessage 目前的交易中,如果是coins交易,金额是放在payload的,但是合约不行,需要修改Transaction结构 // GetMessage 目前的交易中,如果是coins交易,金额是放在payload的,但是合约不行,需要修改Transaction结构
...@@ -175,7 +193,7 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction, index int) (msg *commo ...@@ -175,7 +193,7 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction, index int) (msg *commo
} }
// 此处暂时不考虑消息发送签名的处理,chain33在mempool中对签名做了检查 // 此处暂时不考虑消息发送签名的处理,chain33在mempool中对签名做了检查
from := getCaller(tx) from := getCaller(tx)
to := getReceiver(tx) to := getReceiver(&action)
if to == nil { if to == nil {
return msg, types.ErrInvalidAddress return msg, types.ErrInvalidAddress
} }
...@@ -190,7 +208,7 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction, index int) (msg *commo ...@@ -190,7 +208,7 @@ func (evm *EVMExecutor) GetMessage(tx *types.Transaction, index int) (msg *commo
} }
// 合约的GasLimit即为调用者为本次合约调用准备支付的手续费 // 合约的GasLimit即为调用者为本次合约调用准备支付的手续费
msg = common.NewMessage(from, to, tx.Nonce, action.Amount, gasLimit, gasPrice, action.Code, action.GetAlias(), action.Abi) msg = common.NewMessage(from, to, tx.Nonce, action.Amount, gasLimit, gasPrice, action.Code, action.Para, action.GetAlias())
return msg, err return msg, err
} }
...@@ -252,9 +270,9 @@ func getCaller(tx *types.Transaction) common.Address { ...@@ -252,9 +270,9 @@ func getCaller(tx *types.Transaction) common.Address {
} }
// 从交易信息中获取交易目标地址,在创建合约交易中,此地址为空 // 从交易信息中获取交易目标地址,在创建合约交易中,此地址为空
func getReceiver(tx *types.Transaction) *common.Address { func getReceiver(action *evmtypes.EVMContractAction) *common.Address {
if tx.To == "" { if action.ContractAddr == "" {
return nil return nil
} }
return common.StringToAddress(tx.To) return common.StringToAddress(action.ContractAddr)
} }
...@@ -13,8 +13,8 @@ import ( ...@@ -13,8 +13,8 @@ import (
) )
// CanTransfer 检查合约调用账户是否有充足的金额进行转账交易操作 // CanTransfer 检查合约调用账户是否有充足的金额进行转账交易操作
func CanTransfer(db state.EVMStateDB, sender, recipient common.Address, amount uint64) bool { func CanTransfer(db state.EVMStateDB, sender common.Address, amount uint64) bool {
return db.CanTransfer(sender.String(), recipient.String(), amount) return db.CanTransfer(sender.String(), amount)
} }
// Transfer 在内存数据库中执行转账操作(只修改内存中的金额) // Transfer 在内存数据库中执行转账操作(只修改内存中的金额)
......
...@@ -5,14 +5,15 @@ ...@@ -5,14 +5,15 @@
package executor package executor
import ( import (
"errors"
"fmt" "fmt"
"math/big" "math/big"
"strings" "strings"
"errors" "github.com/33cn/chain33/common"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common" evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
evmCommon "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types" evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
) )
...@@ -25,14 +26,14 @@ func (evm *EVMExecutor) Query_CheckAddrExists(in *evmtypes.CheckEVMAddrReq) (typ ...@@ -25,14 +26,14 @@ func (evm *EVMExecutor) Query_CheckAddrExists(in *evmtypes.CheckEVMAddrReq) (typ
return nil, model.ErrAddrNotExists return nil, model.ErrAddrNotExists
} }
var addr common.Address var addr evmCommon.Address
// 合约名称 // 合约名称
cfg := evm.GetAPI().GetConfig() cfg := evm.GetAPI().GetConfig()
if strings.HasPrefix(addrStr, cfg.ExecName(evmtypes.EvmPrefix)) { if strings.HasPrefix(addrStr, cfg.ExecName(evmtypes.EvmPrefix)) {
addr = common.ExecAddress(addrStr) addr = evmCommon.ExecAddress(addrStr)
} else { } else {
// 合约地址 // 合约地址
nAddr := common.StringToAddress(addrStr) nAddr := evmCommon.StringToAddress(addrStr)
if nAddr == nil { if nAddr == nil {
return nil, model.ErrAddrNotExists return nil, model.ErrAddrNotExists
} }
...@@ -56,25 +57,25 @@ func (evm *EVMExecutor) Query_CheckAddrExists(in *evmtypes.CheckEVMAddrReq) (typ ...@@ -56,25 +57,25 @@ func (evm *EVMExecutor) Query_CheckAddrExists(in *evmtypes.CheckEVMAddrReq) (typ
func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types.Message, error) { func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types.Message, error) {
evm.CheckInit() evm.CheckInit()
var ( var (
caller common.Address caller evmCommon.Address
) )
cfg := evm.GetAPI().GetConfig() cfg := evm.GetAPI().GetConfig()
// 如果未指定调用地址,则直接使用一个虚拟的地址发起调用 // 如果未指定调用地址,则直接使用一个虚拟的地址发起调用
if len(in.Caller) > 0 { if len(in.Caller) > 0 {
callAddr := common.StringToAddress(in.Caller) callAddr := evmCommon.StringToAddress(in.Caller)
if callAddr != nil { if callAddr != nil {
caller = *callAddr caller = *callAddr
} }
} else { } else {
caller = common.ExecAddress(cfg.ExecName(evmtypes.ExecutorName)) caller = evmCommon.ExecAddress(cfg.ExecName(evmtypes.ExecutorName))
} }
to := common.StringToAddress(in.To) to := evmCommon.StringToAddress(in.To)
if to == nil { if to == nil {
to = common.StringToAddress(EvmAddress) to = evmCommon.StringToAddress(EvmAddress)
} }
msg := common.NewMessage(caller, to, 0, in.Amount, evmtypes.MaxGasLimit, 1, in.Code, "estimateGas", in.Abi) msg := evmCommon.NewMessage(caller, to, 0, in.Amount, evmtypes.MaxGasLimit, 1, nil, in.Para, "estimateGas")
txHash := common.BigToHash(big.NewInt(evmtypes.MaxGasLimit)).Bytes() txHash := evmCommon.BigToHash(big.NewInt(evmtypes.MaxGasLimit)).Bytes()
receipt, err := evm.innerExec(msg, txHash, 1, evmtypes.MaxGasLimit, false) receipt, err := evm.innerExec(msg, txHash, 1, evmtypes.MaxGasLimit, false)
if err != nil { if err != nil {
...@@ -134,10 +135,10 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er ...@@ -134,10 +135,10 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er
ret.Caller = in.Caller ret.Caller = in.Caller
var ( var (
caller common.Address caller evmCommon.Address
) )
to := common.StringToAddress(in.Address) to := evmCommon.StringToAddress(in.Address)
if to == nil { if to == nil {
ret.JsonData = fmt.Sprintf("invalid address:%v", in.Address) ret.JsonData = fmt.Sprintf("invalid address:%v", in.Address)
return ret, nil return ret, nil
...@@ -146,16 +147,16 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er ...@@ -146,16 +147,16 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er
// 如果未指定调用地址,则直接使用一个虚拟的地址发起调用 // 如果未指定调用地址,则直接使用一个虚拟的地址发起调用
cfg := evm.GetAPI().GetConfig() cfg := evm.GetAPI().GetConfig()
if len(in.Caller) > 0 { if len(in.Caller) > 0 {
callAddr := common.StringToAddress(in.Caller) callAddr := evmCommon.StringToAddress(in.Caller)
if callAddr != nil { if callAddr != nil {
caller = *callAddr caller = *callAddr
} }
} else { } else {
caller = common.ExecAddress(cfg.ExecName(evmtypes.ExecutorName)) caller = evmCommon.ExecAddress(cfg.ExecName(evmtypes.ExecutorName))
} }
msg := common.NewMessage(caller, common.StringToAddress(in.Address), 0, 0, evmtypes.MaxGasLimit, 1, nil, "estimateGas", in.Input) msg := evmCommon.NewMessage(caller, evmCommon.StringToAddress(in.Address), 0, 0, evmtypes.MaxGasLimit, 1, nil, evmCommon.FromHex(in.Input), "estimateGas")
txHash := common.BigToHash(big.NewInt(evmtypes.MaxGasLimit)).Bytes() txHash := evmCommon.BigToHash(big.NewInt(evmtypes.MaxGasLimit)).Bytes()
receipt, err := evm.innerExec(msg, txHash, 1, evmtypes.MaxGasLimit, true) receipt, err := evm.innerExec(msg, txHash, 1, evmtypes.MaxGasLimit, true)
if err != nil { if err != nil {
...@@ -165,7 +166,7 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er ...@@ -165,7 +166,7 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er
if receipt.Ty == types.ExecOk { if receipt.Ty == types.ExecOk {
callData := getCallReceipt(receipt.GetLogs()) callData := getCallReceipt(receipt.GetLogs())
if callData != nil { if callData != nil {
ret.RawData = common.Bytes2Hex(callData.Ret) ret.RawData = evmCommon.Bytes2Hex(callData.Ret)
ret.JsonData = callData.JsonRet ret.JsonData = callData.JsonRet
return ret, nil return ret, nil
} }
...@@ -173,16 +174,45 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er ...@@ -173,16 +174,45 @@ func (evm *EVMExecutor) Query_Query(in *evmtypes.EvmQueryReq) (types.Message, er
return ret, nil return ret, nil
} }
// Query_QueryABI 此方法用来查询合约绑定的ABI数据,不修改原有执行器的状态数据 func (evm *EVMExecutor) Query_GetNonce(in *evmtypes.EvmGetNonceReq) (types.Message, error) {
func (evm *EVMExecutor) Query_QueryABI(in *evmtypes.EvmQueryAbiReq) (types.Message, error) {
evm.CheckInit() evm.CheckInit()
nonce := evm.mStateDB.GetNonce(in.Address)
return &evmtypes.EvmGetNonceRespose{Nonce: int64(nonce)}, nil
}
addr := common.StringToAddress(in.GetAddress()) func (evm *EVMExecutor) Query_GetPackData(in *evmtypes.EvmGetPackDataReq) (types.Message, error) {
if addr == nil { evm.CheckInit()
return nil, fmt.Errorf("invalid address: %v", in.GetAddress()) _, packData, err := evmAbi.Pack(in.Parameter, in.Abi, true)
if nil != err {
return nil, errors.New("Failed to do evmAbi.Pack" + err.Error())
} }
packStr := common.ToHex(packData)
abiData := evm.mStateDB.GetAbi(addr.String()) return &evmtypes.EvmGetPackDataRespose{PackData: packStr}, nil
}
return &evmtypes.EvmQueryAbiResp{Address: in.GetAddress(), Abi: abiData}, nil func (evm *EVMExecutor) Query_GetUnpackData(in *evmtypes.EvmGetUnpackDataReq) (types.Message, error) {
evm.CheckInit()
methodName, _, err := evmAbi.Pack(in.Parameter, in.Abi, true)
if nil != err {
return nil, errors.New("Failed to do evmAbi.Pack" + err.Error())
}
data, err := common.FromHex(in.Data)
if nil != err {
return nil, errors.New("common.FromHex failed due to:" + err.Error())
}
outputs, err := evmAbi.Unpack(data, methodName, in.Abi)
if err != nil {
return nil, errors.New("unpack evm return error" + err.Error())
}
ret := evmtypes.EvmGetUnpackDataRespose{}
for _, v := range outputs {
ret.UnpackData = append(ret.UnpackData, fmt.Sprintf("%v", v.Value))
}
return &ret, nil
} }
...@@ -142,7 +142,7 @@ func runCase(tt *testing.T, c VMCase, file string) { ...@@ -142,7 +142,7 @@ func runCase(tt *testing.T, c VMCase, file string) {
ret, _, _, err = env.Call(runtime.AccountRef(msg.From()), *common.StringToAddress(c.exec.address), msg.Data(), msg.GasLimit(), msg.Value()) ret, _, _, err = env.Call(runtime.AccountRef(msg.From()), *common.StringToAddress(c.exec.address), msg.Data(), msg.GasLimit(), msg.Value())
} else { } else {
addr := crypto.RandomContractAddress() addr := crypto.RandomContractAddress()
ret, _, _, err = env.Create(runtime.AccountRef(msg.From()), *addr, msg.Data(), msg.GasLimit(), "testExecName", "", "") ret, _, _, err = env.Create(runtime.AccountRef(msg.From()), *addr, msg.Data(), msg.GasLimit(), "testExecName", "", 0)
} }
if err != nil { if err != nil {
......
...@@ -6,6 +6,9 @@ package common ...@@ -6,6 +6,9 @@ package common
import ( import (
"math/big" "math/big"
"strings"
"github.com/ethereum/go-ethereum/common"
"encoding/hex" "encoding/hex"
...@@ -97,6 +100,11 @@ func NewAddress(cfg *types.Chain33Config, txHash []byte) Address { ...@@ -97,6 +100,11 @@ func NewAddress(cfg *types.Chain33Config, txHash []byte) Address {
return Address{Addr: execAddr} return Address{Addr: execAddr}
} }
func NewContractAddress(b Address, txHash []byte) Address {
execAddr := address.GetExecAddress(b.String() + common.Bytes2Hex(txHash))
return Address{Addr: execAddr}
}
// ExecAddress 返回合约地址 // ExecAddress 返回合约地址
func ExecAddress(execName string) Address { func ExecAddress(execName string) Address {
execAddr := address.GetExecAddress(execName) execAddr := address.GetExecAddress(execName)
...@@ -122,6 +130,15 @@ func BytesToHash160Address(b []byte) Hash160Address { ...@@ -122,6 +130,15 @@ func BytesToHash160Address(b []byte) Hash160Address {
func StringToAddress(s string) *Address { func StringToAddress(s string) *Address {
addr, err := address.NewAddrFromString(s) addr, err := address.NewAddrFromString(s)
if err != nil { if err != nil {
//检查是否是十六进制地址数据
hbytes, err := hex.DecodeString(strings.TrimPrefix(s, "0x"))
if err == nil {
if len(hbytes) == 20 {
var addr address.Address
addr.SetBytes(hbytes)
return &Address{Addr: &addr}
}
}
log15.Error("create address form string error", "string:", s) log15.Error("create address form string error", "string:", s)
return nil return nil
} }
...@@ -160,6 +177,7 @@ func Uint256ToAddress(b *uint256.Int) Address { ...@@ -160,6 +177,7 @@ func Uint256ToAddress(b *uint256.Int) Address {
a := new(address.Address) a := new(address.Address)
a.Version = 0 a.Version = 0
out := make([]byte, 20) out := make([]byte, 20)
copy(out[:], b.Bytes()) copy(out[:], b.Bytes())
a.SetBytes(out) a.SetBytes(out)
return Address{Addr: a} return Address{Addr: a}
......
...@@ -8,6 +8,8 @@ import ( ...@@ -8,6 +8,8 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"math/big" "math/big"
ethCrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto" "github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
...@@ -24,13 +26,13 @@ func ValidateSignatureValues(r, s *big.Int) bool { ...@@ -24,13 +26,13 @@ func ValidateSignatureValues(r, s *big.Int) bool {
return true return true
} }
// Ecrecover 根据压缩消息和签名,返回压缩的公钥信息 // Ecrecover 根据压缩消息和签名,返回压缩的公钥信息
func Ecrecover(hash, sig []byte) ([]byte, error) { func Ecrecover(hash, sig []byte) ([]byte, error) {
pub, err := SigToPub(hash, sig) unpressedPub, err := ethCrypto.SigToPub(hash, sig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
bytes := (*btcec.PublicKey)(pub).SerializeUncompressed() bytes := (*btcec.PublicKey)(unpressedPub).SerializeCompressed()
return bytes, err return bytes, err
} }
...@@ -79,3 +81,9 @@ func Keccak256Hash(data ...[]byte) (h common.Hash) { ...@@ -79,3 +81,9 @@ func Keccak256Hash(data ...[]byte) (h common.Hash) {
d.Sum(h[:0]) d.Sum(h[:0])
return h return h
} }
// CreateAddress2 creates an ethereum address given the address bytes, initial
// contract code hash and a salt.
func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash))
}
...@@ -15,11 +15,11 @@ type Message struct { ...@@ -15,11 +15,11 @@ type Message struct {
gasLimit uint64 gasLimit uint64
gasPrice uint32 gasPrice uint32
data []byte data []byte
abi string para []byte
} }
// NewMessage 新建消息结构 // NewMessage 新建消息结构
func NewMessage(from Address, to *Address, nonce int64, amount uint64, gasLimit uint64, gasPrice uint32, data []byte, alias, abi string) *Message { func NewMessage(from Address, to *Address, nonce int64, amount uint64, gasLimit uint64, gasPrice uint32, data, para []byte, alias string) *Message {
return &Message{ return &Message{
from: from, from: from,
to: to, to: to,
...@@ -29,7 +29,7 @@ func NewMessage(from Address, to *Address, nonce int64, amount uint64, gasLimit ...@@ -29,7 +29,7 @@ func NewMessage(from Address, to *Address, nonce int64, amount uint64, gasLimit
gasPrice: gasPrice, gasPrice: gasPrice,
data: data, data: data,
alias: alias, alias: alias,
abi: abi, para: para,
} }
} }
...@@ -57,5 +57,5 @@ func (m Message) GasLimit() uint64 { return m.gasLimit } ...@@ -57,5 +57,5 @@ func (m Message) GasLimit() uint64 { return m.gasLimit }
// Alias 合约别名 // Alias 合约别名
func (m Message) Alias() string { return m.alias } func (m Message) Alias() string { return m.alias }
// ABI 合约ABI // Para 合约参数
func (m Message) ABI() string { return m.abi } func (m Message) Para() []byte { return m.para }
...@@ -81,6 +81,22 @@ func (m *Memory) Get(offset, size int64) (cpy []byte) { ...@@ -81,6 +81,22 @@ func (m *Memory) Get(offset, size int64) (cpy []byte) {
return return
} }
// Get returns offset + size as a new slice
func (m *Memory) GetCopy(offset, size int64) (cpy []byte) {
if size == 0 {
return nil
}
if len(m.Store) > int(offset) {
cpy = make([]byte, size)
copy(cpy, m.Store[offset:offset+size])
return
}
return
}
// GetPtr 同Get操作,不过这里返回的是数据引用 // GetPtr 同Get操作,不过这里返回的是数据引用
func (m *Memory) GetPtr(offset, size int64) []byte { func (m *Memory) GetPtr(offset, size int64) []byte {
if size == 0 { if size == 0 {
......
...@@ -39,23 +39,23 @@ func MakeSwapStackFunc(n int) StackValidationFunc { ...@@ -39,23 +39,23 @@ func MakeSwapStackFunc(n int) StackValidationFunc {
return MakeStackFunc(n, n) return MakeStackFunc(n, n)
} }
//func MinSwapStack(n int) int { func minSwapStack(n int) int {
// return MinStack(n, n) return minStack(n, n)
//} }
//func MaxSwapStack(n int) int { func maxSwapStack(n int) int {
// return MaxStack(n, n) return maxStack(n, n)
//} }
//
//func MinDupStack(n int) int { func minDupStack(n int) int {
// return MinStack(n, n+1) return minStack(n, n+1)
//} }
//func MaxDupStack(n int) int { func maxDupStack(n int) int {
// return MaxStack(n, n+1) return maxStack(n, n+1)
//} }
//func MaxStack(pop, push int) int { func maxStack(pop, push int) int {
// return int(params.StackLimit) + pop - push return int(params.StackLimit) + pop - push
//} }
//func MinStack(pops, push int) int { func minStack(pops, push int) int {
// return pops return pops
//} }
...@@ -12,11 +12,14 @@ var ( ...@@ -12,11 +12,14 @@ var (
// ErrCodeStoreOutOfGas contract creation code storage out of gas // ErrCodeStoreOutOfGas contract creation code storage out of gas
ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas")
// ErrDepth max call depth exceeded // ErrDepth max call depth exceeded
ErrDepth = errors.New("max call depth exceeded") ErrDepth = errors.New("max call depth exceeded")
// ErrInsufficientBalance insufficient balance for transfer
ErrInsufficientBalance = errors.New("insufficient balance for transfer") ErrInsufficientBalance = errors.New("insufficient balance for transfer")
// ErrContractAddressCollision contract address collision // ErrContractAddressCollision contract address collision
ErrContractAddressCollision = errors.New("contract address collision") ErrContractAddressCollision = errors.New("contract address collision")
ErrContractNotExist = errors.New("contract not exist")
ErrABINotExist = errors.New("ABI not exist")
// ErrGasUintOverflow gas uint64 overflow // ErrGasUintOverflow gas uint64 overflow
ErrGasUintOverflow = errors.New("gas uint64 overflow") ErrGasUintOverflow = errors.New("gas uint64 overflow")
// ErrAddrNotExists address not exists // ErrAddrNotExists address not exists
......
package params
import (
"math/big"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
)
// ChainConfig is the core config which determines the blockchain settings.
//
// ChainConfig is stored in the database on a per block basis. This means
// that any network, identified by its genesis block, can have its own
// set of configuration options.
type ChainConfig struct {
ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork)
DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed)
EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium)
ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople)
IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul)
MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin)
YoloV3Block *big.Int `json:"yoloV3Block,omitempty"` // YOLO v3: Gas repricings TODO @holiman add EIP references
EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated)
// Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty"`
Clique *CliqueConfig `json:"clique,omitempty"`
}
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
type EthashConfig struct{}
// String implements the stringer interface, returning the consensus engine details.
func (c *EthashConfig) String() string {
return "ethash"
}
// CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
type CliqueConfig struct {
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint
}
// String implements the stringer interface, returning the consensus engine details.
func (c *CliqueConfig) String() string {
return "clique"
}
package runtime
import (
"math"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/holiman/uint256"
)
// calcMemSize64 calculates the required memory size, and returns
// the size and whether the result overflowed uint64
func calcMemSize64(off, l *uint256.Int) (uint64, bool) {
if !l.IsUint64() {
return 0, true
}
return calcMemSize64WithUint(off, l.Uint64())
}
// calcMemSize64WithUint calculates the required memory size, and returns
// the size and whether the result overflowed uint64
// Identical to calcMemSize64, but length is a uint64
func calcMemSize64WithUint(off *uint256.Int, length64 uint64) (uint64, bool) {
// if length is zero, memsize is always zero, regardless of offset
if length64 == 0 {
return 0, false
}
// Check that offset doesn't overflow
offset64, overflow := off.Uint64WithOverflow()
if overflow {
return 0, true
}
val := offset64 + length64
// if value < either of it's parts, then it overflowed
return val, val < offset64
}
// getData returns a slice from the data based on the start and size and pads
// up to size with zero's. This function is overflow safe.
func getData(data []byte, start uint64, size uint64) []byte {
length := uint64(len(data))
if start > length {
start = length
}
end := start + size
if end > length {
end = length
}
return common.RightPadBytes(data[start:end], int(size))
}
// toWordSize returns the ceiled word size required for memory expansion.
func toWordSize(size uint64) uint64 {
if size > math.MaxUint64-31 {
return math.MaxUint64/32 + 1
}
return (size + 31) / 32
}
func allZero(b []byte) bool {
for _, byte := range b {
if byte != 0 {
return false
}
}
return true
}
This diff is collapsed.
package runtime
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common/crypto"
)
// "input" is (hash, v, r, s), each 32 bytes
//cc2427f9c0de9457dbaeddc063888c47353ce8df2b8571944ebe389acf049dc0100000000000000000000000000000000000000000000000000000000000001b4cf8ae36067ccb3ee2f15b91e7f3e10fac9f38fc020ded6dbae65874c84a9c5d24c849055170d52dd5b19c5b4408e5f64e6f147cb456a01c4160b444fbb11a54
//0x883118bfb20db555e5fc151e81d54bf5718640d72ee28b88823c9686024d7b07000000000000000000000000000000000000000000000000000000000000001cb1badd81830bdc8de25b84333284c5e04241654b6f927cbf353bbba3df35da2a5254673fe57fcb047e334522a12ed49122895a050cfdeed35f98adb7c6cc0c21
func TestEcrecoverSignTypedMessage(t *testing.T) {
hashStr := "0xcc2427f9c0de9457dbaeddc063888c47353ce8df2b8571944ebe389acf049dc0"
sigStr := "0x4cf8ae36067ccb3ee2f15b91e7f3e10fac9f38fc020ded6dbae65874c84a9c5d24c849055170d52dd5b19c5b4408e5f64e6f147cb456a01c4160b444fbb11a541b"
input, _ := common.HexToBytes(hashStr)
sig, _ := common.HexToBytes(sigStr)
sig[64] -= 27
pubKey, err := crypto.Ecrecover(input[:32], sig)
// make sure the public key is a valid one
if err != nil {
log15.Info("ecrecover", "failed due to", err.Error())
panic("ecrecover")
}
//fmt.Println("ecrecover", "pubkey", common.Bytes2Hex(pubKey))
//fmt.Println("recoverd address", address.PubKeyToAddress(pubKey).String())
addr := address.PubKeyToAddress(pubKey)
hash160Str := common.Bytes2Hex(common.LeftPadBytes(addr.Hash160[:], 32))
assert.Equal(t, hash160Str, "0x000000000000000000000000245afbf176934ccdd7ca291a8dddaa13c8184822")
assert.Equal(t, addr.String(), "14KEKbYtKKQm4wMthSK9J4La4nAiidGozt")
//fmt.Println("TestEcrecoverSignTypedMessage", "hash160Str", hash160Str)
//privateKeyStr := "0xcc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944"
//var driver secp256k1.Driver
//privateKeySli, err := chain33Common.FromHex(privateKeyStr)
//if nil != err {
// panic(err.Error())
//
//}
//ownerPrivateKey, err := driver.PrivKeyFromBytes(privateKeySli)
//if nil != err {
// panic(err.Error())
//}
//fmt.Println("Origin user", "pubkey", common.Bytes2Hex(ownerPrivateKey.PubKey().Bytes()))
}
package runtime
//import (
//"fmt"
//"sort"
//
////"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/params"
//)
////
////var activators = map[int]func(*JumpTable){
//// 2929: enable2929,
//// 2200: enable2200,
//// 1884: enable1884,
//// //1344: enable1344,
////}
//
//// EnableEIP enables the given EIP on the config.
//// This operation writes in-place, and callers need to ensure that the globally
//// defined jump tables are not polluted.
//func EnableEIP(eipNum int, jt *JumpTable) error {
// enablerFn, ok := activators[eipNum]
// if !ok {
// return fmt.Errorf("undefined eip %d", eipNum)
// }
// enablerFn(jt)
// return nil
//}
//
//func ValidEip(eipNum int) bool {
// _, ok := activators[eipNum]
// return ok
//}
//func ActivateableEips() []string {
// var nums []string
// for k := range activators {
// nums = append(nums, fmt.Sprintf("%d", k))
// }
// sort.Strings(nums)
// return nums
//}
// enable1884 applies EIP-1884 to the given jump table:
// - Increase cost of BALANCE to 700
// - Increase cost of EXTCODEHASH to 700
// - Increase cost of SLOAD to 800
// - Define SELFBALANCE, with cost GasFastStep (5)
//func enable1884(jt *JumpTable) {
// // Gas cost changes
// jt[SLOAD].constantGas = params.SloadGasEIP1884
// jt[BALANCE].constantGas = params.BalanceGasEIP1884
// jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884
//
// // New opcode
// jt[SELFBALANCE] = &operation{
// execute: opSelfBalance,
// constantGas: GasFastStep,
// minStack: minStack(0, 1),
// maxStack: maxStack(0, 1),
// }
//}
// enable1344 applies EIP-1344 (ChainID Opcode)
// - Adds an opcode that returns the current chain’s EIP-155 unique identifier
//func enable1344(jt *JumpTable) {
// // New opcode
// jt[CHAINID] = &operation{
// execute: opChainID,
// constantGas: GasQuickStep,
// minStack: minStack(0, 1),
// maxStack: maxStack(0, 1),
// }
//}
//enable2200 applies EIP-2200 (Rebalance net-metered SSTORE)
//func enable2200(jt *JumpTable) {
// jt[SLOAD].constantGas = params.SloadGasEIP2200
// //jt[SSTORE].dynamicGas = gasSStoreEIP2200
//}
//enable2929 enables "EIP-2929: Gas cost increases for state access opcodes"
//https://eips.ethereum.org/EIPS/eip-2929
//func enable2929(jt *JumpTable) {
// //jt[SSTORE].dynamicGas = gasSStoreEIP2929
// //
// //jt[SLOAD].constantGas = 0
// //jt[SLOAD].dynamicGas = gasSLoadEIP2929
// //
// //jt[EXTCODECOPY].constantGas = WarmStorageReadCostEIP2929
// //jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929
// //
// //jt[EXTCODESIZE].constantGas = WarmStorageReadCostEIP2929
// //jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck
// //
// //jt[EXTCODEHASH].constantGas = WarmStorageReadCostEIP2929
// //jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck
// //
// //jt[BALANCE].constantGas = WarmStorageReadCostEIP2929
// //jt[BALANCE].dynamicGas = gasEip2929AccountCheck
// //
// //jt[CALL].constantGas = WarmStorageReadCostEIP2929
// //jt[CALL].dynamicGas = gasCallEIP2929
// //
// //jt[CALLCODE].constantGas = WarmStorageReadCostEIP2929
// //jt[CALLCODE].dynamicGas = gasCallCodeEIP2929
// //
// //jt[STATICCALL].constantGas = WarmStorageReadCostEIP2929
// //jt[STATICCALL].dynamicGas = gasStaticCallEIP2929
// //
// //jt[DELEGATECALL].constantGas = WarmStorageReadCostEIP2929
// //jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929
//
// // This was previously part of the dynamic cost, but we're using it as a constantGas
// // factor here
// jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150
// //jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929
//}
package runtime
import (
"errors"
"fmt"
)
// List evm execution errors
var (
// ErrInvalidSubroutineEntry means that a BEGINSUB was reached via iteration,
// as opposed to from a JUMPSUB instruction
ErrOutOfGas = errors.New("out of gas")
ErrExecutionReverted = errors.New("execution reverted")
ErrGasUintOverflow = errors.New("gas uint64 overflow")
)
// ErrStackUnderflow wraps an evm error when the items on the stack less
// than the minimal requirement.
type ErrStackUnderflow struct {
stackLen int
required int
}
func (e *ErrStackUnderflow) Error() string {
return fmt.Sprintf("stack underflow (%d <=> %d)", e.stackLen, e.required)
}
// ErrStackOverflow wraps an evm error when the items on the stack exceeds
// the maximum allowance.
type ErrStackOverflow struct {
stackLen int
limit int
}
func (e *ErrStackOverflow) Error() string {
return fmt.Sprintf("stack limit reached %d (%d)", e.stackLen, e.limit)
}
// ErrInvalidOpCode wraps an evm error when an invalid opcode is encountered.
type ErrInvalidOpCode struct {
opcode OpCode
}
func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode: %s", e.opcode) }
This diff is collapsed.
package runtime
import (
"github.com/holiman/uint256"
)
// Gas costs
const (
GasQuickStep uint64 = 2
GasFastestStep uint64 = 3
GasFastStep uint64 = 5
GasMidStep uint64 = 8
GasSlowStep uint64 = 10
GasExtStep uint64 = 20
)
// callGas returns the actual gas cost of the call.
//
// The cost of gas was changed during the homestead price change HF.
// As part of EIP 150 (TangerineWhistle), the returned gas is gas - base * 63 / 64.
func callGas(isEip150 bool, availableGas, base uint64, callCost *uint256.Int) (uint64, error) {
if isEip150 {
availableGas = availableGas - base
gas := availableGas - availableGas/64
// If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150
// is smaller than the requested amount. Therefore we return the new gas instead
// of returning an error.
if !callCost.IsUint64() || gas < callCost.Uint64() {
return gas, nil
}
}
if !callCost.IsUint64() {
return 0, ErrGasUintOverflow
}
return callCost.Uint64(), nil
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -6,14 +6,15 @@ package runtime ...@@ -6,14 +6,15 @@ package runtime
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io" "io"
"math/big" "math/big"
"strings"
"time" "time"
"github.com/holiman/uint256" "github.com/holiman/uint256"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/mm"
) )
// Tracer 接口用来在合约执行过程中收集跟踪数据。 // Tracer 接口用来在合约执行过程中收集跟踪数据。
...@@ -23,9 +24,9 @@ type Tracer interface { ...@@ -23,9 +24,9 @@ type Tracer interface {
// CaptureStart 开始记录 // CaptureStart 开始记录
CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value uint64) error CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value uint64) error
// CaptureState 保存状态 // CaptureState 保存状态
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, rStack *mm.ReturnStack, rData []byte, contract *Contract, depth int, err error) error CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rData []byte, contract *Contract, depth int, err error) error
// CaptureFault 保存错误 // CaptureFault 保存错误
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, rStack *mm.ReturnStack, contract *Contract, depth int, err error) error CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error
// CaptureEnd 结束记录 // CaptureEnd 结束记录
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error
} }
...@@ -98,7 +99,7 @@ func (logger *JSONLogger) CaptureStart(from common.Address, to common.Address, c ...@@ -98,7 +99,7 @@ func (logger *JSONLogger) CaptureStart(from common.Address, to common.Address, c
} }
// CaptureState 输出当前虚拟机状态 // CaptureState 输出当前虚拟机状态
func (logger *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, rStack *mm.ReturnStack, rData []byte, contract *Contract, depth int, err error) error { func (logger *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rData []byte, contract *Contract, depth int, err error) error {
log := StructLog{ log := StructLog{
Pc: pc, Pc: pc,
Op: op, Op: op,
...@@ -111,7 +112,6 @@ func (logger *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ...@@ -111,7 +112,6 @@ func (logger *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost
} }
log.Memory = formatMemory(memory.Data()) log.Memory = formatMemory(memory.Data())
log.Stack = formatStack(stack.Data()) log.Stack = formatStack(stack.Data())
log.ReturnStack = rStack.Data()
log.ReturnData = rData log.ReturnData = rData
return logger.encoder.Encode(log) return logger.encoder.Encode(log)
} }
...@@ -131,7 +131,7 @@ func formatMemory(data []byte) (res []string) { ...@@ -131,7 +131,7 @@ func formatMemory(data []byte) (res []string) {
} }
//CaptureFault 目前实现为空 //CaptureFault 目前实现为空
func (logger *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, rStack *mm.ReturnStack, contract *Contract, depth int, err error) error { func (logger *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
return nil return nil
} }
...@@ -149,3 +149,69 @@ func (logger *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Durat ...@@ -149,3 +149,69 @@ func (logger *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Durat
} }
return logger.encoder.Encode(endLog{common.Bytes2Hex(output), int64(gasUsed), t, ""}) return logger.encoder.Encode(endLog{common.Bytes2Hex(output), int64(gasUsed), t, ""})
} }
type mdLogger struct {
out io.Writer
cfg *LogConfig
}
// NewMarkdownLogger creates a logger which outputs information in a format adapted
// for human readability, and is also a valid markdown table
func NewMarkdownLogger(cfg *LogConfig, writer io.Writer) *mdLogger {
l := &mdLogger{writer, cfg}
if l.cfg == nil {
l.cfg = &LogConfig{}
}
return l
}
func (t *mdLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value uint64) error {
if !create {
fmt.Fprintf(t.out, "From: `%v`\nTo: `%v`\nData: `0x%x`\nGas: `%d`\nValue `%v` wei\n",
from.String(), to.String(),
input, gas, value)
} else {
fmt.Fprintf(t.out, "From: `%v`\nCreate at: `%v`\nData: `0x%x`\nGas: `%d`\nValue `%v` wei\n",
from.String(), to.String(),
input, gas, value)
}
fmt.Fprintf(t.out, `
| Pc | Op | Cost | Stack | RStack | Refund |
|-------|-------------|------|-----------|-----------|---------|
`)
return nil
}
func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rData []byte, contract *Contract, depth int, err error) error {
fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost)
if !t.cfg.DisableStack {
// format stack
var a []string
for _, elem := range stack.data {
a = append(a, fmt.Sprintf("%v", elem.String()))
}
b := fmt.Sprintf("[%v]", strings.Join(a, ","))
fmt.Fprintf(t.out, "%10v |", b)
}
fmt.Fprintf(t.out, "%10v |", env.StateDB.GetRefund())
fmt.Fprintln(t.out, "")
if err != nil {
fmt.Fprintf(t.out, "Error: %v\n", err)
}
return nil
}
func (t *mdLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error {
fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err)
return nil
}
func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, tm time.Duration, err error) error {
fmt.Fprintf(t.out, "\nOutput: `0x%x`\nConsumed gas: `%d`\nError: `%v`\n",
output, gasUsed, err)
return nil
}
package runtime
import (
"fmt"
"github.com/holiman/uint256"
)
// Memory implements a simple memory model for the ethereum virtual machine.
type Memory struct {
store []byte
lastGasCost uint64
}
// NewMemory returns a new memory model.
func NewMemory() *Memory {
return &Memory{}
}
// Set sets offset + size to value
func (m *Memory) Set(offset, size uint64, value []byte) {
// It's possible the offset is greater than 0 and size equals 0. This is because
// the calcMemSize (common.go) could potentially return 0 when size is zero (NO-OP)
if size > 0 {
// length of store may never be less than offset + size.
// The store should be resized PRIOR to setting the memory
if offset+size > uint64(len(m.store)) {
panic("invalid memory: store empty")
}
copy(m.store[offset:offset+size], value)
}
}
// Set32 sets the 32 bytes starting at offset to the value of val, left-padded with zeroes to
// 32 bytes.
func (m *Memory) Set32(offset uint64, val *uint256.Int) {
// length of store may never be less than offset + size.
// The store should be resized PRIOR to setting the memory
if offset+32 > uint64(len(m.store)) {
panic("invalid memory: store empty")
}
// Zero the memory area
copy(m.store[offset:offset+32], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
// Fill in relevant bits
val.WriteToSlice(m.store[offset:])
}
// Resize resizes the memory to size
func (m *Memory) Resize(size uint64) {
if uint64(m.Len()) < size {
m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)
}
}
// Get returns offset + size as a new slice
func (m *Memory) GetCopy(offset, size int64) (cpy []byte) {
if size == 0 {
return nil
}
if len(m.store) > int(offset) {
cpy = make([]byte, size)
copy(cpy, m.store[offset:offset+size])
return
}
return
}
// GetPtr returns the offset + size
func (m *Memory) GetPtr(offset, size int64) []byte {
if size == 0 {
return nil
}
if len(m.store) > int(offset) {
return m.store[offset : offset+size]
}
return nil
}
// Len returns the length of the backing slice
func (m *Memory) Len() int {
return len(m.store)
}
// Data returns the backing slice
func (m *Memory) Data() []byte {
return m.store
}
// Print dumps the content of the memory.
func (m *Memory) Print() {
fmt.Printf("### mem %d bytes ###\n", len(m.store))
if len(m.store) > 0 {
addr := 0
for i := 0; i+32 <= len(m.store); i += 32 {
fmt.Printf("%03d: % x\n", addr, m.store[i:i+32])
addr++
}
} else {
fmt.Println("-- empty --")
}
fmt.Println("####################")
}
package runtime
func memorySha3(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(1))
}
func memoryCallDataCopy(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(2))
}
func memoryReturnDataCopy(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(2))
}
func memoryCodeCopy(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(2))
}
func memoryExtCodeCopy(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(1), stack.Back(3))
}
func memoryMLoad(stack *Stack) (uint64, bool) {
return calcMemSize64WithUint(stack.Back(0), 32)
}
func memoryMStore8(stack *Stack) (uint64, bool) {
return calcMemSize64WithUint(stack.Back(0), 1)
}
func memoryMStore(stack *Stack) (uint64, bool) {
return calcMemSize64WithUint(stack.Back(0), 32)
}
func memoryCreate(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(1), stack.Back(2))
}
func memoryCreate2(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(1), stack.Back(2))
}
func memoryCall(stack *Stack) (uint64, bool) {
x, overflow := calcMemSize64(stack.Back(5), stack.Back(6))
if overflow {
return 0, true
}
y, overflow := calcMemSize64(stack.Back(3), stack.Back(4))
if overflow {
return 0, true
}
if x > y {
return x, false
}
return y, false
}
func memoryDelegateCall(stack *Stack) (uint64, bool) {
x, overflow := calcMemSize64(stack.Back(4), stack.Back(5))
if overflow {
return 0, true
}
y, overflow := calcMemSize64(stack.Back(2), stack.Back(3))
if overflow {
return 0, true
}
if x > y {
return x, false
}
return y, false
}
func memoryStaticCall(stack *Stack) (uint64, bool) {
x, overflow := calcMemSize64(stack.Back(4), stack.Back(5))
if overflow {
return 0, true
}
y, overflow := calcMemSize64(stack.Back(2), stack.Back(3))
if overflow {
return 0, true
}
if x > y {
return x, false
}
return y, false
}
func memoryReturn(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(1))
}
func memoryRevert(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(1))
}
func memoryLog(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(1))
}
package runtime
import (
"fmt"
"sync"
"github.com/holiman/uint256"
)
var stackPool = sync.Pool{
New: func() interface{} {
return &Stack{data: make([]uint256.Int, 0, 16)}
},
}
// Stack is an object for basic stack operations. Items popped to the stack are
// expected to be changed and modified. stack does not take care of adding newly
// initialised objects.
type Stack struct {
data []uint256.Int
}
func newstack() *Stack {
return stackPool.Get().(*Stack)
}
func returnStack(s *Stack) {
s.data = s.data[:0]
stackPool.Put(s)
}
// Data returns the underlying uint256.Int array.
func (st *Stack) Data() []uint256.Int {
return st.data
}
func (st *Stack) push(d *uint256.Int) {
// NOTE push limit (1024) is checked in baseCheck
st.data = append(st.data, *d)
}
func (st *Stack) pushN(ds ...uint256.Int) {
// FIXME: Is there a way to pass args by pointers.
st.data = append(st.data, ds...)
}
func (st *Stack) pop() (ret uint256.Int) {
ret = st.data[len(st.data)-1]
st.data = st.data[:len(st.data)-1]
return
}
func (st *Stack) len() int {
return len(st.data)
}
func (st *Stack) swap(n int) {
st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n]
}
func (st *Stack) dup(n int) {
st.push(&st.data[st.len()-n])
}
func (st *Stack) peek() *uint256.Int {
return &st.data[st.len()-1]
}
// Back returns the n'th item in stack
func (st *Stack) Back(n int) *uint256.Int {
return &st.data[st.len()-n-1]
}
// Print dumps the content of the stack
func (st *Stack) Print() {
fmt.Println("### stack ###")
if len(st.data) > 0 {
for i, val := range st.data {
fmt.Printf("%-3d %v\n", i, val)
}
} else {
fmt.Println("-- empty --")
}
fmt.Println("#############")
}
package runtime
import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/params"
)
func minSwapStack(n int) int {
return minStack(n, n)
}
func maxSwapStack(n int) int {
return maxStack(n, n)
}
func minDupStack(n int) int {
return minStack(n, n+1)
}
func maxDupStack(n int) int {
return maxStack(n, n+1)
}
func maxStack(pop, push int) int {
return int(params.StackLimit) + pop - push
}
func minStack(pops, push int) int {
return pops
}
[
{
"Input": "0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"Expected": "08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b",
"Name": "vector 4",
"Gas": 0,
"NoBenchmark": false
},
{
"Input": "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"Expected": "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923",
"Name": "vector 5",
"Gas": 12,
"NoBenchmark": false
},
{
"Input": "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000",
"Expected": "75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735",
"Name": "vector 6",
"Gas": 12,
"NoBenchmark": false
},
{
"Input": "0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"Expected": "b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421",
"Name": "vector 7",
"Gas": 1,
"NoBenchmark": false
},
{
"Input": "007A120048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"Expected": "6d2ce9e534d50e18ff866ae92d70cceba79bbcd14c63819fe48752c8aca87a4bb7dcc230d22a4047f0486cfcfb50a17b24b2899eb8fca370f22240adb5170189",
"Name": "vector 8",
"Gas": 8000000,
"NoBenchmark": false
}
]
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
[
{
"Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726607c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7",
"Expected": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915",
"Name": "chfast1",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c91518b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f37266",
"Expected": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204",
"Name": "chfast2",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Name": "cdetrio1",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Name": "cdetrio2",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Name": "cdetrio3",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "",
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Name": "cdetrio4",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Name": "cdetrio5",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Name": "cdetrio6",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Name": "cdetrio7",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Name": "cdetrio8",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Gas": 150,
"Name": "cdetrio9",
"NoBenchmark": false
},
{
"Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Gas": 150,
"Name": "cdetrio10",
"NoBenchmark": false
},
{
"Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
"Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4",
"Name": "cdetrio11",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4",
"Name": "cdetrio12",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98",
"Expected": "15bf2bb17880144b5d1cd2b1f46eff9d617bffd1ca57c37fb5a49bd84e53cf66049c797f9ce0d17083deb32b5e36f2ea2a212ee036598dd7624c168993d1355f",
"Name": "cdetrio13",
"Gas": 150,
"NoBenchmark": false
},
{
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"Name": "cdetrio14",
"Gas": 150,
"NoBenchmark": false
}
]
\ No newline at end of file
[
{
"Input": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20400000000000000000000000000000000000000000000000011138ce750fa15c2",
"Expected": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc",
"Name": "chfast1",
"Gas": 6000,
"NoBenchmark": false
},
{
"Input": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46",
"Expected": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e",
"Name": "chfast2",
"Gas": 6000,
"NoBenchmark": false
},
{
"Input": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3",
"Expected": "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27",
"Name": "chfast3",
"Gas": 6000,
"NoBenchmark": false
},
{
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"Expected": "2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11",
"Name": "cdetrio1",
"Gas": 6000,
"NoBenchmark": false
},
{
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
"Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451",
"Name": "cdetrio2",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000",
"Expected": "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b",
"Name": "cdetrio3",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009",
"Expected": "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575",
"Name": "cdetrio4",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001",
"Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6",
"Name": "cdetrio5",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"Expected": "29e587aadd7c06722aabba753017c093f70ba7eb1f1c0104ec0564e7e3e21f6022b1143f6a41008e7755c71c3d00b6b915d386de21783ef590486d8afa8453b1",
"Name": "cdetrio6",
"Gas": 6000,
"NoBenchmark": false
},
{
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
"Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb",
"Name": "cdetrio7",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000",
"Expected": "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15",
"Name": "cdetrio8",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009",
"Expected": "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a",
"Name": "cdetrio9",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001",
"Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c",
"Name": "cdetrio10",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"Expected": "00a1a234d08efaa2616607e31eca1980128b00b415c845ff25bba3afcb81dc00242077290ed33906aeb8e42fd98c41bcb9057ba03421af3f2d08cfc441186024",
"Name": "cdetrio11",
"Gas": 6000,
"NoBenchmark": false
},
{
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
"Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf",
"Name": "cdetrio12",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000",
"Expected": "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434",
"Name": "cdetrio13",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009",
"Expected": "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f",
"Name": "cdetrio14",
"Gas": 6000,
"NoBenchmark": true
},
{
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001",
"Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98",
"Name": "cdetrio15",
"Gas": 6000,
"NoBenchmark": true
}
]
\ No newline at end of file
[
{
"Input": "a8b53bdf3306a35a7103ab5504a0c9b492295564b6202b1942a84ef300107281000000000000000000000000000000000000000000000000000000000000001b307835653165303366353363653138623737326363623030393366663731663366353366356337356237346463623331613835616138623838393262346538621122334455667788991011121314151617181920212223242526272829303132",
"Expected": "",
"Gas": 3000,
"Name": "CallEcrecoverUnrecoverableKey",
"NoBenchmark": false
},
{
"Input": "cc2427f9c0de9457dbaeddc063888c47353ce8df2b8571944ebe389acf049dc0000000000000000000000000000000000000000000000000000000000000001b4cf8ae36067ccb3ee2f15b91e7f3e10fac9f38fc020ded6dbae65874c84a9c5d24c849055170d52dd5b19c5b4408e5f64e6f147cb456a01c4160b444fbb11a54",
"Expected": "000000000000000000000000245afbf176934ccdd7ca291a8dddaa13c8184822",
"Gas": 3000,
"Name": "ValidKey",
"NoBenchmark": false
},
{
"Input": "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c100000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
"Expected": "",
"Gas": 3000,
"Name": "InvalidHighV-bits-1",
"NoBenchmark": false
},
{
"Input": "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000001000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
"Expected": "",
"Gas": 3000,
"Name": "InvalidHighV-bits-2",
"NoBenchmark": false
},
{
"Input": "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000001000000000000000000000011c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
"Expected": "",
"Gas": 3000,
"Name": "InvalidHighV-bits-3",
"NoBenchmark": false
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "vector 0: empty input"
},
{
"Input": "00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"ExpectedError": "invalid input length",
"Name": "vector 1: less than 213 bytes input"
},
{
"Input": "000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001",
"ExpectedError": "invalid input length",
"Name": "vector 2: more than 213 bytes input"
},
{
"Input": "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002",
"ExpectedError": "invalid final flag",
"Name": "vector 3: malformed final block indicator flag"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_g1add_empty_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1",
"ExpectedError": "invalid input length",
"Name": "bls_g1add_short_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1",
"ExpectedError": "invalid input length",
"Name": "bls_g1add_large_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000108b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_g1add_violate_top_bytes"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1",
"ExpectedError": "must be less than modulus",
"Name": "bls_g1add_invalid_field_element"
},
{
"Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1",
"ExpectedError": "point is not on curve",
"Name": "bls_g1add_point_not_on_curve"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_g1mul_empty_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g1mul_short_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g1mul_large_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000108b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_g1mul_violate_top_bytes"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "must be less than modulus",
"Name": "bls_g1mul_invalid_field_element"
},
{
"Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
"ExpectedError": "point is not on curve",
"Name": "bls_g1mul_point_not_on_curve"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_g1multiexp_empty_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb00000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g1multiexp_short_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g1multiexp_large_input"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "must be less than modulus",
"Name": "bls_g1multiexp_invalid_field_element"
},
{
"Input": "0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000108b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e10000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_g1multiexp_violate_top_bytes"
},
{
"Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
"ExpectedError": "point is not on curve",
"Name": "bls_g1multiexp_point_not_on_curve"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_g2add_empty_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b828010000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be",
"ExpectedError": "invalid input length",
"Name": "bls_g2add_short_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b8280100000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be",
"ExpectedError": "invalid input length",
"Name": "bls_g2add_large_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000010606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_g2add_violate_top_bytes"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be",
"ExpectedError": "must be less than modulus",
"Name": "bls_g2add_invalid_field_element"
},
{
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be",
"ExpectedError": "point is not on curve",
"Name": "bls_g2add_point_not_on_curve"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_g2mul_empty_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b828010000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g2mul_short_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b8280100000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g2mul_large_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000010606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_g2mul_violate_top_bytes"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "must be less than modulus",
"Name": "bls_g2mul_invalid_field_element"
},
{
"Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
"ExpectedError": "point is not on curve",
"Name": "bls_g2mul_point_not_on_curve"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_g2multiexp_empty_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b828010000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g2multiexp_short_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b8280100000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid input length",
"Name": "bls_g2multiexp_large_input"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000010606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_g2multiexp_violate_top_bytes"
},
{
"Input": "00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac0000000000000000000000000000000000000000000000000000000000000007",
"ExpectedError": "must be less than modulus",
"Name": "bls_g2multiexp_invalid_field_element"
},
{
"Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
"ExpectedError": "point is not on curve",
"Name": "bls_g2multiexp_point_not_on_curve"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_mapg1_empty_input"
},
{
"Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"ExpectedError": "invalid input length",
"Name": "bls_mapg1_short_input"
},
{
"Input": "00000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_mapg1_top_bytes"
},
{
"Input": "000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac",
"ExpectedError": "must be less than modulus",
"Name": "bls_mapg1_invalid_fq_element"
}
]
\ No newline at end of file
[
{
"Input": "",
"ExpectedError": "invalid input length",
"Name": "bls_mapg2_empty_input"
},
{
"Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"ExpectedError": "invalid input length",
"Name": "bls_mapg2_short_input"
},
{
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"ExpectedError": "invalid field element top bytes",
"Name": "bls_mapg2_top_bytes"
},
{
"Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac",
"ExpectedError": "must be less than modulus",
"Name": "bls_mapg2_invalid_fq_element"
}
]
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -76,7 +76,7 @@ type EVMStateDB interface { ...@@ -76,7 +76,7 @@ type EVMStateDB interface {
AddPreimage(common.Hash, []byte) AddPreimage(common.Hash, []byte)
// CanTransfer 当前账户余额是否足够转账 // CanTransfer 当前账户余额是否足够转账
CanTransfer(sender, recipient string, amount uint64) bool CanTransfer(sender string, amount uint64) bool
// Transfer 转账交易 // Transfer 转账交易
Transfer(sender, recipient string, amount uint64) bool Transfer(sender, recipient string, amount uint64) bool
......
...@@ -7,6 +7,8 @@ package state ...@@ -7,6 +7,8 @@ package state
import ( import (
"sort" "sort"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common" "github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types" evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
...@@ -84,7 +86,6 @@ func (ver *Snapshot) getData() (kvSet []*types.KeyValue, logs []*types.ReceiptLo ...@@ -84,7 +86,6 @@ func (ver *Snapshot) getData() (kvSet []*types.KeyValue, logs []*types.ReceiptLo
} }
type ( type (
// 基础变更对象,用于封装默认操作 // 基础变更对象,用于封装默认操作
baseChange struct { baseChange struct {
} }
...@@ -149,6 +150,7 @@ type ( ...@@ -149,6 +150,7 @@ type (
addLogChange struct { addLogChange struct {
baseChange baseChange
txhash common.Hash txhash common.Hash
logs []*types.ReceiptLog
} }
// 合约生成sha3事件 // 合约生成sha3事件
...@@ -298,7 +300,18 @@ func (ch addLogChange) revert(mdb *MemoryStateDB) { ...@@ -298,7 +300,18 @@ func (ch addLogChange) revert(mdb *MemoryStateDB) {
} else { } else {
mdb.logs[ch.txhash] = logs[:len(logs)-1] mdb.logs[ch.txhash] = logs[:len(logs)-1]
} }
mdb.logSize-- mdb.logSize--
log15.Info("addLogChange::revert", "mdb.logSize", mdb.logSize)
}
func (ch addLogChange) getLog(mdb *MemoryStateDB) []*types.ReceiptLog {
cfg := mdb.api.GetConfig()
if !cfg.IsDappFork(mdb.blockHeight, "evm", evmtypes.ForkEVMState) {
return nil
}
return ch.logs
} }
func (ch addPreimageChange) revert(mdb *MemoryStateDB) { func (ch addPreimageChange) revert(mdb *MemoryStateDB) {
......
...@@ -39,12 +39,14 @@ message EVMContractAction { ...@@ -39,12 +39,14 @@ message EVMContractAction {
uint32 gasPrice = 3; uint32 gasPrice = 3;
// 合约数据 // 合约数据
bytes code = 4; bytes code = 4;
//交易参数
bytes para = 5;
// 合约别名,方便识别 // 合约别名,方便识别
string alias = 5; string alias = 6;
// 交易备注 // 交易备注
string note = 6; string note = 7;
// 创建或调用合约时携带的ABI数据 ForkEVMABI // 调用合约地址
string abi = 7; string contractAddr = 8;
} }
// 合约创建/调用日志 // 合约创建/调用日志
...@@ -107,10 +109,9 @@ message CheckEVMAddrResp { ...@@ -107,10 +109,9 @@ message CheckEVMAddrResp {
message EstimateEVMGasReq { message EstimateEVMGasReq {
string to = 1; string to = 1;
bytes code = 2; bytes para = 2;
string caller = 3; string caller = 3;
uint64 amount = 4; uint64 amount = 4;
string abi = 5;
} }
message EstimateEVMGasResp { message EstimateEVMGasResp {
uint64 gas = 1; uint64 gas = 1;
...@@ -150,32 +151,63 @@ message EvmQueryResp { ...@@ -150,32 +151,63 @@ message EvmQueryResp {
message EvmContractCreateReq { message EvmContractCreateReq {
string code = 1; string code = 1;
int64 fee = 2; string abi = 2;
string note = 3; int64 fee = 3;
string alias = 4; string note = 4;
string caller = 5; string alias = 5;
string abi = 6; string parameter= 6;
string expire = 7; string expire = 7;
string paraName = 8; string paraName = 8;
int64 amount = 9;
} }
message EvmContractCallReq { message EvmContractCallReq {
uint64 amount = 1; int64 amount = 1;
string code = 2; int64 fee = 2;
int64 fee = 3; string note = 3;
string note = 4; string parameter = 4;
string caller = 5; string contractAddr = 5;
string abi = 6; string expire = 6;
string exec = 7; string paraName = 7;
string expire = 8; string abi = 8;
string paraName = 9; }
message EvmTransferOnlyReq {
string to = 1;
int64 amount = 2;
string paraName = 3;
string note = 4;
}
message EvmGetNonceReq {
string address = 1;
}
message EvmGetNonceRespose {
int64 nonce = 1;
} }
message EvmContractTransferReq { message EvmCalcNewContractAddrReq {
string caller = 1; string caller = 1;
float amount = 2; string txhash = 2;
string exec = 3; }
string expire = 4;
bool isWithdraw = 5; message EvmGetPackDataReq {
string paraName = 6; string abi = 1;
} string parameter = 2;
\ No newline at end of file }
message EvmGetPackDataRespose {
string packData = 1;
}
message EvmGetUnpackDataReq {
string abi = 1;
string parameter = 2;
string data = 3;
}
message EvmGetUnpackDataRespose {
repeated string unpackData = 1;
}
...@@ -8,17 +8,19 @@ import ( ...@@ -8,17 +8,19 @@ import (
"context" "context"
"encoding/hex" "encoding/hex"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
evm "github.com/33cn/plugin/plugin/dapp/evm/types" evm "github.com/33cn/plugin/plugin/dapp/evm/types"
) )
// EvmCreateTx 创建Evm合约接口 // EvmCreateTx 创建Evm合约接口
func (c *Jrpc) EvmCreateTx(parm *evm.EvmContractCreateReq, result *interface{}) error { func (c *Jrpc) CreateDeployTx(parm *evm.EvmContractCreateReq, result *interface{}) error {
if parm == nil { if parm == nil {
return types.ErrInvalidParam return types.ErrInvalidParam
} }
reply, err := c.cli.Create(context.Background(), *parm) reply, err := c.cli.CreateDeployTx(context.Background(), *parm)
if err != nil { if err != nil {
return err return err
} }
...@@ -26,13 +28,13 @@ func (c *Jrpc) EvmCreateTx(parm *evm.EvmContractCreateReq, result *interface{}) ...@@ -26,13 +28,13 @@ func (c *Jrpc) EvmCreateTx(parm *evm.EvmContractCreateReq, result *interface{})
return nil return nil
} }
// EvmCallTx 调用Evm合约接口 // CreateCallTx 创建调用EVM合约交易
func (c *Jrpc) EvmCallTx(parm *evm.EvmContractCallReq, result *interface{}) error { func (c *Jrpc) CreateCallTx(parm *evm.EvmContractCallReq, result *interface{}) error {
if parm == nil { if parm == nil {
return types.ErrInvalidParam return types.ErrInvalidParam
} }
reply, err := c.cli.Call(context.Background(), *parm) reply, err := c.cli.CreateCallTx(context.Background(), *parm)
if err != nil { if err != nil {
return err return err
} }
...@@ -40,32 +42,26 @@ func (c *Jrpc) EvmCallTx(parm *evm.EvmContractCallReq, result *interface{}) erro ...@@ -40,32 +42,26 @@ func (c *Jrpc) EvmCallTx(parm *evm.EvmContractCallReq, result *interface{}) erro
return nil return nil
} }
// EvmTransferTx Evm转账接口 // CreateTransferOnlyTx 创建只进行evm内部转账的交易
func (c *Jrpc) EvmTransferTx(parm *evm.EvmContractTransferReq, result *interface{}) error { func (c *Jrpc) CreateTransferOnlyTx(parm *evm.EvmTransferOnlyReq, result *interface{}) error {
if parm == nil { if parm == nil {
return types.ErrInvalidParam return types.ErrInvalidParam
} }
reply, err := c.cli.Transfer(context.Background(), *parm, false) reply, err := c.cli.CreateTransferOnlyTx(context.Background(), *parm)
if err != nil { if err != nil {
return err return err
} }
*result = hex.EncodeToString(reply.Data) *result = hex.EncodeToString(reply.Data)
return nil return nil
} }
// EvmWithdrawTx Evm转账接口 // CalcNewContractAddr Evm部署合约的地址
func (c *Jrpc) EvmWithdrawTx(parm *evm.EvmContractTransferReq, result *interface{}) error { func (c *Jrpc) CalcNewContractAddr(parm *evm.EvmCalcNewContractAddrReq, result *interface{}) error {
if parm == nil { if parm == nil {
return types.ErrInvalidParam return types.ErrInvalidParam
} }
newContractAddr := address.GetExecAddress(parm.Caller + parm.Txhash)
reply, err := c.cli.Transfer(context.Background(), *parm, true) *result = newContractAddr.String()
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil return nil
} }
...@@ -13,25 +13,44 @@ import ( ...@@ -13,25 +13,44 @@ import (
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
cty "github.com/33cn/chain33/system/dapp/coins/types"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
evmAbi "github.com/33cn/plugin/plugin/dapp/evm/executor/abi"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types" evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
) )
// CreateEvmCallTx 创建未签名的调用evm交易 // CreateEvmCallTx 创建未签名的部署合约交易
func (c *channelClient) Create(ctx context.Context, in evmtypes.EvmContractCreateReq) (*types.UnsignTx, error) { func (c *channelClient) CreateDeployTx(ctx context.Context, in evmtypes.EvmContractCreateReq) (*types.UnsignTx, error) {
amountInt64 := in.Amount
exec := in.ParaName + evmtypes.ExecutorName
toAddr := address.ExecAddress(exec)
bCode, err := common.FromHex(in.Code) bCode, err := common.FromHex(in.Code)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err) fmt.Fprintln(os.Stderr, "parse evm code error", err)
return nil, err return nil, err
} }
if "" != in.Parameter {
packData, err := evmAbi.PackContructorPara(in.Parameter, in.Abi)
if err != nil {
return nil, err
}
bCode = append(bCode, packData...)
}
action := evmtypes.EVMContractAction{Amount: 0, Code: bCode, GasLimit: 0, GasPrice: 0, Note: in.Note, Abi: in.Abi} action := evmtypes.EVMContractAction{
Amount: uint64(amountInt64),
GasLimit: 0,
GasPrice: 0,
Code: bCode,
Para: nil,
Alias: in.Alias,
Note: in.Note,
ContractAddr: toAddr,
}
cfg := c.GetConfig() cfg := c.GetConfig()
execer := cfg.ExecName(in.ParaName + "evm") tx := &types.Transaction{Execer: []byte(exec), Payload: types.Encode(&action), Fee: 0, To: toAddr}
addr := address.ExecAddress(cfg.ExecName(in.ParaName + "evm"))
tx := &types.Transaction{Execer: []byte(execer), Payload: types.Encode(&action), Fee: 0, To: addr}
tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate()) tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate())
if tx.Fee < in.Fee { if tx.Fee < in.Fee {
...@@ -46,20 +65,29 @@ func (c *channelClient) Create(ctx context.Context, in evmtypes.EvmContractCreat ...@@ -46,20 +65,29 @@ func (c *channelClient) Create(ctx context.Context, in evmtypes.EvmContractCreat
return &types.UnsignTx{Data: txHex}, nil return &types.UnsignTx{Data: txHex}, nil
} }
func (c *channelClient) Call(ctx context.Context, in evmtypes.EvmContractCallReq) (*types.UnsignTx, error) { func (c *channelClient) CreateCallTx(ctx context.Context, in evmtypes.EvmContractCallReq) (*types.UnsignTx, error) {
amountInt64 := in.Amount * 1e4 * 1e4 amountInt64 := in.Amount
feeInt64 := in.Fee * 1e4 * 1e4 feeInt64 := in.Fee
toAddr := address.ExecAddress(in.Exec) exec := in.ParaName + evmtypes.ExecutorName
toAddr := address.ExecAddress(exec)
bCode, err := common.FromHex(in.Code) _, packedParameter, err := evmAbi.Pack(in.Parameter, in.Abi, false)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err)
return nil, err return nil, err
} }
action := evmtypes.EVMContractAction{Amount: amountInt64, Code: bCode, GasLimit: 0, GasPrice: 0, Note: in.Note, Abi: in.Abi} action := evmtypes.EVMContractAction{
Amount: uint64(amountInt64),
GasLimit: 0,
GasPrice: 0,
Code: nil,
Para: packedParameter,
Alias: "",
Note: in.Note,
ContractAddr: in.ContractAddr,
}
tx := &types.Transaction{Execer: []byte(in.Exec), Payload: types.Encode(&action), Fee: 0, To: toAddr} tx := &types.Transaction{Execer: []byte(exec), Payload: types.Encode(&action), Fee: 0, To: toAddr}
cfg := c.GetConfig() cfg := c.GetConfig()
tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate()) tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate())
...@@ -75,32 +103,29 @@ func (c *channelClient) Call(ctx context.Context, in evmtypes.EvmContractCallReq ...@@ -75,32 +103,29 @@ func (c *channelClient) Call(ctx context.Context, in evmtypes.EvmContractCallReq
return &types.UnsignTx{Data: txHex}, nil return &types.UnsignTx{Data: txHex}, nil
} }
func (c *channelClient) Transfer(ctx context.Context, in evmtypes.EvmContractTransferReq, isWithdraw bool) (*types.UnsignTx, error) { func (c *channelClient) CreateTransferOnlyTx(ctx context.Context, in evmtypes.EvmTransferOnlyReq) (*types.UnsignTx, error) {
var tx *types.Transaction exec := in.ParaName + evmtypes.ExecutorName
transfer := &cty.CoinsAction{} toAddr := address.ExecAddress(exec)
amountInt64 := int64(in.Amount*1e4) * 1e4
execName := in.Exec
if isWithdraw {
transfer.Value = &cty.CoinsAction_Withdraw{Withdraw: &types.AssetsWithdraw{Amount: amountInt64, ExecName: execName, To: address.ExecAddress(execName)}}
transfer.Ty = cty.CoinsActionWithdraw
} else {
transfer.Value = &cty.CoinsAction_TransferToExec{TransferToExec: &types.AssetsTransferToExec{Amount: amountInt64, ExecName: execName, To: address.ExecAddress(execName)}}
transfer.Ty = cty.CoinsActionTransferToExec
}
cfg := c.GetConfig()
if in.ParaName == "" {
tx = &types.Transaction{Execer: []byte(cfg.ExecName(in.ParaName + "coins")), Payload: types.Encode(transfer), To: address.ExecAddress(execName)}
} else {
tx = &types.Transaction{Execer: []byte(cfg.ExecName(in.ParaName + "coins")), Payload: types.Encode(transfer), To: address.ExecAddress(cfg.ExecName(in.ParaName + "coins"))}
}
var err error r_addr, err := address.NewAddrFromString(in.To)
tx.Fee, err = tx.GetRealFee(cfg.GetMinTxFeeRate()) if nil != err {
if err != nil {
return nil, err return nil, err
} }
action := evmtypes.EVMContractAction{
Amount: uint64(in.Amount),
GasLimit: 0,
GasPrice: 0,
Code: nil,
Para: r_addr.Hash160[:],
Alias: "",
Note: in.Note,
ContractAddr: toAddr,
}
tx := &types.Transaction{Execer: []byte(exec), Payload: types.Encode(&action), Fee: 0, To: toAddr}
cfg := c.GetConfig()
tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate())
random := rand.New(rand.NewSource(time.Now().UnixNano())) random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63() tx.Nonce = random.Int63()
tx.ChainID = cfg.GetChainID() tx.ChainID = cfg.GetChainID()
......
...@@ -147,10 +147,6 @@ func createEvmTx(cfg *types.Chain33Config, param *CreateCallTx) (*types.Transact ...@@ -147,10 +147,6 @@ func createEvmTx(cfg *types.Chain33Config, param *CreateCallTx) (*types.Transact
Note: param.Note, Note: param.Note,
Alias: param.Alias, Alias: param.Alias,
} }
// Abi数据和二进制代码必须指定一个,优先判断ABI
if len(param.Abi) > 0 {
action.Abi = strings.TrimSpace(param.Abi)
}
if len(param.Code) > 0 { if len(param.Code) > 0 {
bCode, err := common.FromHex(param.Code) bCode, err := common.FromHex(param.Code)
if err != nil { if err != nil {
...@@ -160,8 +156,17 @@ func createEvmTx(cfg *types.Chain33Config, param *CreateCallTx) (*types.Transact ...@@ -160,8 +156,17 @@ func createEvmTx(cfg *types.Chain33Config, param *CreateCallTx) (*types.Transact
action.Code = bCode action.Code = bCode
} }
if len(param.Para) > 0 {
para, err := common.FromHex(param.Para)
if err != nil {
elog.Error("create evm Tx error, code is invalid", "param.Code", param.Code)
return nil, err
}
action.Para = para
}
if param.IsCreate { if param.IsCreate {
if len(action.Abi) > 0 && len(action.Code) == 0 { if len(action.Code) == 0 {
elog.Error("create evm Tx error, code is empty") elog.Error("create evm Tx error, code is empty")
return nil, errors.New("code must be set in create tx") return nil, errors.New("code must be set in create tx")
} }
......
...@@ -104,5 +104,4 @@ func TestEvmType_CreateTx(t *testing.T) { ...@@ -104,5 +104,4 @@ func TestEvmType_CreateTx(t *testing.T) {
assert.EqualValues(t, address.ExecAddress(cfg.ExecName(test.Name)), tx.To) assert.EqualValues(t, address.ExecAddress(cfg.ExecName(test.Name)), tx.To)
} }
} }
} }
This diff is collapsed.
...@@ -24,6 +24,6 @@ type CreateCallTx struct { ...@@ -24,6 +24,6 @@ type CreateCallTx struct {
Name string `json:"name"` Name string `json:"name"`
// IsCreate 是否创建合约 // IsCreate 是否创建合约
IsCreate bool `json:"isCreate"` IsCreate bool `json:"isCreate"`
// Abi 创建合约或调用合约时附带的ABI数据 // 调用参数
Abi string `json:"abi"` Para string `json:"para"`
} }
...@@ -24,6 +24,8 @@ const ( ...@@ -24,6 +24,8 @@ const (
TyLogCallContract = 603 TyLogCallContract = 603
// TyLogEVMStateChangeItem 合约状态数据变更项日志 // TyLogEVMStateChangeItem 合约状态数据变更项日志
TyLogEVMStateChangeItem = 604 TyLogEVMStateChangeItem = 604
// TyLogEVMEventData 合约生成新的event日志数据
TyLogEVMEventData = 605
// MaxGasLimit 最大Gas消耗上限 // MaxGasLimit 最大Gas消耗上限
MaxGasLimit = 10000000 MaxGasLimit = 10000000
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment