frostfs-contract/commonclient/transaction.go

64 lines
1.7 KiB
Go

package commonclient
import (
"errors"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
)
// Transaction allows to invoke several contract method at once.
type Transaction struct {
writer *io.BufBinWriter
buffer *io.BufBinWriter
contract util.Uint160
}
var ErrTransactionTooLarge = errors.New("transaction/script size limit exceeded")
// NewTransaction creates new transaction to accumulate contract invocations.
func NewTransaction(contractHash util.Uint160) *Transaction {
return &Transaction{
writer: io.NewBufBinWriter(),
buffer: io.NewBufBinWriter(),
contract: contractHash,
}
}
// WrapCall accept methods and arguments to invoke.
// Should be used with method on clients like Client.MethodNameCall.
func (t Transaction) WrapCall(method string, args []any) error {
t.buffer.Reset()
emit.AppCall(t.buffer.BinWriter, t.contract, method, callflag.All, args...)
if t.writer.Len()+t.buffer.Len() > transaction.MaxScriptLength {
return ErrTransactionTooLarge
}
t.writer.WriteBytes(t.buffer.Bytes())
return t.writer.Err
}
// WrapCallErr accept methods, arguments and error to handle and invoke.
// Should be used with method on clients like *CallErr.
func (t Transaction) WrapCallErr(method string, args []any, err error) error {
if err != nil {
return err
}
return t.WrapCall(method, args)
}
// Bytes returns the resulting buffer and makes future writes return an error.
func (t Transaction) Bytes() ([]byte, error) {
if t.writer.Len() > transaction.MaxScriptLength {
return nil, ErrTransactionTooLarge
}
return t.writer.Bytes(), nil
}