7 "github.com/vapor/blockchain/txbuilder"
8 "github.com/vapor/errors"
9 bytomtypes "github.com/vapor/protocol/bc/types/bytom/types"
12 // NewBuilder return new TemplateBuilder instance
13 func NewBuilder(maxTime time.Time) *TemplateBuilder {
14 return &TemplateBuilder{maxTime: maxTime}
17 // TemplateBuilder is struct of building transactions
18 type TemplateBuilder struct {
19 base *bytomtypes.TxData
20 inputs []*bytomtypes.TxInput
21 outputs []*bytomtypes.TxOutput
22 signingInstructions []*SigningInstruction
28 callbacks []func() error
31 // AddInput add inputs of transactions
32 func (b *TemplateBuilder) AddInput(in *bytomtypes.TxInput, sigInstruction *SigningInstruction) error {
33 if in.InputType() != bytomtypes.CoinbaseInputType && in.Amount() > math.MaxInt64 {
34 return errors.WithDetailf(txbuilder.ErrBadAmount, "amount %d exceeds maximum value 2^63", in.Amount())
36 b.inputs = append(b.inputs, in)
37 b.signingInstructions = append(b.signingInstructions, sigInstruction)
41 // AddOutput add outputs of transactions
42 func (b *TemplateBuilder) AddOutput(o *bytomtypes.TxOutput) error {
43 if o.Amount > math.MaxInt64 {
44 return errors.WithDetailf(txbuilder.ErrBadAmount, "amount %d exceeds maximum value 2^63", o.Amount)
46 b.outputs = append(b.outputs, o)
50 // RestrictMinTime set minTime
51 func (b *TemplateBuilder) RestrictMinTime(t time.Time) {
52 if t.After(b.minTime) {
57 // RestrictMaxTime set maxTime
58 func (b *TemplateBuilder) RestrictMaxTime(t time.Time) {
59 if t.Before(b.maxTime) {
64 // MaxTime return maxTime
65 func (b *TemplateBuilder) MaxTime() time.Time {
69 // OnRollback registers a function that can be
70 // used to attempt to undo any side effects of building
71 // actions. For example, it might cancel any reservations
72 // reservations that were made on UTXOs in a spend action.
73 // Rollback is a "best-effort" operation and not guaranteed
74 // to succeed. Each action's side effects, if any, must be
75 // designed with this in mind.
76 func (b *TemplateBuilder) OnRollback(rollbackFn func()) {
77 b.rollbacks = append(b.rollbacks, rollbackFn)
80 // OnBuild registers a function that will be run after all
81 // actions have been successfully built.
82 func (b *TemplateBuilder) OnBuild(buildFn func() error) {
83 b.callbacks = append(b.callbacks, buildFn)
86 func (b *TemplateBuilder) rollback() {
87 for _, f := range b.rollbacks {
92 // Build build transactions with template
93 func (b *TemplateBuilder) Build() (*Template, *bytomtypes.TxData, error) {
94 // Run any building callbacks.
95 for _, cb := range b.callbacks {
105 tx = &bytomtypes.TxData{
110 if b.timeRange != 0 {
111 tx.TimeRange = b.timeRange
114 // Add all the built outputs.
115 tx.Outputs = append(tx.Outputs, b.outputs...)
117 // Add all the built inputs and their corresponding signing instructions.
118 for i, in := range b.inputs {
119 instruction := b.signingInstructions[i]
120 instruction.Position = uint32(len(tx.Inputs))
122 // Empty signature arrays should be serialized as empty arrays, not null.
123 if instruction.WitnessComponents == nil {
124 instruction.WitnessComponents = []witnessComponent{}
126 tpl.SigningInstructions = append(tpl.SigningInstructions, instruction)
127 tx.Inputs = append(tx.Inputs, in)
130 tpl.Transaction = bytomtypes.NewTx(*tx)