github.com/turingchain2020/turingchain@v1.1.21/types/executor.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package types
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/json"
    10  	"math/rand"
    11  	"reflect"
    12  	"strings"
    13  	"unicode"
    14  
    15  	"github.com/turingchain2020/turingchain/common/address"
    16  	"github.com/golang/protobuf/proto"
    17  )
    18  
    19  func init() {
    20  	rand.Seed(Now().UnixNano())
    21  }
    22  
    23  // LogType 结构体类型
    24  type LogType interface {
    25  	Name() string
    26  	Decode([]byte) (interface{}, error)
    27  	JSON([]byte) ([]byte, error)
    28  }
    29  
    30  type logInfoType struct {
    31  	ty     int64
    32  	execer []byte
    33  }
    34  
    35  func newLogType(execer []byte, ty int64) LogType {
    36  	return &logInfoType{ty: ty, execer: execer}
    37  }
    38  
    39  func (l *logInfoType) Name() string {
    40  	return GetLogName(l.execer, l.ty)
    41  }
    42  
    43  func (l *logInfoType) Decode(data []byte) (interface{}, error) {
    44  	return DecodeLog(l.execer, l.ty, data)
    45  }
    46  
    47  func (l *logInfoType) JSON(data []byte) ([]byte, error) {
    48  	d, err := l.Decode(data)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	if msg, ok := d.(Message); ok {
    53  		return PBToJSON(msg)
    54  	}
    55  	jsdata, err := json.Marshal(d)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	return jsdata, nil
    60  }
    61  
    62  var executorMap = map[string]ExecutorType{}
    63  
    64  // RegistorExecutor 注册执行器
    65  func RegistorExecutor(exec string, util ExecutorType) {
    66  	//tlog.Debug("rpc", "t", funcName, "t", util)
    67  	if util.GetChild() == nil {
    68  		panic("exec " + exec + " executorType child is nil")
    69  	}
    70  	if _, exist := executorMap[exec]; exist {
    71  		panic("DupExecutorType")
    72  	} else {
    73  		executorMap[exec] = util
    74  	}
    75  }
    76  
    77  // LoadExecutorType 加载执行器
    78  func LoadExecutorType(execstr string) ExecutorType {
    79  	//尽可能的加载执行器
    80  	//真正的权限控制在区块执行的时候做控制
    81  	realname := GetRealExecName([]byte(execstr))
    82  	if exec, exist := executorMap[string(realname)]; exist {
    83  		return exec
    84  	}
    85  	return nil
    86  }
    87  
    88  // CallExecNewTx 重构完成后删除
    89  func CallExecNewTx(c *TuringchainConfig, execName, action string, param interface{}) ([]byte, error) {
    90  	exec := LoadExecutorType(execName)
    91  	if exec == nil {
    92  		tlog.Error("callExecNewTx", "Error", "exec not found")
    93  		return nil, ErrNotSupport
    94  	}
    95  	// param is interface{type, var-nil}, check with nil always fail
    96  	if reflect.ValueOf(param).IsNil() {
    97  		tlog.Error("callExecNewTx", "Error", "param in nil")
    98  		return nil, ErrInvalidParam
    99  	}
   100  	jsonStr, err := json.Marshal(param)
   101  	if err != nil {
   102  		tlog.Error("callExecNewTx", "Error", err)
   103  		return nil, err
   104  	}
   105  	tx, err := exec.CreateTx(action, json.RawMessage(jsonStr))
   106  	if err != nil {
   107  		tlog.Error("callExecNewTx", "Error", err)
   108  		return nil, err
   109  	}
   110  	return FormatTxEncode(c, execName, tx)
   111  }
   112  
   113  //CallCreateTransaction 创建一个交易
   114  func CallCreateTransaction(execName, action string, param Message) (*Transaction, error) {
   115  	exec := LoadExecutorType(execName)
   116  	if exec == nil {
   117  		tlog.Error("CallCreateTx", "Error", "exec not found")
   118  		return nil, ErrNotSupport
   119  	}
   120  	// param is interface{type, var-nil}, check with nil always fail
   121  	if param == nil {
   122  		tlog.Error("CallCreateTx", "Error", "param in nil")
   123  		return nil, ErrInvalidParam
   124  	}
   125  	return exec.Create(action, param)
   126  }
   127  
   128  // CallCreateTx 构造交易信息
   129  func CallCreateTx(c *TuringchainConfig, execName, action string, param Message) ([]byte, error) {
   130  	tx, err := CallCreateTransaction(execName, action, param)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  	return FormatTxEncode(c, execName, tx)
   135  }
   136  
   137  //CallCreateTxJSON create tx by json
   138  func CallCreateTxJSON(c *TuringchainConfig, execName, action string, param json.RawMessage) ([]byte, error) {
   139  	exec := LoadExecutorType(execName)
   140  	if exec == nil {
   141  		execer := GetParaExecName([]byte(execName))
   142  		//找不到执行器,并且是user.xxx 的情况下
   143  		if bytes.HasPrefix(execer, UserKey) {
   144  			tx := &Transaction{Payload: param}
   145  			return FormatTxEncode(c, execName, tx)
   146  		}
   147  		tlog.Error("CallCreateTxJSON", "Error", "exec not found")
   148  		return nil, ErrExecNotFound
   149  	}
   150  	// param is interface{type, var-nil}, check with nil always fail
   151  	if param == nil {
   152  		tlog.Error("CallCreateTxJSON", "Error", "param in nil")
   153  		return nil, ErrInvalidParam
   154  	}
   155  	tx, err := exec.CreateTx(action, param)
   156  	if err != nil {
   157  		tlog.Error("CallCreateTxJSON", "Error", err)
   158  		return nil, err
   159  	}
   160  	return FormatTxEncode(c, execName, tx)
   161  }
   162  
   163  // CreateFormatTx 构造交易信息
   164  func CreateFormatTx(c *TuringchainConfig, execName string, payload []byte) (*Transaction, error) {
   165  	//填写nonce,execer,to, fee 等信息, 后面会增加一个修改transaction的函数,会加上execer fee 等的修改
   166  	tx := &Transaction{Payload: payload}
   167  	return FormatTx(c, execName, tx)
   168  }
   169  
   170  // FormatTx 格式化tx交易
   171  func FormatTx(c *TuringchainConfig, execName string, tx *Transaction) (*Transaction, error) {
   172  	//填写nonce,execer,to, fee 等信息, 后面会增加一个修改transaction的函数,会加上execer fee 等的修改
   173  	tx.Nonce = rand.Int63()
   174  	tx.ChainID = c.GetChainID()
   175  	tx.Execer = []byte(execName)
   176  	//平行链,所有的to地址都是合约地址
   177  	if c.IsPara() || tx.To == "" {
   178  		tx.To = address.ExecAddress(string(tx.Execer))
   179  	}
   180  	var err error
   181  	if tx.Fee == 0 {
   182  		tx.Fee, err = tx.GetRealFee(c.GetMinTxFeeRate())
   183  		if err != nil {
   184  			return nil, err
   185  		}
   186  	}
   187  	return tx, nil
   188  }
   189  
   190  // FormatTxEncode 对交易信息编码成byte类型
   191  func FormatTxEncode(c *TuringchainConfig, execName string, tx *Transaction) ([]byte, error) {
   192  	tx, err := FormatTx(c, execName, tx)
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  	txbyte := Encode(tx)
   197  	return txbyte, nil
   198  }
   199  
   200  // LoadLog 加载log类型
   201  func LoadLog(execer []byte, ty int64) LogType {
   202  	loginfo := getLogType(execer, ty)
   203  	if loginfo.Name == "LogReserved" {
   204  		return nil
   205  	}
   206  	return newLogType(execer, ty)
   207  }
   208  
   209  // GetLogName 通过反射,解析日志
   210  func GetLogName(execer []byte, ty int64) string {
   211  	t := getLogType(execer, ty)
   212  	return t.Name
   213  }
   214  
   215  func getLogType(execer []byte, ty int64) *LogInfo {
   216  	//加载执行器已经定义的log
   217  	if execer != nil {
   218  		ety := LoadExecutorType(string(execer))
   219  		if ety != nil {
   220  			logmap := ety.GetLogMap()
   221  			if logty, ok := logmap[ty]; ok {
   222  				return logty
   223  			}
   224  		}
   225  	}
   226  	//如果没有,那么用系统默认类型列表
   227  	if logty, ok := SystemLog[ty]; ok {
   228  		return logty
   229  	}
   230  	//否则就是默认类型
   231  	return SystemLog[0]
   232  }
   233  
   234  // DecodeLog 解析log信息
   235  func DecodeLog(execer []byte, ty int64, data []byte) (interface{}, error) {
   236  	t := getLogType(execer, ty)
   237  	if t.Name == "LogErr" || t.Name == "LogReserved" {
   238  		msg := string(data)
   239  		return msg, nil
   240  	}
   241  	pdata := reflect.New(t.Ty)
   242  	if !pdata.CanInterface() {
   243  		return nil, ErrDecode
   244  	}
   245  	msg, ok := pdata.Interface().(Message)
   246  	if !ok {
   247  		return nil, ErrDecode
   248  	}
   249  	err := Decode(data, msg)
   250  	if err != nil {
   251  		return nil, err
   252  	}
   253  	return msg, nil
   254  }
   255  
   256  // ExecutorType  执行器接口
   257  type ExecutorType interface {
   258  	//获取交易真正的to addr
   259  	GetRealToAddr(tx *Transaction) string
   260  	GetCryptoDriver(ty int) (string, error)
   261  	GetCryptoType(name string) (int, error)
   262  	//给用户显示的from 和 to
   263  	GetViewFromToAddr(tx *Transaction) (string, string)
   264  	ActionName(tx *Transaction) string
   265  	//新版本使用create接口,createTx 重构以后就废弃
   266  	GetAction(action string) (Message, error)
   267  	InitFuncList(list map[string]reflect.Method)
   268  	Create(action string, message Message) (*Transaction, error)
   269  	CreateTx(action string, message json.RawMessage) (*Transaction, error)
   270  	CreateQuery(funcname string, message json.RawMessage) (Message, error)
   271  	AssertCreate(createTx *CreateTx) (*Transaction, error)
   272  	QueryToJSON(funcname string, message Message) ([]byte, error)
   273  	Amount(tx *Transaction) (int64, error)
   274  	DecodePayload(tx *Transaction) (Message, error)
   275  	DecodePayloadValue(tx *Transaction) (string, reflect.Value, error)
   276  	//write for executor
   277  	GetPayload() Message
   278  	GetChild() ExecutorType
   279  	GetName() string
   280  	//exec result of receipt log
   281  	GetLogMap() map[int64]*LogInfo
   282  	GetForks() *Forks
   283  	IsFork(height int64, key string) bool
   284  	//actionType -> name map
   285  	GetTypeMap() map[string]int32
   286  	GetValueTypeMap() map[string]reflect.Type
   287  	//action function list map
   288  	GetFuncMap() map[string]reflect.Method
   289  	GetRPCFuncMap() map[string]reflect.Method
   290  	GetExecFuncMap() map[string]reflect.Method
   291  	CreateTransaction(action string, data Message) (*Transaction, error)
   292  	// collect assets the tx deal with
   293  	GetAssets(tx *Transaction) ([]*Asset, error)
   294  
   295  	// about turingchainConfig
   296  	GetConfig() *TuringchainConfig
   297  	SetConfig(cfg *TuringchainConfig)
   298  }
   299  
   300  // ExecTypeGet  获取类型值
   301  type execTypeGet interface {
   302  	GetTy() int32
   303  }
   304  
   305  // ExecTypeBase  执行类型
   306  type ExecTypeBase struct {
   307  	child               ExecutorType
   308  	childValue          reflect.Value
   309  	actionFunList       map[string]reflect.Method
   310  	execFuncList        map[string]reflect.Method
   311  	actionListValueType map[string]reflect.Type
   312  	rpclist             map[string]reflect.Method
   313  	queryMap            map[string]reflect.Type
   314  	forks               *Forks
   315  	cfg                 *TuringchainConfig
   316  }
   317  
   318  // GetChild  获取子执行器
   319  func (base *ExecTypeBase) GetChild() ExecutorType {
   320  	return base.child
   321  }
   322  
   323  // SetChild  设置子执行器
   324  func (base *ExecTypeBase) SetChild(child ExecutorType) {
   325  	base.child = child
   326  	base.childValue = reflect.ValueOf(child)
   327  	base.rpclist = ListMethod(child)
   328  	base.actionListValueType = make(map[string]reflect.Type)
   329  	base.actionFunList = make(map[string]reflect.Method)
   330  	base.forks = child.GetForks()
   331  
   332  	action := child.GetPayload()
   333  	if action == nil {
   334  		return
   335  	}
   336  	base.actionFunList = ListMethod(action)
   337  	if _, ok := base.actionFunList["XXX_OneofWrappers"]; !ok {
   338  		return
   339  	}
   340  	retval := base.actionFunList["XXX_OneofWrappers"].Func.Call([]reflect.Value{reflect.ValueOf(action)})
   341  	if len(retval) != 1 {
   342  		panic("err XXX_OneofWrappers")
   343  	}
   344  	list := ListType(retval[0].Interface().([]interface{}))
   345  
   346  	for k, v := range list {
   347  		data := strings.Split(k, "_")
   348  		if len(data) != 2 {
   349  			panic("name create " + k)
   350  		}
   351  		base.actionListValueType["Value_"+data[1]] = v
   352  		field := v.Field(0)
   353  		base.actionListValueType[field.Name] = field.Type.Elem()
   354  		_, ok := v.FieldByName(data[1])
   355  		if !ok {
   356  			panic("no filed " + k)
   357  		}
   358  	}
   359  	//check type map is all in value type list
   360  	typelist := base.child.GetTypeMap()
   361  	for k := range typelist {
   362  		if _, ok := base.actionListValueType[k]; !ok {
   363  			panic("value type not found " + k)
   364  		}
   365  		if _, ok := base.actionListValueType["Value_"+k]; !ok {
   366  			panic("value type not found " + k)
   367  		}
   368  	}
   369  }
   370  
   371  // GetForks  获取fork信息
   372  func (base *ExecTypeBase) GetForks() *Forks {
   373  	return &Forks{}
   374  }
   375  
   376  // GetCryptoDriver  获取Crypto驱动
   377  func (base *ExecTypeBase) GetCryptoDriver(ty int) (string, error) {
   378  	return "", ErrNotSupport
   379  }
   380  
   381  // GetCryptoType  获取Crypto类型
   382  func (base *ExecTypeBase) GetCryptoType(name string) (int, error) {
   383  	return 0, ErrNotSupport
   384  }
   385  
   386  // InitFuncList  初始化函数列表
   387  func (base *ExecTypeBase) InitFuncList(list map[string]reflect.Method) {
   388  	base.execFuncList = list
   389  	actionList := base.GetFuncMap()
   390  	for k, v := range actionList {
   391  		base.execFuncList[k] = v
   392  	}
   393  	//查询所有的Query_ 接口, 做一个函数名称 和 类型的映射
   394  	_, base.queryMap = BuildQueryType("Query_", base.execFuncList)
   395  }
   396  
   397  // GetRPCFuncMap  获取rpc的接口列表
   398  func (base *ExecTypeBase) GetRPCFuncMap() map[string]reflect.Method {
   399  	return base.rpclist
   400  }
   401  
   402  // GetExecFuncMap  获取执行交易的接口列表
   403  func (base *ExecTypeBase) GetExecFuncMap() map[string]reflect.Method {
   404  	return base.execFuncList
   405  }
   406  
   407  // GetName  获取name
   408  func (base *ExecTypeBase) GetName() string {
   409  	return "typedriverbase"
   410  }
   411  
   412  // IsFork  是否fork高度
   413  func (base *ExecTypeBase) IsFork(height int64, key string) bool {
   414  	if base.GetForks() == nil {
   415  		return false
   416  	}
   417  	return base.forks.IsFork(height, key)
   418  }
   419  
   420  // GetValueTypeMap  获取执行函数
   421  func (base *ExecTypeBase) GetValueTypeMap() map[string]reflect.Type {
   422  	return base.actionListValueType
   423  }
   424  
   425  //GetRealToAddr 用户看到的ToAddr
   426  func (base *ExecTypeBase) GetRealToAddr(tx *Transaction) string {
   427  	if !base.cfg.IsPara() {
   428  		return tx.To
   429  	}
   430  	//平行链中的处理方式
   431  	_, v, err := base.child.DecodePayloadValue(tx)
   432  	if err != nil {
   433  		return tx.To
   434  	}
   435  	payload := v.Interface()
   436  	if to, ok := getTo(payload); ok {
   437  		return to
   438  	}
   439  	return tx.To
   440  }
   441  
   442  //三种assert的结构体,genesis 排除
   443  func getTo(payload interface{}) (string, bool) {
   444  	if ato, ok := payload.(*AssetsTransfer); ok {
   445  		return ato.GetTo(), true
   446  	}
   447  	if ato, ok := payload.(*AssetsWithdraw); ok {
   448  		return ato.GetTo(), true
   449  	}
   450  	if ato, ok := payload.(*AssetsTransferToExec); ok {
   451  		return ato.GetTo(), true
   452  	}
   453  	return "", false
   454  }
   455  
   456  //IsAssetsTransfer 是否是资产转移相关的交易
   457  func IsAssetsTransfer(payload interface{}) bool {
   458  	if _, ok := payload.(*AssetsTransfer); ok {
   459  		return true
   460  	}
   461  	if _, ok := payload.(*AssetsWithdraw); ok {
   462  		return true
   463  	}
   464  	if _, ok := payload.(*AssetsTransferToExec); ok {
   465  		return true
   466  	}
   467  	return false
   468  }
   469  
   470  //Amounter 转账金额
   471  type Amounter interface {
   472  	GetAmount() int64
   473  }
   474  
   475  //Amount 获取tx交易中的转账金额
   476  func (base *ExecTypeBase) Amount(tx *Transaction) (int64, error) {
   477  	_, v, err := base.child.DecodePayloadValue(tx)
   478  	if err != nil {
   479  		return 0, err
   480  	}
   481  	payload := v.Interface()
   482  	//四种assert的结构体
   483  	if ato, ok := payload.(Amounter); ok {
   484  		return ato.GetAmount(), nil
   485  	}
   486  	return 0, nil
   487  }
   488  
   489  //GetViewFromToAddr 用户看到的FromAddr
   490  func (base *ExecTypeBase) GetViewFromToAddr(tx *Transaction) (string, string) {
   491  	return tx.From(), tx.To
   492  }
   493  
   494  //GetFuncMap 获取函数列表
   495  func (base *ExecTypeBase) GetFuncMap() map[string]reflect.Method {
   496  	return base.actionFunList
   497  }
   498  
   499  //DecodePayload 解析tx交易中的payload
   500  func (base *ExecTypeBase) DecodePayload(tx *Transaction) (Message, error) {
   501  	if base.child == nil {
   502  		return nil, ErrActionNotSupport
   503  	}
   504  	payload := base.child.GetPayload()
   505  	if payload == nil {
   506  		return nil, ErrActionNotSupport
   507  	}
   508  	err := Decode(tx.GetPayload(), payload)
   509  	if err != nil {
   510  		return nil, err
   511  	}
   512  	return payload, nil
   513  }
   514  
   515  //DecodePayloadValue 解析tx交易中的payload具体Value值
   516  func (base *ExecTypeBase) DecodePayloadValue(tx *Transaction) (string, reflect.Value, error) {
   517  	name, value, err := base.decodePayloadValue(tx)
   518  	return name, value, err
   519  }
   520  
   521  func (base *ExecTypeBase) decodePayloadValue(tx *Transaction) (string, reflect.Value, error) {
   522  	if base.child == nil {
   523  		return "", nilValue, ErrActionNotSupport
   524  	}
   525  	action, err := base.child.DecodePayload(tx)
   526  	if err != nil || action == nil {
   527  		tlog.Error("DecodePayload", "err", err, "exec", string(tx.Execer))
   528  		return "", nilValue, err
   529  	}
   530  	name, ty, val, err := GetActionValue(action, base.child.GetFuncMap())
   531  	if err != nil {
   532  		return "", nilValue, err
   533  	}
   534  	typemap := base.child.GetTypeMap()
   535  	//check types is ok
   536  	if v, ok := typemap[name]; !ok || v != ty {
   537  		tlog.Error("GetTypeMap is not ok")
   538  		return "", nilValue, ErrActionNotSupport
   539  	}
   540  	return name, val, nil
   541  }
   542  
   543  //ActionName 获取交易中payload的action name
   544  func (base *ExecTypeBase) ActionName(tx *Transaction) string {
   545  	payload, err := base.child.DecodePayload(tx)
   546  	if err != nil {
   547  		return "unknown-err"
   548  	}
   549  	tm := base.child.GetTypeMap()
   550  	if get, ok := payload.(execTypeGet); ok {
   551  		ty := get.GetTy()
   552  		for k, v := range tm {
   553  			if v == ty {
   554  				return lowcaseFirst(k)
   555  			}
   556  		}
   557  	}
   558  	return "unknown"
   559  }
   560  
   561  func lowcaseFirst(v string) string {
   562  	if len(v) == 0 {
   563  		return ""
   564  	}
   565  	change := []rune(v)
   566  	if unicode.IsUpper(change[0]) {
   567  		change[0] = unicode.ToLower(change[0])
   568  		return string(change)
   569  	}
   570  	return v
   571  }
   572  
   573  //CreateQuery Query接口查询
   574  func (base *ExecTypeBase) CreateQuery(funcname string, message json.RawMessage) (Message, error) {
   575  	if _, ok := base.queryMap[funcname]; !ok {
   576  		return nil, ErrActionNotSupport
   577  	}
   578  	ty := base.queryMap[funcname]
   579  	p := reflect.New(ty.In(1).Elem())
   580  	queryin := p.Interface()
   581  	if in, ok := queryin.(proto.Message); ok {
   582  		data, err := message.MarshalJSON()
   583  		if err != nil {
   584  			return nil, err
   585  		}
   586  		err = JSONToPB(data, in)
   587  		if err != nil {
   588  			return nil, err
   589  		}
   590  		return in, nil
   591  	}
   592  	return nil, ErrActionNotSupport
   593  }
   594  
   595  //QueryToJSON 转换成json格式
   596  func (base *ExecTypeBase) QueryToJSON(funcname string, message Message) ([]byte, error) {
   597  	if _, ok := base.queryMap[funcname]; !ok {
   598  		return nil, ErrActionNotSupport
   599  	}
   600  	return PBToJSON(message)
   601  }
   602  
   603  func (base *ExecTypeBase) callRPC(method reflect.Method, action string, msg interface{}) (tx *Transaction, err error) {
   604  	valueret := method.Func.Call([]reflect.Value{base.childValue, reflect.ValueOf(action), reflect.ValueOf(msg)})
   605  	if len(valueret) != 2 {
   606  		return nil, ErrMethodNotFound
   607  	}
   608  	if !valueret[0].CanInterface() {
   609  		return nil, ErrMethodNotFound
   610  	}
   611  	if !valueret[1].CanInterface() {
   612  		return nil, ErrMethodNotFound
   613  	}
   614  	r1 := valueret[0].Interface()
   615  	if r1 != nil {
   616  		if r, ok := r1.(*Transaction); ok {
   617  			tx = r
   618  		} else {
   619  			return nil, ErrMethodReturnType
   620  		}
   621  	}
   622  	//参数2
   623  	r2 := valueret[1].Interface()
   624  	err = nil
   625  	if r2 != nil {
   626  		if r, ok := r2.(error); ok {
   627  			err = r
   628  		} else {
   629  			return nil, ErrMethodReturnType
   630  		}
   631  	}
   632  	if tx == nil && err == nil {
   633  		return nil, ErrActionNotSupport
   634  	}
   635  	return tx, err
   636  }
   637  
   638  //AssertCreate 构造assets资产交易
   639  func (base *ExecTypeBase) AssertCreate(c *CreateTx) (*Transaction, error) {
   640  	if c.ExecName != "" && !IsAllowExecName([]byte(c.ExecName), []byte(c.ExecName)) {
   641  		tlog.Error("CreateTx", "Error", ErrExecNameNotMatch)
   642  		return nil, ErrExecNameNotMatch
   643  	}
   644  	if c.Amount < 0 {
   645  		return nil, ErrAmount
   646  	}
   647  	if c.IsWithdraw {
   648  		p := &AssetsWithdraw{Cointoken: c.GetTokenSymbol(), Amount: c.Amount,
   649  			Note: c.Note, ExecName: c.ExecName, To: c.To}
   650  		return base.child.CreateTransaction("Withdraw", p)
   651  	}
   652  	if c.ExecName != "" {
   653  		v := &AssetsTransferToExec{Cointoken: c.GetTokenSymbol(), Amount: c.Amount,
   654  			Note: c.Note, ExecName: c.ExecName, To: c.To}
   655  		return base.child.CreateTransaction("TransferToExec", v)
   656  	}
   657  	v := &AssetsTransfer{Cointoken: c.GetTokenSymbol(), Amount: c.Amount, Note: c.GetNote(), To: c.To}
   658  	return base.child.CreateTransaction("Transfer", v)
   659  }
   660  
   661  //Create 构造tx交易
   662  func (base *ExecTypeBase) Create(action string, msg Message) (*Transaction, error) {
   663  	//先判断 FuncList 中有没有符合要求的函数 RPC_{action}
   664  	if msg == nil {
   665  		return nil, ErrInvalidParam
   666  	}
   667  	if action == "" {
   668  		action = "Default_Process"
   669  	}
   670  	funclist := base.GetRPCFuncMap()
   671  	if method, ok := funclist["RPC_"+action]; ok {
   672  		return base.callRPC(method, action, msg)
   673  	}
   674  	if _, ok := msg.(Message); !ok {
   675  		return nil, ErrInvalidParam
   676  	}
   677  	typemap := base.child.GetTypeMap()
   678  	if _, ok := typemap[action]; ok {
   679  		ty1 := base.actionListValueType[action]
   680  		ty2 := reflect.TypeOf(msg).Elem()
   681  		if ty1 != ty2 {
   682  			return nil, ErrInvalidParam
   683  		}
   684  		return base.CreateTransaction(action, msg.(Message))
   685  	}
   686  	tlog.Error(action + " ErrActionNotSupport")
   687  	return nil, ErrActionNotSupport
   688  }
   689  
   690  //GetAction 获取action
   691  func (base *ExecTypeBase) GetAction(action string) (Message, error) {
   692  	typemap := base.child.GetTypeMap()
   693  	if _, ok := typemap[action]; ok {
   694  		tyvalue := reflect.New(base.actionListValueType[action])
   695  		if !tyvalue.CanInterface() {
   696  			tlog.Error(action + " tyvalue.CanInterface error")
   697  			return nil, ErrActionNotSupport
   698  		}
   699  		data, ok := tyvalue.Interface().(Message)
   700  		if !ok {
   701  			tlog.Error(action + " tyvalue is not Message")
   702  			return nil, ErrActionNotSupport
   703  		}
   704  		return data, nil
   705  	}
   706  	tlog.Error(action + " ErrActionNotSupport")
   707  	return nil, ErrActionNotSupport
   708  }
   709  
   710  //CreateTx 通过json rpc 创建交易
   711  func (base *ExecTypeBase) CreateTx(action string, msg json.RawMessage) (*Transaction, error) {
   712  	data, err := base.GetAction(action)
   713  	if err != nil {
   714  		return nil, err
   715  	}
   716  	b, err := msg.MarshalJSON()
   717  	if err != nil {
   718  		tlog.Error(action + " MarshalJSON  error")
   719  		return nil, err
   720  	}
   721  	err = JSONToPB(b, data)
   722  	if err != nil {
   723  		tlog.Error(action + " jsontopb  error")
   724  		return nil, err
   725  	}
   726  	return base.CreateTransaction(action, data)
   727  }
   728  
   729  //CreateTransaction 构造Transaction
   730  func (base *ExecTypeBase) CreateTransaction(action string, data Message) (tx *Transaction, err error) {
   731  	defer func() {
   732  		if e := recover(); e != nil {
   733  			err = ErrActionNotSupport
   734  		}
   735  	}()
   736  	value := base.child.GetPayload()
   737  	v := reflect.New(base.actionListValueType["Value_"+action])
   738  	vn := reflect.Indirect(v)
   739  	if vn.Kind() != reflect.Struct {
   740  		tlog.Error("CreateTransaction vn not struct kind", "exectutor", base.child.GetName(), "action", action)
   741  		return nil, ErrActionNotSupport
   742  	}
   743  	field := vn.FieldByName(action)
   744  	if !field.IsValid() || !field.CanSet() {
   745  		tlog.Error("CreateTransaction vn filed can't set", "exectutor", base.child.GetName(), "action", action)
   746  		return nil, ErrActionNotSupport
   747  	}
   748  	field.Set(reflect.ValueOf(data))
   749  	value2 := reflect.Indirect(reflect.ValueOf(value))
   750  	if value2.Kind() != reflect.Struct {
   751  		tlog.Error("CreateTransaction value2 not struct kind", "exectutor", base.child.GetName(), "action", action)
   752  		return nil, ErrActionNotSupport
   753  	}
   754  	field = value2.FieldByName("Value")
   755  	if !field.IsValid() || !field.CanSet() {
   756  		tlog.Error("CreateTransaction value filed can't set", "exectutor", base.child.GetName(), "action", action)
   757  		return nil, ErrActionNotSupport
   758  	}
   759  	field.Set(v)
   760  
   761  	field = value2.FieldByName("Ty")
   762  	if !field.IsValid() || !field.CanSet() {
   763  		tlog.Error("CreateTransaction ty filed can't set", "exectutor", base.child.GetName(), "action", action)
   764  		return nil, ErrActionNotSupport
   765  	}
   766  	tymap := base.child.GetTypeMap()
   767  	if tyid, ok := tymap[action]; ok {
   768  		field.Set(reflect.ValueOf(tyid))
   769  		tx := &Transaction{
   770  			Payload: Encode(value),
   771  		}
   772  		return tx, nil
   773  	}
   774  	return nil, ErrActionNotSupport
   775  }
   776  
   777  // GetAssets 获取资产信息
   778  func (base *ExecTypeBase) GetAssets(tx *Transaction) ([]*Asset, error) {
   779  	_, v, err := base.child.DecodePayloadValue(tx)
   780  	if err != nil {
   781  		return nil, err
   782  	}
   783  	payload := v.Interface()
   784  	asset := &Asset{Exec: string(tx.Execer)}
   785  	if a, ok := payload.(*AssetsTransfer); ok {
   786  		asset.Symbol = a.Cointoken
   787  	} else if a, ok := payload.(*AssetsWithdraw); ok {
   788  		asset.Symbol = a.Cointoken
   789  	} else if a, ok := payload.(*AssetsTransferToExec); ok {
   790  		asset.Symbol = a.Cointoken
   791  	} else {
   792  		return nil, nil
   793  	}
   794  	amount, err := tx.Amount()
   795  	if err != nil {
   796  		return nil, nil
   797  	}
   798  	asset.Amount = amount
   799  	return []*Asset{asset}, nil
   800  }
   801  
   802  //GetConfig ...
   803  func (base *ExecTypeBase) GetConfig() *TuringchainConfig {
   804  	return base.cfg
   805  }
   806  
   807  //SetConfig ...
   808  func (base *ExecTypeBase) SetConfig(cfg *TuringchainConfig) {
   809  	base.cfg = cfg
   810  }