github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/state/oracle.go (about) 1 package state 2 3 import ( 4 "errors" 5 "math/big" 6 "unicode/utf8" 7 8 "github.com/nspcc-dev/neo-go/pkg/util" 9 "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" 10 ) 11 12 // OracleRequest represents an oracle request. 13 type OracleRequest struct { 14 OriginalTxID util.Uint256 15 GasForResponse uint64 16 URL string 17 Filter *string 18 CallbackContract util.Uint160 19 CallbackMethod string 20 UserData []byte 21 } 22 23 // ToStackItem implements stackitem.Convertible interface. It never returns an 24 // error. 25 func (o *OracleRequest) ToStackItem() (stackitem.Item, error) { 26 filter := stackitem.Item(stackitem.Null{}) 27 if o.Filter != nil { 28 filter = stackitem.Make(*o.Filter) 29 } 30 return stackitem.NewArray([]stackitem.Item{ 31 stackitem.NewByteArray(o.OriginalTxID.BytesBE()), 32 stackitem.NewBigInteger(new(big.Int).SetUint64(o.GasForResponse)), 33 stackitem.Make(o.URL), 34 filter, 35 stackitem.NewByteArray(o.CallbackContract.BytesBE()), 36 stackitem.Make(o.CallbackMethod), 37 stackitem.NewByteArray(o.UserData), 38 }), nil 39 } 40 41 // FromStackItem implements stackitem.Convertible interface. 42 func (o *OracleRequest) FromStackItem(it stackitem.Item) error { 43 arr, ok := it.Value().([]stackitem.Item) 44 if !ok || len(arr) < 7 { 45 return errors.New("not an array of needed length") 46 } 47 bs, err := arr[0].TryBytes() 48 if err != nil { 49 return err 50 } 51 o.OriginalTxID, err = util.Uint256DecodeBytesBE(bs) 52 if err != nil { 53 return err 54 } 55 56 gas, err := arr[1].TryInteger() 57 if err != nil { 58 return err 59 } 60 o.GasForResponse = gas.Uint64() 61 62 s, isNull, ok := itemToString(arr[2]) 63 if !ok || isNull { 64 return errors.New("invalid URL") 65 } 66 o.URL = s 67 68 s, isNull, ok = itemToString(arr[3]) 69 if !ok { 70 return errors.New("invalid filter") 71 } else if !isNull { 72 filter := s 73 o.Filter = &filter 74 } 75 76 bs, err = arr[4].TryBytes() 77 if err != nil { 78 return err 79 } 80 o.CallbackContract, err = util.Uint160DecodeBytesBE(bs) 81 if err != nil { 82 return err 83 } 84 85 o.CallbackMethod, isNull, ok = itemToString(arr[5]) 86 if !ok || isNull { 87 return errors.New("invalid callback method") 88 } 89 90 o.UserData, err = arr[6].TryBytes() 91 return err 92 } 93 94 func itemToString(it stackitem.Item) (string, bool, bool) { 95 _, ok := it.(stackitem.Null) 96 if ok { 97 return "", true, true 98 } 99 bs, err := it.TryBytes() 100 if err != nil || !utf8.Valid(bs) { 101 return "", false, false 102 } 103 return string(bs), false, true 104 }