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 }