OSDN Git Service

Revert "update master (#487)" (#518)
[bytom/bytom.git] / blockchain / txbuilder / constraint.go
1 package txbuilder
2
3 import (
4         "github.com/bytom/crypto/sha3pool"
5         "github.com/bytom/protocol/bc"
6         "github.com/bytom/protocol/vm"
7         "github.com/bytom/protocol/vm/vmutil"
8 )
9
10 // Constraint types express a constraint on an input of a proposed
11 // transaction, and know how to turn that constraint into part of a
12 // signature program in that input's witness.
13 type constraint interface {
14         // Code produces bytecode expressing the constraint. The code, when
15         // executed, must consume nothing from the stack and leave a new
16         // boolean value on top of it.
17         code() []byte
18 }
19
20 // outpointConstraint requires the outputID (and therefore, the outpoint) being spent to equal the
21 // given value.
22 type outputIDConstraint bc.Hash
23
24 func (o outputIDConstraint) code() []byte {
25         builder := vmutil.NewBuilder()
26         builder.AddData(bc.Hash(o).Bytes())
27         builder.AddOp(vm.OP_OUTPUTID)
28         builder.AddOp(vm.OP_EQUAL)
29         prog, _ := builder.Build() // error is impossible
30         return prog
31 }
32
33 // refdataConstraint requires the refdatahash of the transaction (if
34 // tx is true) or the input (if tx is false) to match that of the
35 // given data.
36 type refdataConstraint struct {
37         data []byte
38         tx   bool
39 }
40
41 func (r refdataConstraint) code() []byte {
42         var h [32]byte
43         sha3pool.Sum256(h[:], r.data)
44         builder := vmutil.NewBuilder()
45         builder.AddData(h[:])
46         if r.tx {
47                 builder.AddOp(vm.OP_TXDATA)
48         } else {
49                 builder.AddOp(vm.OP_ENTRYDATA)
50         }
51         builder.AddOp(vm.OP_EQUAL)
52         prog, _ := builder.Build() // error is impossible
53         return prog
54 }
55
56 // PayConstraint requires the transaction to include a given output
57 // at the given index, optionally with the given refdatahash.
58 type payConstraint struct {
59         Index int
60         bc.AssetAmount
61         Program     []byte
62         RefDataHash *bc.Hash
63 }
64
65 func (p payConstraint) code() []byte {
66         builder := vmutil.NewBuilder()
67         builder.AddInt64(int64(p.Index))
68         if p.RefDataHash == nil {
69                 builder.AddData([]byte{})
70         } else {
71                 builder.AddData(p.RefDataHash.Bytes())
72         }
73         builder.AddInt64(int64(p.Amount)).AddData(p.AssetId.Bytes()).AddInt64(1).AddData(p.Program)
74         builder.AddOp(vm.OP_CHECKOUTPUT)
75         prog, _ := builder.Build() // error is impossible
76         return prog
77 }