github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/rpcclient/oracle/oracle.go (about) 1 /* 2 Package oracle allows to work with the native OracleContract contract via RPC. 3 4 Safe methods are encapsulated into ContractReader structure while Contract provides 5 various methods to perform state-changing calls. 6 */ 7 package oracle 8 9 import ( 10 "math/big" 11 12 "github.com/nspcc-dev/neo-go/pkg/core/native/nativehashes" 13 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 14 "github.com/nspcc-dev/neo-go/pkg/neorpc/result" 15 "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" 16 "github.com/nspcc-dev/neo-go/pkg/util" 17 ) 18 19 // Invoker is used by ContractReader to call various methods. 20 type Invoker interface { 21 Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error) 22 } 23 24 // Actor is used by Contract to create and send transactions. 25 type Actor interface { 26 Invoker 27 28 MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error) 29 MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error) 30 SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error) 31 } 32 33 // Hash stores the hash of the native OracleContract contract. 34 var Hash = nativehashes.OracleContract 35 36 const priceSetter = "setPrice" 37 38 // ContractReader provides an interface to call read-only OracleContract 39 // contract's methods. "verify" method is not exposed since it's very specific 40 // and can't be executed successfully outside of the proper oracle response 41 // transaction. 42 type ContractReader struct { 43 invoker Invoker 44 } 45 46 // Contract represents the OracleContract contract client that can be used to 47 // invoke its "setPrice" method. Other methods are useless for direct calls, 48 // "request" requires a callback that entry script can't provide and "finish" 49 // will only work in an oracle transaction. Since "setPrice" can be called 50 // successfully only by the network's committee, an appropriate Actor is needed 51 // for Contract. 52 type Contract struct { 53 ContractReader 54 55 actor Actor 56 } 57 58 // RequestEvent represents an OracleRequest notification event emitted from 59 // the OracleContract contract. 60 type RequestEvent struct { 61 ID int64 62 Contract util.Uint160 63 URL string 64 Filter string 65 } 66 67 // ResponseEvent represents an OracleResponse notification event emitted from 68 // the OracleContract contract. 69 type ResponseEvent struct { 70 ID int64 71 OriginalTx util.Uint256 72 } 73 74 // NewReader creates an instance of ContractReader that can be used to read 75 // data from the contract. 76 func NewReader(invoker Invoker) *ContractReader { 77 return &ContractReader{invoker} 78 } 79 80 // New creates an instance of Contract to perform actions using 81 // the given Actor. 82 func New(actor Actor) *Contract { 83 return &Contract{*NewReader(actor), actor} 84 } 85 86 // GetPrice returns current price of the oracle request call. 87 func (c *ContractReader) GetPrice() (*big.Int, error) { 88 return unwrap.BigInt(c.invoker.Call(Hash, "getPrice")) 89 } 90 91 // SetPrice creates and sends a transaction that sets the new price for the 92 // oracle request call. The action is successful when transaction ends in HALT 93 // state. The returned values are transaction hash, its ValidUntilBlock value and 94 // an error if any. 95 func (c *Contract) SetPrice(value *big.Int) (util.Uint256, uint32, error) { 96 return c.actor.SendCall(Hash, priceSetter, value) 97 } 98 99 // SetPriceTransaction creates a transaction that sets the new price for the 100 // oracle request call. The action is successful when transaction ends in HALT 101 // state. The transaction is signed, but not sent to the network, instead it's 102 // returned to the caller. 103 func (c *Contract) SetPriceTransaction(value *big.Int) (*transaction.Transaction, error) { 104 return c.actor.MakeCall(Hash, priceSetter, value) 105 } 106 107 // SetPriceUnsigned creates a transaction that sets the new price for the 108 // oracle request call. The action is successful when transaction ends in HALT 109 // state. The transaction is not signed and just returned to the caller. 110 func (c *Contract) SetPriceUnsigned(value *big.Int) (*transaction.Transaction, error) { 111 return c.actor.MakeUnsignedCall(Hash, priceSetter, nil, value) 112 }