OSDN Git Service

modify contract illustration
[bytom/vapor.git] / protocol / vm / vmutil / magnetic_v2.go
1 package vmutil
2
3 import "github.com/bytom/vapor/protocol/vm"
4
5 // P2WMCProgramV2 return the segwit pay to magnetic contract
6 func P2WMCProgramV2(magneticContractArgs MagneticContractArgs) ([]byte, error) {
7         builder := NewBuilder()
8         builder.AddInt64(1)
9         builder.AddData(magneticContractArgs.RequestedAsset.Bytes())
10         builder.AddInt64(magneticContractArgs.RatioNumerator)
11         builder.AddInt64(magneticContractArgs.RatioDenominator)
12         builder.AddData(magneticContractArgs.SellerProgram)
13         builder.AddData(magneticContractArgs.SellerKey)
14         return builder.Build()
15 }
16
17 // P2MCProgramV2 generates the script for control with the v2 version of magnetic contract
18 //
19 // MagneticV2 contract source code:
20 // contract MagneticV2(requestedAsset: Asset,
21 //                                              ratioNumerator: Integer,
22 //                                              ratioDenominator: Integer,
23 //                                              sellerProgram: Program,
24 //                                              standardProgram: Program,
25 //                                              sellerKey: PublicKey) locks valueAmount of valueAsset {
26 //  clause partialTrade(exchangeAmount: Amount, fee: Amount) {
27 //              define actualAmount: Integer = exchangeAmount * ratioDenominator / ratioNumerator
28 //              verify actualAmount >= 0 && actualAmount < valueAmount
29 //              define receiveAmount: Integer = exchangeAmount * (10000 - fee) / 10000
30 //              verify receiveAmount >= 0
31 //              lock receiveAmount of requestedAsset with sellerProgram
32 //              lock valueAmount-actualAmount of valueAsset with standardProgram
33 //              unlock actualAmount of valueAsset
34 //      }
35 //      clause fullTrade(fee: Amount) {
36 //              define requestedAmount: Integer = valueAmount * ratioNumerator / ratioDenominator
37 //              define tradeAmount: Integer = requestedAmount * (10000 - fee) / 10000
38 //              verify tradeAmount >= 0
39 //              lock tradeAmount of requestedAsset with sellerProgram
40 //              unlock valueAmount of valueAsset
41 //      }
42 //      clause cancel(sellerSig: Signature) {
43 //              verify checkTxSig(sellerKey, sellerSig)
44 //              unlock valueAmount of valueAsset
45 //      }
46 // }
47 //
48 // contract stack flow:
49 // 7                        [... <position> <clause selector> sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset 7]
50 // ROLL                     [... <clause selector> sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset <position>]
51 // TOALTSTACK               [... <clause selector> sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
52 // 6                        [... <clause selector> sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset 6]
53 // ROLL                     [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset <clause selector>]
54 // DUP                      [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset <clause selector> <clause selector>]
55 // 2                        [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset <clause selector> <clause selector> 2]
56 // NUMEQUAL                 [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset <clause selector> (<clause selector> == 2)]
57 // JUMPIF:$cancel           [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset <clause selector>]
58 // JUMPIF:$fullTrade        [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
59 // $partialTrade            [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
60 // 7                        [... exchangeAmount fee sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset 7]
61 // PICK                     [... exchangeAmount fee sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset exchangeAmount]
62 // 3                        [... exchangeAmount fee sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset exchangeAmount 3]
63 // ROLL                     [... exchangeAmount fee sellerKey standardProgram sellerProgram ratioNumerator requestedAsset exchangeAmount ratioDenominator]
64 // 3                        [... exchangeAmount fee sellerKey standardProgram sellerProgram ratioNumerator requestedAsset exchangeAmount ratioDenominator 3]
65 // ROLL                     [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset exchangeAmount ratioDenominator ratioNumerator]
66 // MULFRACTION              [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount]
67 // AMOUNT                   [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount]
68 // OVER                     [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount]
69 // 0                        [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount 0]
70 // GREATERTHANOREQUAL       [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount >= 0)]
71 // 2                        [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount >= 0) 2]
72 // PICK                     [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount (actualAmount >= 0) actualAmount]
73 // ROT                      [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount (actualAmount >= 0) actualAmount valueAmount]
74 // LESSTHAN                 [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount (actualAmount >= 0) (actualAmount < valueAmount)]
75 // BOOLAND                  [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount ((actualAmount >= 0) && (actualAmount < valueAmount))]
76 // VERIFY                   [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount]
77 // 6                        [... exchangeAmount fee sellerKey standardProgram sellerProgram requestedAsset actualAmount 6]
78 // ROLL                     [... fee sellerKey standardProgram sellerProgram requestedAsset actualAmount exchangeAmount]
79 // 10000                    [... fee sellerKey standardProgram sellerProgram requestedAsset actualAmount exchangeAmount 10000]
80 // 7                        [... fee sellerKey standardProgram sellerProgram requestedAsset actualAmount exchangeAmount 10000 7]
81 // ROLL                     [... sellerKey standardProgram sellerProgram requestedAsset actualAmount exchangeAmount 10000 fee]
82 // SUB                      [... sellerKey standardProgram sellerProgram requestedAsset actualAmount exchangeAmount (10000 - fee)]
83 // 10000                    [... sellerKey standardProgram sellerProgram requestedAsset actualAmount exchangeAmount (10000 - fee) 10000]
84 // MULFRACTION              [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount]
85 // DUP                      [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount receiveAmount]
86 // 0                        [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount receiveAmount 0]
87 // GREATERTHANOREQUAL       [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount (receiveAmount >= 0)]
88 // VERIFY                   [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount]
89 // FROMALTSTACK             [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount <position>]
90 // DUP                      [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount <position> <position>]
91 // TOALTSTACK               [... sellerKey standardProgram sellerProgram requestedAsset actualAmount receiveAmount <position>]
92 // SWAP                     [... sellerKey standardProgram sellerProgram requestedAsset actualAmount <position> receiveAmount]
93 // 3                        [... sellerKey standardProgram sellerProgram requestedAsset actualAmount <position> receiveAmount 3]
94 // ROLL                     [... sellerKey standardProgram sellerProgram actualAmount <position> receiveAmount requestedAsset]
95 // 1                        [... sellerKey standardProgram sellerProgram actualAmount <position> receiveAmount requestedAsset 1]
96 // 5                        [... sellerKey standardProgram sellerProgram actualAmount <position> receiveAmount requestedAsset 1 5]
97 // ROLL                     [... sellerKey standardProgram actualAmount <position> receiveAmount requestedAsset 1 sellerProgram]
98 // CHECKOUTPUT              [... sellerKey standardProgram actualAmount checkOutput(receiveAmount, requestedAsset, sellerProgram)]
99 // VERIFY                   [... sellerKey standardProgram actualAmount]
100 // FROMALTSTACK             [... sellerKey standardProgram actualAmount <position>]
101 // 1                        [... sellerKey standardProgram actualAmount <position> 1]
102 // ADD                      [... sellerKey standardProgram actualAmount (<position> + 1)]
103 // AMOUNT                   [... sellerKey standardProgram actualAmount (<position> + 1) valueAmount]
104 // ROT                      [... sellerKey standardProgram (<position> + 1) valueAmount actualAmount]
105 // SUB                      [... sellerKey standardProgram (<position> + 1) (valueAmount - actualAmount)]
106 // ASSET                    [... sellerKey standardProgram (<position> + 1) (valueAmount - actualAmount) valueAsset]
107 // 1                        [... sellerKey standardProgram (<position> + 1) (valueAmount - actualAmount) valueAsset 1]
108 // 4                        [... sellerKey standardProgram (<position> + 1) (valueAmount - actualAmount) valueAsset 1 4]
109 // ROLL                     [... sellerKey (<position> + 1) (valueAmount - actualAmount) valueAsset 1 standardProgram]
110 // CHECKOUTPUT              [... sellerKey checkOutput((valueAmount - actualAmount), valueAsset, standardProgram)]
111 // JUMP:$_end               [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
112 // $fullTrade               [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
113 // AMOUNT                   [... fee sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset valueAmount]
114 // ROT                      [... fee sellerKey standardProgram sellerProgram ratioDenominator requestedAsset valueAmount ratioNumerator]
115 // 3                        [... fee sellerKey standardProgram sellerProgram ratioDenominator requestedAsset valueAmount ratioNumerator 3]
116 // ROLL                     [... fee sellerKey standardProgram sellerProgram requestedAsset valueAmount ratioNumerator ratioDenominator]
117 // MULFRACTION              [... fee sellerKey standardProgram sellerProgram requestedAsset requestedAmount]
118 // 10000                    [... fee sellerKey standardProgram sellerProgram requestedAsset requestedAmount 10000]
119 // 6                        [... fee sellerKey standardProgram sellerProgram requestedAsset requestedAmount 10000 6]
120 // ROLL                     [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount 10000 fee]
121 // SUB                      [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount (10000 - fee)]
122 // 10000                    [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount (10000 - fee) 10000]
123 // MULFRACTION              [... sellerKey standardProgram sellerProgram requestedAsset tradeAmount]
124 // DUP                      [... sellerKey standardProgram sellerProgram requestedAsset tradeAmount tradeAmount]
125 // 0                        [... sellerKey standardProgram sellerProgram requestedAsset tradeAmount tradeAmount 0]
126 // GREATERTHANOREQUAL       [... sellerKey standardProgram sellerProgram requestedAsset tradeAmount (tradeAmount >= 0)]
127 // VERIFY                   [... sellerKey standardProgram sellerProgram requestedAsset tradeAmount]
128 // FROMALTSTACK             [... sellerKey standardProgram sellerProgram requestedAsset tradeAmount <position>]
129 // SWAP                     [... sellerKey standardProgram sellerProgram requestedAsset <position> tradeAmount]
130 // ROT                      [... sellerKey standardProgram sellerProgram <position> tradeAmount requestedAsset]
131 // 1                        [... sellerKey standardProgram sellerProgram <position> tradeAmount requestedAsset 1]
132 // 4                        [... sellerKey standardProgram sellerProgram <position> tradeAmount requestedAsset 1 4]
133 // ROLL                     [... sellerKey standardProgram <position> tradeAmount requestedAsset 1 sellerProgram]
134 // CHECKOUTPUT              [... sellerKey standardProgram checkOutput(tradeAmount, requestedAsset, sellerProgram)]
135 // JUMP:$_end               [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
136 // $cancel                  [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset <clause selector>]
137 // DROP                     [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
138 // 6                        [... sellerSig sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset 6]
139 // ROLL                     [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset sellerSig]
140 // 6                        [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset sellerSig 6]
141 // ROLL                     [... standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset sellerSig sellerKey]
142 // TXSIGHASH SWAP CHECKSIG  [... standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset checkTxSig(sellerKey, sellerSig)]
143 // $_end                    [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset]
144 func P2MCProgramV2(magneticContractArgs MagneticContractArgs) ([]byte, error) {
145         standardProgram, err := P2WMCProgramV2(magneticContractArgs)
146         if err != nil {
147                 return nil, err
148         }
149
150         builder := NewBuilder()
151         // contract arguments
152         builder.AddData(magneticContractArgs.SellerKey)
153         builder.AddData(standardProgram)
154         builder.AddData(magneticContractArgs.SellerProgram)
155         builder.AddInt64(magneticContractArgs.RatioDenominator)
156         builder.AddInt64(magneticContractArgs.RatioNumerator)
157         builder.AddData(magneticContractArgs.RequestedAsset.Bytes())
158
159         // contract instructions
160         builder.AddOp(vm.OP_7)
161         builder.AddOp(vm.OP_ROLL)
162         builder.AddOp(vm.OP_TOALTSTACK)
163         builder.AddOp(vm.OP_6)
164         builder.AddOp(vm.OP_ROLL)
165         builder.AddOp(vm.OP_DUP)
166         builder.AddOp(vm.OP_2)
167         builder.AddOp(vm.OP_NUMEQUAL)
168         builder.AddJumpIf(0)
169         builder.AddJumpIf(1)
170
171         builder.AddOp(vm.OP_7)
172         builder.AddOp(vm.OP_PICK)
173         builder.AddOp(vm.OP_3)
174         builder.AddOp(vm.OP_ROLL)
175         builder.AddOp(vm.OP_3)
176         builder.AddOp(vm.OP_ROLL)
177         builder.AddOp(vm.OP_MULFRACTION)
178         builder.AddOp(vm.OP_AMOUNT)
179         builder.AddOp(vm.OP_OVER)
180         builder.AddOp(vm.OP_0)
181         builder.AddOp(vm.OP_GREATERTHANOREQUAL)
182         builder.AddOp(vm.OP_2)
183         builder.AddOp(vm.OP_PICK)
184         builder.AddOp(vm.OP_ROT)
185         builder.AddOp(vm.OP_LESSTHAN)
186         builder.AddOp(vm.OP_BOOLAND)
187         builder.AddOp(vm.OP_VERIFY)
188
189         builder.AddOp(vm.OP_6)
190         builder.AddOp(vm.OP_ROLL)
191         builder.AddInt64(10000)
192         builder.AddOp(vm.OP_7)
193         builder.AddOp(vm.OP_ROLL)
194         builder.AddOp(vm.OP_SUB)
195         builder.AddInt64(10000)
196         builder.AddOp(vm.OP_MULFRACTION)
197         builder.AddOp(vm.OP_DUP)
198         builder.AddOp(vm.OP_0)
199         builder.AddOp(vm.OP_GREATERTHANOREQUAL)
200         builder.AddOp(vm.OP_VERIFY)
201
202         builder.AddOp(vm.OP_FROMALTSTACK)
203         builder.AddOp(vm.OP_DUP)
204         builder.AddOp(vm.OP_TOALTSTACK)
205         builder.AddOp(vm.OP_SWAP)
206         builder.AddOp(vm.OP_3)
207         builder.AddOp(vm.OP_ROLL)
208         builder.AddOp(vm.OP_1)
209         builder.AddOp(vm.OP_5)
210         builder.AddOp(vm.OP_ROLL)
211         builder.AddOp(vm.OP_CHECKOUTPUT)
212
213         builder.AddOp(vm.OP_VERIFY)
214         builder.AddOp(vm.OP_FROMALTSTACK)
215         builder.AddOp(vm.OP_1)
216         builder.AddOp(vm.OP_ADD)
217         builder.AddOp(vm.OP_AMOUNT)
218         builder.AddOp(vm.OP_ROT)
219         builder.AddOp(vm.OP_SUB)
220         builder.AddOp(vm.OP_ASSET)
221         builder.AddOp(vm.OP_1)
222         builder.AddOp(vm.OP_4)
223         builder.AddOp(vm.OP_ROLL)
224         builder.AddOp(vm.OP_CHECKOUTPUT)
225
226         builder.AddJump(2)
227         builder.SetJumpTarget(1)
228         builder.AddOp(vm.OP_AMOUNT)
229         builder.AddOp(vm.OP_ROT)
230         builder.AddOp(vm.OP_3)
231         builder.AddOp(vm.OP_ROLL)
232         builder.AddOp(vm.OP_MULFRACTION)
233         builder.AddInt64(10000)
234         builder.AddOp(vm.OP_6)
235         builder.AddOp(vm.OP_ROLL)
236         builder.AddOp(vm.OP_SUB)
237         builder.AddInt64(10000)
238         builder.AddOp(vm.OP_MULFRACTION)
239         builder.AddOp(vm.OP_DUP)
240         builder.AddOp(vm.OP_0)
241         builder.AddOp(vm.OP_GREATERTHANOREQUAL)
242         builder.AddOp(vm.OP_VERIFY)
243         builder.AddOp(vm.OP_FROMALTSTACK)
244         builder.AddOp(vm.OP_SWAP)
245         builder.AddOp(vm.OP_ROT)
246         builder.AddOp(vm.OP_1)
247         builder.AddOp(vm.OP_4)
248         builder.AddOp(vm.OP_ROLL)
249         builder.AddOp(vm.OP_CHECKOUTPUT)
250
251         builder.AddJump(3)
252         builder.SetJumpTarget(0)
253         builder.AddOp(vm.OP_DROP)
254         builder.AddOp(vm.OP_6)
255         builder.AddOp(vm.OP_ROLL)
256         builder.AddOp(vm.OP_6)
257         builder.AddOp(vm.OP_ROLL)
258         builder.AddOp(vm.OP_TXSIGHASH)
259         builder.AddOp(vm.OP_SWAP)
260         builder.AddOp(vm.OP_CHECKSIG)
261         builder.SetJumpTarget(2)
262         builder.SetJumpTarget(3)
263         return builder.Build()
264 }