/
phoenixchain_contract_tool.go
109 lines (96 loc) · 3.14 KB
/
phoenixchain_contract_tool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package vm
import (
"reflect"
"strconv"
"github.com/PhoenixGlobal/Phoenix-Chain-Core/libs/common"
"github.com/PhoenixGlobal/Phoenix-Chain-Core/libs/log"
"github.com/PhoenixGlobal/Phoenix-Chain-Core/pos/plugin"
"github.com/PhoenixGlobal/Phoenix-Chain-Core/pos/xcom"
)
func execPhoenixchainContract(input []byte, command map[uint16]interface{}) (ret []byte, err error) {
// verify the tx data by contracts method
_, fn, params, err := plugin.VerifyTxData(input, command)
if nil != err {
log.Error("Failed to verify contract tx before exec", "err", err)
return xcom.NewResult(common.InvalidParameter, nil), err
}
// execute contracts method
result := reflect.ValueOf(fn).Call(params)
switch errtyp := result[1].Interface().(type) {
case *common.BizError:
log.Error("Failed to execute contract tx", "err", errtyp)
return xcom.NewResult(errtyp, nil), errtyp
case error:
log.Error("Failed to execute contract tx", "err", errtyp)
return xcom.NewResult(common.InternalError, nil), errtyp
default:
}
return result[0].Bytes(), nil
}
func txResultHandler(contractAddr common.Address, evm *EVM, title, reason string, fncode int, errCode *common.BizError) ([]byte, error) {
event := strconv.Itoa(fncode)
receipt := strconv.Itoa(int(errCode.Code))
blockNumber := evm.BlockNumber.Uint64()
if errCode.Code != 0 {
txHash := evm.StateDB.TxHash()
log.Error("Failed to "+title, "txHash", txHash.Hex(),
"blockNumber", blockNumber, "receipt: ", receipt, "the reason", reason)
}
xcom.AddLog(evm.StateDB, blockNumber, contractAddr, event, receipt)
if errCode.Code == common.NoErr.Code {
return []byte(receipt), nil
}
return []byte(receipt), errCode
}
func txResultHandlerWithRes(contractAddr common.Address, evm *EVM, title, reason string, fncode, errCode int, res interface{}) []byte {
event := strconv.Itoa(fncode)
receipt := strconv.Itoa(errCode)
blockNumber := evm.BlockNumber.Uint64()
if errCode != 0 {
txHash := evm.StateDB.TxHash()
log.Error("Failed to "+title, "txHash", txHash.Hex(),
"blockNumber", blockNumber, "receipt: ", receipt, "the reason", reason)
}
xcom.AddLogWithRes(evm.StateDB, blockNumber, contractAddr, event, receipt, res)
return []byte(receipt)
}
func callResultHandler(evm *EVM, title string, resultValue interface{}, err *common.BizError) []byte {
txHash := evm.StateDB.TxHash()
blockNumber := evm.BlockNumber.Uint64()
if nil != err {
log.Error("Failed to "+title, "txHash", txHash.Hex(),
"blockNumber", blockNumber, "the reason", err.Error())
return xcom.NewResult(err, nil)
}
if IsBlank(resultValue) {
return xcom.NewResult(common.NotFound, nil)
}
log.Debug("Call "+title+" finished", "blockNumber", blockNumber,
"txHash", txHash, "result", resultValue)
return xcom.NewResult(nil, resultValue)
}
func IsBlank(i interface{}) bool {
defer func() {
recover()
}()
typ := reflect.TypeOf(i)
val := reflect.ValueOf(i)
if typ == nil {
return true
} else {
if typ.Kind() == reflect.Slice {
return val.Len() == 0
}
if typ.Kind() == reflect.Map {
return val.Len() == 0
}
}
return val.IsNil()
}
func checkInputEmpty(input []byte) bool {
if len(input) == 0 {
return true
} else {
return false
}
}