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  }