Commit f1e49e77 authored by Litian's avatar Litian Committed by 33cn

fix linter

parent 1c444966
......@@ -28,6 +28,7 @@ import (
"github.com/spf13/cobra"
)
//EvmCmd 是Evm命令行入口
func EvmCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "evm",
......@@ -36,32 +37,32 @@ func EvmCmd() *cobra.Command {
}
cmd.AddCommand(
CreateContractCmd(),
CallContractCmd(),
EstimateContractCmd(),
CheckContractAddrCmd(),
EvmDebugCmd(),
EvmTransferCmd(),
EvmWithdrawCmd(),
GetEvmBalanceCmd(),
EvmToolsCmd(),
createContractCmd(),
callContractCmd(),
estimateContractCmd(),
checkContractAddrCmd(),
evmDebugCmd(),
evmTransferCmd(),
evmWithdrawCmd(),
getEvmBalanceCmd(),
evmToolsCmd(),
)
return cmd
}
// some tools for evm op
func EvmToolsCmd() *cobra.Command {
func evmToolsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "tool",
Short: "Some tools for evm op",
}
cmd.AddCommand(EvmToolsAddressCmd())
cmd.AddCommand(evmToolsAddressCmd())
return cmd
}
// transfer address format between ethereum and chain33
func EvmToolsAddressCmd() *cobra.Command {
func evmToolsAddressCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "address",
Short: "Transfer address format between ethereum and local (you should input one address of them)",
......@@ -105,7 +106,7 @@ func transferAddress(cmd *cobra.Command, args []string) {
addr = *addrP
fmt.Println(fmt.Sprintf("Local Address: %v", local))
}
fmt.Println(fmt.Sprintf("Ethereum Address: %v", ChecksumAddr(addr.Bytes())))
fmt.Println(fmt.Sprintf("Ethereum Address: %v", checksumAddr(addr.Bytes())))
return
}
......@@ -113,7 +114,7 @@ func transferAddress(cmd *cobra.Command, args []string) {
}
// get balance of an execer
func GetEvmBalanceCmd() *cobra.Command {
func getEvmBalanceCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "balance",
Short: "Get balance of a evm contract address",
......@@ -161,11 +162,16 @@ func evmBalance(cmd *cobra.Command, args []string) {
ctx.Run()
}
// AccountResult 账户余额查询出来之后进行单位转换
type AccountResult struct {
Currency int32 `json:"currency,omitempty"`
Balance string `json:"balance,omitempty"`
Frozen string `json:"frozen,omitempty"`
Addr string `json:"addr,omitempty"`
// 货币
Currency int32 `json:"currency,omitempty"`
// 余额
Balance string `json:"balance,omitempty"`
// 冻结余额
Frozen string `json:"frozen,omitempty"`
// 账户地址
Addr string `json:"addr,omitempty"`
}
func parseGetBalanceRes(arg interface{}) (interface{}, error) {
......@@ -182,7 +188,7 @@ func parseGetBalanceRes(arg interface{}) (interface{}, error) {
}
// 创建EVM合约
func CreateContractCmd() *cobra.Command {
func createContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Create a new EVM contract",
......@@ -319,7 +325,7 @@ func createEvmTransferTx(cmd *cobra.Command, caller, execName, expire, rpcLaddr
}
// 调用EVM合约
func CallContractCmd() *cobra.Command {
func callContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "call",
Short: "Call the EVM contract",
......@@ -431,7 +437,7 @@ func addEstimateFlags(cmd *cobra.Command) {
}
// 估算合约消耗
func EstimateContractCmd() *cobra.Command {
func estimateContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "estimate",
Short: "Estimate the gas cost of calling or creating a contract",
......@@ -442,7 +448,7 @@ func EstimateContractCmd() *cobra.Command {
}
// 检查地址是否为EVM合约
func CheckContractAddrCmd() *cobra.Command {
func checkContractAddrCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "check",
Short: "Check if the address is a valid EVM contract",
......@@ -485,34 +491,34 @@ func checkContractAddr(cmd *cobra.Command, args []string) {
}
// 查询或设置EVM调试开关
func EvmDebugCmd() *cobra.Command {
func evmDebugCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "debug",
Short: "Query or set evm debug status",
}
cmd.AddCommand(
EvmDebugQueryCmd(),
EvmDebugSetCmd(),
EvmDebugClearCmd())
evmDebugQueryCmd(),
evmDebugSetCmd(),
evmDebugClearCmd())
return cmd
}
func EvmDebugQueryCmd() *cobra.Command {
func evmDebugQueryCmd() *cobra.Command {
return &cobra.Command{
Use: "query",
Short: "Query evm debug status",
Run: evmDebugQuery,
}
}
func EvmDebugSetCmd() *cobra.Command {
func evmDebugSetCmd() *cobra.Command {
return &cobra.Command{
Use: "set",
Short: "Set evm debug to ON",
Run: evmDebugSet,
}
}
func EvmDebugClearCmd() *cobra.Command {
func evmDebugClearCmd() *cobra.Command {
return &cobra.Command{
Use: "clear",
Short: "Set evm debug to OFF",
......@@ -521,17 +527,17 @@ func EvmDebugClearCmd() *cobra.Command {
}
func evmDebugQuery(cmd *cobra.Command, args []string) {
evmDebugRpc(cmd, 0)
evmDebugRPC(cmd, 0)
}
func evmDebugSet(cmd *cobra.Command, args []string) {
evmDebugRpc(cmd, 1)
evmDebugRPC(cmd, 1)
}
func evmDebugClear(cmd *cobra.Command, args []string) {
evmDebugRpc(cmd, -1)
evmDebugRPC(cmd, -1)
}
func evmDebugRpc(cmd *cobra.Command, flag int32) {
func evmDebugRPC(cmd *cobra.Command, flag int32) {
var debugReq = evmtypes.EvmDebugReq{Optype: flag}
var debugResp evmtypes.EvmDebugResp
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
......@@ -545,7 +551,7 @@ func evmDebugRpc(cmd *cobra.Command, flag int32) {
}
// 向EVM合约地址转账
func EvmTransferCmd() *cobra.Command {
func evmTransferCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "transfer",
Short: "Transfer to evm contract address",
......@@ -593,7 +599,7 @@ func evmTransfer(cmd *cobra.Command, args []string) {
}
// 向EVM合约地址转账
func EvmWithdrawCmd() *cobra.Command {
func evmWithdrawCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "withdraw",
Short: "Withdraw from evm contract address to caller's balance",
......@@ -662,7 +668,7 @@ func sendQuery(rpcAddr, funcName string, request interface{}, result proto.Messa
}
// 这里实现 EIP55中提及的以太坊地址表示方式(增加Checksum)
func ChecksumAddr(address []byte) string {
func checksumAddr(address []byte) string {
unchecksummed := hex.EncodeToString(address[:])
sha := sha3.NewKeccak256()
sha.Write([]byte(unchecksummed))
......
......@@ -24,7 +24,7 @@ import (
var (
evmDebug = false
// 本合约地址
// EvmAddress 本合约地址
EvmAddress = address.ExecAddress(types.ExecName(evmtypes.ExecutorName))
)
......@@ -35,6 +35,7 @@ func init() {
ety.InitFuncList(types.ListMethod(&EVMExecutor{}))
}
// Init 初始化本合约对象
func Init(name string, sub []byte) {
driverName = name
drivers.Register(driverName, newEVMDriver, types.GetDappFork(driverName, "Enable"))
......@@ -43,6 +44,7 @@ func Init(name string, sub []byte) {
state.InitForkData()
}
// GetName 返回本合约名称
func GetName() string {
return newEVMDriver().GetName()
}
......@@ -53,13 +55,14 @@ func newEVMDriver() drivers.Driver {
return evm
}
// EVM执行器结构
// EVMExecutor EVM执行器结构
type EVMExecutor struct {
drivers.DriverBase
vmCfg *runtime.Config
mStateDB *state.MemoryStateDB
}
// NewEVMExecutor 新创建执行器对象
func NewEVMExecutor() *EVMExecutor {
exec := &EVMExecutor{}
......@@ -70,15 +73,18 @@ func NewEVMExecutor() *EVMExecutor {
return exec
}
// GetFuncMap 获取方法列表
func (evm *EVMExecutor) GetFuncMap() map[string]reflect.Method {
ety := types.LoadExecutorType(driverName)
return ety.GetExecFuncMap()
}
// GetDriverName 获取本合约驱动名称
func (evm *EVMExecutor) GetDriverName() string {
return evmtypes.ExecutorName
}
// Allow 允许哪些交易在本命执行器执行
func (evm *EVMExecutor) Allow(tx *types.Transaction, index int) error {
err := evm.DriverBase.Allow(tx, index)
if err == nil {
......@@ -94,6 +100,7 @@ func (evm *EVMExecutor) Allow(tx *types.Transaction, index int) error {
return types.ErrNotAllow
}
// IsFriend 是否允许对应的KEY
func (evm *EVMExecutor) IsFriend(myexec, writekey []byte, othertx *types.Transaction) bool {
if othertx == nil {
return false
......@@ -115,11 +122,12 @@ func (evm *EVMExecutor) getNewAddr(txHash []byte) common.Address {
return common.NewAddress(txHash)
}
// CheckTx 校验交易
func (evm *EVMExecutor) CheckTx(tx *types.Transaction, index int) error {
return nil
}
//获取运行状态名
// GetActionName 获取运行状态名
func (evm *EVMExecutor) GetActionName(tx *types.Transaction) string {
if bytes.Equal(tx.Execer, []byte(types.ExecName(evmtypes.ExecutorName))) {
return types.ExecName(evmtypes.ExecutorName)
......@@ -127,15 +135,17 @@ func (evm *EVMExecutor) GetActionName(tx *types.Transaction) string {
return tx.ActionName()
}
// GetMStateDB 获取内部状态数据库
func (evm *EVMExecutor) GetMStateDB() *state.MemoryStateDB {
return evm.mStateDB
}
// GetVMConfig 获取VM配置
func (evm *EVMExecutor) GetVMConfig() *runtime.Config {
return evm.vmCfg
}
// 构造一个新的EVM上下文对象
// NewEVMContext 构造一个新的EVM上下文对象
func (evm *EVMExecutor) NewEVMContext(msg *common.Message) runtime.Context {
return runtime.Context{
CanTransfer: CanTransfer,
......
......@@ -18,6 +18,7 @@ import (
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// Exec 本合约执行逻辑
func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, error) {
evm.CheckInit()
// 先转换消息
......@@ -76,17 +77,17 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
if vmerr != nil {
log.Error("evm contract exec error", "error info", vmerr)
return nil, vmerr
} else {
// 计算消耗了多少费用(实际消耗的费用)
usedFee, overflow := common.SafeMul(usedGas, uint64(msg.GasPrice()))
// 费用消耗溢出,执行失败
if overflow || usedFee > uint64(tx.Fee) {
// 如果操作没有回滚,则在这里处理
if curVer != nil && snapshot >= curVer.GetId() && curVer.GetId() > -1 {
evm.mStateDB.RevertToSnapshot(snapshot)
}
return nil, model.ErrOutOfGas
}
// 计算消耗了多少费用(实际消耗的费用)
usedFee, overflow := common.SafeMul(usedGas, uint64(msg.GasPrice()))
// 费用消耗溢出,执行失败
if overflow || usedFee > uint64(tx.Fee) {
// 如果操作没有回滚,则在这里处理
if curVer != nil && snapshot >= curVer.GetID() && curVer.GetID() > -1 {
evm.mStateDB.RevertToSnapshot(snapshot)
}
return nil, model.ErrOutOfGas
}
// 打印合约中生成的日志
......@@ -96,7 +97,7 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
return nil, nil
}
// 从状态机中获取数据变更和变更日志
data, logs := evm.mStateDB.GetChangedData(curVer.GetId())
data, logs := evm.mStateDB.GetChangedData(curVer.GetID())
contractReceipt := &evmtypes.ReceiptEVMContract{Caller: msg.From().String(), ContractName: execName, ContractAddr: contractAddr.String(), UsedGas: usedGas, Ret: ret}
......@@ -125,13 +126,14 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
return receipt, nil
}
// CheckInit 检查是否初始化数据库
func (evm *EVMExecutor) CheckInit() {
if evm.mStateDB == nil {
evm.mStateDB = state.NewMemoryStateDB(evm.GetStateDB(), evm.GetLocalDB(), evm.GetCoinsAccount(), evm.GetHeight())
}
}
// 目前的交易中,如果是coins交易,金额是放在payload的,但是合约不行,需要修改Transaction结构
// GetMessage 目前的交易中,如果是coins交易,金额是放在payload的,但是合约不行,需要修改Transaction结构
func (evm *EVMExecutor) GetMessage(tx *types.Transaction) (msg *common.Message, err error) {
var action evmtypes.EVMContractAction
err = types.Decode(tx.Payload, &action)
......
......@@ -9,6 +9,7 @@ import (
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// ExecDelLocal 处理区块回滚
func (evm *EVMExecutor) ExecDelLocal(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := evm.DriverBase.ExecDelLocal(tx, receipt, index)
if err != nil {
......
......@@ -11,6 +11,7 @@ import (
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// ExecLocal 处理本地区块新增逻辑
func (evm *EVMExecutor) ExecLocal(tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set, err := evm.DriverBase.ExecLocal(tx, receipt, index)
if err != nil {
......
......@@ -12,18 +12,18 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/state"
)
// 检查合约调用账户是否有充足的金额进行转账交易操作
func CanTransfer(db state.StateDB, sender, recipient common.Address, amount uint64) bool {
// CanTransfer 检查合约调用账户是否有充足的金额进行转账交易操作
func CanTransfer(db state.EVMStateDB, sender, recipient common.Address, amount uint64) bool {
return db.CanTransfer(sender.String(), recipient.String(), amount)
}
// 在内存数据库中执行转账操作(只修改内存中的金额)
// Transfer 在内存数据库中执行转账操作(只修改内存中的金额)
// 从外部账户地址到合约账户地址
func Transfer(db state.StateDB, sender, recipient common.Address, amount uint64) bool {
func Transfer(db state.EVMStateDB, sender, recipient common.Address, amount uint64) bool {
return db.Transfer(sender.String(), recipient.String(), amount)
}
// 获取制定高度区块的哈希
// GetHashFn 获取制定高度区块的哈希
func GetHashFn(api client.QueueProtocolAPI) func(blockHeight uint64) common.Hash {
return func(blockHeight uint64) common.Hash {
if api != nil {
......
......@@ -17,7 +17,7 @@ import (
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// 检查合约地址是否存在,此操作不会改变任何状态,所以可以直接从statedb查询
// Query_CheckAddrExists 检查合约地址是否存在,此操作不会改变任何状态,所以可以直接从statedb查询
func (evm *EVMExecutor) Query_CheckAddrExists(in *evmtypes.CheckEVMAddrReq) (types.Message, error) {
evm.CheckInit()
addrStr := in.Addr
......@@ -51,7 +51,7 @@ func (evm *EVMExecutor) Query_CheckAddrExists(in *evmtypes.CheckEVMAddrReq) (typ
return ret, nil
}
// 此方法用来估算合约消耗的Gas,不能修改原有执行器的状态数据
// Query_EstimateGas 此方法用来估算合约消耗的Gas,不能修改原有执行器的状态数据
func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types.Message, error) {
evm.CheckInit()
var (
......@@ -100,7 +100,7 @@ func (evm *EVMExecutor) Query_EstimateGas(in *evmtypes.EstimateEVMGasReq) (types
return result, vmerr
}
// 此方法用来估算合约消耗的Gas,不能修改原有执行器的状态数据
// Query_EvmDebug 此方法用来估算合约消耗的Gas,不能修改原有执行器的状态数据
func (evm *EVMExecutor) Query_EvmDebug(in *evmtypes.EvmDebugReq) (types.Message, error) {
evm.CheckInit()
optype := in.Optype
......
......@@ -23,7 +23,7 @@ func TestCreateContract1(t *testing.T) {
gasLimit := gas
tx := createTx(privKey, deployCode, gas, 10000000)
mdb := buildStateDB(getAddr(privKey).String(), 500000000)
ret, addr, leftGas, err, statedb := createContract(mdb, tx, 0)
ret, addr, leftGas, statedb, err := createContract(mdb, tx, 0)
test := NewTester(t)
test.assertNil(err)
......@@ -33,7 +33,7 @@ func TestCreateContract1(t *testing.T) {
test.assertNotEqualsI(common.Address(addr), common.EmptyAddress())
// 检查返回数据是否正确
test.assertEqualsV(statedb.GetLastSnapshot().GetId(), 0)
test.assertEqualsV(statedb.GetLastSnapshot().GetID(), 0)
}
// 创建合约gas不足
......@@ -46,7 +46,7 @@ func TestCreateContract2(t *testing.T) {
gas := uint64(30)
tx := createTx(privKey, deployCode, gas, 0)
mdb := buildStateDB(getAddr(privKey).String(), 100000000)
ret, _, leftGas, err, _ := createContract(mdb, tx, 0)
ret, _, leftGas, _, err := createContract(mdb, tx, 0)
test := NewTester(t)
......@@ -72,7 +72,7 @@ func TestCreateContract3(t *testing.T) {
gasLimit := gas
tx := createTx(privKey, deployCode, gas, 0)
mdb := buildStateDB(getAddr(privKey).String(), 100000000)
ret, _, leftGas, err, _ := createContract(mdb, tx, 0)
ret, _, leftGas, _, err := createContract(mdb, tx, 0)
test := NewTester(t)
......@@ -98,7 +98,7 @@ func TestCreateContract4(t *testing.T) {
gasLimit := gas
tx := createTx(privKey, deployCode, gas, 0)
mdb := buildStateDB(getAddr(privKey).String(), 100000000)
ret, _, leftGas, err, _ := createContract(mdb, tx, 50)
ret, _, leftGas, _, err := createContract(mdb, tx, 50)
test := NewTester(t)
......
......@@ -144,12 +144,11 @@ func runCase(tt *testing.T, c VMCase, file string) {
// 合约执行出错的情况下,判断错误是否相同,如果相同,则返回,不判断post
if len(c.err) > 0 && c.err == err.Error() {
return
} else {
// 非意料情况下的出错,视为错误
tt.Errorf("test case:%s, failed:%s", c.name, err)
tt.Fail()
return
}
// 非意料情况下的出错,视为错误
tt.Errorf("test case:%s, failed:%s", c.name, err)
tt.Fail()
return
}
// 4 检查执行结果 post (注意,这里不检查Gas具体扣费数额,因为计费规则不一样,值检查执行结果是否正确)
t := NewTester(tt)
......
......@@ -79,11 +79,11 @@ func scanTestData(basePath string) {
// 检查两个文件是否都存在
if _, err := os.Stat(keyFile); os.IsNotExist(err) {
fmt.Println(fmt.Errorf("test template file:%s, not exists!", keyFile))
fmt.Println(fmt.Errorf("test template file:%s, not exists", keyFile))
return nil
}
if _, err := os.Stat(dataFile); os.IsNotExist(err) {
fmt.Println(fmt.Errorf("test data file:%s, not exists!", dataFile))
fmt.Println(fmt.Errorf("test data file:%s, not exists", dataFile))
return nil
}
testmap[keyFile] = dataFile
......
......@@ -4,19 +4,21 @@
package tests
// VMCase 一个测试用例
type VMCase struct {
name string
env EnvJson
exec ExecJson
env EnvJSON
exec ExecJSON
gas int64
logs string
out string
err string
pre map[string]AccountJson
post map[string]AccountJson
pre map[string]AccountJSON
post map[string]AccountJSON
}
type EnvJson struct {
// EnvJSON 上下文信息
type EnvJSON struct {
currentCoinbase string
currentDifficulty int64
currentGasLimit int64
......@@ -24,7 +26,8 @@ type EnvJson struct {
currentTimestamp int64
}
type ExecJson struct {
// ExecJSON 调用信息
type ExecJSON struct {
address string
caller string
code string
......@@ -35,7 +38,8 @@ type ExecJson struct {
value int64
}
type AccountJson struct {
// AccountJSON 账户信息
type AccountJSON struct {
balance int64
code string
nonce int64
......
......@@ -10,10 +10,12 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
)
// Tester 测试执行对象
type Tester struct {
t *testing.T
}
// NewTester 新创建测试执行对象
func NewTester(t *testing.T) *Tester {
return &Tester{t: t}
}
......
......@@ -68,9 +68,9 @@ func parseVMCase(data interface{}, ut *VMCase) {
}
}
func parseEnv(data interface{}) EnvJson {
func parseEnv(data interface{}) EnvJSON {
m := data.(map[string]interface{})
ut := EnvJson{}
ut := EnvJSON{}
for k, v := range m {
switch k {
case "currentCoinbase":
......@@ -90,9 +90,9 @@ func parseEnv(data interface{}) EnvJson {
return ut
}
func parseExec(data interface{}) ExecJson {
func parseExec(data interface{}) ExecJSON {
m := data.(map[string]interface{})
ut := ExecJson{}
ut := ExecJSON{}
for k, v := range m {
switch k {
case "address":
......@@ -118,8 +118,8 @@ func parseExec(data interface{}) ExecJson {
return ut
}
func parseAccount(data interface{}) map[string]AccountJson {
ret := make(map[string]AccountJson)
func parseAccount(data interface{}) map[string]AccountJSON {
ret := make(map[string]AccountJSON)
m := data.(map[string]interface{})
for k, v := range m {
ret[unpre(k)] = parseAccount2(v)
......@@ -127,9 +127,9 @@ func parseAccount(data interface{}) map[string]AccountJson {
return ret
}
func parseAccount2(data interface{}) AccountJson {
func parseAccount2(data interface{}) AccountJSON {
m := data.(map[string]interface{})
ut := AccountJson{}
ut := AccountJSON{}
for k, v := range m {
switch k {
case "balance":
......@@ -215,7 +215,7 @@ func addAccount(mdb *db.GoMemDB, execAddr string, acc1 *types.Account) {
}
}
func addContractAccount(db *state.MemoryStateDB, mdb *db.GoMemDB, addr string, a AccountJson, creator string) {
func addContractAccount(db *state.MemoryStateDB, mdb *db.GoMemDB, addr string, a AccountJSON, creator string) {
acc := state.NewContractAccount(addr, db)
acc.SetCreator(creator)
code, err := hex.DecodeString(a.code)
......@@ -247,7 +247,7 @@ func buildStateDB(addr string, balance int64) *db.GoMemDB {
return mdb
}
func createContract(mdb *db.GoMemDB, tx types.Transaction, maxCodeSize int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error, statedb *state.MemoryStateDB) {
func createContract(mdb *db.GoMemDB, tx types.Transaction, maxCodeSize int) (ret []byte, contractAddr common.Address, leftOverGas uint64, statedb *state.MemoryStateDB, err error) {
inst := evm.NewEVMExecutor()
inst.CheckInit()
msg, _ := inst.GetMessage(&tx)
......@@ -273,5 +273,5 @@ func createContract(mdb *db.GoMemDB, tx types.Transaction, maxCodeSize int) (ret
addr := *crypto2.RandomContractAddress()
ret, _, leftGas, err := env.Create(runtime.AccountRef(msg.From()), addr, msg.Data(), msg.GasLimit(), fmt.Sprintf("%s%s", evmtypes.EvmPrefix, common.BytesToHash(tx.Hash()).Hex()), "")
return ret, addr, leftGas, err, statedb
return ret, addr, leftGas, statedb, err
}
......@@ -13,37 +13,43 @@ import (
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// 封装地址结构体,并提供各种常用操作封装
// Address 封装地址结构体,并提供各种常用操作封装
// 这里封装的操作主要是为了提供Address<->big.Int, Address<->[]byte 之间的互相转换
// 并且转换的核心是使用地址对象中的Hash160元素,因为在EVM中地址固定为[20]byte,超出此范围的地址无法正确解释执行
type Address struct {
addr *address.Address
}
// String 字符串结构
func (a Address) String() string { return a.addr.String() }
// Bytes 字节数组
func (a Address) Bytes() []byte {
return a.addr.Hash160[:]
}
// Big 大数字
func (a Address) Big() *big.Int {
ret := new(big.Int).SetBytes(a.Bytes())
return ret
}
// txHash生成EVM合约地址
// NewAddress xHash生成EVM合约地址
func NewAddress(txHash []byte) Address {
execAddr := address.GetExecAddress(types.ExecName(evmtypes.EvmPrefix) + BytesToHash(txHash).Hex())
return Address{addr: execAddr}
}
// ExecAddress 返回合约地址
func ExecAddress(execName string) Address {
execAddr := address.GetExecAddress(execName)
return Address{addr: execAddr}
}
// Hash 计算地址哈希
func (a Address) Hash() Hash { return ToHash(a.Bytes()) }
// BytesToAddress 字节向地址转换
func BytesToAddress(b []byte) Address {
a := new(address.Address)
a.Version = 0
......@@ -51,6 +57,7 @@ func BytesToAddress(b []byte) Address {
return Address{addr: a}
}
// StringToAddress 字符串转换为地址
func StringToAddress(s string) *Address {
addr, err := address.NewAddrFromString(s)
if err != nil {
......@@ -70,6 +77,7 @@ func bigBytes(b *big.Int) (out [20]byte) {
return
}
// BigToAddress 大数字转换为地址
func BigToAddress(b *big.Int) Address {
a := new(address.Address)
a.Version = 0
......@@ -77,4 +85,5 @@ func BigToAddress(b *big.Int) Address {
return Address{addr: a}
}
// EmptyAddress 返回空地址
func EmptyAddress() Address { return BytesToAddress([]byte{0}) }
......@@ -11,28 +11,34 @@ import (
// 常用的大整数常量定义
var (
Big0 = big.NewInt(0)
Big1 = big.NewInt(1)
Big32 = big.NewInt(32)
// Big0 大数字0
Big0 = big.NewInt(0)
// Big1 大数字1
Big1 = big.NewInt(1)
// Big32 大数字32
Big32 = big.NewInt(32)
// Big256 大数字256
Big256 = big.NewInt(256)
// Big257 大数字257
Big257 = big.NewInt(257)
)
// 2的各种常用取幂结果
var (
// TT255 2的255次幂
TT255 = BigPow(2, 255)
tt256 = BigPow(2, 256)
tt256m1 = new(big.Int).Sub(tt256, big.NewInt(1))
)
const (
// 一个big.Word类型取值占用多少个位
// WordBits 一个big.Word类型取值占用多少个位
WordBits = 32 << (uint64(^big.Word(0)) >> 63)
// 一个big.Word类型取值占用多少个字节
// WordBytes 一个big.Word类型取值占用多少个字节
WordBytes = WordBits / 8
)
// 返回两者之中的较大值
// BigMax 返回两者之中的较大值
func BigMax(x, y *big.Int) *big.Int {
if x.Cmp(y) < 0 {
return y
......@@ -40,7 +46,7 @@ func BigMax(x, y *big.Int) *big.Int {
return x
}
// 返回两者之中的较小值
// BigMin 返回两者之中的较小值
func BigMin(x, y *big.Int) *big.Int {
if x.Cmp(y) > 0 {
return y
......@@ -48,13 +54,13 @@ func BigMin(x, y *big.Int) *big.Int {
return x
}
// 返回a的b次幂
// BigPow 返回a的b次幂
func BigPow(a, b int64) *big.Int {
r := big.NewInt(a)
return r.Exp(r, big.NewInt(b), nil)
}
// 求补
// U256 求补
func U256(x *big.Int) *big.Int {
return x.And(x, tt256m1)
}
......@@ -68,12 +74,11 @@ func U256(x *big.Int) *big.Int {
func S256(x *big.Int) *big.Int {
if x.Cmp(TT255) < 0 {
return x
} else {
return new(big.Int).Sub(x, tt256)
}
return new(big.Int).Sub(x, tt256)
}
// 指数函数,可以指定底数,结果被截断为256位长度
// Exp 指数函数,可以指定底数,结果被截断为256位长度
func Exp(base, exponent *big.Int) *big.Int {
result := big.NewInt(1)
......@@ -89,7 +94,7 @@ func Exp(base, exponent *big.Int) *big.Int {
return result
}
// big.Int以小端编码时,第n个位置的字节取值
// Byte big.Int以小端编码时,第n个位置的字节取值
// 例如: bigint '5', padlength 32, n=31 => 5
func Byte(bigint *big.Int, padlength, n int) byte {
if n >= padlength {
......@@ -117,17 +122,7 @@ func bigEndianByteAt(bigint *big.Int, n int) byte {
return byte(word >> shift)
}
// 以大端方式将big.Int编码为字节数组,结果数组长度为n
func PaddedBigBytes(bigint *big.Int, n int) []byte {
if bigint.BitLen()/8 >= n {
return bigint.Bytes()
}
ret := make([]byte, n)
ReadBits(bigint, ret)
return ret
}
// 以大端方式将big.Int编码为字节数组
// ReadBits 以大端方式将big.Int编码为字节数组
func ReadBits(bigint *big.Int, buf []byte) {
i := len(buf)
for _, d := range bigint.Bits() {
......@@ -139,17 +134,12 @@ func ReadBits(bigint *big.Int, buf []byte) {
}
}
// 减法运算,返回是否溢出
func SafeSub(x, y uint64) (uint64, bool) {
return x - y, x < y
}
// 加法运算,返回是否溢出
// SafeAdd 加法运算,返回是否溢出
func SafeAdd(x, y uint64) (uint64, bool) {
return x + y, y > math.MaxUint64-x
}
// 乘法运算,返回是否溢出
// SafeMul 乘法运算,返回是否溢出
func SafeMul(x, y uint64) (uint64, bool) {
if x == 0 || y == 0 {
return 0, false
......@@ -157,6 +147,7 @@ func SafeMul(x, y uint64) (uint64, bool) {
return x * y, y > math.MaxUint64/x
}
// Zero 检查数字是否为0
func Zero(value *big.Int) bool {
if value == nil || value.Sign() == 0 {
return true
......
......@@ -9,7 +9,7 @@ import (
"sort"
)
// 右填充字节数组
// RightPadBytes 右填充字节数组
func RightPadBytes(slice []byte, l int) []byte {
if l <= len(slice) {
return slice
......@@ -21,7 +21,7 @@ func RightPadBytes(slice []byte, l int) []byte {
return padded
}
// 左填充字节数组
// LeftPadBytes 左填充字节数组
func LeftPadBytes(slice []byte, l int) []byte {
if l <= len(slice) {
return slice
......@@ -33,7 +33,7 @@ func LeftPadBytes(slice []byte, l int) []byte {
return padded
}
// 十六进制的字符串转换为字节数组
// FromHex 十六进制的字符串转换为字节数组
func FromHex(s string) []byte {
if len(s) > 1 {
if s[0:2] == "0x" || s[0:2] == "0X" {
......@@ -46,13 +46,13 @@ func FromHex(s string) []byte {
return Hex2Bytes(s)
}
// 十六进制字符串转换为字节数组
// Hex2Bytes 十六进制字符串转换为字节数组
func Hex2Bytes(str string) []byte {
h, _ := hex.DecodeString(str)
return h
}
// 将字节数组转换为16进制的字符串表示
// Bytes2Hex 将字节数组转换为16进制的字符串表示
func Bytes2Hex(b []byte) string {
enc := make([]byte, len(b)*2+2)
copy(enc, "0x")
......@@ -60,7 +60,7 @@ func Bytes2Hex(b []byte) string {
return string(enc)
}
// 将字节数组转换为16进制的字符串表示
// Bytes2HexTrim 将字节数组转换为16进制的字符串表示
// 并且将前面多余的0去除
func Bytes2HexTrim(b []byte) string {
// 获取字节数组中第一个非零字节位置
......
......@@ -9,7 +9,7 @@ import (
"math/big"
)
// 返回从开始位置制定长度的数据
// GetData 返回从开始位置制定长度的数据
// 如果源数据不足,则剩余位置用零填充
func GetData(data []byte, start uint64, size uint64) []byte {
length := uint64(len(data))
......@@ -23,7 +23,7 @@ func GetData(data []byte, start uint64, size uint64) []byte {
return RightPadBytes(data[start:end], int(size))
}
// 返回从开始位置制定长度的数据
// GetDataBig 返回从开始位置制定长度的数据
// 如果源数据不足,则剩余位置用零填充
func GetDataBig(data []byte, start *big.Int, size *big.Int) []byte {
dlen := big.NewInt(int64(len(data)))
......@@ -33,12 +33,12 @@ func GetDataBig(data []byte, start *big.Int, size *big.Int) []byte {
return RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64()))
}
// 将大整数转换为uint64,并判断是否溢出
// BigUint64 将大整数转换为uint64,并判断是否溢出
func BigUint64(v *big.Int) (uint64, bool) {
return v.Uint64(), v.BitLen() > 64
}
// 计算制定字节长度所对应的字长度(一个字,对应32个字节,也就是256位)
// ToWordSize 计算制定字节长度所对应的字长度(一个字,对应32个字节,也就是256位)
// 如果长度不足一个字长,则补足
// EVM在内存中存储时的最小单位是字长(256位),而不是字节
func ToWordSize(size uint64) uint64 {
......@@ -49,7 +49,7 @@ func ToWordSize(size uint64) uint64 {
return (size + 31) / 32
}
// 判断字节数组内容是否全为零
// AllZero 判断字节数组内容是否全为零
func AllZero(b []byte) bool {
for _, byte := range b {
if byte != 0 {
......
......@@ -59,54 +59,54 @@ func (g *G1) String() string {
}
// CurvePoints returns p's curve points in big integer
func (e *G1) CurvePoints() (*big.Int, *big.Int, *big.Int, *big.Int) {
return e.p.x, e.p.y, e.p.z, e.p.t
func (g *G1) CurvePoints() (*big.Int, *big.Int, *big.Int, *big.Int) {
return g.p.x, g.p.y, g.p.z, g.p.t
}
// ScalarBaseMult sets e to g*k where g is the generator of the group and
// then returns e.
func (e *G1) ScalarBaseMult(k *big.Int) *G1 {
if e.p == nil {
e.p = newCurvePoint(nil)
func (g *G1) ScalarBaseMult(k *big.Int) *G1 {
if g.p == nil {
g.p = newCurvePoint(nil)
}
e.p.Mul(curveGen, k, new(bnPool))
return e
g.p.Mul(curveGen, k, new(bnPool))
return g
}
// ScalarMult sets e to a*k and then returns e.
func (e *G1) ScalarMult(a *G1, k *big.Int) *G1 {
if e.p == nil {
e.p = newCurvePoint(nil)
func (g *G1) ScalarMult(a *G1, k *big.Int) *G1 {
if g.p == nil {
g.p = newCurvePoint(nil)
}
e.p.Mul(a.p, k, new(bnPool))
return e
g.p.Mul(a.p, k, new(bnPool))
return g
}
// Add sets e to a+b and then returns e.
// BUG(agl): this function is not complete: a==b fails.
func (e *G1) Add(a, b *G1) *G1 {
if e.p == nil {
e.p = newCurvePoint(nil)
func (g *G1) Add(a, b *G1) *G1 {
if g.p == nil {
g.p = newCurvePoint(nil)
}
e.p.Add(a.p, b.p, new(bnPool))
return e
g.p.Add(a.p, b.p, new(bnPool))
return g
}
// Neg sets e to -a and then returns e.
func (e *G1) Neg(a *G1) *G1 {
if e.p == nil {
e.p = newCurvePoint(nil)
func (g *G1) Neg(a *G1) *G1 {
if g.p == nil {
g.p = newCurvePoint(nil)
}
e.p.Negative(a.p)
return e
g.p.Negative(a.p)
return g
}
// Marshal converts n to a byte slice.
func (n *G1) Marshal() []byte {
n.p.MakeAffine(nil)
func (g *G1) Marshal() []byte {
g.p.MakeAffine(nil)
xBytes := new(big.Int).Mod(n.p.x, P).Bytes()
yBytes := new(big.Int).Mod(n.p.y, P).Bytes()
xBytes := new(big.Int).Mod(g.p.x, P).Bytes()
yBytes := new(big.Int).Mod(g.p.y, P).Bytes()
// Each value is a 256-bit number.
const numBytes = 256 / 8
......@@ -120,35 +120,35 @@ func (n *G1) Marshal() []byte {
// Unmarshal sets e to the result of converting the output of Marshal back into
// a group element and then returns e.
func (e *G1) Unmarshal(m []byte) ([]byte, error) {
func (g *G1) Unmarshal(m []byte) ([]byte, error) {
// Each value is a 256-bit number.
const numBytes = 256 / 8
if len(m) != 2*numBytes {
return nil, errors.New("bn256: not enough data")
}
// Unmarshal the points and check their caps
if e.p == nil {
e.p = newCurvePoint(nil)
if g.p == nil {
g.p = newCurvePoint(nil)
}
e.p.x.SetBytes(m[0*numBytes : 1*numBytes])
if e.p.x.Cmp(P) >= 0 {
g.p.x.SetBytes(m[0*numBytes : 1*numBytes])
if g.p.x.Cmp(P) >= 0 {
return nil, errors.New("bn256: coordinate exceeds modulus")
}
e.p.y.SetBytes(m[1*numBytes : 2*numBytes])
if e.p.y.Cmp(P) >= 0 {
g.p.y.SetBytes(m[1*numBytes : 2*numBytes])
if g.p.y.Cmp(P) >= 0 {
return nil, errors.New("bn256: coordinate exceeds modulus")
}
// Ensure the point is on the curve
if e.p.x.Sign() == 0 && e.p.y.Sign() == 0 {
if g.p.x.Sign() == 0 && g.p.y.Sign() == 0 {
// This is the point at infinity.
e.p.y.SetInt64(1)
e.p.z.SetInt64(0)
e.p.t.SetInt64(0)
g.p.y.SetInt64(1)
g.p.z.SetInt64(0)
g.p.t.SetInt64(0)
} else {
e.p.z.SetInt64(1)
e.p.t.SetInt64(1)
g.p.z.SetInt64(1)
g.p.t.SetInt64(1)
if !e.p.IsOnCurve() {
if !g.p.IsOnCurve() {
return nil, errors.New("bn256: malformed point")
}
}
......@@ -161,7 +161,7 @@ type G2 struct {
p *twistPoint
}
// RandomG1 returns x and g₂ˣ where x is a random, non-zero number read from r.
// RandomG2 returns x and g₂ˣ where x is a random, non-zero number read from r.
func RandomG2(r io.Reader) (*big.Int, *G2, error) {
var k *big.Int
var err error
......@@ -185,47 +185,47 @@ func (g *G2) String() string {
// CurvePoints returns the curve points of p which includes the real
// and imaginary parts of the curve point.
func (e *G2) CurvePoints() (*gfP2, *gfP2, *gfP2, *gfP2) {
return e.p.x, e.p.y, e.p.z, e.p.t
}
//func (g *G2) CurvePoints() (*gfP2, *gfP2, *gfP2, *gfP2) {
// return g.p.x, g.p.y, g.p.z, g.p.t
//}
// ScalarBaseMult sets e to g*k where g is the generator of the group and
// then returns out.
func (e *G2) ScalarBaseMult(k *big.Int) *G2 {
if e.p == nil {
e.p = newTwistPoint(nil)
func (g *G2) ScalarBaseMult(k *big.Int) *G2 {
if g.p == nil {
g.p = newTwistPoint(nil)
}
e.p.Mul(twistGen, k, new(bnPool))
return e
g.p.Mul(twistGen, k, new(bnPool))
return g
}
// ScalarMult sets e to a*k and then returns e.
func (e *G2) ScalarMult(a *G2, k *big.Int) *G2 {
if e.p == nil {
e.p = newTwistPoint(nil)
func (g *G2) ScalarMult(a *G2, k *big.Int) *G2 {
if g.p == nil {
g.p = newTwistPoint(nil)
}
e.p.Mul(a.p, k, new(bnPool))
return e
g.p.Mul(a.p, k, new(bnPool))
return g
}
// Add sets e to a+b and then returns e.
// BUG(agl): this function is not complete: a==b fails.
func (e *G2) Add(a, b *G2) *G2 {
if e.p == nil {
e.p = newTwistPoint(nil)
func (g *G2) Add(a, b *G2) *G2 {
if g.p == nil {
g.p = newTwistPoint(nil)
}
e.p.Add(a.p, b.p, new(bnPool))
return e
g.p.Add(a.p, b.p, new(bnPool))
return g
}
// Marshal converts n into a byte slice.
func (n *G2) Marshal() []byte {
n.p.MakeAffine(nil)
func (g *G2) Marshal() []byte {
g.p.MakeAffine(nil)
xxBytes := new(big.Int).Mod(n.p.x.x, P).Bytes()
xyBytes := new(big.Int).Mod(n.p.x.y, P).Bytes()
yxBytes := new(big.Int).Mod(n.p.y.x, P).Bytes()
yyBytes := new(big.Int).Mod(n.p.y.y, P).Bytes()
xxBytes := new(big.Int).Mod(g.p.x.x, P).Bytes()
xyBytes := new(big.Int).Mod(g.p.x.y, P).Bytes()
yxBytes := new(big.Int).Mod(g.p.y.x, P).Bytes()
yyBytes := new(big.Int).Mod(g.p.y.y, P).Bytes()
// Each value is a 256-bit number.
const numBytes = 256 / 8
......@@ -241,46 +241,46 @@ func (n *G2) Marshal() []byte {
// Unmarshal sets e to the result of converting the output of Marshal back into
// a group element and then returns e.
func (e *G2) Unmarshal(m []byte) ([]byte, error) {
func (g *G2) Unmarshal(m []byte) ([]byte, error) {
// Each value is a 256-bit number.
const numBytes = 256 / 8
if len(m) != 4*numBytes {
return nil, errors.New("bn256: not enough data")
}
// Unmarshal the points and check their caps
if e.p == nil {
e.p = newTwistPoint(nil)
if g.p == nil {
g.p = newTwistPoint(nil)
}
e.p.x.x.SetBytes(m[0*numBytes : 1*numBytes])
if e.p.x.x.Cmp(P) >= 0 {
g.p.x.x.SetBytes(m[0*numBytes : 1*numBytes])
if g.p.x.x.Cmp(P) >= 0 {
return nil, errors.New("bn256: coordinate exceeds modulus")
}
e.p.x.y.SetBytes(m[1*numBytes : 2*numBytes])
if e.p.x.y.Cmp(P) >= 0 {
g.p.x.y.SetBytes(m[1*numBytes : 2*numBytes])
if g.p.x.y.Cmp(P) >= 0 {
return nil, errors.New("bn256: coordinate exceeds modulus")
}
e.p.y.x.SetBytes(m[2*numBytes : 3*numBytes])
if e.p.y.x.Cmp(P) >= 0 {
g.p.y.x.SetBytes(m[2*numBytes : 3*numBytes])
if g.p.y.x.Cmp(P) >= 0 {
return nil, errors.New("bn256: coordinate exceeds modulus")
}
e.p.y.y.SetBytes(m[3*numBytes : 4*numBytes])
if e.p.y.y.Cmp(P) >= 0 {
g.p.y.y.SetBytes(m[3*numBytes : 4*numBytes])
if g.p.y.y.Cmp(P) >= 0 {
return nil, errors.New("bn256: coordinate exceeds modulus")
}
// Ensure the point is on the curve
if e.p.x.x.Sign() == 0 &&
e.p.x.y.Sign() == 0 &&
e.p.y.x.Sign() == 0 &&
e.p.y.y.Sign() == 0 {
if g.p.x.x.Sign() == 0 &&
g.p.x.y.Sign() == 0 &&
g.p.y.x.Sign() == 0 &&
g.p.y.y.Sign() == 0 {
// This is the point at infinity.
e.p.y.SetOne()
e.p.z.SetZero()
e.p.t.SetZero()
g.p.y.SetOne()
g.p.z.SetZero()
g.p.t.SetZero()
} else {
e.p.z.SetOne()
e.p.t.SetOne()
g.p.z.SetOne()
g.p.t.SetOne()
if !e.p.IsOnCurve() {
if !g.p.IsOnCurve() {
return nil, errors.New("bn256: malformed point")
}
}
......@@ -298,48 +298,48 @@ func (g *GT) String() string {
}
// ScalarMult sets e to a*k and then returns e.
func (e *GT) ScalarMult(a *GT, k *big.Int) *GT {
if e.p == nil {
e.p = newGFp12(nil)
func (g *GT) ScalarMult(a *GT, k *big.Int) *GT {
if g.p == nil {
g.p = newGFp12(nil)
}
e.p.Exp(a.p, k, new(bnPool))
return e
g.p.Exp(a.p, k, new(bnPool))
return g
}
// Add sets e to a+b and then returns e.
func (e *GT) Add(a, b *GT) *GT {
if e.p == nil {
e.p = newGFp12(nil)
func (g *GT) Add(a, b *GT) *GT {
if g.p == nil {
g.p = newGFp12(nil)
}
e.p.Mul(a.p, b.p, new(bnPool))
return e
g.p.Mul(a.p, b.p, new(bnPool))
return g
}
// Neg sets e to -a and then returns e.
func (e *GT) Neg(a *GT) *GT {
if e.p == nil {
e.p = newGFp12(nil)
func (g *GT) Neg(a *GT) *GT {
if g.p == nil {
g.p = newGFp12(nil)
}
e.p.Invert(a.p, new(bnPool))
return e
g.p.Invert(a.p, new(bnPool))
return g
}
// Marshal converts n into a byte slice.
func (n *GT) Marshal() []byte {
n.p.Minimal()
xxxBytes := n.p.x.x.x.Bytes()
xxyBytes := n.p.x.x.y.Bytes()
xyxBytes := n.p.x.y.x.Bytes()
xyyBytes := n.p.x.y.y.Bytes()
xzxBytes := n.p.x.z.x.Bytes()
xzyBytes := n.p.x.z.y.Bytes()
yxxBytes := n.p.y.x.x.Bytes()
yxyBytes := n.p.y.x.y.Bytes()
yyxBytes := n.p.y.y.x.Bytes()
yyyBytes := n.p.y.y.y.Bytes()
yzxBytes := n.p.y.z.x.Bytes()
yzyBytes := n.p.y.z.y.Bytes()
func (g *GT) Marshal() []byte {
g.p.Minimal()
xxxBytes := g.p.x.x.x.Bytes()
xxyBytes := g.p.x.x.y.Bytes()
xyxBytes := g.p.x.y.x.Bytes()
xyyBytes := g.p.x.y.y.Bytes()
xzxBytes := g.p.x.z.x.Bytes()
xzyBytes := g.p.x.z.y.Bytes()
yxxBytes := g.p.y.x.x.Bytes()
yxyBytes := g.p.y.x.y.Bytes()
yyxBytes := g.p.y.y.x.Bytes()
yyyBytes := g.p.y.y.y.Bytes()
yzxBytes := g.p.y.z.x.Bytes()
yzyBytes := g.p.y.z.y.Bytes()
// Each value is a 256-bit number.
const numBytes = 256 / 8
......@@ -363,7 +363,7 @@ func (n *GT) Marshal() []byte {
// Unmarshal sets e to the result of converting the output of Marshal back into
// a group element and then returns e.
func (e *GT) Unmarshal(m []byte) (*GT, bool) {
func (g *GT) Unmarshal(m []byte) (*GT, bool) {
// Each value is a 256-bit number.
const numBytes = 256 / 8
......@@ -371,24 +371,24 @@ func (e *GT) Unmarshal(m []byte) (*GT, bool) {
return nil, false
}
if e.p == nil {
e.p = newGFp12(nil)
if g.p == nil {
g.p = newGFp12(nil)
}
e.p.x.x.x.SetBytes(m[0*numBytes : 1*numBytes])
e.p.x.x.y.SetBytes(m[1*numBytes : 2*numBytes])
e.p.x.y.x.SetBytes(m[2*numBytes : 3*numBytes])
e.p.x.y.y.SetBytes(m[3*numBytes : 4*numBytes])
e.p.x.z.x.SetBytes(m[4*numBytes : 5*numBytes])
e.p.x.z.y.SetBytes(m[5*numBytes : 6*numBytes])
e.p.y.x.x.SetBytes(m[6*numBytes : 7*numBytes])
e.p.y.x.y.SetBytes(m[7*numBytes : 8*numBytes])
e.p.y.y.x.SetBytes(m[8*numBytes : 9*numBytes])
e.p.y.y.y.SetBytes(m[9*numBytes : 10*numBytes])
e.p.y.z.x.SetBytes(m[10*numBytes : 11*numBytes])
e.p.y.z.y.SetBytes(m[11*numBytes : 12*numBytes])
return e, true
g.p.x.x.x.SetBytes(m[0*numBytes : 1*numBytes])
g.p.x.x.y.SetBytes(m[1*numBytes : 2*numBytes])
g.p.x.y.x.SetBytes(m[2*numBytes : 3*numBytes])
g.p.x.y.y.SetBytes(m[3*numBytes : 4*numBytes])
g.p.x.z.x.SetBytes(m[4*numBytes : 5*numBytes])
g.p.x.z.y.SetBytes(m[5*numBytes : 6*numBytes])
g.p.y.x.x.SetBytes(m[6*numBytes : 7*numBytes])
g.p.y.x.y.SetBytes(m[7*numBytes : 8*numBytes])
g.p.y.y.x.SetBytes(m[8*numBytes : 9*numBytes])
g.p.y.y.y.SetBytes(m[9*numBytes : 10*numBytes])
g.p.y.z.x.SetBytes(m[10*numBytes : 11*numBytes])
g.p.y.z.y.SetBytes(m[11*numBytes : 12*numBytes])
return g, true
}
// Pair calculates an Optimal Ate pairing.
......
......@@ -20,7 +20,7 @@ func bigFromBase10(s string) *big.Int {
// u is the BN parameter that determines the prime: 1868033³.
var u = bigFromBase10("4965661367192848881")
// p is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.
// P is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.
var P = bigFromBase10("21888242871839275222246405745257275088696311157297823662689037894645226208583")
// Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1.
......
......@@ -190,14 +190,14 @@ func (c *curvePoint) Double(a *curvePoint, pool *bnPool) {
A.Mod(A, P)
B := pool.Get().Mul(a.y, a.y)
B.Mod(B, P)
C_ := pool.Get().Mul(B, B)
C_.Mod(C_, P)
C := pool.Get().Mul(B, B)
C.Mod(C, P)
t := pool.Get().Add(a.x, B)
t2 := pool.Get().Mul(t, t)
t2.Mod(t2, P)
t.Sub(t2, A)
t2.Sub(t, C_)
t2.Sub(t, C)
d := pool.Get().Add(t2, t2)
t.Add(A, A)
e := pool.Get().Add(t, A)
......@@ -207,7 +207,7 @@ func (c *curvePoint) Double(a *curvePoint, pool *bnPool) {
t.Add(d, d)
c.x.Sub(f, t)
t.Add(C_, C_)
t.Add(C, C)
t2.Add(t, t)
t.Add(t2, t2)
c.y.Sub(d, c.x)
......@@ -221,7 +221,7 @@ func (c *curvePoint) Double(a *curvePoint, pool *bnPool) {
pool.Put(A)
pool.Put(B)
pool.Put(C_)
pool.Put(C)
pool.Put(t)
pool.Put(t2)
pool.Put(d)
......
......@@ -134,7 +134,7 @@ func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 {
return e
}
func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 {
func (e *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 {
sum := newGFp12(pool)
sum.SetOne()
t := newGFp12(pool)
......@@ -148,12 +148,12 @@ func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 {
}
}
c.Set(sum)
e.Set(sum)
sum.Put(pool)
t.Put(pool)
return c
return e
}
func (e *gfP12) Square(a *gfP12, pool *bnPool) *gfP12 {
......
......@@ -106,7 +106,7 @@ func (e *gfP2) Double(a *gfP2) *gfP2 {
return e
}
func (c *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 {
func (e *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 {
sum := newGFp2(pool)
sum.SetOne()
t := newGFp2(pool)
......@@ -120,12 +120,12 @@ func (c *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 {
}
}
c.Set(sum)
e.Set(sum)
sum.Put(pool)
t.Put(pool)
return c
return e
}
// See "Multiplication and Squaring in Pairing-Friendly Fields",
......
......@@ -270,13 +270,13 @@ func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 {
t1.Mul(a.y, a.z, pool)
B.Sub(B, t1)
C_ := newGFp2(pool)
C_.Square(a.y, pool)
C := newGFp2(pool)
C.Square(a.y, pool)
t1.Mul(a.x, a.z, pool)
C_.Sub(C_, t1)
C.Sub(C, t1)
F := newGFp2(pool)
F.Mul(C_, a.y, pool)
F.Mul(C, a.y, pool)
F.MulXi(F, pool)
t1.Mul(A, a.z, pool)
F.Add(F, t1)
......@@ -286,14 +286,14 @@ func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 {
F.Invert(F, pool)
e.x.Mul(C_, F, pool)
e.x.Mul(C, F, pool)
e.y.Mul(B, F, pool)
e.z.Mul(A, F, pool)
t1.Put(pool)
A.Put(pool)
B.Put(pool)
C_.Put(pool)
C.Put(pool)
F.Put(pool)
return e
......
......@@ -92,12 +92,12 @@ func lineFunctionDouble(r *twistPoint, q *curvePoint, pool *bnPool) (a, b, c *gf
A := newGFp2(pool).Square(r.x, pool)
B := newGFp2(pool).Square(r.y, pool)
C_ := newGFp2(pool).Square(B, pool)
C := newGFp2(pool).Square(B, pool)
D := newGFp2(pool).Add(r.x, B)
D.Square(D, pool)
D.Sub(D, A)
D.Sub(D, C_)
D.Sub(D, C)
D.Add(D, D)
E := newGFp2(pool).Add(A, A)
......@@ -116,7 +116,7 @@ func lineFunctionDouble(r *twistPoint, q *curvePoint, pool *bnPool) (a, b, c *gf
rOut.y.Sub(D, rOut.x)
rOut.y.Mul(rOut.y, E, pool)
t := newGFp2(pool).Add(C_, C_)
t := newGFp2(pool).Add(C, C)
t.Add(t, t)
t.Add(t, t)
rOut.y.Sub(rOut.y, t)
......@@ -146,7 +146,7 @@ func lineFunctionDouble(r *twistPoint, q *curvePoint, pool *bnPool) (a, b, c *gf
A.Put(pool)
B.Put(pool)
C_.Put(pool)
C.Put(pool)
D.Put(pool)
E.Put(pool)
G.Put(pool)
......
......@@ -175,12 +175,12 @@ func (c *twistPoint) Double(a *twistPoint, pool *bnPool) {
// See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3
A := newGFp2(pool).Square(a.x, pool)
B := newGFp2(pool).Square(a.y, pool)
C_ := newGFp2(pool).Square(B, pool)
C := newGFp2(pool).Square(B, pool)
t := newGFp2(pool).Add(a.x, B)
t2 := newGFp2(pool).Square(t, pool)
t.Sub(t2, A)
t2.Sub(t, C_)
t2.Sub(t, C)
d := newGFp2(pool).Add(t2, t2)
t.Add(A, A)
e := newGFp2(pool).Add(t, A)
......@@ -189,7 +189,7 @@ func (c *twistPoint) Double(a *twistPoint, pool *bnPool) {
t.Add(d, d)
c.x.Sub(f, t)
t.Add(C_, C_)
t.Add(C, C)
t2.Add(t, t)
t.Add(t2, t2)
c.y.Sub(d, c.x)
......@@ -201,7 +201,7 @@ func (c *twistPoint) Double(a *twistPoint, pool *bnPool) {
A.Put(pool)
B.Put(pool)
C_.Put(pool)
C.Put(pool)
t.Put(pool)
t2.Put(pool)
d.Put(pool)
......
......@@ -16,7 +16,7 @@ import (
"golang.org/x/crypto/sha3"
)
// 校验签名信息是否正确
// ValidateSignatureValues 校验签名信息是否正确
func ValidateSignatureValues(r, s *big.Int) bool {
if r.Cmp(common.Big1) < 0 || s.Cmp(common.Big1) < 0 {
return false
......@@ -24,7 +24,7 @@ func ValidateSignatureValues(r, s *big.Int) bool {
return true
}
// 根据压缩消息和签名,返回未压缩的公钥信息
// Ecrecover 根据压缩消息和签名,返回未压缩的公钥信息
func Ecrecover(hash, sig []byte) ([]byte, error) {
pub, err := SigToPub(hash, sig)
if err != nil {
......@@ -34,7 +34,7 @@ func Ecrecover(hash, sig []byte) ([]byte, error) {
return bytes, err
}
// 根据签名返回公钥信息
// SigToPub 根据签名返回公钥信息
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
btcsig := make([]byte, 65)
btcsig[0] = sig[64] + 27
......@@ -44,7 +44,7 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
return (*ecdsa.PublicKey)(pub), err
}
// 随机生成一个新的地址,给新创建的合约地址使用
// RandomContractAddress 随机生成一个新的地址,给新创建的合约地址使用
func RandomContractAddress() *common.Address {
c, err := crypto.New(types.GetSignName("", types.SECP256K1))
if err != nil {
......
......@@ -11,17 +11,26 @@ import (
)
const (
// HashLength 哈希长度
HashLength = 32
)
// Hash 重定义哈希类型
type Hash common.Hash
func (h Hash) Str() string { return string(h[:]) }
// Str 字符串形式
func (h Hash) Str() string { return string(h[:]) }
// Bytes 二进制形式
func (h Hash) Bytes() []byte { return h[:] }
// Big 大数字形式
func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) }
func (h Hash) Hex() string { return Bytes2Hex(h[:]) }
// 设置哈希中的字节值,如果字节数组长度超过哈希长度,则被截断,只保留后面的部分
// Hex 十六进制形式
func (h Hash) Hex() string { return Bytes2Hex(h[:]) }
// SetBytes 设置哈希中的字节值,如果字节数组长度超过哈希长度,则被截断,只保留后面的部分
func (h *Hash) SetBytes(b []byte) {
if len(b) > len(h) {
b = b[len(b)-HashLength:]
......@@ -30,20 +39,17 @@ func (h *Hash) SetBytes(b []byte) {
copy(h[HashLength-len(b):], b)
}
// BigToHash 大数字转换为哈希
func BigToHash(b *big.Int) Hash {
return Hash(common.BigToHash(b))
}
// 将[]byte直接当做哈希处理
// BytesToHash 将[]byte直接当做哈希处理
func BytesToHash(b []byte) Hash {
return Hash(common.BytesToHash(b))
}
func EmptyHash(h Hash) bool {
return h == Hash{}
}
// 将[]byte经过哈希计算后转化为哈希对象
// ToHash 将[]byte经过哈希计算后转化为哈希对象
func ToHash(data []byte) Hash {
return BytesToHash(common.Sha256(data))
}
......@@ -4,7 +4,7 @@
package common
// 合约交易消息模型
// Message 合约交易消息模型
// 在EVM执行器中传递此消息,由外部Tx等价构造
type Message struct {
to *Address
......@@ -17,6 +17,7 @@ type Message struct {
data []byte
}
// NewMessage 新建消息结构
func NewMessage(from Address, to *Address, nonce int64, amount uint64, gasLimit uint64, gasPrice uint32, data []byte, alias string) *Message {
return &Message{
from: from,
......@@ -30,11 +31,26 @@ func NewMessage(from Address, to *Address, nonce int64, amount uint64, gasLimit
}
}
func (m Message) From() Address { return m.from }
func (m Message) To() *Address { return m.to }
// From 来源
func (m Message) From() Address { return m.from }
// To 目的地址
func (m Message) To() *Address { return m.to }
// GasPrice Gas价格
func (m Message) GasPrice() uint32 { return m.gasPrice }
func (m Message) Value() uint64 { return m.amount }
func (m Message) Nonce() int64 { return m.nonce }
func (m Message) Data() []byte { return m.data }
// Value 转账金额
func (m Message) Value() uint64 { return m.amount }
// Nonce nonce值
func (m Message) Nonce() int64 { return m.nonce }
// Data 附带数据
func (m Message) Data() []byte { return m.data }
// GasLimit Gas限制
func (m Message) GasLimit() uint64 { return m.gasLimit }
func (m Message) Alias() string { return m.alias }
// Alias 合约别名
func (m Message) Alias() string { return m.alias }
......@@ -11,20 +11,26 @@ import (
)
const (
GasQuickStep uint64 = 2
// GasQuickStep 计费
GasQuickStep uint64 = 2
// GasFastestStep 计费
GasFastestStep uint64 = 3
GasFastStep uint64 = 5
GasMidStep uint64 = 8
GasSlowStep uint64 = 10
GasExtStep uint64 = 20
// 允许开辟的最大内存空间大小,超过此值时将会导致溢出
// GasFastStep 计费
GasFastStep uint64 = 5
// GasMidStep 计费
GasMidStep uint64 = 8
// GasSlowStep 计费
GasSlowStep uint64 = 10
// GasExtStep 计费
GasExtStep uint64 = 20
// MaxNewMemSize 允许开辟的最大内存空间大小,超过此值时将会导致溢出
MaxNewMemSize uint64 = 0xffffffffe0
)
// 返回真实花费的Gas
// availableGas - base * 63 / 64.
func callGas(gasTable GasTable, availableGas, base uint64, callCost *big.Int) (uint64, error) {
func callGas(gasTable Table, availableGas, base uint64, callCost *big.Int) (uint64, error) {
if availableGas == callCost.Uint64() {
availableGas = availableGas - base
gas := availableGas - availableGas/64
......
......@@ -14,25 +14,32 @@ import (
// 本文件中定义各种操作中需要花费的Gas逻辑
type (
GasFunc func(GasTable, *params.EVMParam, *params.GasParam, *mm.Stack, *mm.Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
// CalcGasFunc 计算Gas的方法定义
CalcGasFunc func(Table, *params.EVMParam, *params.GasParam, *mm.Stack, *mm.Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
)
// 此文件中定义各种指令操作花费的Gas计算
// Table 此文件中定义各种指令操作花费的Gas计算
// Gas定价表结构
type GasTable struct {
type Table struct {
// ExtcodeSize 扩展代码大小计价
ExtcodeSize uint64
// ExtcodeCopy 代码复制价格
ExtcodeCopy uint64
Balance uint64
SLoad uint64
Calls uint64
Suicide uint64
// Balance 账户计价
Balance uint64
// SLoad 加载数据计价
SLoad uint64
// Calls 调用方法计价
Calls uint64
// Suicide 自杀计价
Suicide uint64
// ExpByte 额外数据计价
ExpByte uint64
}
var (
// 定义各种操作的Gas定价
GasTableHomestead = GasTable{
// TableHomestead 定义各种操作的Gas定价
TableHomestead = Table{
ExtcodeSize: 20,
ExtcodeCopy: 20,
Balance: 20,
......@@ -74,15 +81,15 @@ func memoryGasCost(mem *mm.Memory, newMemSize uint64) (uint64, error) {
return 0, nil
}
// Gas计算逻辑封装,返回固定值的Gas计算都可以使用此方法
func ConstGasFunc(gas uint64) GasFunc {
return func(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// ConstGasFunc Gas计算逻辑封装,返回固定值的Gas计算都可以使用此方法
func ConstGasFunc(gas uint64) CalcGasFunc {
return func(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return gas, nil
}
}
// 计算数据复制需要花费的Gas
func GasCallDataCopy(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// CallDataCopy 计算数据复制需要花费的Gas
func CallDataCopy(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
......@@ -108,7 +115,8 @@ func GasCallDataCopy(gt GasTable, evm *params.EVMParam, contractGas *params.GasP
return gas, nil
}
func GasReturnDataCopy(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// ReturnDataCopy 计算数据复制的价格
func ReturnDataCopy(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
......@@ -134,7 +142,8 @@ func GasReturnDataCopy(gt GasTable, evm *params.EVMParam, contractGas *params.Ga
return gas, nil
}
func GasSStore(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// SStore 计算数据存储的价格
func SStore(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var (
y, x = stack.Back(1), stack.Back(0)
val = evm.StateDB.GetState(contractGas.Address.String(), common.BigToHash(x))
......@@ -157,8 +166,9 @@ func GasSStore(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam,
}
}
func MakeGasLog(n uint64) GasFunc {
return func(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// MakeGasLog 生成Gas计算方法
func MakeGasLog(n uint64) CalcGasFunc {
return func(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
requestedSize, overflow := common.BigUint64(stack.Back(1))
if overflow {
return 0, model.ErrGasUintOverflow
......@@ -187,7 +197,8 @@ func MakeGasLog(n uint64) GasFunc {
}
}
func GasSha3(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Sha3 sha3计费
func Sha3(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var overflow bool
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
......@@ -211,7 +222,8 @@ func GasSha3(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, st
return gas, nil
}
func GasCodeCopy(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// CodeCopy 代码复制计费
func CodeCopy(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
......@@ -235,7 +247,8 @@ func GasCodeCopy(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam
return gas, nil
}
func GasExtCodeCopy(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// ExtCodeCopy 扩展代码复制计费
func ExtCodeCopy(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
......@@ -261,7 +274,8 @@ func GasExtCodeCopy(gt GasTable, evm *params.EVMParam, contractGas *params.GasPa
return gas, nil
}
func GasMLoad(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// MLoad 内存加载计费
func MLoad(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var overflow bool
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
......@@ -273,7 +287,8 @@ func GasMLoad(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, s
return gas, nil
}
func GasMStore8(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// MStore8 内存存储计费
func MStore8(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var overflow bool
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
......@@ -285,7 +300,8 @@ func GasMStore8(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam,
return gas, nil
}
func GasMStore(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// MStore 内存存储计费
func MStore(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var overflow bool
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
......@@ -297,7 +313,8 @@ func GasMStore(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam,
return gas, nil
}
func GasCreate(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Create 开辟内存计费
func Create(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var overflow bool
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
......@@ -309,19 +326,23 @@ func GasCreate(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam,
return gas, nil
}
func GasBalance(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Balance 获取余额计费
func Balance(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return gt.Balance, nil
}
func GasExtCodeSize(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// ExtCodeSize 获取代码大小计费
func ExtCodeSize(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return gt.ExtcodeSize, nil
}
func GasSLoad(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// SLoad 加载存储计费
func SLoad(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return gt.SLoad, nil
}
func GasExp(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Exp exp运算计费
func Exp(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
expByteLen := uint64((stack.Items[stack.Len()-2].BitLen() + 7) / 8)
var (
......@@ -334,7 +355,8 @@ func GasExp(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, sta
return gas, nil
}
func GasCall(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Call 调用合约计费
func Call(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var (
gas = gt.Calls
transfersValue = stack.Back(2).Sign() != 0
......@@ -365,7 +387,8 @@ func GasCall(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, st
return gas, nil
}
func GasCallCode(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// CallCode 调用合约代码计费
func CallCode(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
gas := gt.Calls
if stack.Back(2).Sign() != 0 {
gas += params.CallValueTransferGas
......@@ -389,15 +412,18 @@ func GasCallCode(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam
return gas, nil
}
func GasReturn(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Return 返回操作计费
func Return(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return memoryGasCost(mem, memorySize)
}
func GasRevert(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Revert revert操作计费
func Revert(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return memoryGasCost(mem, memorySize)
}
func GasSuicide(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Suicide 自杀操作计费
func Suicide(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
var gas uint64
if !evm.StateDB.HasSuicided(contractGas.Address.String()) {
evm.StateDB.AddRefund(params.SuicideRefundGas)
......@@ -405,7 +431,8 @@ func GasSuicide(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam,
return gas, nil
}
func GasDelegateCall(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// DelegateCall 委托调用计费
func DelegateCall(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
......@@ -425,7 +452,8 @@ func GasDelegateCall(gt GasTable, evm *params.EVMParam, contractGas *params.GasP
return gas, nil
}
func GasStaticCall(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// StaticCall 静态调用计费
func StaticCall(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
......@@ -445,14 +473,17 @@ func GasStaticCall(gt GasTable, evm *params.EVMParam, contractGas *params.GasPar
return gas, nil
}
func GasPush(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Push 压栈计费
func Push(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return GasFastestStep, nil
}
func GasSwap(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Swap 交换计费
func Swap(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return GasFastestStep, nil
}
func GasDup(gt GasTable, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
// Dup dup操作计费
func Dup(gt Table, evm *params.EVMParam, contractGas *params.GasParam, stack *mm.Stack, mem *mm.Memory, memorySize uint64) (uint64, error) {
return GasFastestStep, nil
}
......@@ -12,15 +12,17 @@ import (
// 整数池允许的最大长度
const poolLimit = 256
// big.Int组成的内存池
// IntPool big.Int组成的内存池
type IntPool struct {
pool *Stack
}
// NewIntPool 创建新的内存池
func NewIntPool() *IntPool {
return &IntPool{pool: NewStack()}
}
// Get 取数据
func (p *IntPool) Get() *big.Int {
if p.pool.Len() > 0 {
return p.pool.Pop()
......@@ -28,6 +30,7 @@ func (p *IntPool) Get() *big.Int {
return new(big.Int)
}
// Put 存数据
func (p *IntPool) Put(is ...*big.Int) {
if len(p.pool.Items) > poolLimit {
return
......@@ -38,7 +41,7 @@ func (p *IntPool) Put(is ...*big.Int) {
}
}
// 返回一个零值的big.Int
// GetZero 返回一个零值的big.Int
func (p *IntPool) GetZero() *big.Int {
if p.pool.Len() > 0 {
return p.pool.Pop().SetUint64(0)
......@@ -49,17 +52,18 @@ func (p *IntPool) GetZero() *big.Int {
// 默认容量
const poolDefaultCap = 25
// 用于管理IntPool的Pool
// IntPoolPool 用于管理IntPool的Pool
type IntPoolPool struct {
pools []*IntPool
lock sync.Mutex
}
// PoolOfIntPools 内存缓冲池
var PoolOfIntPools = &IntPoolPool{
pools: make([]*IntPool, 0, poolDefaultCap),
}
// get is looking for an available pool to return.
// Get 返回一个可用的内存池
func (ipp *IntPoolPool) Get() *IntPool {
ipp.lock.Lock()
defer ipp.lock.Unlock()
......@@ -72,7 +76,7 @@ func (ipp *IntPoolPool) Get() *IntPool {
return NewIntPool()
}
// put a pool that has been allocated with get.
// Put 放入一个初始化过的内存池
func (ipp *IntPoolPool) Put(ip *IntPool) {
ipp.lock.Lock()
defer ipp.lock.Unlock()
......
......@@ -12,19 +12,20 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
)
// 内存操作封装,在EVM中使用此对象模拟物理内存
// Memory 内存操作封装,在EVM中使用此对象模拟物理内存
type Memory struct {
// 内存中存储的数据
// Store 内存中存储的数据
Store []byte
// 上次开辟内存消耗的Gas
// LastGasCost 上次开辟内存消耗的Gas
LastGasCost uint64
}
// NewMemory 创建内存对象结构
func NewMemory() *Memory {
return &Memory{}
}
// 设置内存中的值, value => offset:offset + size
// Set 设置内存中的值, value => offset:offset + size
func (m *Memory) Set(offset, size uint64, value []byte) (err error) {
if size > 0 {
// 偏移量+大小一定不会大于内存长度
......@@ -39,7 +40,7 @@ func (m *Memory) Set(offset, size uint64, value []byte) (err error) {
return nil
}
// 从offset开始设置32个字节的内存值,如果值长度不足32个字节,左零值填充
// Set32 从offset开始设置32个字节的内存值,如果值长度不足32个字节,左零值填充
func (m *Memory) Set32(offset uint64, val *big.Int) (err error) {
// 确保长度足够设置值
......@@ -58,14 +59,14 @@ func (m *Memory) Set32(offset uint64, val *big.Int) (err error) {
return nil
}
// 扩充内存到指定大小
// Resize 扩充内存到指定大小
func (m *Memory) Resize(size uint64) {
if uint64(m.Len()) < size {
m.Store = append(m.Store, make([]byte, size-uint64(m.Len()))...)
}
}
// 获取内存中制定偏移量开始的指定长度的数据,返回数据的拷贝而非引用
// Get 获取内存中制定偏移量开始的指定长度的数据,返回数据的拷贝而非引用
func (m *Memory) Get(offset, size int64) (cpy []byte) {
if size == 0 {
return nil
......@@ -81,7 +82,7 @@ func (m *Memory) Get(offset, size int64) (cpy []byte) {
return
}
// 同Get操作,不过这里返回的是数据引用
// GetPtr 同Get操作,不过这里返回的是数据引用
func (m *Memory) GetPtr(offset, size int64) []byte {
if size == 0 {
return nil
......@@ -94,17 +95,17 @@ func (m *Memory) GetPtr(offset, size int64) []byte {
return nil
}
// 返回内存中已开辟空间的大小(以字节计算)
// Len 返回内存中已开辟空间的大小(以字节计算)
func (m *Memory) Len() int {
return len(m.Store)
}
// 返回内存中的原始数据引用
// Data 返回内存中的原始数据引用
func (m *Memory) Data() []byte {
return m.Store
}
// 打印内存中的数据(调试用)
// Print 打印内存中的数据(调试用)
func (m *Memory) Print() {
fmt.Printf("### mem %d bytes ###\n", len(m.Store))
if len(m.Store) > 0 {
......
......@@ -13,46 +13,56 @@ import (
// 本文件中定义各种操作下计算内存大小的逻辑
type (
// 计算所需内存大小
// MemorySizeFunc 计算所需内存大小
MemorySizeFunc func(*Stack) *big.Int
)
// MemorySha3 sha3计算所需内存大小
func MemorySha3(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), stack.Back(1))
}
//MemoryCallDataCopy callDataCopy所需内存大小
func MemoryCallDataCopy(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), stack.Back(2))
}
//MemoryReturnDataCopy returnDataCopy所需内存大小
func MemoryReturnDataCopy(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), stack.Back(2))
}
//MemoryCodeCopy codeCopy所需内存大小
func MemoryCodeCopy(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), stack.Back(2))
}
//MemoryExtCodeCopy extCodeCopy所需内存大小
func MemoryExtCodeCopy(stack *Stack) *big.Int {
return calcMemSize(stack.Back(1), stack.Back(3))
}
//MemoryMLoad mload所需内存大小
func MemoryMLoad(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), big.NewInt(32))
}
//MemoryMStore8 mstore8所需内存大小
func MemoryMStore8(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), big.NewInt(1))
}
//MemoryMStore mstore所需内存大小
func MemoryMStore(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), big.NewInt(32))
}
//MemoryCreate create所需内存大小
func MemoryCreate(stack *Stack) *big.Int {
return calcMemSize(stack.Back(1), stack.Back(2))
}
//MemoryCall call所需内存大小
func MemoryCall(stack *Stack) *big.Int {
x := calcMemSize(stack.Back(5), stack.Back(6))
y := calcMemSize(stack.Back(3), stack.Back(4))
......@@ -60,6 +70,7 @@ func MemoryCall(stack *Stack) *big.Int {
return common.BigMax(x, y)
}
//MemoryDelegateCall delegateCall所需内存大小
func MemoryDelegateCall(stack *Stack) *big.Int {
x := calcMemSize(stack.Back(4), stack.Back(5))
y := calcMemSize(stack.Back(2), stack.Back(3))
......@@ -67,6 +78,7 @@ func MemoryDelegateCall(stack *Stack) *big.Int {
return common.BigMax(x, y)
}
//MemoryStaticCall staticCall所需内存大小
func MemoryStaticCall(stack *Stack) *big.Int {
x := calcMemSize(stack.Back(4), stack.Back(5))
y := calcMemSize(stack.Back(2), stack.Back(3))
......@@ -74,14 +86,17 @@ func MemoryStaticCall(stack *Stack) *big.Int {
return common.BigMax(x, y)
}
//MemoryReturn return所需内存大小
func MemoryReturn(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), stack.Back(1))
}
//MemoryRevert revert所需内存大小
func MemoryRevert(stack *Stack) *big.Int {
return calcMemSize(stack.Back(0), stack.Back(1))
}
//MemoryLog log所需内存大小
func MemoryLog(stack *Stack) *big.Int {
mSize, mStart := stack.Back(1), stack.Back(0)
return calcMemSize(mStart, mSize)
......
......@@ -11,63 +11,64 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/params"
)
// 栈对象封装,提供常用的栈操作
// Stack 栈对象封装,提供常用的栈操作
type Stack struct {
Items []*big.Int
}
// NewStack 新创建栈对象
func NewStack() *Stack {
return &Stack{Items: make([]*big.Int, 0, params.StackLimit)}
}
// 返回栈中的所有底层数据
// Data 返回栈中的所有底层数据
func (st *Stack) Data() []*big.Int {
return st.Items
}
// 数据入栈
// Push 数据入栈
func (st *Stack) Push(d *big.Int) {
st.Items = append(st.Items, d)
}
// 同时压栈多个数据
// PushN 同时压栈多个数据
func (st *Stack) PushN(ds ...*big.Int) {
st.Items = append(st.Items, ds...)
}
// 弹出栈顶数据
// Pop 弹出栈顶数据
func (st *Stack) Pop() (ret *big.Int) {
ret = st.Items[len(st.Items)-1]
st.Items = st.Items[:len(st.Items)-1]
return
}
// 栈长度
// Len 栈长度
func (st *Stack) Len() int {
return len(st.Items)
}
// 将栈顶数据和栈中指定位置的数据互换位置
// Swap 将栈顶数据和栈中指定位置的数据互换位置
func (st *Stack) Swap(n int) {
st.Items[st.Len()-n], st.Items[st.Len()-1] = st.Items[st.Len()-1], st.Items[st.Len()-n]
}
// 复制栈中指定位置的数据的栈顶
// Dup 复制栈中指定位置的数据的栈顶
func (st *Stack) Dup(pool *IntPool, n int) {
st.Push(pool.Get().Set(st.Items[st.Len()-n]))
}
// 返回顶端数据
// Peek 返回顶端数据
func (st *Stack) Peek() *big.Int {
return st.Items[st.Len()-1]
}
// 返回第n个取值
// Back 返回第n个取值
func (st *Stack) Back(n int) *big.Int {
return st.Items[st.Len()-n-1]
}
// 检查栈是否满足长度要求
// Require 检查栈是否满足长度要求
func (st *Stack) Require(n int) error {
if st.Len() < n {
return fmt.Errorf("stack underflow (%d <=> %d)", len(st.Items), n)
......@@ -75,7 +76,7 @@ func (st *Stack) Require(n int) error {
return nil
}
// 印栈对象(调试用)
// Print 印栈对象(调试用)
func (st *Stack) Print() {
fmt.Println("### stack ###")
if len(st.Items) > 0 {
......
......@@ -11,11 +11,11 @@ import (
)
type (
// 校验栈中数据是否满足计算要求
// StackValidationFunc 校验栈中数据是否满足计算要求
StackValidationFunc func(*Stack) error
)
// 栈校验的通用逻辑封装(主要就是检查栈的深度和空间是否够用)
// MakeStackFunc 栈校验的通用逻辑封装(主要就是检查栈的深度和空间是否够用)
func MakeStackFunc(pop, push int) StackValidationFunc {
return func(stack *Stack) error {
if err := stack.Require(pop); err != nil {
......@@ -29,10 +29,12 @@ func MakeStackFunc(pop, push int) StackValidationFunc {
}
}
// MakeDupStackFunc 创建栈大小计算方法对象
func MakeDupStackFunc(n int) StackValidationFunc {
return MakeStackFunc(n, n+1)
}
// MakeSwapStackFunc 创建栈大小计算方法对象
func MakeSwapStackFunc(n int) StackValidationFunc {
return MakeStackFunc(n, n)
}
......@@ -5,8 +5,8 @@
package model
const (
// 内存中存储的字,占用多少位
// WordBitSize 内存中存储的字,占用多少位
WordBitSize = 256
// 内存中存储的字,占用多少字节
// WordByteSize 内存中存储的字,占用多少字节
WordByteSize = WordBitSize / 8
)
......@@ -7,24 +7,38 @@ package model
import "errors"
var (
ErrOutOfGas = errors.New("out of gas")
ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas")
ErrDepth = errors.New("max call depth exceeded")
ErrTraceLimitReached = errors.New("the number of logs reached the specified limit")
ErrInsufficientBalance = errors.New("insufficient balance for transfer")
// ErrOutOfGas out of gas
ErrOutOfGas = errors.New("out of gas")
// ErrCodeStoreOutOfGas contract creation code storage out of gas
ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas")
// ErrDepth max call depth exceeded
ErrDepth = errors.New("max call depth exceeded")
// ErrInsufficientBalance insufficient balance for transfer
ErrInsufficientBalance = errors.New("insufficient balance for transfer")
// ErrContractAddressCollision contract address collision
ErrContractAddressCollision = errors.New("contract address collision")
ErrGasLimitReached = errors.New("gas limit reached")
ErrGasUintOverflow = errors.New("gas uint64 overflow")
ErrAddrNotExists = errors.New("address not exists")
// ErrGasUintOverflow gas uint64 overflow
ErrGasUintOverflow = errors.New("gas uint64 overflow")
// ErrAddrNotExists address not exists
ErrAddrNotExists = errors.New("address not exists")
// ErrTransferBetweenContracts transferring between contracts not supports
ErrTransferBetweenContracts = errors.New("transferring between contracts not supports")
ErrTransferBetweenEOA = errors.New("transferring between external accounts not supports")
ErrNoCreator = errors.New("contract has no creator information")
ErrDestruct = errors.New("contract has been destructed")
// ErrTransferBetweenEOA transferring between external accounts not supports
ErrTransferBetweenEOA = errors.New("transferring between external accounts not supports")
// ErrNoCreator contract has no creator information
ErrNoCreator = errors.New("contract has no creator information")
// ErrDestruct contract has been destructed
ErrDestruct = errors.New("contract has been destructed")
ErrWriteProtection = errors.New("evm: write protection")
// ErrWriteProtection evm: write protection
ErrWriteProtection = errors.New("evm: write protection")
// ErrReturnDataOutOfBounds evm: return data out of bounds
ErrReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
ErrExecutionReverted = errors.New("evm: execution reverted")
ErrMaxCodeSizeExceeded = errors.New("evm: max code size exceeded")
// ErrExecutionReverted evm: execution reverted
ErrExecutionReverted = errors.New("evm: execution reverted")
// ErrMaxCodeSizeExceeded evm: max code size exceeded
ErrMaxCodeSizeExceeded = errors.New("evm: max code size exceeded")
NoCoinsAccount = errors.New("no coins account in executor!")
// ErrNoCoinsAccount no coins account in executor!
ErrNoCoinsAccount = errors.New("no coins account in executor")
)
......@@ -9,26 +9,26 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
)
// 合约在日志,对应EVM中的Log指令,可以生成指定的日志信息
// ContractLog 合约在日志,对应EVM中的Log指令,可以生成指定的日志信息
// 目前这些日志只是在合约执行完成时进行打印,没有其它用途
type ContractLog struct {
// 合约地址
// Address 合约地址
Address common.Address
// 对应交易哈希
// TxHash 对应交易哈希
TxHash common.Hash
// 日志序号
// Index 日志序号
Index int
// 此合约提供的主题信息
// Topics 此合约提供的主题信息
Topics []common.Hash
// 日志数据
// Data 日志数据
Data []byte
}
// 合约日志打印格式
// PrintLog 合约日志打印格式
func (log *ContractLog) PrintLog() {
log15.Debug("!Contract Log!", "Contract address", log.Address.String(), "TxHash", log.TxHash.Hex(), "Log Index", log.Index, "Log Topics", log.Topics, "Log Data", common.Bytes2Hex(log.Data))
}
......@@ -11,19 +11,19 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/state"
)
// 解释器中调用Gas计算时所传递的合约中和Gas相关的参数结构
// GasParam 解释器中调用Gas计算时所传递的合约中和Gas相关的参数结构
// 之所以单独封装,是为了将解释器、指令集、Gas计算三者解耦
// 此结构包含的属性均为只读
type GasParam struct {
// 此合约对象的可用Gas(合约执行过程中会修改此值)
// Gas 此合约对象的可用Gas(合约执行过程中会修改此值)
Gas uint64
// 上下文中合约自身的地址
// Address 上下文中合约自身的地址
// 注意,当合约通过CallCode调用时,这个地址并不是当前合约代码对应的地址,而是调用者的地址
Address common.Address
}
// 解释器中调用Gas计算时所传递的合约中和EVM相关的参数结构
// EVMParam 解释器中调用Gas计算时所传递的合约中和EVM相关的参数结构
// 之所以单独封装,是为了将解释器、Gas计算两者解耦
// 此结构包含的属性中StateDB和CallGasTemp可写,解释器调用Gas计算的步骤如下:
// 1. 使用EVM构造EVMParam(属性除CallGasTemp外,全部传递引用);
......@@ -31,14 +31,14 @@ type GasParam struct {
// 3. 计算结束后,使用EVMParam中的值回填到EVM中;
type EVMParam struct {
// 状态数据操作入口
StateDB state.StateDB
// EVMStateDB 状态数据操作入口
StateDB state.EVMStateDB
// 此属性用于临时存储计算出来的Gas消耗值
// CallGasTemp 此属性用于临时存储计算出来的Gas消耗值
// 在指令执行时,会调用指令的gasCost方法,计算出此指令需要消耗的Gas,并存放在此临时属性中
// 然后在执行opCall时,从此属性获取消耗的Gas值
CallGasTemp uint64
// NUMBER 指令,当前区块高度
// BlockNumber NUMBER 指令,当前区块高度
BlockNumber *big.Int
}
......@@ -5,43 +5,75 @@
package params
const (
MaxCodeSize = 24576 // 合约允许的最大字节数
CallCreateDepth uint64 = 1024 // 合约递归调用最大深度
StackLimit uint64 = 1024 // 栈允许的最大深度
// MaxCodeSize 合约允许的最大字节数
MaxCodeSize = 24576
// CallCreateDepth 合约递归调用最大深度
CallCreateDepth uint64 = 1024
// StackLimit 栈允许的最大深度
StackLimit uint64 = 1024
// 各种操作对应的Gas定价
CreateDataGas uint64 = 200 // 创建合约时,按字节计费
CallStipend uint64 = 2300 // 每次CALL调用之前,给予一定额度的免费Gas
CallValueTransferGas uint64 = 9000 // 转账操作
CallNewAccountGas uint64 = 25000 // 操作目标地址事先不存在
QuadCoeffDiv uint64 = 512 // 计算开辟内存花费时,在计算出的内存大小平方基础上除此值
CopyGas uint64 = 3 // 内存数据复制时,按字计费
// CreateDataGas 创建合约时,按字节计费
CreateDataGas uint64 = 200
// CallStipend 每次CALL调用之前,给予一定额度的免费Gas
CallStipend uint64 = 2300
// CallValueTransferGas 转账操作
CallValueTransferGas uint64 = 9000
// CallNewAccountGas 操作目标地址事先不存在
CallNewAccountGas uint64 = 25000
// QuadCoeffDiv 计算开辟内存花费时,在计算出的内存大小平方基础上除此值
QuadCoeffDiv uint64 = 512
// CopyGas 内存数据复制时,按字计费
CopyGas uint64 = 3
Sha3Gas uint64 = 30 // SHA3操作
Sha3WordGas uint64 = 6 // SHA3操作的数据按字计费
SstoreSetGas uint64 = 20000 // SSTORE 从零值地址到非零值地址存储
SstoreResetGas uint64 = 5000 // SSTORE 从非零值地址到非零值地址存储
SstoreClearGas uint64 = 5000 // SSTORE 从非零值地址到零值地址存储
SstoreRefundGas uint64 = 15000 // SSTORE 删除值时给予的奖励
JumpdestGas uint64 = 1 // JUMPDEST 指令
LogGas uint64 = 375 // LOGN 操作计费
LogDataGas uint64 = 8 // LOGN生成的数据,每个字节的计费价格
LogTopicGas uint64 = 375 // LOGN 生成日志时,使用N*此值计费
CreateGas uint64 = 32000 // CREATE 指令
SuicideRefundGas uint64 = 24000 // SUICIDE 操作时给予的奖励
MemoryGas uint64 = 3 // 开辟新内存时按字收费
// Sha3Gas SHA3操作
Sha3Gas uint64 = 30
// Sha3WordGas SHA3操作的数据按字计费
Sha3WordGas uint64 = 6
// SstoreSetGas SSTORE 从零值地址到非零值地址存储
SstoreSetGas uint64 = 20000
// SstoreResetGas SSTORE 从非零值地址到非零值地址存储
SstoreResetGas uint64 = 5000
// SstoreClearGas SSTORE 从非零值地址到零值地址存储
SstoreClearGas uint64 = 5000
// SstoreRefundGas SSTORE 删除值时给予的奖励
SstoreRefundGas uint64 = 15000
// JumpdestGas JUMPDEST 指令
JumpdestGas uint64 = 1
// LogGas LOGN 操作计费
LogGas uint64 = 375
// LogDataGas LOGN生成的数据,每个字节的计费价格
LogDataGas uint64 = 8
// LogTopicGas LOGN 生成日志时,使用N*此值计费
LogTopicGas uint64 = 375
// CreateGas CREATE 指令
CreateGas uint64 = 32000
// SuicideRefundGas SUICIDE 操作时给予的奖励
SuicideRefundGas uint64 = 24000
// MemoryGas 开辟新内存时按字收费
MemoryGas uint64 = 3
// 预编译合约的Gas定价
EcrecoverGas uint64 = 3000 // ecrecover 指令
Sha256BaseGas uint64 = 60 // SHA256 基础计费
Sha256PerWordGas uint64 = 12 // SHA256 按字长计费 (总计费等于两者相加)
Ripemd160BaseGas uint64 = 600 // RIPEMD160 基础计费
Ripemd160PerWordGas uint64 = 120 // RIPEMD160 按字长计费 (总计费等于两者相加)
IdentityBaseGas uint64 = 15 // dataCopy 基础计费
IdentityPerWordGas uint64 = 3 // dataCopy 按字长计费(总计费等于两者相加)
ModExpQuadCoeffDiv uint64 = 20 // 大整数取模运算时计算出的费用除此数
Bn256AddGas uint64 = 500 // Bn256Add 计费
Bn256ScalarMulGas uint64 = 40000 // Bn256ScalarMul 计费
Bn256PairingBaseGas uint64 = 100000 // bn256Pairing 基础计费
Bn256PairingPerPointGas uint64 = 80000 // bn256Pairing 按point计费(总计费等于两者相加)
// EcrecoverGas ecrecover 指令
EcrecoverGas uint64 = 3000
// Sha256BaseGas SHA256 基础计费
Sha256BaseGas uint64 = 60
// Sha256PerWordGas SHA256 按字长计费 (总计费等于两者相加)
Sha256PerWordGas uint64 = 12
// Ripemd160BaseGas RIPEMD160 基础计费
Ripemd160BaseGas uint64 = 600
// Ripemd160PerWordGas RIPEMD160 按字长计费 (总计费等于两者相加)
Ripemd160PerWordGas uint64 = 120
// IdentityBaseGas dataCopy 基础计费
IdentityBaseGas uint64 = 15
// IdentityPerWordGas dataCopy 按字长计费(总计费等于两者相加)
IdentityPerWordGas uint64 = 3
// ModExpQuadCoeffDiv 大整数取模运算时计算出的费用除此数
ModExpQuadCoeffDiv uint64 = 20
// Bn256AddGas Bn256Add 计费
Bn256AddGas uint64 = 500
// Bn256ScalarMulGas Bn256ScalarMul 计费
Bn256ScalarMulGas uint64 = 40000
// Bn256PairingBaseGas bn256Pairing 基础计费
Bn256PairingBaseGas uint64 = 100000
// Bn256PairingPerPointGas bn256Pairing 按point计费(总计费等于两者相加)
Bn256PairingPerPointGas uint64 = 80000
)
......@@ -15,7 +15,7 @@ import (
// JUMPDEST指令会使用此对象进行跳转位置判断
type Destinations map[common.Hash]bitvec
// 检查PC只想的代码是否存在JUMPDEST指令,并且跳转目标有效
// Has 检查PC只想的代码是否存在JUMPDEST指令,并且跳转目标有效
func (d Destinations) Has(codehash common.Hash, code []byte, dest *big.Int) bool {
// 首先需要检查PC(指令指针),它不可能比代码长度还大,也不可能大于63位
// 注意,这里的参数dest就是PC指针
......
......@@ -8,22 +8,22 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
)
// 合约对象引用
// ContractRef 合约对象引用
type ContractRef interface {
Address() common.Address
}
// 账户对象引用 (实现了合约对象引用ContractRef接口)
// AccountRef 账户对象引用 (实现了合约对象引用ContractRef接口)
// 因为在合约调用过程中,调用者有可能是外部账户,也有可能是合约账户,所以两者的结构是互通的
type AccountRef common.Address
// 将账户引用转换为普通地址对象
// Address 将账户引用转换为普通地址对象
func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
// 合约对象,它在内存中表示一个合约账户的代码即地址信息实体
// Contract 合约对象,它在内存中表示一个合约账户的代码即地址信息实体
// 每次合约调用都会创建一个新的合约对象
type Contract struct {
// 调用者地址,应该为外部账户的地址
// CallerAddress 调用者地址,应该为外部账户的地址
// 如果是通过合约再调用合约时,会从上级合约中获取调用者地址进行赋值
CallerAddress common.Address
......@@ -34,28 +34,30 @@ type Contract struct {
// 但是,二般情况下(外部账户通过CallCode直接调用合约代码时,此地址会设置为外部账户的地址,就是和caller一样)
self ContractRef
// 存储跳转信息,供JUMP和JUMPI指令使用
// Jumpdests 存储跳转信息,供JUMP和JUMPI指令使用
Jumpdests Destinations
// 合约代码和代码哈希
Code []byte
// Code合约代码
Code []byte
// CodeHash 代码哈希
CodeHash common.Hash
// 合约地址以及输入参数
// CodeAddr 合约地址
CodeAddr *common.Address
Input []byte
// Input 输入参数
Input []byte
// 此合约对象的可用Gas(合约执行过程中会修改此值)
// Gas 此合约对象的可用Gas(合约执行过程中会修改此值)
Gas uint64
// 合约调用的同时,如果包含转账逻辑,则此处为转账金额
// value 合约调用的同时,如果包含转账逻辑,则此处为转账金额
value uint64
// 委托调用时,此属性会被设置为true
// DelegateCall 委托调用时,此属性会被设置为true
DelegateCall bool
}
// 创建一个新的合约调用对象
// NewContract 创建一个新的合约调用对象
// 不管合约是否存在,每次调用时都会新创建一个合约对象交给解释器执行,对象持有合约代码和合约地址
func NewContract(caller ContractRef, object ContractRef, value uint64, gas uint64) *Contract {
......@@ -76,7 +78,7 @@ func NewContract(caller ContractRef, object ContractRef, value uint64, gas uint6
return c
}
// 设置当前的合约对象为被委托调用
// AsDelegate 设置当前的合约对象为被委托调用
// 返回当前合约对象的指针,以便在多层调用链模式下使用
func (c *Contract) AsDelegate() *Contract {
c.DelegateCall = true
......@@ -92,12 +94,12 @@ func (c *Contract) AsDelegate() *Contract {
return c
}
// 获取合约代码中制定位置的操作码
// GetOp 获取合约代码中制定位置的操作码
func (c *Contract) GetOp(n uint64) OpCode {
return OpCode(c.GetByte(n))
}
// 获取合约代码中制定位置的字节值
// GetByte 获取合约代码中制定位置的字节值
func (c *Contract) GetByte(n uint64) byte {
if n < uint64(len(c.Code)) {
return c.Code[n]
......@@ -106,14 +108,14 @@ func (c *Contract) GetByte(n uint64) byte {
return 0
}
// 返回合约的调用者
// Caller 返回合约的调用者
// 如果当前合约为委托调用,则调用它的不是外部账户,而是合约账户,所以此时的caller为调用此合约的合约的caller
// 这个关系可以一直递归向上,直到定位到caller为外部账户地址
func (c *Contract) Caller() common.Address {
return c.CallerAddress
}
// 从合约的可用gas中进行gas消费
// UseGas 从合约的可用gas中进行gas消费
func (c *Contract) UseGas(gas uint64) (ok bool) {
if c.Gas < gas {
return false
......@@ -122,26 +124,26 @@ func (c *Contract) UseGas(gas uint64) (ok bool) {
return true
}
// 返回上下文中合约自身的地址
// Address 返回上下文中合约自身的地址
// 注意,当合约通过CallCode调用时,这个地址并不是当前合约代码对应的地址,而是调用者的地址
func (c *Contract) Address() common.Address {
return c.self.Address()
}
// 合约包含转账逻辑时,转账的金额
// Value 合约包含转账逻辑时,转账的金额
func (c *Contract) Value() uint64 {
return c.value
}
// 设置合约代码内容
func (self *Contract) SetCode(hash common.Hash, code []byte) {
self.Code = code
self.CodeHash = hash
// SetCode 设置合约代码内容
func (c *Contract) SetCode(hash common.Hash, code []byte) {
c.Code = code
c.CodeHash = hash
}
// 设置合约代码和代码哈希
func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
self.Code = code
self.CodeHash = hash
self.CodeAddr = addr
// SetCallCode 设置合约代码和代码哈希
func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) {
c.Code = code
c.CodeHash = hash
c.CodeAddr = addr
}
......@@ -17,7 +17,7 @@ import (
"golang.org/x/crypto/ripemd160"
)
// 系统内置合约实现的接口,只包含两个操作:
// PrecompiledContract 系统内置合约实现的接口,只包含两个操作:
// 1 根据合约自身逻辑和入参,计算所需Gas;
// 2 执行合约。
type PrecompiledContract interface {
......@@ -28,7 +28,7 @@ type PrecompiledContract interface {
Run(input []byte) ([]byte, error)
}
// chain33平台支持君士坦丁堡版本支持的所有预编译合约指令,并从此版本开始同步支持EVM黄皮书中的新增指令;
// PrecompiledContractsByzantium chain33平台支持君士坦丁堡版本支持的所有预编译合约指令,并从此版本开始同步支持EVM黄皮书中的新增指令;
// 保存拜占庭版本支持的所有预编译合约(包括之前版本的合约);
// 后面如果有硬分叉,需要在此处考虑分叉逻辑,根据区块高度分别处理;
// 下面的8个预编译指令,直接引用go-ethereum中的EVM实现
......@@ -46,7 +46,7 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{8}): &bn256Pairing{},
}
// 调用预编译的合约逻辑并返回结果
// RunPrecompiledContract 调用预编译的合约逻辑并返回结果
func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contract) (ret []byte, err error) {
gas := p.RequiredGas(input)
if contract.UseGas(gas) {
......@@ -58,10 +58,12 @@ func RunPrecompiledContract(p PrecompiledContract, input []byte, contract *Contr
// 预编译合约 ECRECOVER 椭圆曲线算法支持
type ecrecover struct{}
// RequiredGas 需要消耗多少Gas
func (c *ecrecover) RequiredGas(input []byte) uint64 {
return params.EcrecoverGas
}
// Run 运算
func (c *ecrecover) Run(input []byte) ([]byte, error) {
const ecRecoverInputLength = 128
......@@ -98,6 +100,8 @@ type sha256hash struct{}
func (c *sha256hash) RequiredGas(input []byte) uint64 {
return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas
}
// Run run
func (c *sha256hash) Run(input []byte) ([]byte, error) {
h := sha256.Sum256(input)
return h[:], nil
......@@ -113,6 +117,8 @@ type ripemd160hash struct{}
func (c *ripemd160hash) RequiredGas(input []byte) uint64 {
return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas
}
// Run run
func (c *ripemd160hash) Run(input []byte) ([]byte, error) {
ripemd := ripemd160.New()
ripemd.Write(input)
......@@ -129,6 +135,8 @@ type dataCopy struct{}
func (c *dataCopy) RequiredGas(input []byte) uint64 {
return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas
}
// Run run
func (c *dataCopy) Run(in []byte) ([]byte, error) {
return in, nil
}
......@@ -210,6 +218,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 {
return gas.Uint64()
}
// Run run
func (c *bigModExp) Run(input []byte) ([]byte, error) {
var (
baseLen = new(big.Int).SetBytes(common.GetData(input, 0, 32)).Uint64()
......
......@@ -19,13 +19,13 @@ import (
)
type (
// 检查制定账户是否有足够的金额进行转账
CanTransferFunc func(state.StateDB, common.Address, common.Address, uint64) bool
// CanTransferFunc 检查制定账户是否有足够的金额进行转账
CanTransferFunc func(state.EVMStateDB, common.Address, common.Address, uint64) bool
// 执行转账逻辑
TransferFunc func(state.StateDB, common.Address, common.Address, uint64) bool
// TransferFunc 执行转账逻辑
TransferFunc func(state.EVMStateDB, common.Address, common.Address, uint64) bool
// 获取制定高度区块的哈希
// GetHashFunc 获取制定高度区块的哈希
// 给 BLOCKHASH 指令使用
GetHashFunc func(uint64) common.Hash
)
......@@ -48,30 +48,32 @@ func run(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
return ret, err
}
// EVM操作辅助上下文
// Context EVM操作辅助上下文
// 外部在构造EVM实例时传入,EVM实例构造完成后不允许修改
type Context struct {
// 下面这三个方法的说明,请查看方法类型的定义
// CanTransfer 是否可转账
CanTransfer CanTransferFunc
Transfer TransferFunc
GetHash GetHashFunc
// Transfer 转账
Transfer TransferFunc
// GetHash 获取区块哈希
GetHash GetHashFunc
// ORIGIN 指令返回数据, 合约调用者地址
// Origin 指令返回数据, 合约调用者地址
Origin common.Address
// GASPRICE 指令返回数据
// GasPrice 指令返回数据
GasPrice uint32
// COINBASE 指令, 区块打包者地址
// Coinbase 指令, 区块打包者地址
Coinbase *common.Address
// GASLIMIT 指令,当前交易的GasLimit
// GasLimit 指令,当前交易的GasLimit
GasLimit uint64
// NUMBER 指令,当前区块高度
// BlockNumber NUMBER 指令,当前区块高度
BlockNumber *big.Int
// TIME 指令, 当前区块打包时间
// Time 指令, 当前区块打包时间
Time *big.Int
// DIFFICULTY 指令,当前区块难度
// Difficulty 指令,当前区块难度
Difficulty *big.Int
}
......@@ -80,24 +82,24 @@ type Context struct {
// 在合约代码执行过程中发生的任何错误,都将会导致对状态数据的修改被回滚,并且依然消耗掉剩余的Gas
// 此对象为每个交易创建一个实例,其操作非线程安全
type EVM struct {
// 链相关的一些辅助属性和操作方法
// Context 链相关的一些辅助属性和操作方法
Context
// 状态数据操作入口
StateDB state.StateDB
// EVMStateDB 状态数据操作入口
StateDB state.EVMStateDB
// 当前调用深度
depth int
// 虚拟机配置属性信息
VmConfig Config
// VMConfig 虚拟机配置属性信息
VMConfig Config
// EVM指令解释器,生命周期同EVM
// Interpreter EVM指令解释器,生命周期同EVM
Interpreter *Interpreter
// EVM执行流程结束标志
// 不允许手工设置
abort int32
// 此属性用于临时存储计算出来的Gas消耗值
// CallGasTemp 此属性用于临时存储计算出来的Gas消耗值
// 在指令执行时,会调用指令的gasCost方法,计算出此指令需要消耗的Gas,并存放在此临时属性中
// 然后在执行opCall时,从此属性获取消耗的Gas值
CallGasTemp uint64
......@@ -106,14 +108,13 @@ type EVM struct {
maxCodeSize int
}
// 创建一个新的EVM实例对象
// NewEVM 创建一个新的EVM实例对象
// 在同一个节点中,一个EVM实例对象只服务于一个交易执行的生命周期
func NewEVM(ctx Context, statedb state.StateDB, vmConfig Config) *EVM {
func NewEVM(ctx Context, statedb state.EVMStateDB, vmConfig Config) *EVM {
evm := &EVM{
Context: ctx,
StateDB: statedb,
VmConfig: vmConfig,
VMConfig: vmConfig,
maxCodeSize: params.MaxCodeSize,
}
......@@ -121,18 +122,18 @@ func NewEVM(ctx Context, statedb state.StateDB, vmConfig Config) *EVM {
return evm
}
// 返回不同操作消耗的Gas定价表
// GasTable 返回不同操作消耗的Gas定价表
// 接收区块高度作为参数,方便以后在这里作分叉处理
func (c *EVM) GasTable(num *big.Int) gas.GasTable {
return gas.GasTableHomestead
func (evm *EVM) GasTable(num *big.Int) gas.Table {
return gas.TableHomestead
}
// 调用此操作会在任意时刻取消此EVM的解释运行逻辑,支持重复调用
// Cancel 调用此操作会在任意时刻取消此EVM的解释运行逻辑,支持重复调用
func (evm *EVM) Cancel() {
atomic.StoreInt32(&evm.abort, 1)
}
// 设置合约代码的最大支持长度
// SetMaxCodeSize 设置合约代码的最大支持长度
func (evm *EVM) SetMaxCodeSize(maxCodeSize int) {
if maxCodeSize < 1 || maxCodeSize > params.MaxCodeSize {
return
......@@ -144,7 +145,7 @@ func (evm *EVM) SetMaxCodeSize(maxCodeSize int) {
// 封装合约的各种调用逻辑中通用的预检查逻辑
func (evm *EVM) preCheck(caller ContractRef, recipient common.Address, value uint64) (pass bool, err error) {
// 检查调用深度是否合法
if evm.VmConfig.NoRecursion && evm.depth > 0 {
if evm.VMConfig.NoRecursion && evm.depth > 0 {
return false, nil
}
......@@ -164,7 +165,7 @@ func (evm *EVM) preCheck(caller ContractRef, recipient common.Address, value uin
return true, nil
}
// 此方法提供合约外部调用入口
// Call 此方法提供合约外部调用入口
// 根据合约地址调用已经存在的合约,input为合约调用参数
// 合约调用逻辑支持在合约调用的同时进行向合约转账的操作
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value uint64) (ret []byte, snapshot int, leftOverGas uint64, err error) {
......@@ -181,16 +182,16 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// 只有一种情况会走到这里来,就是合约账户向外部账户转账的情况
if len(input) > 0 || value == 0 {
// 其它情况要求地址必须存在,所以需要报错
if evm.VmConfig.Debug && evm.depth == 0 {
evm.VmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
evm.VmConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
if evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
evm.VMConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
}
return nil, -1, gas, model.ErrAddrNotExists
}
} else {
// 否则,为预编译合约,创建一个新的账号
// 此分支先屏蔽,不需要为预编译合约创建账号也可以调用合约逻辑,因为预编译合约只有逻辑没有存储状态,可以不对应具体的账号存储
// evm.StateDB.CreateAccount(addr, caller.Address())
// evm.EVMStateDB.CreateAccount(addr, caller.Address())
}
}
......@@ -213,11 +214,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
start := types.Now()
// 调试模式下启用跟踪
if evm.VmConfig.Debug && evm.depth == 0 {
evm.VmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
if evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
defer func() {
evm.VmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, types.Since(start), err)
evm.VMConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, types.Since(start), err)
}()
}
......@@ -238,7 +239,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
return ret, snapshot, contract.Gas, err
}
// 合约内部调用合约的入口
// CallCode 合约内部调用合约的入口
// 执行逻辑同Call方法,但是有以下几点不同:
// 在创建合约对象时,合约对象的上下文地址(合约对象的self属性)被设置为caller的地址
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value uint64) (ret []byte, leftOverGas uint64, err error) {
......@@ -273,7 +274,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
return ret, contract.Gas, err
}
// 合约内部调用合约的入口
// DelegateCall 合约内部调用合约的入口
// 不支持向合约转账
// 和CallCode不同的是,它会把合约的外部调用地址设置成caller的caller
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
......@@ -309,7 +310,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
return ret, contract.Gas, err
}
// 合约内部调用合约的入口
// StaticCall 合约内部调用合约的入口
// 不支持向合约转账
// 在合约逻辑中,可以指定其它的合约地址以及输入参数进行合约调用,但是,这种情况下禁止修改MemoryStateDB中的任何数据,否则执行会出错
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
......@@ -355,7 +356,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
return ret, contract.Gas, err
}
// 此方法提供合约外部创建入口;
// Create 此方法提供合约外部创建入口;
// 使用传入的部署代码创建新的合约;
// 目前chain33为了保证账户安全,不允许合约中涉及到外部账户的转账操作,
// 所以,本步骤不接收转账金额参数
......@@ -374,8 +375,8 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b
snapshot = evm.StateDB.Snapshot()
evm.StateDB.CreateAccount(contractAddr.String(), contract.CallerAddress.String(), execName, alias)
if evm.VmConfig.Debug && evm.depth == 0 {
evm.VmConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, gas, 0)
if evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, gas, 0)
}
start := types.Now()
......@@ -412,8 +413,8 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b
err = model.ErrMaxCodeSizeExceeded
}
if evm.VmConfig.Debug && evm.depth == 0 {
evm.VmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, types.Since(start), err)
if evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, types.Since(start), err)
}
return ret, snapshot, contract.Gas, err
......
......@@ -397,7 +397,7 @@ func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *mm.Memory, stack *
data := memory.Get(offset.Int64(), size.Int64())
hash := crypto.Keccak256(data)
if evm.VmConfig.EnablePreimageRecording {
if evm.VMConfig.EnablePreimageRecording {
evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
}
......
......@@ -15,26 +15,27 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/params"
)
// 解释器的配置模型
// Config 解释器的配置模型
type Config struct {
// 调试开关
// Debug 调试开关
Debug bool
// 记录操作日志
// Tracer 记录操作日志
Tracer Tracer
// 不允许使用Call, CallCode, DelegateCall
// NoRecursion 不允许使用Call, CallCode, DelegateCall
NoRecursion bool
// SHA3/keccak 操作时是否保存数据
// EnablePreimageRecording SHA3/keccak 操作时是否保存数据
EnablePreimageRecording bool
// 指令跳转表
// JumpTable 指令跳转表
JumpTable [256]Operation
}
// 解释器接结构定义
// Interpreter 解释器接结构定义
type Interpreter struct {
evm *EVM
cfg Config
gasTable gas.GasTable
IntPool *mm.IntPool
gasTable gas.Table
// IntPool 整数内存池
IntPool *mm.IntPool
// 是否允许修改数据
readOnly bool
......@@ -42,6 +43,7 @@ type Interpreter struct {
ReturnData []byte
}
// NewInterpreter 新创建一个解释器
func NewInterpreter(evm *EVM, cfg Config) *Interpreter {
// 使用是否包含第一个STOP指令判断jump table是否完成初始化
// 需要注意,后继如果新增指令,需要在这里判断硬分叉,指定不同的指令集
......@@ -67,7 +69,7 @@ func (in *Interpreter) enforceRestrictions(op OpCode, operation Operation, stack
return nil
}
// 合约代码的解释执行主逻辑
// Run 合约代码的解释执行主逻辑
// 需要注意的是,如果返回执行出错,依然会扣除剩余的Gas
// (除非返回的是ErrExecutionReverted,这种情况下会保留剩余的Gas)
func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err error) {
......
......@@ -11,42 +11,45 @@ import (
)
type (
// 指令执行函数,每个操作指令对应一个实现,它实现了指令的具体操作逻辑
// ExecutionFunc 指令执行函数,每个操作指令对应一个实现,它实现了指令的具体操作逻辑
ExecutionFunc func(pc *uint64, env *EVM, contract *Contract, memory *mm.Memory, stack *mm.Stack) ([]byte, error)
)
// 定义指令操作的结构提
// Operation 定义指令操作的结构提
type Operation struct {
// 指令的具体操作逻辑
// Execute 指令的具体操作逻辑
Execute ExecutionFunc
// 计算当前指令执行所需消耗的Gas
GasCost gas.GasFunc
// GasCost 计算当前指令执行所需消耗的Gas
GasCost gas.CalcGasFunc
// 检查内存栈中的数据是否满足本操作执行的要求
// ValidateStack 检查内存栈中的数据是否满足本操作执行的要求
ValidateStack mm.StackValidationFunc
// 计算本次操作所需要的内存大小
// MemorySize 计算本次操作所需要的内存大小
MemorySize mm.MemorySizeFunc
Halts bool // 是否需要暂停(将会结束本合约后面操作的执行)
Jumps bool // 是否需要执行跳转(此种情况下PC不递增)
Writes bool // 是否涉及到修改状态操作(在合约委托调用的情况下,此操作非法,将会抛异常)
Valid bool // 是否为有效操作
Reverts bool // 是否恢复原始状态(强制暂停,将会结束本合约后面操作的执行)
Returns bool // 是否返回
// Halts 是否需要暂停(将会结束本合约后面操作的执行)
Halts bool
// Jumps 是否需要执行跳转(此种情况下PC不递增)
Jumps bool
// Writes 是否涉及到修改状态操作(在合约委托调用的情况下,此操作非法,将会抛异常)
Writes bool
// Valid 是否为有效操作
Valid bool
// Reverts 是否恢复原始状态(强制暂停,将会结束本合约后面操作的执行)
Reverts bool
// Returns 是否返回
Returns bool
}
var (
// 对应EVM不同版本的指令集,从上往下,从旧版本到新版本,
// ConstantinopleInstructionSet 对应EVM不同版本的指令集,从上往下,从旧版本到新版本,
// 新版本包含旧版本的指令集(目前直接使用康士坦丁堡指令集)
FrontierInstructionSet = NewFrontierInstructionSet()
HomesteadInstructionSet = NewHomesteadInstructionSet()
ByzantiumInstructionSet = NewByzantiumInstructionSet()
ConstantinopleInstructionSet = NewConstantinopleInstructionSet()
)
// 康士坦丁堡 版本支持的指令集
// NewConstantinopleInstructionSet 康士坦丁堡 版本支持的指令集
func NewConstantinopleInstructionSet() [256]Operation {
instructionSet := NewByzantiumInstructionSet()
instructionSet[SHL] = Operation{
......@@ -70,12 +73,12 @@ func NewConstantinopleInstructionSet() [256]Operation {
return instructionSet
}
// 拜占庭 版本支持的指令集
// NewByzantiumInstructionSet 拜占庭 版本支持的指令集
func NewByzantiumInstructionSet() [256]Operation {
instructionSet := NewHomesteadInstructionSet()
instructionSet[STATICCALL] = Operation{
Execute: opStaticCall,
GasCost: gas.GasStaticCall,
GasCost: gas.StaticCall,
ValidateStack: mm.MakeStackFunc(6, 1),
MemorySize: mm.MemoryStaticCall,
Valid: true,
......@@ -89,14 +92,14 @@ func NewByzantiumInstructionSet() [256]Operation {
}
instructionSet[RETURNDATACOPY] = Operation{
Execute: opReturnDataCopy,
GasCost: gas.GasReturnDataCopy,
GasCost: gas.ReturnDataCopy,
ValidateStack: mm.MakeStackFunc(3, 0),
MemorySize: mm.MemoryReturnDataCopy,
Valid: true,
}
instructionSet[REVERT] = Operation{
Execute: opRevert,
GasCost: gas.GasRevert,
GasCost: gas.Revert,
ValidateStack: mm.MakeStackFunc(2, 0),
MemorySize: mm.MemoryRevert,
Valid: true,
......@@ -106,12 +109,12 @@ func NewByzantiumInstructionSet() [256]Operation {
return instructionSet
}
// 家园 版本支持的指令集
// NewHomesteadInstructionSet 家园 版本支持的指令集
func NewHomesteadInstructionSet() [256]Operation {
instructionSet := NewFrontierInstructionSet()
instructionSet[DELEGATECALL] = Operation{
Execute: opDelegateCall,
GasCost: gas.GasDelegateCall,
GasCost: gas.DelegateCall,
ValidateStack: mm.MakeStackFunc(6, 1),
MemorySize: mm.MemoryDelegateCall,
Valid: true,
......@@ -120,7 +123,7 @@ func NewHomesteadInstructionSet() [256]Operation {
return instructionSet
}
// 边境 版本支持的指令集
// NewFrontierInstructionSet 边境 版本支持的指令集
func NewFrontierInstructionSet() [256]Operation {
return [256]Operation{
STOP: {
......@@ -186,7 +189,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
EXP: {
Execute: opExp,
GasCost: gas.GasExp,
GasCost: gas.Exp,
ValidateStack: mm.MakeStackFunc(2, 1),
Valid: true,
},
......@@ -264,7 +267,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
SHA3: {
Execute: opSha3,
GasCost: gas.GasSha3,
GasCost: gas.Sha3,
ValidateStack: mm.MakeStackFunc(2, 1),
MemorySize: mm.MemorySha3,
Valid: true,
......@@ -277,7 +280,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
BALANCE: {
Execute: opBalance,
GasCost: gas.GasBalance,
GasCost: gas.Balance,
ValidateStack: mm.MakeStackFunc(1, 1),
Valid: true,
},
......@@ -313,7 +316,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
CALLDATACOPY: {
Execute: opCallDataCopy,
GasCost: gas.GasCallDataCopy,
GasCost: gas.CallDataCopy,
ValidateStack: mm.MakeStackFunc(3, 0),
MemorySize: mm.MemoryCallDataCopy,
Valid: true,
......@@ -326,7 +329,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
CODECOPY: {
Execute: opCodeCopy,
GasCost: gas.GasCodeCopy,
GasCost: gas.CodeCopy,
ValidateStack: mm.MakeStackFunc(3, 0),
MemorySize: mm.MemoryCodeCopy,
Valid: true,
......@@ -339,13 +342,13 @@ func NewFrontierInstructionSet() [256]Operation {
},
EXTCODESIZE: {
Execute: opExtCodeSize,
GasCost: gas.GasExtCodeSize,
GasCost: gas.ExtCodeSize,
ValidateStack: mm.MakeStackFunc(1, 1),
Valid: true,
},
EXTCODECOPY: {
Execute: opExtCodeCopy,
GasCost: gas.GasExtCodeCopy,
GasCost: gas.ExtCodeCopy,
ValidateStack: mm.MakeStackFunc(4, 0),
MemorySize: mm.MemoryExtCodeCopy,
Valid: true,
......@@ -394,21 +397,21 @@ func NewFrontierInstructionSet() [256]Operation {
},
MLOAD: {
Execute: opMload,
GasCost: gas.GasMLoad,
GasCost: gas.MLoad,
ValidateStack: mm.MakeStackFunc(1, 1),
MemorySize: mm.MemoryMLoad,
Valid: true,
},
MSTORE: {
Execute: opMstore,
GasCost: gas.GasMStore,
GasCost: gas.MStore,
ValidateStack: mm.MakeStackFunc(2, 0),
MemorySize: mm.MemoryMStore,
Valid: true,
},
MSTORE8: {
Execute: opMstore8,
GasCost: gas.GasMStore8,
GasCost: gas.MStore8,
MemorySize: mm.MemoryMStore8,
ValidateStack: mm.MakeStackFunc(2, 0),
......@@ -416,13 +419,13 @@ func NewFrontierInstructionSet() [256]Operation {
},
SLOAD: {
Execute: opSload,
GasCost: gas.GasSLoad,
GasCost: gas.SLoad,
ValidateStack: mm.MakeStackFunc(1, 1),
Valid: true,
},
SSTORE: {
Execute: opSstore,
GasCost: gas.GasSStore,
GasCost: gas.SStore,
ValidateStack: mm.MakeStackFunc(2, 0),
Valid: true,
Writes: true,
......@@ -467,385 +470,385 @@ func NewFrontierInstructionSet() [256]Operation {
},
PUSH1: {
Execute: makePush(1, 1),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH2: {
Execute: makePush(2, 2),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH3: {
Execute: makePush(3, 3),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH4: {
Execute: makePush(4, 4),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH5: {
Execute: makePush(5, 5),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH6: {
Execute: makePush(6, 6),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH7: {
Execute: makePush(7, 7),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH8: {
Execute: makePush(8, 8),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH9: {
Execute: makePush(9, 9),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH10: {
Execute: makePush(10, 10),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH11: {
Execute: makePush(11, 11),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH12: {
Execute: makePush(12, 12),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH13: {
Execute: makePush(13, 13),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH14: {
Execute: makePush(14, 14),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH15: {
Execute: makePush(15, 15),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH16: {
Execute: makePush(16, 16),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH17: {
Execute: makePush(17, 17),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH18: {
Execute: makePush(18, 18),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH19: {
Execute: makePush(19, 19),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH20: {
Execute: makePush(20, 20),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH21: {
Execute: makePush(21, 21),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH22: {
Execute: makePush(22, 22),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH23: {
Execute: makePush(23, 23),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH24: {
Execute: makePush(24, 24),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH25: {
Execute: makePush(25, 25),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH26: {
Execute: makePush(26, 26),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH27: {
Execute: makePush(27, 27),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH28: {
Execute: makePush(28, 28),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH29: {
Execute: makePush(29, 29),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH30: {
Execute: makePush(30, 30),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH31: {
Execute: makePush(31, 31),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
PUSH32: {
Execute: makePush(32, 32),
GasCost: gas.GasPush,
GasCost: gas.Push,
ValidateStack: mm.MakeStackFunc(0, 1),
Valid: true,
},
DUP1: {
Execute: makeDup(1),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(1),
Valid: true,
},
DUP2: {
Execute: makeDup(2),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(2),
Valid: true,
},
DUP3: {
Execute: makeDup(3),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(3),
Valid: true,
},
DUP4: {
Execute: makeDup(4),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(4),
Valid: true,
},
DUP5: {
Execute: makeDup(5),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(5),
Valid: true,
},
DUP6: {
Execute: makeDup(6),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(6),
Valid: true,
},
DUP7: {
Execute: makeDup(7),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(7),
Valid: true,
},
DUP8: {
Execute: makeDup(8),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(8),
Valid: true,
},
DUP9: {
Execute: makeDup(9),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(9),
Valid: true,
},
DUP10: {
Execute: makeDup(10),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(10),
Valid: true,
},
DUP11: {
Execute: makeDup(11),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(11),
Valid: true,
},
DUP12: {
Execute: makeDup(12),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(12),
Valid: true,
},
DUP13: {
Execute: makeDup(13),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(13),
Valid: true,
},
DUP14: {
Execute: makeDup(14),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(14),
Valid: true,
},
DUP15: {
Execute: makeDup(15),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(15),
Valid: true,
},
DUP16: {
Execute: makeDup(16),
GasCost: gas.GasDup,
GasCost: gas.Dup,
ValidateStack: mm.MakeDupStackFunc(16),
Valid: true,
},
SWAP1: {
Execute: makeSwap(1),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(2),
Valid: true,
},
SWAP2: {
Execute: makeSwap(2),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(3),
Valid: true,
},
SWAP3: {
Execute: makeSwap(3),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(4),
Valid: true,
},
SWAP4: {
Execute: makeSwap(4),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(5),
Valid: true,
},
SWAP5: {
Execute: makeSwap(5),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(6),
Valid: true,
},
SWAP6: {
Execute: makeSwap(6),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(7),
Valid: true,
},
SWAP7: {
Execute: makeSwap(7),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(8),
Valid: true,
},
SWAP8: {
Execute: makeSwap(8),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(9),
Valid: true,
},
SWAP9: {
Execute: makeSwap(9),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(10),
Valid: true,
},
SWAP10: {
Execute: makeSwap(10),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(11),
Valid: true,
},
SWAP11: {
Execute: makeSwap(11),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(12),
Valid: true,
},
SWAP12: {
Execute: makeSwap(12),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(13),
Valid: true,
},
SWAP13: {
Execute: makeSwap(13),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(14),
Valid: true,
},
SWAP14: {
Execute: makeSwap(14),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(15),
Valid: true,
},
SWAP15: {
Execute: makeSwap(15),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(16),
Valid: true,
},
SWAP16: {
Execute: makeSwap(16),
GasCost: gas.GasSwap,
GasCost: gas.Swap,
ValidateStack: mm.MakeSwapStackFunc(17),
Valid: true,
},
......@@ -891,7 +894,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
CREATE: {
Execute: opCreate,
GasCost: gas.GasCreate,
GasCost: gas.Create,
ValidateStack: mm.MakeStackFunc(3, 1),
MemorySize: mm.MemoryCreate,
Valid: true,
......@@ -900,7 +903,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
CALL: {
Execute: opCall,
GasCost: gas.GasCall,
GasCost: gas.Call,
ValidateStack: mm.MakeStackFunc(7, 1),
MemorySize: mm.MemoryCall,
Valid: true,
......@@ -908,7 +911,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
CALLCODE: {
Execute: opCallCode,
GasCost: gas.GasCallCode,
GasCost: gas.CallCode,
ValidateStack: mm.MakeStackFunc(7, 1),
MemorySize: mm.MemoryCall,
Valid: true,
......@@ -916,7 +919,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
RETURN: {
Execute: opReturn,
GasCost: gas.GasReturn,
GasCost: gas.Return,
ValidateStack: mm.MakeStackFunc(2, 0),
MemorySize: mm.MemoryReturn,
Halts: true,
......@@ -924,7 +927,7 @@ func NewFrontierInstructionSet() [256]Operation {
},
SELFDESTRUCT: {
Execute: opSuicide,
GasCost: gas.GasSuicide,
GasCost: gas.Suicide,
ValidateStack: mm.MakeStackFunc(1, 0),
Halts: true,
Valid: true,
......
......@@ -15,44 +15,60 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/mm"
)
// Tracer接口用来在合约执行过程中收集跟踪数据。
// Tracer 接口用来在合约执行过程中收集跟踪数据。
// CaptureState 会在EVM解释每条指令时调用。
// 需要注意的是,传入的引用参数不允许修改,否则会影响EVM解释执行;如果需要使用其中的数据,请复制后使用。
type Tracer interface {
// CaptureStart 开始记录
CaptureStart(from common.Address, to common.Address, call bool, input []byte, gas uint64, value uint64) error
// CaptureState 保存状态
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, contract *Contract, depth int, err error) error
// CaptureFault 保存错误
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, contract *Contract, depth int, err error) error
// CaptureEnd 结束记录
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error
}
// 使用json格式打印日志
// JSONLogger 使用json格式打印日志
type JSONLogger struct {
encoder *json.Encoder
}
// 指令执行状态信息
// StructLog 指令执行状态信息
type StructLog struct {
Pc uint64 `json:"pc"`
Op string `json:"op"`
Gas uint64 `json:"gas"`
GasCost uint64 `json:"gasCost"`
Memory []string `json:"memory"`
MemorySize int `json:"memSize"`
Stack []string `json:"stack"`
Storage map[common.Hash]common.Hash `json:"-"`
Depth int `json:"depth"`
Err error `json:"-"`
// Pc pc指针
Pc uint64 `json:"pc"`
// Op 操作码
Op string `json:"op"`
// Gas gas
Gas uint64 `json:"gas"`
// GasCost 花费
GasCost uint64 `json:"gasCost"`
// Memory 内存对象
Memory []string `json:"memory"`
// MemorySize 内存大小
MemorySize int `json:"memSize"`
// Stack 栈对象
Stack []string `json:"stack"`
// Storage 存储对象
Storage map[common.Hash]common.Hash `json:"-"`
// Depth 调用深度
Depth int `json:"depth"`
// Err 错误信息
Err error `json:"-"`
}
// NewJSONLogger 创建新的日志记录器
func NewJSONLogger(writer io.Writer) *JSONLogger {
return &JSONLogger{json.NewEncoder(writer)}
}
// CaptureStart 开始记录
func (logger *JSONLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value uint64) error {
return nil
}
// CaptureState outputs state information on the logger.
// CaptureState 输出当前虚拟机状态
func (logger *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, contract *Contract, depth int, err error) error {
log := StructLog{
Pc: pc,
......@@ -83,12 +99,12 @@ func formatMemory(data []byte) (res []string) {
return
}
// CaptureFault outputs state information on the logger.
// CaptureFault 目前实现为空
func (logger *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *mm.Memory, stack *mm.Stack, contract *Contract, depth int, err error) error {
return nil
}
// CaptureEnd is triggered at end of execution.
// CaptureEnd 结束记录
func (logger *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
type endLog struct {
Output string `json:"output"`
......
......@@ -4,10 +4,10 @@
package runtime
// EVM操作码定义,本质上就是一个字节,所以操作码最多只支持256个
// OpCode EVM操作码定义,本质上就是一个字节,所以操作码最多只支持256个
type OpCode byte
// 是否为压栈操作
// IsPush 是否为压栈操作
func (op OpCode) IsPush() bool {
if op >= PUSH1 && op <= PUSH32 {
return true
......@@ -15,14 +15,14 @@ func (op OpCode) IsPush() bool {
return false
}
// 是否为跳转操作
// IsStaticJump 是否为跳转操作
func (op OpCode) IsStaticJump() bool {
return op == JUMP
}
var opmap map[OpCode]string
// 是否为跳转操作
// String 打印字符串形式
func (op OpCode) String() string {
if opmap == nil {
initMap()
......@@ -197,178 +197,310 @@ func initMap() {
// unofficial opcodes used for parsing
const (
// PUSH 压栈操作
PUSH OpCode = 0xb0 + iota
// DUP 操作
DUP
// SWAP 操作
SWAP
)
const (
// 0x0 算术操作
// STOP 0x0 算术操作
STOP OpCode = iota
// ADD 操作
ADD
// MUL op
MUL
// SUB op
SUB
// DIV op
DIV
// SDIV op
SDIV
// MOD op
MOD
// SMOD op
SMOD
// ADDMOD op
ADDMOD
// MULMOD op
MULMOD
// EXP op
EXP
// SIGNEXTEND op
SIGNEXTEND
)
const (
// 比较、位操作
// LT 比较、位操作
LT OpCode = iota + 0x10
// GT op
GT
// SLT op
SLT
// SGT op
SGT
// EQ op
EQ
// ISZERO op
ISZERO
// AND op
AND
// OR op
OR
// XOR op
XOR
// NOT op
NOT
// BYTE op
BYTE
// SHL op
SHL
// SHR op
SHR
// SAR op
SAR
// SHA3 op
SHA3 = 0x20
)
const (
// 0x30 合约数据操作
// ADDRESS 0x30 合约数据操作
ADDRESS OpCode = 0x30 + iota
// BALANCE op
BALANCE
// ORIGIN op
ORIGIN
// CALLER op
CALLER
// CALLVALUE op
CALLVALUE
// CALLDATALOAD op
CALLDATALOAD
// CALLDATASIZE op
CALLDATASIZE
// CALLDATACOPY op
CALLDATACOPY
// CODESIZE op
CODESIZE
// CODECOPY op
CODECOPY
// GASPRICE op
GASPRICE
// EXTCODESIZE op
EXTCODESIZE
// EXTCODECOPY op
EXTCODECOPY
// RETURNDATASIZE op
RETURNDATASIZE
// RETURNDATACOPY op
RETURNDATACOPY
)
const (
// 0x40 区块相关操作
// BLOCKHASH 0x40 区块相关操作
BLOCKHASH OpCode = 0x40 + iota
// COINBASE op
COINBASE
// TIMESTAMP op
TIMESTAMP
// NUMBER op
NUMBER
// DIFFICULTY op
DIFFICULTY
// GASLIMIT op
GASLIMIT
)
const (
// 0x50 存储相关操作
// POP 0x50 存储相关操作
POP OpCode = 0x50 + iota
// MLOAD op
MLOAD
// MSTORE op
MSTORE
// MSTORE8 op
MSTORE8
// SLOAD op
SLOAD
// SSTORE op
SSTORE
// JUMP op
JUMP
// JUMPI op
JUMPI
// PC op
PC
// MSIZE op
MSIZE
// GAS op
GAS
// JUMPDEST op
JUMPDEST
)
const (
// 0x60 栈操作
// PUSH1 0x60 栈操作
PUSH1 OpCode = 0x60 + iota
// PUSH2 op
PUSH2
// PUSH3 op
PUSH3
// PUSH4 op
PUSH4
// PUSH5 op
PUSH5
// PUSH6 op
PUSH6
// PUSH7 op
PUSH7
// PUSH8 op
PUSH8
// PUSH9 op
PUSH9
// PUSH10 op
PUSH10
// PUSH11 op
PUSH11
// PUSH12 op
PUSH12
// PUSH13 op
PUSH13
// PUSH14 op
PUSH14
// PUSH15 op
PUSH15
// PUSH16 op
PUSH16
// PUSH17 op
PUSH17
// PUSH18 op
PUSH18
// PUSH19 op
PUSH19
// PUSH20 op
PUSH20
// PUSH21 op
PUSH21
// PUSH22 op
PUSH22
// PUSH23 op
PUSH23
// PUSH24 op
PUSH24
// PUSH25 op
PUSH25
// PUSH26 op
PUSH26
// PUSH27 op
PUSH27
// PUSH28 op
PUSH28
// PUSH29 op
PUSH29
// PUSH30 op
PUSH30
// PUSH31 op
PUSH31
// PUSH32 op
PUSH32
// DUP1 op
DUP1
// DUP2 op
DUP2
// DUP3 op
DUP3
// DUP4 op
DUP4
// DUP5 op
DUP5
// DUP6 op
DUP6
// DUP7 op
DUP7
// DUP8 op
DUP8
// DUP9 op
DUP9
// DUP10 op
DUP10
// DUP11 op
DUP11
// DUP12 op
DUP12
// DUP13 op
DUP13
// DUP14 op
DUP14
// DUP15 op
DUP15
// DUP16 op
DUP16
// SWAP1 op
SWAP1
// SWAP2 op
SWAP2
// SWAP3 op
SWAP3
// SWAP4 op
SWAP4
// SWAP5 op
SWAP5
// SWAP6 op
SWAP6
// SWAP7 op
SWAP7
// SWAP8 op
SWAP8
// SWAP9 op
SWAP9
// SWAP10 op
SWAP10
// SWAP11 op
SWAP11
// SWAP12 op
SWAP12
// SWAP13 op
SWAP13
// SWAP14 op
SWAP14
// SWAP15 op
SWAP15
// SWAP16 op
SWAP16
)
const (
// 生成日志
// LOG0 生成日志
LOG0 OpCode = 0xa0 + iota
// LOG1 op
LOG1
// LOG2 op
LOG2
// LOG3 op
LOG3
// LOG4 op
LOG4
)
const (
// 过程调用
// CREATE 过程调用
CREATE OpCode = 0xf0 + iota
// CALL op
CALL
// CALLCODE op
CALLCODE
// RETURN op
RETURN
// DELEGATECALL op
DELEGATECALL
// STATICCALL op
STATICCALL = 0xfa
REVERT = 0xfd
// REVERT op
REVERT = 0xfd
// SELFDESTRUCT op
SELFDESTRUCT = 0xff
)
......@@ -15,24 +15,24 @@ import (
"github.com/golang/protobuf/proto"
)
// 合约账户对象
// ContractAccount 合约账户对象
type ContractAccount struct {
mdb *MemoryStateDB
// 合约代码地址
// Addr 合约代码地址
Addr string
// 合约固定数据
// Data 合约固定数据
Data evmtypes.EVMContractData
// 合约状态数据
// State 合约状态数据
State evmtypes.EVMContractState
// 当前的状态数据缓存
stateCache map[string]common.Hash
}
// 创建一个新的合约对象
// NewContractAccount 创建一个新的合约对象
// 注意,此时合约对象有可能已经存在也有可能不存在
// 需要通过LoadContract进行判断
func NewContractAccount(addr string, db *MemoryStateDB) *ContractAccount {
......@@ -46,74 +46,73 @@ func NewContractAccount(addr string, db *MemoryStateDB) *ContractAccount {
return ca
}
// 获取状态数据;
// GetState 获取状态数据;
// 获取数据分为两层,一层是从当前的缓存中获取,如果获取不到,再从localdb中获取
func (self *ContractAccount) GetState(key common.Hash) common.Hash {
func (ca *ContractAccount) GetState(key common.Hash) common.Hash {
// 从ForkV19开始,状态数据使用单独的KEY存储
if types.IsDappFork(self.mdb.blockHeight, "evm", "ForkEVMState") {
if val, ok := self.stateCache[key.Hex()]; ok {
if types.IsDappFork(ca.mdb.blockHeight, "evm", "ForkEVMState") {
if val, ok := ca.stateCache[key.Hex()]; ok {
return val
}
keyStr := getStateItemKey(self.Addr, key.Hex())
keyStr := getStateItemKey(ca.Addr, key.Hex())
// 如果缓存中取不到数据,则只能到本地数据库中查询
val, err := self.mdb.LocalDB.Get([]byte(keyStr))
val, err := ca.mdb.LocalDB.Get([]byte(keyStr))
if err != nil {
log15.Debug("GetState error!", "key", key, "error", err)
return common.Hash{}
}
valHash := common.BytesToHash(val)
self.stateCache[key.Hex()] = valHash
ca.stateCache[key.Hex()] = valHash
return valHash
} else {
return common.BytesToHash(self.State.GetStorage()[key.Hex()])
}
return common.BytesToHash(ca.State.GetStorage()[key.Hex()])
}
// 设置状态数据
func (self *ContractAccount) SetState(key, value common.Hash) {
self.mdb.addChange(storageChange{
// SetState 设置状态数据
func (ca *ContractAccount) SetState(key, value common.Hash) {
ca.mdb.addChange(storageChange{
baseChange: baseChange{},
account: self.Addr,
account: ca.Addr,
key: key,
prevalue: self.GetState(key),
prevalue: ca.GetState(key),
})
if types.IsDappFork(self.mdb.blockHeight, "evm", "ForkEVMState") {
self.stateCache[key.Hex()] = value
if types.IsDappFork(ca.mdb.blockHeight, "evm", "ForkEVMState") {
ca.stateCache[key.Hex()] = value
//需要设置到localdb中,以免同一个区块中同一个合约多次调用时,状态数据丢失
keyStr := getStateItemKey(self.Addr, key.Hex())
self.mdb.LocalDB.Set([]byte(keyStr), value.Bytes())
keyStr := getStateItemKey(ca.Addr, key.Hex())
ca.mdb.LocalDB.Set([]byte(keyStr), value.Bytes())
} else {
self.State.GetStorage()[key.Hex()] = value.Bytes()
self.updateStorageHash()
ca.State.GetStorage()[key.Hex()] = value.Bytes()
ca.updateStorageHash()
}
}
// 从原有的存储在一个对象,将状态数据分散存储到多个KEY,保证合约可以支撑大量状态数据
func (self *ContractAccount) TransferState() {
if len(self.State.Storage) > 0 {
storage := self.State.Storage
// TransferState 从原有的存储在一个对象,将状态数据分散存储到多个KEY,保证合约可以支撑大量状态数据
func (ca *ContractAccount) TransferState() {
if len(ca.State.Storage) > 0 {
storage := ca.State.Storage
// 为了保证不会造成新、旧数据并存的情况,需要将旧的状态数据清空
self.State.Storage = make(map[string][]byte)
self.State.StorageHash = common.ToHash([]byte{}).Bytes()
ca.State.Storage = make(map[string][]byte)
ca.State.StorageHash = common.ToHash([]byte{}).Bytes()
// 从旧的区块迁移状态数据到新的区块,模拟状态数据变更的操作
for key, value := range storage {
self.SetState(common.BytesToHash(common.FromHex(key)), common.BytesToHash(value))
ca.SetState(common.BytesToHash(common.FromHex(key)), common.BytesToHash(value))
}
// 更新本合约的状态数据(删除旧的map存储信息)
self.mdb.UpdateState(self.Addr)
ca.mdb.UpdateState(ca.Addr)
return
}
}
func (self *ContractAccount) updateStorageHash() {
func (ca *ContractAccount) updateStorageHash() {
// 从ForkV20开始,状态数据使用单独KEY存储
if types.IsDappFork(self.mdb.blockHeight, "evm", "ForkEVMState") {
if types.IsDappFork(ca.mdb.blockHeight, "evm", "ForkEVMState") {
return
}
var state = &evmtypes.EVMContractState{Suicided: self.State.Suicided, Nonce: self.State.Nonce}
var state = &evmtypes.EVMContractState{Suicided: ca.State.Suicided, Nonce: ca.State.Nonce}
state.Storage = make(map[string][]byte)
for k, v := range self.State.GetStorage() {
for k, v := range ca.State.GetStorage() {
state.Storage[k] = v
}
ret, err := proto.Marshal(state)
......@@ -122,152 +121,160 @@ func (self *ContractAccount) updateStorageHash() {
return
}
self.State.StorageHash = common.ToHash(ret).Bytes()
ca.State.StorageHash = common.ToHash(ret).Bytes()
}
// 从外部恢复合约数据
func (self *ContractAccount) resotreData(data []byte) {
func (ca *ContractAccount) resotreData(data []byte) {
var content evmtypes.EVMContractData
err := proto.Unmarshal(data, &content)
if err != nil {
log15.Error("read contract data error", self.Addr)
log15.Error("read contract data error", ca.Addr)
return
}
self.Data = content
ca.Data = content
}
// 从外部恢复合约状态
func (self *ContractAccount) resotreState(data []byte) {
func (ca *ContractAccount) resotreState(data []byte) {
var content evmtypes.EVMContractState
err := proto.Unmarshal(data, &content)
if err != nil {
log15.Error("read contract state error", self.Addr)
log15.Error("read contract state error", ca.Addr)
return
}
self.State = content
if self.State.Storage == nil {
self.State.Storage = make(map[string][]byte)
ca.State = content
if ca.State.Storage == nil {
ca.State.Storage = make(map[string][]byte)
}
}
// 从数据库中加载合约信息(在只有合约地址的情况下)
func (self *ContractAccount) LoadContract(db db.KV) {
// LoadContract 从数据库中加载合约信息(在只有合约地址的情况下)
func (ca *ContractAccount) LoadContract(db db.KV) {
// 加载代码数据
data, err := db.Get(self.GetDataKey())
data, err := db.Get(ca.GetDataKey())
if err != nil {
return
}
self.resotreData(data)
ca.resotreData(data)
// 加载状态数据
data, err = db.Get(self.GetStateKey())
data, err = db.Get(ca.GetStateKey())
if err != nil {
return
}
self.resotreState(data)
ca.resotreState(data)
}
// 设置合约二进制代码
// SetCode 设置合约二进制代码
// 会同步生成代码哈希
func (self *ContractAccount) SetCode(code []byte) {
prevcode := self.Data.GetCode()
self.mdb.addChange(codeChange{
func (ca *ContractAccount) SetCode(code []byte) {
prevcode := ca.Data.GetCode()
ca.mdb.addChange(codeChange{
baseChange: baseChange{},
account: self.Addr,
prevhash: self.Data.GetCodeHash(),
account: ca.Addr,
prevhash: ca.Data.GetCodeHash(),
prevcode: prevcode,
})
self.Data.Code = code
self.Data.CodeHash = common.ToHash(code).Bytes()
ca.Data.Code = code
ca.Data.CodeHash = common.ToHash(code).Bytes()
}
func (self *ContractAccount) SetCreator(creator string) {
// SetCreator 设置创建者
func (ca *ContractAccount) SetCreator(creator string) {
if len(creator) == 0 {
log15.Error("SetCreator error", "creator", creator)
return
}
self.Data.Creator = creator
ca.Data.Creator = creator
}
func (self *ContractAccount) SetExecName(execName string) {
// SetExecName 设置合约名称
func (ca *ContractAccount) SetExecName(execName string) {
if len(execName) == 0 {
log15.Error("SetExecName error", "execName", execName)
return
}
self.Data.Name = execName
ca.Data.Name = execName
}
func (self *ContractAccount) SetAliasName(alias string) {
// SetAliasName 设置合约别名
func (ca *ContractAccount) SetAliasName(alias string) {
if len(alias) == 0 {
log15.Error("SetAliasName error", "aliasName", alias)
return
}
self.Data.Alias = alias
ca.Data.Alias = alias
}
func (self *ContractAccount) GetAliasName() string {
return self.Data.Alias
// GetAliasName 获取合约别名
func (ca *ContractAccount) GetAliasName() string {
return ca.Data.Alias
}
func (self *ContractAccount) GetCreator() string {
return self.Data.Creator
// GetCreator 获取创建者
func (ca *ContractAccount) GetCreator() string {
return ca.Data.Creator
}
func (self *ContractAccount) GetExecName() string {
return self.Data.Name
// GetExecName 获取合约明名称
func (ca *ContractAccount) GetExecName() string {
return ca.Data.Name
}
// 合约固定数据,包含合约代码,以及代码哈希
func (self *ContractAccount) GetDataKV() (kvSet []*types.KeyValue) {
self.Data.Addr = self.Addr
datas, err := proto.Marshal(&self.Data)
// GetDataKV 合约固定数据,包含合约代码,以及代码哈希
func (ca *ContractAccount) GetDataKV() (kvSet []*types.KeyValue) {
ca.Data.Addr = ca.Addr
datas, err := proto.Marshal(&ca.Data)
if err != nil {
log15.Error("marshal contract data error!", "addr", self.Addr, "error", err)
log15.Error("marshal contract data error!", "addr", ca.Addr, "error", err)
return
}
kvSet = append(kvSet, &types.KeyValue{Key: self.GetDataKey(), Value: datas})
kvSet = append(kvSet, &types.KeyValue{Key: ca.GetDataKey(), Value: datas})
return
}
// 获取合约状态数据,包含nonce、是否自杀、存储哈希、存储数据
func (self *ContractAccount) GetStateKV() (kvSet []*types.KeyValue) {
datas, err := proto.Marshal(&self.State)
// GetStateKV 获取合约状态数据,包含nonce、是否自杀、存储哈希、存储数据
func (ca *ContractAccount) GetStateKV() (kvSet []*types.KeyValue) {
datas, err := proto.Marshal(&ca.State)
if err != nil {
log15.Error("marshal contract state error!", "addr", self.Addr, "error", err)
log15.Error("marshal contract state error!", "addr", ca.Addr, "error", err)
return
}
kvSet = append(kvSet, &types.KeyValue{Key: self.GetStateKey(), Value: datas})
kvSet = append(kvSet, &types.KeyValue{Key: ca.GetStateKey(), Value: datas})
return
}
// 构建变更日志
func (self *ContractAccount) BuildDataLog() (log *types.ReceiptLog) {
datas, err := proto.Marshal(&self.Data)
// BuildDataLog 构建变更日志
func (ca *ContractAccount) BuildDataLog() (log *types.ReceiptLog) {
datas, err := proto.Marshal(&ca.Data)
if err != nil {
log15.Error("marshal contract data error!", "addr", self.Addr, "error", err)
log15.Error("marshal contract data error!", "addr", ca.Addr, "error", err)
return
}
return &types.ReceiptLog{Ty: evmtypes.TyLogContractData, Log: datas}
}
// 构建变更日志
func (self *ContractAccount) BuildStateLog() (log *types.ReceiptLog) {
datas, err := proto.Marshal(&self.State)
// BuildStateLog 构建变更日志
func (ca *ContractAccount) BuildStateLog() (log *types.ReceiptLog) {
datas, err := proto.Marshal(&ca.State)
if err != nil {
log15.Error("marshal contract state log error!", "addr", self.Addr, "error", err)
log15.Error("marshal contract state log error!", "addr", ca.Addr, "error", err)
return
}
return &types.ReceiptLog{Ty: evmtypes.TyLogContractState, Log: datas}
}
func (self *ContractAccount) GetDataKey() []byte {
return []byte("mavl-" + evmtypes.ExecutorName + "-data: " + self.Addr)
// GetDataKey 获取数据KEY
func (ca *ContractAccount) GetDataKey() []byte {
return []byte("mavl-" + evmtypes.ExecutorName + "-data: " + ca.Addr)
}
func (self *ContractAccount) GetStateKey() []byte {
return []byte("mavl-" + evmtypes.ExecutorName + "-state: " + self.Addr)
// GetStateKey 获取状态key
func (ca *ContractAccount) GetStateKey() []byte {
return []byte("mavl-" + evmtypes.ExecutorName + "-state: " + ca.Addr)
}
// 这份数据是存在LocalDB中的
......@@ -275,28 +282,33 @@ func getStateItemKey(addr, key string) string {
return fmt.Sprintf("LODB-"+evmtypes.ExecutorName+"-state:%v:%v", addr, key)
}
func (self *ContractAccount) Suicide() bool {
self.State.Suicided = true
// Suicide 自杀
func (ca *ContractAccount) Suicide() bool {
ca.State.Suicided = true
return true
}
func (self *ContractAccount) HasSuicided() bool {
return self.State.GetSuicided()
// HasSuicided 是否已经自杀
func (ca *ContractAccount) HasSuicided() bool {
return ca.State.GetSuicided()
}
func (self *ContractAccount) Empty() bool {
return self.Data.GetCodeHash() == nil || len(self.Data.GetCodeHash()) == 0
// Empty 是否为空对象
func (ca *ContractAccount) Empty() bool {
return ca.Data.GetCodeHash() == nil || len(ca.Data.GetCodeHash()) == 0
}
func (self *ContractAccount) SetNonce(nonce uint64) {
self.mdb.addChange(nonceChange{
// SetNonce 设置nonce值
func (ca *ContractAccount) SetNonce(nonce uint64) {
ca.mdb.addChange(nonceChange{
baseChange: baseChange{},
account: self.Addr,
prev: self.State.GetNonce(),
account: ca.Addr,
prev: ca.State.GetNonce(),
})
self.State.Nonce = nonce
ca.State.Nonce = nonce
}
func (self *ContractAccount) GetNonce() uint64 {
return self.State.GetNonce()
// GetNonce 获取nonce值
func (ca *ContractAccount) GetNonce() uint64 {
return ca.State.GetNonce()
}
......@@ -12,8 +12,7 @@ import (
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// 本文件用来存储硬分叉中需要用到的数据
// BlockData 本文件用来存储硬分叉中需要用到的数据
type BlockData struct {
blockHeight int64
testnet bool
......@@ -21,9 +20,11 @@ type BlockData struct {
txs map[string]*TxData
}
// TxData 交易数据
type TxData struct {
// KV 交易生成的KV数据
KV map[string][]byte
// Key 为logType_logIndex
// Logs Key 为logType_logIndex
Logs map[string][]byte
}
......@@ -47,6 +48,7 @@ func makeLogReceiptKey(logType int32, logIndex int) string {
return fmt.Sprintf("%v_%v", logType, logIndex)
}
// InitForkData 初始化硬分叉数据
func InitForkData() {
forkData = make(map[int64]*BlockData)
......@@ -72,6 +74,7 @@ func InitForkData() {
forkData[556294] = data
}
// ProcessFork 处理硬分叉逻辑
func ProcessFork(blockHeight int64, txHash []byte, receipt *types.Receipt) {
if types.IsLocal() {
return
......
......@@ -9,69 +9,69 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model"
)
// 状态数据库封装,面向EVM业务执行逻辑;
// EVMStateDB 状态数据库封装,面向EVM业务执行逻辑;
// 生命周期为一个区块,在同一个区块内多个交易执行时使用的是同一个StateDB实例;
// StateDB包含区块的状态和交易的状态(当前上下文),所以不支持并发操作,区块内的多个交易只能按顺序单线程执行;
// StateDB除了查询状态数据,还会保留在交易执行时对数据的变更信息,每个交易完成之后会返回变更影响的数据给执行器;
type StateDB interface {
// 创建新的合约对象
type EVMStateDB interface {
// CreateAccount 创建新的合约对象
CreateAccount(string, string, string, string)
// 从指定地址扣除金额
// SubBalance 从指定地址扣除金额
SubBalance(string, string, uint64)
// 向指定地址增加金额
// AddBalance 向指定地址增加金额
AddBalance(string, string, uint64)
// 获取指定地址的余额
// GetBalance 获取指定地址的余额
GetBalance(string) uint64
// 获取nonce值(只有合约对象有,外部对象为0)
// GetNonce 获取nonce值(只有合约对象有,外部对象为0)
GetNonce(string) uint64
// 设置nonce值(只有合约对象有,外部对象为0)
// SetNonce 设置nonce值(只有合约对象有,外部对象为0)
SetNonce(string, uint64)
// 获取指定地址合约的代码哈希
// GetCodeHash 获取指定地址合约的代码哈希
GetCodeHash(string) common.Hash
// 获取指定地址合约代码
// GetCode 获取指定地址合约代码
GetCode(string) []byte
// 设置指定地址合约代码
// SetCode 设置指定地址合约代码
SetCode(string, []byte)
// 获取指定地址合约代码大小
// GetCodeSize 获取指定地址合约代码大小
GetCodeSize(string) int
// 合约Gas奖励回馈
// AddRefund 合约Gas奖励回馈
AddRefund(uint64)
// 获取合约Gas奖励
// GetRefund 获取合约Gas奖励
GetRefund() uint64
// 获取合约状态数据
// GetState 获取合约状态数据
GetState(string, common.Hash) common.Hash
// 设置合约状态数据
// SetState 设置合约状态数据
SetState(string, common.Hash, common.Hash)
// 合约自销毁
// Suicide 合约自销毁
Suicide(string) bool
// 合约是否已经销毁
// HasSuicided 合约是否已经销毁
HasSuicided(string) bool
// 判断一个合约地址是否存在(已经销毁的合约地址对象依然存在)
// Exist 判断一个合约地址是否存在(已经销毁的合约地址对象依然存在)
Exist(string) bool
// 判断一个合约地址是否为空(不包含任何代码、也没有余额的合约为空)
// Empty 判断一个合约地址是否为空(不包含任何代码、也没有余额的合约为空)
Empty(string) bool
// 回滚到制定版本(从当前版本到回滚版本之间的数据变更全部撤销)
// RevertToSnapshot 回滚到制定版本(从当前版本到回滚版本之间的数据变更全部撤销)
RevertToSnapshot(int)
// 生成一个新版本号(递增操作)
// Snapshot 生成一个新版本号(递增操作)
Snapshot() int
// 转换合约状态数据存储
// TransferStateData 转换合约状态数据存储
TransferStateData(addr string)
// 添加新的日志信息
// AddLog 添加新的日志信息
AddLog(*model.ContractLog)
// 添加sha3记录
// AddPreimage 添加sha3记录
AddPreimage(common.Hash, []byte)
// 当前账户余额是否足够转账
// CanTransfer 当前账户余额是否足够转账
CanTransfer(sender, recipient string, amount uint64) bool
// 转账交易
// Transfer 转账交易
Transfer(sender, recipient string, amount uint64) bool
}
......@@ -12,7 +12,7 @@ import (
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// 数据状态变更接口
// DataChange 数据状态变更接口
// 所有的数据状态变更事件实现此接口,并且封装各自的变更数据以及回滚动作
// 在调用合约时(具体的Tx执行时),会根据操作生成对应的变更对象并缓存下来
// 如果合约执行出错,会按生成顺序的倒序,依次调用变更对象的回滚接口进行数据回滚,并同步删除变更对象缓存
......@@ -23,14 +23,15 @@ type DataChange interface {
getLog(mdb *MemoryStateDB) []*types.ReceiptLog
}
// 版本结构,包含版本号以及当前版本包含的变更对象在变更序列中的开始序号
// Snapshot 版本结构,包含版本号以及当前版本包含的变更对象在变更序列中的开始序号
type Snapshot struct {
id int
entries []DataChange
statedb *MemoryStateDB
}
func (ver *Snapshot) GetId() int {
// GetID 获取ID
func (ver *Snapshot) GetID() int {
return ver.id
}
......
......@@ -16,20 +16,20 @@ import (
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/model"
)
// 内存状态数据库,保存在区块操作时内部的数据变更操作
// MemoryStateDB 内存状态数据库,保存在区块操作时内部的数据变更操作
// 本数据库不会直接写文件,只会暂存变更记录
// 在区块打包完成后,这里的缓存变更数据会被清空(通过区块打包分别写入blockchain和statedb数据库)
// 在交易执行过程中,本数据库会暂存并变更,在交易执行结束后,会返回变更的数据集,返回给blockchain
// 执行器的Exec阶段会返回:交易收据、合约账户(包含合约地址、合约代码、合约存储信息)
// 执行器的ExecLocal阶段会返回:合约创建人和合约的关联信息
type MemoryStateDB struct {
// 状态DB,从执行器框架传入
// StateDB 状态DB,从执行器框架传入
StateDB db.KV
// 本地DB,从执行器框架传入
// LocalDB 本地DB,从执行器框架传入
LocalDB db.KVDB
// Coins账户操作对象,从执行器框架传入
// CoinsAccount Coins账户操作对象,从执行器框架传入
CoinsAccount *account.DB
// 缓存账户对象
......@@ -45,7 +45,7 @@ type MemoryStateDB struct {
// 版本号,用于标识数据变更版本
snapshots []*Snapshot
currentVer *Snapshot
versionId int
versionID int
// 存储sha3指令对应的数据,仅用于debug日志
preimages map[common.Hash][]byte
......@@ -62,7 +62,7 @@ type MemoryStateDB struct {
dataDirty map[string]interface{}
}
// 基于执行器框架的三个DB构建内存状态机对象
// NewMemoryStateDB 基于执行器框架的三个DB构建内存状态机对象
// 此对象的生命周期对应一个区块,在同一个区块内的多个交易执行时共享同一个DB对象
// 开始执行下一个区块时(执行器框架调用setEnv设置的区块高度发生变更时),会重新创建此DB对象
func NewMemoryStateDB(StateDB db.KV, LocalDB db.KVDB, CoinsAccount *account.DB, blockHeight int64) *MemoryStateDB {
......@@ -82,55 +82,55 @@ func NewMemoryStateDB(StateDB db.KV, LocalDB db.KVDB, CoinsAccount *account.DB,
return mdb
}
// 每一个交易执行之前调用此方法,设置此交易的上下文信息
// Prepare 每一个交易执行之前调用此方法,设置此交易的上下文信息
// 目前的上下文中包含交易哈希以及交易在区块中的序号
func (self *MemoryStateDB) Prepare(txHash common.Hash, txIndex int) {
self.txHash = txHash
self.txIndex = txIndex
func (mdb *MemoryStateDB) Prepare(txHash common.Hash, txIndex int) {
mdb.txHash = txHash
mdb.txIndex = txIndex
}
// 创建一个新的合约账户对象
func (self *MemoryStateDB) CreateAccount(addr, creator string, execName, alias string) {
acc := self.GetAccount(addr)
// CreateAccount 创建一个新的合约账户对象
func (mdb *MemoryStateDB) CreateAccount(addr, creator string, execName, alias string) {
acc := mdb.GetAccount(addr)
if acc == nil {
// 这种情况下为新增合约账户
acc := NewContractAccount(addr, self)
acc := NewContractAccount(addr, mdb)
acc.SetCreator(creator)
acc.SetExecName(execName)
acc.SetAliasName(alias)
self.accounts[addr] = acc
self.addChange(createAccountChange{baseChange: baseChange{}, account: addr})
mdb.accounts[addr] = acc
mdb.addChange(createAccountChange{baseChange: baseChange{}, account: addr})
}
}
func (self *MemoryStateDB) addChange(entry DataChange) {
if self.currentVer != nil {
self.currentVer.append(entry)
func (mdb *MemoryStateDB) addChange(entry DataChange) {
if mdb.currentVer != nil {
mdb.currentVer.append(entry)
}
}
// 从外部账户地址扣钱(钱其实是打到合约账户中的)
func (self *MemoryStateDB) SubBalance(addr, caddr string, value uint64) {
res := self.Transfer(addr, caddr, value)
// SubBalance 从外部账户地址扣钱(钱其实是打到合约账户中的)
func (mdb *MemoryStateDB) SubBalance(addr, caddr string, value uint64) {
res := mdb.Transfer(addr, caddr, value)
log15.Debug("transfer result", "from", addr, "to", caddr, "amount", value, "result", res)
}
// 向外部账户地址打钱(钱其实是外部账户之前打到合约账户中的)
func (self *MemoryStateDB) AddBalance(addr, caddr string, value uint64) {
res := self.Transfer(caddr, addr, value)
// AddBalance 向外部账户地址打钱(钱其实是外部账户之前打到合约账户中的)
func (mdb *MemoryStateDB) AddBalance(addr, caddr string, value uint64) {
res := mdb.Transfer(caddr, addr, value)
log15.Debug("transfer result", "from", addr, "to", caddr, "amount", value, "result", res)
}
// 这里需要区分对待,如果是合约账户,则查看合约账户所有者地址在此合约下的余额;
// GetBalance 这里需要区分对待,如果是合约账户,则查看合约账户所有者地址在此合约下的余额;
// 如果是外部账户,则直接返回外部账户的余额
func (self *MemoryStateDB) GetBalance(addr string) uint64 {
if self.CoinsAccount == nil {
func (mdb *MemoryStateDB) GetBalance(addr string) uint64 {
if mdb.CoinsAccount == nil {
return 0
}
isExec := self.Exist(addr)
isExec := mdb.Exist(addr)
var ac *types.Account
if isExec {
contract := self.GetAccount(addr)
contract := mdb.GetAccount(addr)
if contract == nil {
return 0
}
......@@ -138,9 +138,9 @@ func (self *MemoryStateDB) GetBalance(addr string) uint64 {
if len(creator) == 0 {
return 0
}
ac = self.CoinsAccount.LoadExecAccount(creator, addr)
ac = mdb.CoinsAccount.LoadExecAccount(creator, addr)
} else {
ac = self.CoinsAccount.LoadAccount(addr)
ac = mdb.CoinsAccount.LoadAccount(addr)
}
if ac != nil {
return uint64(ac.Balance)
......@@ -148,152 +148,156 @@ func (self *MemoryStateDB) GetBalance(addr string) uint64 {
return 0
}
// 目前chain33中没有保留账户的nonce信息,这里临时添加到合约账户中;
// GetNonce 目前chain33中没有保留账户的nonce信息,这里临时添加到合约账户中;
// 所以,目前只有合约对象有nonce值
func (self *MemoryStateDB) GetNonce(addr string) uint64 {
acc := self.GetAccount(addr)
func (mdb *MemoryStateDB) GetNonce(addr string) uint64 {
acc := mdb.GetAccount(addr)
if acc != nil {
return acc.GetNonce()
}
return 0
}
func (self *MemoryStateDB) SetNonce(addr string, nonce uint64) {
acc := self.GetAccount(addr)
// SetNonce 设置nonce值
func (mdb *MemoryStateDB) SetNonce(addr string, nonce uint64) {
acc := mdb.GetAccount(addr)
if acc != nil {
acc.SetNonce(nonce)
}
}
func (self *MemoryStateDB) GetCodeHash(addr string) common.Hash {
acc := self.GetAccount(addr)
// GetCodeHash 获取代码哈希
func (mdb *MemoryStateDB) GetCodeHash(addr string) common.Hash {
acc := mdb.GetAccount(addr)
if acc != nil {
return common.BytesToHash(acc.Data.GetCodeHash())
}
return common.Hash{}
}
func (self *MemoryStateDB) GetCode(addr string) []byte {
acc := self.GetAccount(addr)
// GetCode 获取代码内容
func (mdb *MemoryStateDB) GetCode(addr string) []byte {
acc := mdb.GetAccount(addr)
if acc != nil {
return acc.Data.GetCode()
}
return nil
}
func (self *MemoryStateDB) SetCode(addr string, code []byte) {
acc := self.GetAccount(addr)
// SetCode 设置代码内容
func (mdb *MemoryStateDB) SetCode(addr string, code []byte) {
acc := mdb.GetAccount(addr)
if acc != nil {
self.dataDirty[addr] = true
mdb.dataDirty[addr] = true
acc.SetCode(code)
}
}
// 获取合约代码自身的大小
// GetCodeSize 获取合约代码自身的大小
// 对应 EXTCODESIZE 操作码
func (self *MemoryStateDB) GetCodeSize(addr string) int {
code := self.GetCode(addr)
func (mdb *MemoryStateDB) GetCodeSize(addr string) int {
code := mdb.GetCode(addr)
if code != nil {
return len(code)
}
return 0
}
// 合约自杀或SSTORE指令时,返还Gas
func (self *MemoryStateDB) AddRefund(gas uint64) {
self.addChange(refundChange{baseChange: baseChange{}, prev: self.refund})
self.refund += gas
// AddRefund 合约自杀或SSTORE指令时,返还Gas
func (mdb *MemoryStateDB) AddRefund(gas uint64) {
mdb.addChange(refundChange{baseChange: baseChange{}, prev: mdb.refund})
mdb.refund += gas
}
func (self *MemoryStateDB) GetRefund() uint64 {
return self.refund
// GetRefund 获取奖励
func (mdb *MemoryStateDB) GetRefund() uint64 {
return mdb.refund
}
// 从缓存中获取或加载合约账户
func (self *MemoryStateDB) GetAccount(addr string) *ContractAccount {
if acc, ok := self.accounts[addr]; ok {
// GetAccount 从缓存中获取或加载合约账户
func (mdb *MemoryStateDB) GetAccount(addr string) *ContractAccount {
if acc, ok := mdb.accounts[addr]; ok {
return acc
} else {
// 需要加载合约对象,根据是否存在合约代码来判断是否有合约对象
contract := NewContractAccount(addr, self)
contract.LoadContract(self.StateDB)
if contract.Empty() {
return nil
}
self.accounts[addr] = contract
return contract
}
// 需要加载合约对象,根据是否存在合约代码来判断是否有合约对象
contract := NewContractAccount(addr, mdb)
contract.LoadContract(mdb.StateDB)
if contract.Empty() {
return nil
}
mdb.accounts[addr] = contract
return contract
}
// SLOAD 指令加载合约状态数据
func (self *MemoryStateDB) GetState(addr string, key common.Hash) common.Hash {
// GetState SLOAD 指令加载合约状态数据
func (mdb *MemoryStateDB) GetState(addr string, key common.Hash) common.Hash {
// 先从合约缓存中获取
acc := self.GetAccount(addr)
acc := mdb.GetAccount(addr)
if acc != nil {
return acc.GetState(key)
}
return common.Hash{}
}
// SSTORE 指令修改合约状态数据
func (self *MemoryStateDB) SetState(addr string, key common.Hash, value common.Hash) {
acc := self.GetAccount(addr)
// SetState SSTORE 指令修改合约状态数据
func (mdb *MemoryStateDB) SetState(addr string, key common.Hash, value common.Hash) {
acc := mdb.GetAccount(addr)
if acc != nil {
acc.SetState(key, value)
// 新的分叉中状态数据变更不需要单独进行标识
if !types.IsDappFork(self.blockHeight, "evm", "ForkEVMState") {
self.stateDirty[addr] = true
if !types.IsDappFork(mdb.blockHeight, "evm", "ForkEVMState") {
mdb.stateDirty[addr] = true
}
}
}
// 转换合约状态数据存储
func (self *MemoryStateDB) TransferStateData(addr string) {
acc := self.GetAccount(addr)
// TransferStateData 转换合约状态数据存储
func (mdb *MemoryStateDB) TransferStateData(addr string) {
acc := mdb.GetAccount(addr)
if acc != nil {
acc.TransferState()
}
}
// 表示合约地址的状态数据发生了变更,需要进行更新
func (self *MemoryStateDB) UpdateState(addr string) {
self.stateDirty[addr] = true
// UpdateState 表示合约地址的状态数据发生了变更,需要进行更新
func (mdb *MemoryStateDB) UpdateState(addr string) {
mdb.stateDirty[addr] = true
}
// SELFDESTRUCT 合约对象自杀
// Suicide SELFDESTRUCT 合约对象自杀
// 合约自杀后,合约对象依然存在,只是无法被调用,也无法恢复
func (self *MemoryStateDB) Suicide(addr string) bool {
acc := self.GetAccount(addr)
func (mdb *MemoryStateDB) Suicide(addr string) bool {
acc := mdb.GetAccount(addr)
if acc != nil {
self.addChange(suicideChange{
mdb.addChange(suicideChange{
baseChange: baseChange{},
account: addr,
prev: acc.State.GetSuicided(),
})
self.stateDirty[addr] = true
mdb.stateDirty[addr] = true
return acc.Suicide()
}
return false
}
// 判断此合约对象是否已经自杀
// HasSuicided 判断此合约对象是否已经自杀
// 自杀的合约对象是不允许调用的
func (self *MemoryStateDB) HasSuicided(addr string) bool {
acc := self.GetAccount(addr)
func (mdb *MemoryStateDB) HasSuicided(addr string) bool {
acc := mdb.GetAccount(addr)
if acc != nil {
return acc.HasSuicided()
}
return false
}
// 判断合约对象是否存在
func (self *MemoryStateDB) Exist(addr string) bool {
return self.GetAccount(addr) != nil
// Exist 判断合约对象是否存在
func (mdb *MemoryStateDB) Exist(addr string) bool {
return mdb.GetAccount(addr) != nil
}
// 判断合约对象是否为空
func (self *MemoryStateDB) Empty(addr string) bool {
acc := self.GetAccount(addr)
// Empty 判断合约对象是否为空
func (mdb *MemoryStateDB) Empty(addr string) bool {
acc := mdb.GetAccount(addr)
// 如果包含合约代码,则不为空
if acc != nil && !acc.Empty() {
......@@ -301,19 +305,19 @@ func (self *MemoryStateDB) Empty(addr string) bool {
}
// 账户有余额,也不为空
if self.GetBalance(addr) != 0 {
if mdb.GetBalance(addr) != 0 {
return false
}
return true
}
// 将数据状态回滚到指定快照版本(中间的版本数据将会被删除)
func (self *MemoryStateDB) RevertToSnapshot(version int) {
if version >= len(self.snapshots) {
// RevertToSnapshot 将数据状态回滚到指定快照版本(中间的版本数据将会被删除)
func (mdb *MemoryStateDB) RevertToSnapshot(version int) {
if version >= len(mdb.snapshots) {
return
}
ver := self.snapshots[version]
ver := mdb.snapshots[version]
// 如果版本号不对,回滚失败
if ver == nil || ver.id != version {
......@@ -322,50 +326,50 @@ func (self *MemoryStateDB) RevertToSnapshot(version int) {
}
// 从最近版本开始回滚
for index := len(self.snapshots) - 1; index >= version; index-- {
self.snapshots[index].revert()
for index := len(mdb.snapshots) - 1; index >= version; index-- {
mdb.snapshots[index].revert()
}
// 只保留回滚版本之前的版本数据
self.snapshots = self.snapshots[:version]
self.versionId = version
mdb.snapshots = mdb.snapshots[:version]
mdb.versionID = version
if version == 0 {
self.currentVer = nil
mdb.currentVer = nil
} else {
self.currentVer = self.snapshots[version-1]
mdb.currentVer = mdb.snapshots[version-1]
}
}
// 对当前的数据状态打快照,并生成快照版本号,方便后面回滚数据
func (self *MemoryStateDB) Snapshot() int {
id := self.versionId
self.versionId++
self.currentVer = &Snapshot{id: id, statedb: self}
self.snapshots = append(self.snapshots, self.currentVer)
// Snapshot 对当前的数据状态打快照,并生成快照版本号,方便后面回滚数据
func (mdb *MemoryStateDB) Snapshot() int {
id := mdb.versionID
mdb.versionID++
mdb.currentVer = &Snapshot{id: id, statedb: mdb}
mdb.snapshots = append(mdb.snapshots, mdb.currentVer)
return id
}
// 获取最后一次成功的快照版本号
func (self *MemoryStateDB) GetLastSnapshot() *Snapshot {
if self.versionId == 0 {
// GetLastSnapshot 获取最后一次成功的快照版本号
func (mdb *MemoryStateDB) GetLastSnapshot() *Snapshot {
if mdb.versionID == 0 {
return nil
}
return self.snapshots[self.versionId-1]
return mdb.snapshots[mdb.versionID-1]
}
// 获取合约对象的变更日志
func (self *MemoryStateDB) GetReceiptLogs(addr string) (logs []*types.ReceiptLog) {
acc := self.GetAccount(addr)
// GetReceiptLogs 获取合约对象的变更日志
func (mdb *MemoryStateDB) GetReceiptLogs(addr string) (logs []*types.ReceiptLog) {
acc := mdb.GetAccount(addr)
if acc != nil {
if self.stateDirty[addr] != nil {
if mdb.stateDirty[addr] != nil {
stateLog := acc.BuildStateLog()
if stateLog != nil {
logs = append(logs, stateLog)
}
}
if self.dataDirty[addr] != nil {
if mdb.dataDirty[addr] != nil {
logs = append(logs, acc.BuildDataLog())
}
return
......@@ -373,16 +377,16 @@ func (self *MemoryStateDB) GetReceiptLogs(addr string) (logs []*types.ReceiptLog
return
}
// 获取本次操作所引起的状态数据变更
// GetChangedData 获取本次操作所引起的状态数据变更
// 因为目前执行器每次执行都是一个新的MemoryStateDB,所以,所有的快照都是从0开始的,
// 这里获取的应该是从0到目前快照的所有变更;
// 另外,因为合约内部会调用其它合约,也会产生数据变更,所以这里返回的数据,不止是一个合约的数据。
func (self *MemoryStateDB) GetChangedData(version int) (kvSet []*types.KeyValue, logs []*types.ReceiptLog) {
func (mdb *MemoryStateDB) GetChangedData(version int) (kvSet []*types.KeyValue, logs []*types.ReceiptLog) {
if version < 0 {
return
}
for _, snapshot := range self.snapshots {
for _, snapshot := range mdb.snapshots {
kv, log := snapshot.getData()
if kv != nil {
kvSet = append(kvSet, kv...)
......@@ -395,12 +399,12 @@ func (self *MemoryStateDB) GetChangedData(version int) (kvSet []*types.KeyValue,
return
}
// 借助coins执行器进行转账相关操作
func (self *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64) bool {
// CanTransfer 借助coins执行器进行转账相关操作
func (mdb *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64) bool {
log15.Debug("check CanTransfer", "sender", sender, "recipient", recipient, "amount", amount)
tType, errInfo := self.checkTransfer(sender, recipient, amount)
tType, errInfo := mdb.checkTransfer(sender, recipient, amount)
if errInfo != nil {
log15.Error("check transfer error", "sender", sender, "recipient", recipient, "amount", amount, "err info", errInfo)
......@@ -416,7 +420,7 @@ func (self *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64)
case NoNeed:
return true
case ToExec:
accFrom := self.CoinsAccount.LoadExecAccount(sender, recipient)
accFrom := mdb.CoinsAccount.LoadExecAccount(sender, recipient)
b := accFrom.GetBalance() - value
if b < 0 {
log15.Error("check transfer error", "error info", types.ErrNoBalance)
......@@ -424,13 +428,13 @@ func (self *MemoryStateDB) CanTransfer(sender, recipient string, amount uint64)
}
return true
case FromExec:
return self.checkExecAccount(sender, value)
return mdb.checkExecAccount(sender, value)
default:
return false
}
}
func (self *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
func (mdb *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
var err error
defer func() {
if err != nil {
......@@ -442,7 +446,7 @@ func (self *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
err = types.ErrAmount
return false
}
contract := self.GetAccount(addr)
contract := mdb.GetAccount(addr)
if contract == nil {
err = model.ErrAddrNotExists
return false
......@@ -453,7 +457,7 @@ func (self *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
return false
}
accFrom := self.CoinsAccount.LoadExecAccount(contract.GetCreator(), addr)
accFrom := mdb.CoinsAccount.LoadExecAccount(contract.GetCreator(), addr)
b := accFrom.GetBalance() - value
if b < 0 {
err = types.ErrNoBalance
......@@ -462,28 +466,33 @@ func (self *MemoryStateDB) checkExecAccount(addr string, value int64) bool {
return true
}
// TransferType 定义转账类型
type TransferType int
const (
_ TransferType = iota
// NoNeed 无需转账
NoNeed
// ToExec 向合约转账
ToExec
// FromExec 从合约转入
FromExec
// Error 处理出错
Error
)
func (self *MemoryStateDB) checkTransfer(sender, recipient string, amount uint64) (tType TransferType, err error) {
func (mdb *MemoryStateDB) checkTransfer(sender, recipient string, amount uint64) (tType TransferType, err error) {
if amount == 0 {
return NoNeed, nil
}
if self.CoinsAccount == nil {
if mdb.CoinsAccount == nil {
log15.Error("no coinsaccount exists", "sender", sender, "recipient", recipient, "amount", amount)
return Error, model.NoCoinsAccount
return Error, model.ErrNoCoinsAccount
}
// 首先需要检查转账双方的信息,是属于合约账户还是外部账户
execSender := self.Exist(sender)
execRecipient := self.Exist(recipient)
execSender := mdb.Exist(sender)
execRecipient := mdb.Exist(recipient)
if execRecipient && execSender {
// 双方均为合约账户,不支持
......@@ -506,12 +515,12 @@ func (self *MemoryStateDB) checkTransfer(sender, recipient string, amount uint64
return tType, err
}
// 借助coins执行器进行转账相关操作
// Transfer 借助coins执行器进行转账相关操作
// 只支持 合约账户到合约账户,其它情况不支持
func (self *MemoryStateDB) Transfer(sender, recipient string, amount uint64) bool {
func (mdb *MemoryStateDB) Transfer(sender, recipient string, amount uint64) bool {
log15.Debug("transfer from contract to external(contract)", "sender", sender, "recipient", recipient, "amount", amount)
tType, errInfo := self.checkTransfer(sender, recipient, amount)
tType, errInfo := mdb.checkTransfer(sender, recipient, amount)
if errInfo != nil {
log15.Error("transfer error", "sender", sender, "recipient", recipient, "amount", amount, "err info", errInfo)
......@@ -532,9 +541,9 @@ func (self *MemoryStateDB) Transfer(sender, recipient string, amount uint64) boo
case NoNeed:
return true
case ToExec:
ret, err = self.transfer2Contract(sender, recipient, value)
ret, err = mdb.transfer2Contract(sender, recipient, value)
case FromExec:
ret, err = self.transfer2External(sender, recipient, value)
ret, err = mdb.transfer2External(sender, recipient, value)
default:
return false
}
......@@ -543,17 +552,16 @@ func (self *MemoryStateDB) Transfer(sender, recipient string, amount uint64) boo
if err != nil {
log15.Error("transfer error", "sender", sender, "recipient", recipient, "amount", amount, "err info", err)
return false
} else {
if ret != nil {
self.addChange(transferChange{
baseChange: baseChange{},
amount: value,
data: ret.KV,
logs: ret.Logs,
})
}
return true
}
if ret != nil {
mdb.addChange(transferChange{
baseChange: baseChange{},
amount: value,
data: ret.KV,
logs: ret.Logs,
})
}
return true
}
// 因为chain33的限制,在执行器中转账只能在以下几个方向进行:
......@@ -561,9 +569,9 @@ func (self *MemoryStateDB) Transfer(sender, recipient string, amount uint64) boo
// 其它情况不支持,所以要想实现EVM合约与账户之间的转账需要经过中转处理,比如A要向B创建的X合约转账,则执行以下流程:
// A -> A:X -> B:X; (其中第一步需要外部手工执行)
// 本方法封装第二步转账逻辑;
func (self *MemoryStateDB) transfer2Contract(sender, recipient string, amount int64) (ret *types.Receipt, err error) {
func (mdb *MemoryStateDB) transfer2Contract(sender, recipient string, amount int64) (ret *types.Receipt, err error) {
// 首先获取合约的创建者信息
contract := self.GetAccount(recipient)
contract := mdb.GetAccount(recipient)
if contract == nil {
return nil, model.ErrAddrNotExists
}
......@@ -577,7 +585,7 @@ func (self *MemoryStateDB) transfer2Contract(sender, recipient string, amount in
// 有可能是外部账户调用自己创建的合约,这种情况下这一步可以省略
ret = &types.Receipt{}
if strings.Compare(sender, creator) != 0 {
rs, err := self.CoinsAccount.ExecTransfer(sender, creator, execAddr, amount)
rs, err := mdb.CoinsAccount.ExecTransfer(sender, creator, execAddr, amount)
if err != nil {
return nil, err
}
......@@ -591,9 +599,9 @@ func (self *MemoryStateDB) transfer2Contract(sender, recipient string, amount in
// chain33转账限制请参考方法 Transfer2Contract ;
// 本方法封装从合约账户到外部账户的转账逻辑;
func (self *MemoryStateDB) transfer2External(sender, recipient string, amount int64) (ret *types.Receipt, err error) {
func (mdb *MemoryStateDB) transfer2External(sender, recipient string, amount int64) (ret *types.Receipt, err error) {
// 首先获取合约的创建者信息
contract := self.GetAccount(sender)
contract := mdb.GetAccount(sender)
if contract == nil {
return nil, model.ErrAddrNotExists
}
......@@ -607,7 +615,7 @@ func (self *MemoryStateDB) transfer2External(sender, recipient string, amount in
// 第一步先从创建者的合约账户到接受者的合约账户
// 如果是自己调用自己创建的合约,这一步也可以省略
if strings.Compare(creator, recipient) != 0 {
ret, err = self.CoinsAccount.ExecTransfer(creator, recipient, execAddr, amount)
ret, err = mdb.CoinsAccount.ExecTransfer(creator, recipient, execAddr, amount)
if err != nil {
return nil, err
}
......@@ -615,17 +623,17 @@ func (self *MemoryStateDB) transfer2External(sender, recipient string, amount in
// 第二步再从接收者的合约账户取款到接受者账户
// 本操作不允许,需要外部操作coins账户
//rs, err := self.CoinsAccount.TransferWithdraw(recipient.String(), sender.String(), amount)
//rs, err := mdb.CoinsAccount.TransferWithdraw(recipient.String(), sender.String(), amount)
//if err != nil {
// return nil, err
//}
//
//ret = self.mergeResult(ret, rs)
//ret = mdb.mergeResult(ret, rs)
return ret, nil
}
func (self *MemoryStateDB) mergeResult(one, two *types.Receipt) (ret *types.Receipt) {
func (mdb *MemoryStateDB) mergeResult(one, two *types.Receipt) (ret *types.Receipt) {
ret = one
if ret == nil {
ret = two
......@@ -636,45 +644,45 @@ func (self *MemoryStateDB) mergeResult(one, two *types.Receipt) (ret *types.Rece
return
}
// LOG0-4 指令对应的具体操作
// AddLog LOG0-4 指令对应的具体操作
// 生成对应的日志信息,目前这些生成的日志信息会在合约执行后打印到日志文件中
func (self *MemoryStateDB) AddLog(log *model.ContractLog) {
self.addChange(addLogChange{txhash: self.txHash})
log.TxHash = self.txHash
log.Index = int(self.logSize)
self.logs[self.txHash] = append(self.logs[self.txHash], log)
self.logSize++
func (mdb *MemoryStateDB) AddLog(log *model.ContractLog) {
mdb.addChange(addLogChange{txhash: mdb.txHash})
log.TxHash = mdb.txHash
log.Index = int(mdb.logSize)
mdb.logs[mdb.txHash] = append(mdb.logs[mdb.txHash], log)
mdb.logSize++
}
// 存储sha3指令对应的数据
func (self *MemoryStateDB) AddPreimage(hash common.Hash, data []byte) {
// AddPreimage 存储sha3指令对应的数据
func (mdb *MemoryStateDB) AddPreimage(hash common.Hash, data []byte) {
// 目前只用于打印日志
if _, ok := self.preimages[hash]; !ok {
self.addChange(addPreimageChange{hash: hash})
if _, ok := mdb.preimages[hash]; !ok {
mdb.addChange(addPreimageChange{hash: hash})
pi := make([]byte, len(data))
copy(pi, data)
self.preimages[hash] = pi
mdb.preimages[hash] = pi
}
}
// 本合约执行完毕之后打印合约生成的日志(如果有)
// PrintLogs 本合约执行完毕之后打印合约生成的日志(如果有)
// 这里不保证当前区块可以打包成功,只是在执行区块中的交易时,如果交易执行成功,就会打印合约日志
func (self *MemoryStateDB) PrintLogs() {
items := self.logs[self.txHash]
func (mdb *MemoryStateDB) PrintLogs() {
items := mdb.logs[mdb.txHash]
for _, item := range items {
item.PrintLog()
}
}
// 打印本区块内生成的preimages日志
func (self *MemoryStateDB) WritePreimages(number int64) {
for k, v := range self.preimages {
// WritePreimages 打印本区块内生成的preimages日志
func (mdb *MemoryStateDB) WritePreimages(number int64) {
for k, v := range mdb.preimages {
log15.Debug("Contract preimages ", "key:", k.Str(), "value:", common.Bytes2Hex(v), "block height:", number)
}
}
// 测试用,清空版本数据
func (self *MemoryStateDB) ResetDatas() {
self.currentVer = nil
self.snapshots = self.snapshots[:0]
// ResetDatas 测试用,清空版本数据
func (mdb *MemoryStateDB) ResetDatas() {
mdb.currentVer = nil
mdb.snapshots = mdb.snapshots[:0]
}
......@@ -32,34 +32,39 @@ func init() {
types.RegisterDappFork(ExecutorName, "Enable", 500000)
}
// EvmType EVM类型定义
type EvmType struct {
types.ExecTypeBase
}
// NewType 新建EVM类型对象
func NewType() *EvmType {
c := &EvmType{}
c.SetChild(c)
return c
}
// GetPayload 获取消息负载结构
func (evm *EvmType) GetPayload() types.Message {
return &EVMContractAction{}
}
// ActionName 获取ActionName
func (evm EvmType) ActionName(tx *types.Transaction) string {
// 这个需要通过合约交易目标地址来判断Action
// 如果目标地址为空,或为evm的固定合约地址,则为创建合约,否则为调用合约
if strings.EqualFold(tx.To, address.ExecAddress(types.ExecName(ExecutorName))) {
return "createEvmContract"
} else {
return "callEvmContract"
}
return "callEvmContract"
}
// GetTypeMap 获取类型映射
func (evm *EvmType) GetTypeMap() map[string]int32 {
return actionName
}
// GetRealToAddr 获取实际地址
func (evm EvmType) GetRealToAddr(tx *types.Transaction) string {
if string(tx.Execer) == ExecutorName {
return tx.To
......@@ -72,10 +77,12 @@ func (evm EvmType) GetRealToAddr(tx *types.Transaction) string {
return tx.To
}
// Amount 获取金额
func (evm EvmType) Amount(tx *types.Transaction) (int64, error) {
return 0, nil
}
// CreateTx 创建交易对象
func (evm EvmType) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) {
elog.Debug("evm.CreateTx", "action", action)
if action == "CreateCall" {
......@@ -85,74 +92,25 @@ func (evm EvmType) CreateTx(action string, message json.RawMessage) (*types.Tran
elog.Error("CreateTx", "Error", err)
return nil, types.ErrInvalidParam
}
return CreateRawEvmCreateCallTx(&param)
} else {
return nil, types.ErrNotSupport
return createRawEvmCreateCallTx(&param)
}
return nil, types.ErrNotSupport
}
// GetLogMap 获取日志类型映射
func (evm *EvmType) GetLogMap() map[int64]*types.LogInfo {
return logInfo
}
type EvmCheckAddrExists struct {
}
func (t *EvmCheckAddrExists) JsonToProto(message json.RawMessage) ([]byte, error) {
var req CheckEVMAddrReq
err := json.Unmarshal(message, &req)
if err != nil {
return nil, err
}
return types.Encode(&req), nil
}
func (t *EvmCheckAddrExists) ProtoToJson(reply *types.Message) (interface{}, error) {
return reply, nil
}
type EvmEstimateGas struct {
}
func (t *EvmEstimateGas) JsonToProto(message json.RawMessage) ([]byte, error) {
var req EstimateEVMGasReq
err := json.Unmarshal(message, &req)
if err != nil {
return nil, err
}
return types.Encode(&req), nil
}
func (t *EvmEstimateGas) ProtoToJson(reply *types.Message) (interface{}, error) {
return reply, nil
}
type EvmDebug struct {
}
func (t *EvmDebug) JsonToProto(message json.RawMessage) ([]byte, error) {
var req EvmDebugReq
err := json.Unmarshal(message, &req)
if err != nil {
return nil, err
}
return types.Encode(&req), nil
}
func (t *EvmDebug) ProtoToJson(reply *types.Message) (interface{}, error) {
return reply, nil
}
//different with other exector, the name is defined by parm
func CreateRawEvmCreateCallTx(parm *CreateCallTx) (*types.Transaction, error) {
func createRawEvmCreateCallTx(parm *CreateCallTx) (*types.Transaction, error) {
if parm == nil {
elog.Error("CreateRawEvmCreateCallTx", "parm", parm)
elog.Error("createRawEvmCreateCallTx", "parm", parm)
return nil, types.ErrInvalidParam
}
bCode, err := common.FromHex(parm.Code)
if err != nil {
elog.Error("CreateRawEvmCreateCallTx", "parm.Code", parm.Code)
elog.Error("createRawEvmCreateCallTx", "parm.Code", parm.Code)
return nil, err
}
......
......@@ -4,14 +4,24 @@
package types
// CreateCallTx 创建或调用合约交易结构
type CreateCallTx struct {
Amount uint64 `json:"amount"`
Code string `json:"code"`
// Amount 金额
Amount uint64 `json:"amount"`
// Code 合约代码
Code string `json:"code"`
// GasLimit gas限制
GasLimit uint64 `json:"gasLimit"`
// GasPrice gas定价
GasPrice uint32 `json:"gasPrice"`
Note string `json:"note"`
Alias string `json:"alias"`
Fee int64 `json:"fee"`
Name string `json:"name"`
IsCreate bool `json:"isCreate"`
// Note 备注
Note string `json:"note"`
// Alias 合约别名
Alias string `json:"alias"`
// Fee 交易手续费
Fee int64 `json:"fee"`
// Name 交易名称
Name string `json:"name"`
// IsCreate 是否创建合约
IsCreate bool `json:"isCreate"`
}
......@@ -11,34 +11,33 @@ import (
)
const (
// EvmCreateAction 创建合约
EvmCreateAction = 1
EvmCallAction = 2
// EvmCallAction 调用合约
EvmCallAction = 2
// 合约代码变更日志
// TyLogContractData 合约代码变更日志
TyLogContractData = 601
// 合约状态数据变更日志
// TyLogContractState 合约状态数据变更日志
TyLogContractState = 602
// 合约状态数据变更日志
// TyLogCallContract 合约状态数据变更日志
TyLogCallContract = 603
// 合约状态数据变更项日志
// TyLogEVMStateChangeItem 合约状态数据变更项日志
TyLogEVMStateChangeItem = 604
// 查询方法
FuncCheckAddrExists = "CheckAddrExists"
FuncEstimateGas = "EstimateGas"
FuncEvmDebug = "EvmDebug"
// 最大Gas消耗上限
// MaxGasLimit 最大Gas消耗上限
MaxGasLimit = 10000000
)
var (
// 本执行器前缀
// EvmPrefix 本执行器前缀
EvmPrefix = "user.evm."
// 本执行器名称
// ExecutorName 本执行器名称
ExecutorName = "evm"
ExecerEvm = []byte(ExecutorName)
// ExecerEvm EVM执行器名称
ExecerEvm = []byte(ExecutorName)
// UserPrefix 执行器前缀
UserPrefix = []byte(EvmPrefix)
logInfo = map[int64]*types.LogInfo{
......
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