github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/transaction/witness_rule.go (about) 1 package transaction 2 3 import ( 4 "encoding/json" 5 "errors" 6 "math/big" 7 8 "github.com/nspcc-dev/neo-go/pkg/io" 9 "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" 10 ) 11 12 //go:generate stringer -type=WitnessAction -linecomment 13 14 // WitnessAction represents an action to perform in WitnessRule if 15 // WitnessCondition matches. 16 type WitnessAction byte 17 18 const ( 19 // WitnessDeny rejects current witness if condition is met. 20 WitnessDeny WitnessAction = 0 // Deny 21 // WitnessAllow approves current witness if condition is met. 22 WitnessAllow WitnessAction = 1 // Allow 23 ) 24 25 // WitnessRule represents a single rule for Rules witness scope. 26 type WitnessRule struct { 27 Action WitnessAction `json:"action"` 28 Condition WitnessCondition `json:"condition"` 29 } 30 31 type witnessRuleAux struct { 32 Action string `json:"action"` 33 Condition json.RawMessage `json:"condition"` 34 } 35 36 // EncodeBinary implements the Serializable interface. 37 func (w *WitnessRule) EncodeBinary(bw *io.BinWriter) { 38 bw.WriteB(byte(w.Action)) 39 w.Condition.EncodeBinary(bw) 40 } 41 42 // DecodeBinary implements the Serializable interface. 43 func (w *WitnessRule) DecodeBinary(br *io.BinReader) { 44 w.Action = WitnessAction(br.ReadB()) 45 if br.Err == nil && w.Action != WitnessDeny && w.Action != WitnessAllow { 46 br.Err = errors.New("unknown witness rule action") 47 return 48 } 49 w.Condition = DecodeBinaryCondition(br) 50 } 51 52 // UnmarshalJSON implements the json.Unmarshaler interface. 53 func (w *WitnessRule) MarshalJSON() ([]byte, error) { 54 cond, err := w.Condition.MarshalJSON() 55 if err != nil { 56 return nil, err 57 } 58 aux := &witnessRuleAux{ 59 Action: w.Action.String(), 60 Condition: cond, 61 } 62 return json.Marshal(aux) 63 } 64 65 // UnmarshalJSON implements the json.Unmarshaler interface. 66 func (w *WitnessRule) UnmarshalJSON(data []byte) error { 67 aux := &witnessRuleAux{} 68 err := json.Unmarshal(data, aux) 69 if err != nil { 70 return err 71 } 72 var action WitnessAction 73 switch aux.Action { 74 case WitnessDeny.String(): 75 action = WitnessDeny 76 case WitnessAllow.String(): 77 action = WitnessAllow 78 default: 79 return errors.New("unknown witness rule action") 80 } 81 cond, err := UnmarshalConditionJSON(aux.Condition) 82 if err != nil { 83 return err 84 } 85 w.Action = action 86 w.Condition = cond 87 return nil 88 } 89 90 // ToStackItem implements Convertible interface. 91 func (w *WitnessRule) ToStackItem() stackitem.Item { 92 return stackitem.NewArray([]stackitem.Item{ 93 stackitem.NewBigInteger(big.NewInt(int64(w.Action))), 94 w.Condition.ToStackItem(), 95 }) 96 } 97 98 // Copy creates a deep copy of the WitnessRule. 99 func (w *WitnessRule) Copy() *WitnessRule { 100 return &WitnessRule{ 101 Action: w.Action, 102 Condition: w.Condition.Copy(), 103 } 104 }