github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/pkg/stafidecoder/types.go (about) 1 package stafi_decoder 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "io" 8 "math" 9 "math/big" 10 "regexp" 11 "strconv" 12 "strings" 13 "unicode/utf8" 14 15 "github.com/huandu/xstrings" 16 "github.com/itering/scale.go/utiles" 17 "github.com/itering/scale.go/utiles/crypto/ethereum" 18 "github.com/itering/scale.go/utiles/uint128" 19 "github.com/shopspring/decimal" 20 commonTypes "github.com/stafiprotocol/go-substrate-rpc-client/types/common" 21 ) 22 23 type HexBytes struct { 24 ScaleDecoder 25 } 26 27 func (h *HexBytes) Process() { 28 length := h.ProcessAndUpdateData("Compact<u32>").(int) 29 h.Value = utiles.AddHex(utiles.BytesToHex(h.NextBytes(int(length)))) 30 } 31 32 type U8 struct { 33 ScaleDecoder 34 } 35 36 func (u *U8) Process() { 37 u.Value = u.GetNextU8() 38 } 39 40 type U16 struct { 41 Reader io.Reader 42 ScaleDecoder 43 } 44 45 func (u *U16) Process() { 46 buf := &bytes.Buffer{} 47 u.Reader = buf 48 _, _ = buf.Write(u.NextBytes(2)) 49 c := make([]byte, 2) 50 _, _ = u.Reader.Read(c) 51 u.Value = binary.LittleEndian.Uint16(c) 52 } 53 54 type U32 struct { 55 Reader io.Reader 56 ScaleDecoder 57 } 58 59 func (u *U32) Process() { 60 buf := &bytes.Buffer{} 61 u.Reader = buf 62 _, _ = buf.Write(u.NextBytes(4)) 63 c := make([]byte, 4) 64 _, _ = u.Reader.Read(c) 65 u.Value = binary.LittleEndian.Uint32(c) 66 } 67 68 func (u *U32) Encode(value int) { 69 bs := make([]byte, 4) 70 binary.LittleEndian.PutUint32(bs, uint32(value)) 71 u.Data = ScaleBytes{Data: bs} 72 } 73 74 type U64 struct { 75 ScaleDecoder 76 Reader io.Reader 77 } 78 79 func (u *U64) Process() { 80 buf := &bytes.Buffer{} 81 u.Reader = buf 82 _, _ = buf.Write(u.NextBytes(8)) 83 c := make([]byte, 8) 84 _, _ = u.Reader.Read(c) 85 u.Value = binary.LittleEndian.Uint64(c) 86 } 87 88 type U128 struct { 89 ScaleDecoder 90 } 91 92 func (u *U128) Process() { 93 elementBytes := u.NextBytes(16) 94 if len(elementBytes) < 16 { 95 elementBytes = utiles.HexToBytes(xstrings.LeftJustify(utiles.BytesToHex(elementBytes), 32, "0")) 96 } 97 u.Value = uint128.FromBytes(elementBytes).String() 98 } 99 100 type H256 struct { 101 ScaleDecoder 102 } 103 104 func (h *H256) Process() { 105 h.Value = utiles.AddHex(utiles.BytesToHex(h.NextBytes(32))) 106 } 107 108 type H512 struct { 109 ScaleDecoder 110 } 111 112 func (h *H512) Process() { 113 h.Value = utiles.AddHex(utiles.BytesToHex(h.NextBytes(64))) 114 } 115 116 type Era struct { 117 ScaleDecoder 118 } 119 120 func (e *Era) Process() { 121 optionHex := utiles.BytesToHex(e.NextBytes(1)) 122 if optionHex == "00" { 123 e.Value = optionHex 124 } else { 125 e.Value = optionHex + utiles.BytesToHex(e.NextBytes(1)) 126 } 127 } 128 129 type EraExtrinsic struct { 130 ScaleDecoder 131 } 132 133 func (e *EraExtrinsic) Process() { 134 optionHex := utiles.BytesToHex(e.NextBytes(1)) 135 if optionHex == "00" { 136 e.Value = optionHex 137 } else { 138 e.Value = optionHex + utiles.BytesToHex(e.NextBytes(1)) 139 } 140 } 141 142 type Bool struct { 143 ScaleDecoder 144 } 145 146 func (b *Bool) Process() { 147 b.Value = b.getNextBool() 148 } 149 150 type Moment struct { 151 CompactU32 152 } 153 154 func (m *Moment) Init(data ScaleBytes, option *ScaleDecoderOption) { 155 m.TypeString = "Compact<Moment>" 156 m.ScaleDecoder.Init(data, option) 157 } 158 159 func (m *Moment) Process() { 160 m.CompactU32.Process() 161 if m.Value.(int) > 10000000000 { 162 m.Value = m.Value.(int) / 1000 163 } 164 } 165 166 type Struct struct { 167 ScaleDecoder 168 } 169 170 func (s *Struct) Process() { 171 result := make(map[string]interface{}) 172 if s.TypeMapping != nil { 173 for k, v := range s.TypeMapping.Names { 174 result[v] = s.ProcessAndUpdateData(s.TypeMapping.Types[k]) 175 } 176 } 177 s.Value = result 178 } 179 180 type BlockNumber struct { 181 U32 182 } 183 184 type Vec struct { 185 ScaleDecoder 186 } 187 188 func (v *Vec) Init(data ScaleBytes, option *ScaleDecoderOption) { 189 if v.SubType != "" && option != nil { 190 option.SubType = v.SubType 191 } 192 v.ScaleDecoder.Init(data, option) 193 } 194 195 func (v *Vec) Process() { 196 elementCount := v.ProcessAndUpdateData("Compact<u32>").(int) 197 var result []interface{} 198 if elementCount > 20000 { 199 panic(fmt.Sprintf("Vec length %d exceeds %d", elementCount, 1000)) 200 } 201 for i := 0; i < elementCount; i++ { 202 element := v.ProcessAndUpdateData(v.SubType) 203 result = append(result, element) 204 } 205 v.Value = result 206 } 207 208 type Address struct { 209 ScaleDecoder 210 AccountLength string `json:"account_length"` 211 } 212 213 // only support latest address type 214 func (a *Address) Process() { 215 AccountLength := a.NextBytes(1) 216 a.AccountLength = utiles.BytesToHex(AccountLength) 217 if a.AccountLength == "ff" { 218 a.Value = utiles.BytesToHex(a.NextBytes(32)) 219 return 220 } 221 a.Value = utiles.BytesToHex(append(AccountLength, a.NextBytes(31)...)) 222 } 223 224 type GenericAddress struct { 225 ScaleDecoder 226 AccountLength string `json:"account_length"` 227 } 228 229 func (a *GenericAddress) Process() { 230 AccountLength := a.NextBytes(1) 231 a.AccountLength = utiles.BytesToHex(AccountLength) 232 if a.AccountLength == "ff" { 233 a.Value = utiles.BytesToHex(a.NextBytes(32)) 234 return 235 } 236 switch a.AccountLength { 237 case "fc": 238 a.NextBytes(2) 239 case "fd": 240 a.NextBytes(4) 241 case "fe": 242 a.NextBytes(8) 243 default: 244 a.Value = utiles.BytesToHex(append(AccountLength, a.NextBytes(31)...)) 245 } 246 } 247 248 type Signature struct { 249 ScaleDecoder 250 } 251 252 func (s *Signature) Process() { 253 s.Value = utiles.BytesToHex(s.NextBytes(64)) 254 } 255 256 type Enum struct { 257 ScaleDecoder 258 ValueList []string `json:"value_list"` 259 Index int `json:"index"` 260 } 261 262 func (e *Enum) Init(data ScaleBytes, option *ScaleDecoderOption) { 263 e.Index = 0 264 if option != nil && len(e.ValueList) == 0 { 265 e.ValueList = option.ValueList 266 } 267 e.ScaleDecoder.Init(data, option) 268 } 269 270 func (e *Enum) Process() { 271 index := utiles.BytesToHex(e.NextBytes(1)) 272 if utiles.U256(index) != nil { 273 e.Index = int(utiles.U256(index).Uint64()) 274 } 275 if e.TypeMapping != nil { 276 // check c-like enum 277 isCLikeEnum := true 278 for _, subType := range e.TypeMapping.Types { 279 if !regexp.MustCompile("^[0-9]+$").MatchString(subType) { 280 isCLikeEnum = false 281 break 282 } 283 } 284 rustEnum := make(map[int]string) 285 if isCLikeEnum { 286 for index, v := range e.TypeMapping.Names { 287 rustEnum[utiles.StringToInt(e.TypeMapping.Types[index])] = v 288 } 289 e.Value = rustEnum[e.Index] 290 return 291 } 292 if subType := e.TypeMapping.Types[e.Index]; subType != "" { 293 e.Value = map[string]interface{}{e.TypeMapping.Names[e.Index]: e.ProcessAndUpdateData(subType)} 294 return 295 } 296 } 297 if e.ValueList[e.Index] != "" { 298 e.Value = e.ValueList[e.Index] 299 } 300 } 301 302 type StorageHasher struct { 303 Enum 304 } 305 306 func (s *StorageHasher) Init(data ScaleBytes, option *ScaleDecoderOption) { 307 option.ValueList = []string{"Blake2_128", "Blake2_256", "Blake2_128Concat", "Twox128", "Twox256", "Twox64Concat", "Identity"} 308 s.Enum.Init(data, option) 309 } 310 311 type Null struct { 312 ScaleDecoder 313 } 314 315 type VecU8FixedLength struct { 316 ScaleDecoder 317 FixedLength int 318 } 319 320 func (s *VecU8FixedLength) Process() { 321 s.Value = utiles.AddHex(utiles.BytesToHex(s.NextBytes(s.FixedLength))) 322 } 323 324 type AccountId struct { 325 ScaleDecoder 326 } 327 328 func (s *AccountId) Process() { 329 s.Value = xstrings.RightJustify(utiles.BytesToHex(s.NextBytes(32)), 64, "0") 330 } 331 332 type BoxProposal struct { 333 ScaleDecoder 334 } 335 336 func (s *BoxProposal) Process() { 337 callIndex := utiles.BytesToHex(s.NextBytes(2)) 338 callModule := s.Metadata.CallIndex[callIndex] 339 result := map[string]interface{}{ 340 "call_index": callIndex, 341 "call_name": callModule.Call.Name, 342 "call_module": callModule.Module.Name, 343 } 344 var param []commonTypes.ExtrinsicParam 345 for _, arg := range callModule.Call.Args { 346 param = append(param, commonTypes.ExtrinsicParam{ 347 Name: arg.Name, 348 Type: arg.Type, 349 Value: s.ProcessAndUpdateData(arg.Type), 350 }) 351 } 352 result["params"] = param 353 s.Value = result 354 } 355 356 type Balance struct { 357 ScaleDecoder 358 Reader io.Reader 359 } 360 361 func (b *Balance) Process() { 362 buf := &bytes.Buffer{} 363 b.Reader = buf 364 _, _ = buf.Write(b.NextBytes(16)) 365 c := make([]byte, 16) 366 _, _ = b.Reader.Read(c) 367 if utiles.BytesToHex(c) == "ffffffffffffffffffffffffffffffff" { 368 b.Value = decimal.Zero 369 return 370 } 371 b.Value = decimal.NewFromBigInt(uint128.FromBytes(c).Big(), 0) 372 } 373 374 type Index struct{ U64 } 375 376 type SessionIndex struct{ U32 } 377 378 type EraIndex struct{ U32 } 379 380 type ParaId struct{ U32 } 381 382 type Set struct { 383 ScaleDecoder 384 SetValue int 385 ValueList []string 386 BitLength int 387 } 388 389 func (s *Set) Init(data ScaleBytes, option *ScaleDecoderOption) { 390 s.SetValue = 0 391 if option.ValueList != nil { 392 s.ValueList = option.ValueList 393 } 394 s.ScaleDecoder.Init(data, option) 395 } 396 397 func (s *Set) Process() { 398 setValue := s.ProcessAndUpdateData(fmt.Sprintf("U%d", s.BitLength)) 399 switch v := setValue.(type) { 400 case uint64: 401 s.SetValue = int(v) 402 case uint8: 403 s.SetValue = int(v) 404 case uint32: 405 s.SetValue = int(v) 406 case uint16: 407 s.SetValue = int(v) 408 } 409 var result []string 410 if s.SetValue > 0 { 411 for k, value := range s.ValueList { 412 if s.SetValue&int(math.Pow(2, float64(k))) > 0 { 413 result = append(result, value) 414 } 415 } 416 } 417 s.Value = result 418 } 419 420 type LogDigest struct{ Enum } 421 422 func (l *LogDigest) Init(data ScaleBytes, option *ScaleDecoderOption) { 423 l.ValueList = []string{"Other", "AuthoritiesChange", "ChangesTrieRoot", "SealV0", "Consensus", "Seal", "PreRuntime"} 424 l.Enum.Init(data, option) 425 } 426 427 func (l *LogDigest) Process() { 428 index := utiles.BytesToHex(l.NextBytes(1)) 429 if utiles.U256(index) != nil { 430 l.Index = int(utiles.U256(index).Uint64()) 431 } 432 indexType := l.ValueList[l.Index] 433 if indexType == "" { 434 panic(fmt.Sprintf("LogDigest index %d not in list", l.Index)) 435 } 436 l.Value = map[string]interface{}{ 437 "type": indexType, 438 "value": l.ProcessAndUpdateData(indexType), 439 } 440 } 441 442 type Other struct{ HexBytes } 443 444 type ChangesTrieRoot struct{ HexBytes } 445 446 type AuthoritiesChange struct{ Vec } 447 448 func (l *AuthoritiesChange) Init(data ScaleBytes, option *ScaleDecoderOption) { 449 option.SubType = "AccountId" 450 l.Vec.Init(data, option) 451 } 452 453 type SealV0 struct{ Struct } 454 455 func (s *SealV0) Init(data ScaleBytes, option *ScaleDecoderOption) { 456 s.Struct.TypeMapping = &TypeMapping{Names: []string{"slot", "signature"}, Types: []string{"u64", "Signature"}} 457 s.Struct.Init(data, option) 458 } 459 460 type Consensus struct{ Struct } 461 462 func (s *Consensus) Init(data ScaleBytes, option *ScaleDecoderOption) { 463 s.Struct.TypeMapping = &TypeMapping{Names: []string{"engine", "data"}, Types: []string{"u32", "Vec<u8>"}} 464 s.Struct.Init(data, option) 465 } 466 467 type Seal struct{ Struct } 468 469 func (s *Seal) Init(data ScaleBytes, option *ScaleDecoderOption) { 470 s.Struct.TypeMapping = &TypeMapping{Names: []string{"engine", "data"}, Types: []string{"u32", "HexBytes"}} 471 s.Struct.Init(data, option) 472 } 473 474 type PreRuntime struct{ Struct } 475 476 func (s *PreRuntime) Init(data ScaleBytes, option *ScaleDecoderOption) { 477 s.Struct.TypeMapping = &TypeMapping{Names: []string{"engine", "data"}, Types: []string{"u32", "HexBytes"}} 478 s.Struct.Init(data, option) 479 } 480 481 type Exposure struct{ Struct } 482 483 func (s *Exposure) Init(data ScaleBytes, option *ScaleDecoderOption) { 484 s.Struct.TypeMapping = &TypeMapping{Names: []string{"total", "own", "others"}, Types: []string{"Compact<Balance>", "Compact<Balance>", "Vec<IndividualExposure<AccountId, Balance>>"}} 485 s.Struct.Init(data, option) 486 } 487 488 type IndividualExposure struct{ Struct } 489 490 func (s *IndividualExposure) Init(data ScaleBytes, option *ScaleDecoderOption) { 491 s.Struct.TypeMapping = &TypeMapping{Names: []string{"who", "value"}, Types: []string{"AccountId", "Compact<Balance>"}} 492 s.Struct.Init(data, option) 493 } 494 495 type RawAuraPreDigest struct{ Struct } 496 497 func (s *RawAuraPreDigest) Init(data ScaleBytes, option *ScaleDecoderOption) { 498 s.Struct.TypeMapping = &TypeMapping{Names: []string{"slotNumber"}, Types: []string{"u64"}} 499 s.Struct.Init(data, option) 500 } 501 502 type RawBabePreDigest struct { 503 Struct 504 } 505 506 func (r *RawBabePreDigest) Init(data ScaleBytes, option *ScaleDecoderOption) { 507 r.Struct.TypeMapping = &TypeMapping{Names: []string{"isPhantom", "Primary", "Secondary", "VRF"}, Types: []string{"bool", "RawBabePreDigestPrimary", "RawBabePreDigestSecondary", "RawBabePreDigestSecondaryVRF"}} 508 r.Struct.Init(data, option) 509 } 510 511 func (r *RawBabePreDigest) Process() { 512 label := r.ProcessAndUpdateData("RawBabeLabel").(string) 513 for k, name := range r.Struct.TypeMapping.Names { 514 if name == label { 515 r.Value = map[string]interface{}{label: r.ProcessAndUpdateData(r.TypeMapping.Types[k])} 516 break 517 } 518 } 519 } 520 521 type RawBabeLabel struct { 522 Enum 523 } 524 525 func (s *RawBabeLabel) Init(data ScaleBytes, option *ScaleDecoderOption) { 526 option.ValueList = []string{"isPhantom", "Primary", "Secondary", "VRF"} 527 s.Enum.Init(data, option) 528 } 529 530 type RawBabePreDigestPrimary struct{ Struct } 531 532 type RawBabePreDigestSecondary struct{ Struct } 533 534 type SlotNumber struct{ U64 } 535 536 type BabeBlockWeight struct{ U32 } 537 538 func (r *RawBabePreDigestPrimary) Init(data ScaleBytes, option *ScaleDecoderOption) { 539 r.Struct.TypeMapping = &TypeMapping{ 540 Names: []string{"authorityIndex", "slotNumber", "weight", "vrfOutput", "vrfProof"}, 541 Types: []string{"u32", "SlotNumber", "BabeBlockWeight", "H256", "H256"}, 542 } 543 r.Struct.Init(data, option) 544 } 545 546 func (r *RawBabePreDigestSecondary) Init(data ScaleBytes, option *ScaleDecoderOption) { 547 r.Struct.TypeMapping = &TypeMapping{Names: []string{"authorityIndex", "slotNumber", "weight"}, Types: []string{"u32", "SlotNumber", "BabeBlockWeight"}} 548 r.Struct.Init(data, option) 549 } 550 551 type RawBabePreDigestSecondaryVRF struct{ Struct } 552 553 func (r *RawBabePreDigestSecondaryVRF) Init(data ScaleBytes, option *ScaleDecoderOption) { 554 r.Struct.TypeMapping = &TypeMapping{Names: []string{"authorityIndex", "slotNumber", "vrfOutput", "vrfProof"}, Types: []string{"u32", "SlotNumber", "VrfData", "VrfProof"}} 555 r.Struct.Init(data, option) 556 } 557 558 type LockIdentifier struct { 559 ScaleDecoder 560 } 561 562 func (l *LockIdentifier) Process() { 563 l.Value = utiles.AddHex(utiles.BytesToHex(l.NextBytes(8))) 564 } 565 566 type AccountIndex struct{ U32 } 567 568 type FixedLengthArray struct { 569 ScaleDecoder 570 FixedLength int 571 SubType string 572 } 573 574 func (f *FixedLengthArray) Init(data ScaleBytes, option *ScaleDecoderOption) { 575 if option != nil && option.FixedLength != 0 { 576 f.FixedLength = option.FixedLength 577 } 578 f.ScaleDecoder.Init(data, option) 579 } 580 581 func (f *FixedLengthArray) Process() { 582 var result []interface{} 583 if f.FixedLength > 0 { 584 for i := 0; i < f.FixedLength; i++ { 585 result = append(result, f.ProcessAndUpdateData(f.SubType)) 586 } 587 } else { 588 f.GetNextU8() 589 } 590 f.Value = result 591 } 592 593 type AuthorityId struct{ H256 } 594 595 type EcdsaSignature struct { 596 ScaleDecoder 597 } 598 599 func (e *EcdsaSignature) Process() { 600 e.Value = utiles.AddHex(utiles.BytesToHex(e.NextBytes(65))) 601 } 602 603 type Call struct { 604 ScaleDecoder 605 } 606 607 func (s *Call) Process() { 608 callIndex := utiles.BytesToHex(s.NextBytes(2)) 609 callModule := s.Metadata.CallIndex[callIndex] 610 result := map[string]interface{}{ 611 "call_index": callIndex, 612 "call_name": callModule.Call.Name, 613 "call_module": callModule.Module.Name, 614 } 615 var param []commonTypes.ExtrinsicParam 616 for _, arg := range callModule.Call.Args { 617 param = append(param, commonTypes.ExtrinsicParam{ 618 Name: arg.Name, 619 Type: arg.Type, 620 Value: s.ProcessAndUpdateData(arg.Type), 621 }) 622 } 623 result["params"] = param 624 s.Value = result 625 626 } 627 628 type ReferendumIndex struct{ U32 } 629 630 type PropIndex struct{ U32 } 631 632 type EthereumAddress struct { 633 ScaleDecoder 634 } 635 636 func (e *EthereumAddress) Process() { 637 e.Value = ethereum.Encode(utiles.BytesToHex(e.NextBytes(20))) 638 } 639 640 type Data struct { 641 Enum 642 } 643 644 func (d *Data) Init(data ScaleBytes, option *ScaleDecoderOption) { 645 d.TypeMapping = &TypeMapping{ 646 Names: []string{"None", "Raw", "BlakeTwo256", "Sha256", "Keccak256", "ShaThree256"}, 647 Types: []string{"Null", "String", "H256", "H256", "H256", "H256"}, 648 } 649 d.Enum.Init(data, option) 650 } 651 652 func (d *Data) Process() { 653 c := utiles.BytesToHex(d.NextBytes(1)) 654 if c == "" || utiles.U256(c).Uint64() == 0 { 655 d.Value = map[string]interface{}{"None": nil} 656 return 657 } 658 659 d.Index = int(utiles.U256(c).Uint64()) 660 661 if d.Index >= 1 && d.Index <= 33 { 662 data := d.NextBytes(d.Index - 1) 663 if utf8.Valid(data) { 664 d.Value = map[string]interface{}{"Raw": string(data)} 665 } else { 666 d.Value = map[string]interface{}{"Raw": utiles.BytesToHex(data)} 667 } 668 669 } 670 if d.Index >= 34 && d.Index <= 37 { 671 enumKey := d.TypeMapping.Names[d.Index-32] 672 d.Value = map[string]interface{}{enumKey: d.ProcessAndUpdateData(d.TypeMapping.Types[d.Index-32])} 673 } 674 } 675 676 type Vote struct { 677 U8 678 } 679 680 type VoteOutcome struct { 681 ScaleDecoder 682 } 683 684 func (v *VoteOutcome) Process() { 685 v.Value = utiles.BytesToHex(v.NextBytes(32)) 686 } 687 688 type H160 struct{ ScaleDecoder } 689 690 func (h *H160) Process() { 691 h.Value = utiles.AddHex(utiles.BytesToHex(h.NextBytes(20))) 692 } 693 694 type IntFixed struct { 695 ScaleDecoder 696 FixedLength int 697 Reader io.Reader 698 } 699 700 func (f *IntFixed) Init(data ScaleBytes, option *ScaleDecoderOption) { 701 if option != nil && option.FixedLength != 0 { 702 f.FixedLength = option.FixedLength 703 } 704 f.ScaleDecoder.Init(data, option) 705 } 706 707 func (f *IntFixed) Process() { 708 value := utiles.U256(utiles.BytesToHex(utiles.ReverseBytes(f.NextBytes(f.FixedLength)))) 709 var i, e, b = big.NewInt(2), big.NewInt(int64(f.FixedLength*8) - 1), big.NewInt(int64(f.FixedLength * 8)) 710 unsignedMid := big.NewInt(2).Exp(i, e, nil) 711 ceiling := big.NewInt(2).Exp(i, b, nil) 712 if value.Cmp(unsignedMid) > 0 { 713 f.Value = value.Sub(value, ceiling) 714 return 715 } 716 f.Value = value 717 } 718 719 type Key struct{ Bytes } 720 721 type OpaqueCall struct { 722 Bytes 723 } 724 725 func (f *OpaqueCall) Process() { 726 f.Bytes.Process() 727 e := ScaleDecoder{} 728 option := ScaleDecoderOption{Metadata: f.Metadata, Spec: f.Spec} 729 e.Init(ScaleBytes{Data: utiles.HexToBytes(f.Value.(string))}, &option) 730 value := e.ProcessAndUpdateData("Call") 731 f.Value = value 732 } 733 734 type GenericLookupSource struct { 735 ScaleDecoder 736 } 737 738 func (g *GenericLookupSource) Process() { 739 if len(g.Data.Data) == 32 { 740 g.Value = utiles.BytesToHex(g.NextBytes(32)) 741 } 742 AccountLength := g.NextBytes(1) 743 accountLength := utiles.BytesToHex(AccountLength) 744 if accountLength == "ff" { 745 g.Value = utiles.BytesToHex(g.NextBytes(32)) 746 return 747 } 748 offset, length := readLength(AccountLength) 749 e := ScaleDecoder{} 750 e.Init(ScaleBytes{Data: g.Data.Data[offset : offset+length]}, nil) 751 g.Value = strconv.Itoa(int(e.ProcessAndUpdateData("U32").(uint32))) 752 } 753 754 func readLength(value []byte) (int, int) { 755 first := value[0] 756 switch first { 757 case 0xfc: 758 return 1, 2 759 case 0xfd: 760 return 1, 4 761 case 0xfe: 762 return 1, 8 763 } 764 return 0, 1 765 } 766 767 type BTreeMap struct{ ScaleDecoder } 768 769 func (b *BTreeMap) Process() { 770 elementCount := b.ProcessAndUpdateData("Compact<u32>").(int) 771 var result []interface{} 772 if elementCount > 1000 { 773 panic(fmt.Sprintf("BTreeMap length %d exceeds %d", elementCount, 1000)) 774 } 775 for i := 0; i < elementCount; i++ { 776 subType := strings.Split(b.SubType, ",") 777 key := utiles.ToString(b.ProcessAndUpdateData(subType[0])) 778 result = append(result, map[string]interface{}{ 779 key: b.ProcessAndUpdateData(subType[1]), 780 }) 781 } 782 b.Value = result 783 }