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 }