github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/rpcclient/policy/policy.go (about)

     1  /*
     2  Package policy allows to work with the native PolicyContract contract via RPC.
     3  
     4  Safe methods are encapsulated into ContractReader structure while Contract provides
     5  various methods to perform PolicyContract state-changing calls.
     6  */
     7  package policy
     8  
     9  import (
    10  	"github.com/nspcc-dev/neo-go/pkg/core/native/nativehashes"
    11  	"github.com/nspcc-dev/neo-go/pkg/core/transaction"
    12  	"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
    13  	"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
    14  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
    15  	"github.com/nspcc-dev/neo-go/pkg/util"
    16  )
    17  
    18  // Invoker is used by ContractReader to call various methods.
    19  type Invoker interface {
    20  	Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error)
    21  }
    22  
    23  // Actor is used by Contract to create and send transactions.
    24  type Actor interface {
    25  	Invoker
    26  
    27  	MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
    28  	MakeRun(script []byte) (*transaction.Transaction, error)
    29  	MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
    30  	MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
    31  	SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
    32  	SendRun(script []byte) (util.Uint256, uint32, error)
    33  }
    34  
    35  // Hash stores the hash of the native PolicyContract contract.
    36  var Hash = nativehashes.PolicyContract
    37  
    38  const (
    39  	execFeeSetter      = "setExecFeeFactor"
    40  	feePerByteSetter   = "setFeePerByte"
    41  	storagePriceSetter = "setStoragePrice"
    42  	attributeFeeSetter = "setAttributeFee"
    43  )
    44  
    45  // ContractReader provides an interface to call read-only PolicyContract
    46  // contract's methods.
    47  type ContractReader struct {
    48  	invoker Invoker
    49  }
    50  
    51  // Contract represents a PolicyContract contract client that can be used to
    52  // invoke all of its methods.
    53  type Contract struct {
    54  	ContractReader
    55  
    56  	actor Actor
    57  }
    58  
    59  // NewReader creates an instance of ContractReader that can be used to read
    60  // data from the contract.
    61  func NewReader(invoker Invoker) *ContractReader {
    62  	return &ContractReader{invoker}
    63  }
    64  
    65  // New creates an instance of Contract to perform actions using
    66  // the given Actor. Notice that PolicyContract's state can be changed
    67  // only by the network's committee, so the Actor provided must be a committee
    68  // actor for all methods to work properly.
    69  func New(actor Actor) *Contract {
    70  	return &Contract{*NewReader(actor), actor}
    71  }
    72  
    73  // GetExecFeeFactor returns current execution fee factor used by the network.
    74  // This setting affects all executions of all transactions.
    75  func (c *ContractReader) GetExecFeeFactor() (int64, error) {
    76  	return unwrap.Int64(c.invoker.Call(Hash, "getExecFeeFactor"))
    77  }
    78  
    79  // GetFeePerByte returns current minimal per-byte network fee value which
    80  // affects all transactions on the network.
    81  func (c *ContractReader) GetFeePerByte() (int64, error) {
    82  	return unwrap.Int64(c.invoker.Call(Hash, "getFeePerByte"))
    83  }
    84  
    85  // GetStoragePrice returns current per-byte storage price. Any contract saving
    86  // data to the storage pays for it according to this value.
    87  func (c *ContractReader) GetStoragePrice() (int64, error) {
    88  	return unwrap.Int64(c.invoker.Call(Hash, "getStoragePrice"))
    89  }
    90  
    91  // GetAttributeFee returns current fee for the specified attribute usage. Any
    92  // contract saving data to the storage pays for it according to this value.
    93  func (c *ContractReader) GetAttributeFee(t transaction.AttrType) (int64, error) {
    94  	return unwrap.Int64(c.invoker.Call(Hash, "getAttributeFee", byte(t)))
    95  }
    96  
    97  // IsBlocked checks if the given account is blocked in the PolicyContract.
    98  func (c *ContractReader) IsBlocked(account util.Uint160) (bool, error) {
    99  	return unwrap.Bool(c.invoker.Call(Hash, "isBlocked", account))
   100  }
   101  
   102  // SetExecFeeFactor creates and sends a transaction that sets the new
   103  // execution fee factor for the network to use. The action is successful when
   104  // transaction ends in HALT state. The returned values are transaction hash, its
   105  // ValidUntilBlock value and an error if any.
   106  func (c *Contract) SetExecFeeFactor(value int64) (util.Uint256, uint32, error) {
   107  	return c.actor.SendCall(Hash, execFeeSetter, value)
   108  }
   109  
   110  // SetExecFeeFactorTransaction creates a transaction that sets the new execution
   111  // fee factor. This transaction is signed, but not sent to the network,
   112  // instead it's returned to the caller.
   113  func (c *Contract) SetExecFeeFactorTransaction(value int64) (*transaction.Transaction, error) {
   114  	return c.actor.MakeCall(Hash, execFeeSetter, value)
   115  }
   116  
   117  // SetExecFeeFactorUnsigned creates a transaction that sets the new execution
   118  // fee factor. This transaction is not signed and just returned to the caller.
   119  func (c *Contract) SetExecFeeFactorUnsigned(value int64) (*transaction.Transaction, error) {
   120  	return c.actor.MakeUnsignedCall(Hash, execFeeSetter, nil, value)
   121  }
   122  
   123  // SetFeePerByte creates and sends a transaction that sets the new minimal
   124  // per-byte network fee value. The action is successful when transaction ends in
   125  // HALT state. The returned values are transaction hash, its ValidUntilBlock
   126  // value and an error if any.
   127  func (c *Contract) SetFeePerByte(value int64) (util.Uint256, uint32, error) {
   128  	return c.actor.SendCall(Hash, feePerByteSetter, value)
   129  }
   130  
   131  // SetFeePerByteTransaction creates a transaction that sets the new minimal
   132  // per-byte network fee value. This transaction is signed, but not sent to the
   133  // network, instead it's returned to the caller.
   134  func (c *Contract) SetFeePerByteTransaction(value int64) (*transaction.Transaction, error) {
   135  	return c.actor.MakeCall(Hash, feePerByteSetter, value)
   136  }
   137  
   138  // SetFeePerByteUnsigned creates a transaction that sets the new minimal per-byte
   139  // network fee value. This transaction is not signed and just returned to the
   140  // caller.
   141  func (c *Contract) SetFeePerByteUnsigned(value int64) (*transaction.Transaction, error) {
   142  	return c.actor.MakeUnsignedCall(Hash, feePerByteSetter, nil, value)
   143  }
   144  
   145  // SetStoragePrice creates and sends a transaction that sets the storage price
   146  // for contracts. The action is successful when transaction ends in HALT
   147  // state. The returned values are transaction hash, its ValidUntilBlock value
   148  // and an error if any.
   149  func (c *Contract) SetStoragePrice(value int64) (util.Uint256, uint32, error) {
   150  	return c.actor.SendCall(Hash, storagePriceSetter, value)
   151  }
   152  
   153  // SetStoragePriceTransaction creates a transaction that sets the storage price
   154  // for contracts. This transaction is signed, but not sent to the network,
   155  // instead it's returned to the caller.
   156  func (c *Contract) SetStoragePriceTransaction(value int64) (*transaction.Transaction, error) {
   157  	return c.actor.MakeCall(Hash, storagePriceSetter, value)
   158  }
   159  
   160  // SetStoragePriceUnsigned creates a transaction that sets the storage price
   161  // for contracts. This transaction is not signed and just returned to the
   162  // caller.
   163  func (c *Contract) SetStoragePriceUnsigned(value int64) (*transaction.Transaction, error) {
   164  	return c.actor.MakeUnsignedCall(Hash, storagePriceSetter, nil, value)
   165  }
   166  
   167  // SetAttributeFee creates and sends a transaction that sets the new attribute
   168  // fee value for the specified attribute. The action is successful when
   169  // transaction ends in HALT state. The returned values are transaction hash, its
   170  // ValidUntilBlock value and an error if any.
   171  func (c *Contract) SetAttributeFee(t transaction.AttrType, value int64) (util.Uint256, uint32, error) {
   172  	return c.actor.SendCall(Hash, attributeFeeSetter, byte(t), value)
   173  }
   174  
   175  // SetAttributeFeeTransaction creates a transaction that sets the new attribute
   176  // fee value for the specified attribute. This transaction is signed, but not
   177  // sent to the network, instead it's returned to the caller.
   178  func (c *Contract) SetAttributeFeeTransaction(t transaction.AttrType, value int64) (*transaction.Transaction, error) {
   179  	return c.actor.MakeCall(Hash, attributeFeeSetter, byte(t), value)
   180  }
   181  
   182  // SetAttributeFeeUnsigned creates a transaction that sets the new attribute fee
   183  // value for the specified attribute. This transaction is not signed and just
   184  // returned to the caller.
   185  func (c *Contract) SetAttributeFeeUnsigned(t transaction.AttrType, value int64) (*transaction.Transaction, error) {
   186  	return c.actor.MakeUnsignedCall(Hash, attributeFeeSetter, nil, byte(t), value)
   187  }
   188  
   189  // BlockAccount creates and sends a transaction that blocks an account on the
   190  // network (via `blockAccount` method), it fails (with FAULT state) if it's not
   191  // successful. The returned values are transaction hash, its
   192  // ValidUntilBlock value and an error if any.
   193  func (c *Contract) BlockAccount(account util.Uint160) (util.Uint256, uint32, error) {
   194  	return c.actor.SendRun(blockScript(account))
   195  }
   196  
   197  // BlockAccountTransaction creates a transaction that blocks an account on the
   198  // network and checks for the result of the appropriate call, failing the
   199  // transaction if it's not true. This transaction is signed, but not sent to the
   200  // network, instead it's returned to the caller.
   201  func (c *Contract) BlockAccountTransaction(account util.Uint160) (*transaction.Transaction, error) {
   202  	return c.actor.MakeRun(blockScript(account))
   203  }
   204  
   205  // BlockAccountUnsigned creates a transaction that blocks an account on the
   206  // network and checks for the result of the appropriate call, failing the
   207  // transaction if it's not true. This transaction is not signed and just returned
   208  // to the caller.
   209  func (c *Contract) BlockAccountUnsigned(account util.Uint160) (*transaction.Transaction, error) {
   210  	return c.actor.MakeUnsignedRun(blockScript(account), nil)
   211  }
   212  
   213  func blockScript(account util.Uint160) []byte {
   214  	// We know parameters exactly (unlike with nep17.Transfer), so this can't fail.
   215  	script, _ := smartcontract.CreateCallWithAssertScript(Hash, "blockAccount", account)
   216  	return script
   217  }
   218  
   219  // UnblockAccount creates and sends a transaction that removes previously blocked
   220  // account from the stop list. It uses `unblockAccount` method and checks for the
   221  // result returned, failing the transaction if it's not true. The returned values
   222  // are transaction hash, its ValidUntilBlock value and an error if any.
   223  func (c *Contract) UnblockAccount(account util.Uint160) (util.Uint256, uint32, error) {
   224  	return c.actor.SendRun(unblockScript(account))
   225  }
   226  
   227  // UnblockAccountTransaction creates a transaction that unblocks previously
   228  // blocked account via `unblockAccount` method and checks for the result returned,
   229  // failing the transaction if it's not true. This transaction is signed, but not
   230  // sent to the network, instead it's returned to the caller.
   231  func (c *Contract) UnblockAccountTransaction(account util.Uint160) (*transaction.Transaction, error) {
   232  	return c.actor.MakeRun(unblockScript(account))
   233  }
   234  
   235  // UnblockAccountUnsigned creates a transaction that unblocks the given account
   236  // if it was blocked previously. It uses `unblockAccount` method and checks for
   237  // its return value, failing the transaction if it's not true. This transaction
   238  // is not signed and just returned to the caller.
   239  func (c *Contract) UnblockAccountUnsigned(account util.Uint160) (*transaction.Transaction, error) {
   240  	return c.actor.MakeUnsignedRun(unblockScript(account), nil)
   241  }
   242  
   243  func unblockScript(account util.Uint160) []byte {
   244  	// We know parameters exactly (unlike with nep17.Transfer), so this can't fail.
   245  	script, _ := smartcontract.CreateCallWithAssertScript(Hash, "unblockAccount", account)
   246  	return script
   247  }