forked from TrueCloudLab/frostfs-contract
64 lines
1.7 KiB
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
|
||
|
}
|