forked from TrueCloudLab/neoneo-go
114 lines
4.1 KiB
Go
114 lines
4.1 KiB
Go
|
/*
|
||
|
Package oracle allows to work with the native OracleContract contract via RPC.
|
||
|
|
||
|
Safe methods are encapsulated into ContractReader structure while Contract provides
|
||
|
various methods to perform state-changing calls.
|
||
|
*/
|
||
|
package oracle
|
||
|
|
||
|
import (
|
||
|
"math/big"
|
||
|
|
||
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||
|
)
|
||
|
|
||
|
// Invoker is used by ContractReader to call various methods.
|
||
|
type Invoker interface {
|
||
|
Call(contract util.Uint160, operation string, params ...interface{}) (*result.Invoke, error)
|
||
|
}
|
||
|
|
||
|
// Actor is used by Contract to create and send transactions.
|
||
|
type Actor interface {
|
||
|
Invoker
|
||
|
|
||
|
MakeCall(contract util.Uint160, method string, params ...interface{}) (*transaction.Transaction, error)
|
||
|
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...interface{}) (*transaction.Transaction, error)
|
||
|
SendCall(contract util.Uint160, method string, params ...interface{}) (util.Uint256, uint32, error)
|
||
|
}
|
||
|
|
||
|
// Hash stores the hash of the native OracleContract contract.
|
||
|
var Hash = state.CreateNativeContractHash(nativenames.Oracle)
|
||
|
|
||
|
const priceSetter = "setPrice"
|
||
|
|
||
|
// ContractReader provides an interface to call read-only OracleContract
|
||
|
// contract's methods. "verify" method is not exposed since it's very specific
|
||
|
// and can't be executed successfully outside of the proper oracle response
|
||
|
// transaction.
|
||
|
type ContractReader struct {
|
||
|
invoker Invoker
|
||
|
}
|
||
|
|
||
|
// Contract represents the OracleContract contract client that can be used to
|
||
|
// invoke its "setPrice" method. Other methods are useless for direct calls,
|
||
|
// "request" requires a callback that entry script can't provide and "finish"
|
||
|
// will only work in an oracle transaction. Since "setPrice" can be called
|
||
|
// successfully only by the network's committee, an appropriate Actor is needed
|
||
|
// for Contract.
|
||
|
type Contract struct {
|
||
|
ContractReader
|
||
|
|
||
|
actor Actor
|
||
|
}
|
||
|
|
||
|
// RequestEvent represents an OracleRequest notification event emitted from
|
||
|
// the OracleContract contract.
|
||
|
type RequestEvent struct {
|
||
|
ID int64
|
||
|
Contract util.Uint160
|
||
|
URL string
|
||
|
Filter string
|
||
|
}
|
||
|
|
||
|
// ResponseEvent represents an OracleResponse notification event emitted from
|
||
|
// the OracleContract contract.
|
||
|
type ResponseEvent struct {
|
||
|
ID int64
|
||
|
OriginalTx util.Uint256
|
||
|
}
|
||
|
|
||
|
// NewReader creates an instance of ContractReader that can be used to read
|
||
|
// data from the contract.
|
||
|
func NewReader(invoker Invoker) *ContractReader {
|
||
|
return &ContractReader{invoker}
|
||
|
}
|
||
|
|
||
|
// New creates an instance of Contract to perform actions using
|
||
|
// the given Actor.
|
||
|
func New(actor Actor) *Contract {
|
||
|
return &Contract{*NewReader(actor), actor}
|
||
|
}
|
||
|
|
||
|
// GetPrice returns current price of the oracle request call.
|
||
|
func (c *ContractReader) GetPrice() (*big.Int, error) {
|
||
|
return unwrap.BigInt(c.invoker.Call(Hash, "getPrice"))
|
||
|
}
|
||
|
|
||
|
// SetPrice creates and sends a transaction that sets the new price for the
|
||
|
// oracle request call. The action is successful when transaction ends in HALT
|
||
|
// state. The returned values are transaction hash, its ValidUntilBlock value and
|
||
|
// an error if any.
|
||
|
func (c *Contract) SetPrice(value *big.Int) (util.Uint256, uint32, error) {
|
||
|
return c.actor.SendCall(Hash, priceSetter, value)
|
||
|
}
|
||
|
|
||
|
// SetPriceTransaction creates a transaction that sets the new price for the
|
||
|
// oracle request call. The action is successful when transaction ends in HALT
|
||
|
// state. The transaction is signed, but not sent to the network, instead it's
|
||
|
// returned to the caller.
|
||
|
func (c *Contract) SetPriceTransaction(value *big.Int) (*transaction.Transaction, error) {
|
||
|
return c.actor.MakeCall(Hash, priceSetter, value)
|
||
|
}
|
||
|
|
||
|
// SetPriceUnsigned creates a transaction that sets the new price for the
|
||
|
// oracle request call. The action is successful when transaction ends in HALT
|
||
|
// state. The transaction is not signed and just returned to the caller.
|
||
|
func (c *Contract) SetPriceUnsigned(value *big.Int) (*transaction.Transaction, error) {
|
||
|
return c.actor.MakeUnsignedCall(Hash, priceSetter, nil, value)
|
||
|
}
|