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"
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.
20 // outpointConstraint requires the outputID (and therefore, the outpoint) being spent to equal the
22 type outputIDConstraint bc.Hash
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
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
36 type refdataConstraint struct {
41 func (r refdataConstraint) code() []byte {
43 sha3pool.Sum256(h[:], r.data)
44 builder := vmutil.NewBuilder()
47 builder.AddOp(vm.OP_TXDATA)
49 builder.AddOp(vm.OP_ENTRYDATA)
51 builder.AddOp(vm.OP_EQUAL)
52 prog, _ := builder.Build() // error is impossible
56 // PayConstraint requires the transaction to include a given output
57 // at the given index, optionally with the given refdatahash.
58 type payConstraint struct {
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{})
71 builder.AddData(p.RefDataHash.Bytes())
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