3 import "github.com/bytom/vapor/protocol/vm"
5 // P2WMCProgramV2 return the segwit pay to magnetic contract
6 func P2WMCProgramV2(magneticContractArgs MagneticContractArgs) ([]byte, error) {
7 builder := NewBuilder()
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()
17 // P2MCProgramV2 generates the script for control with the v2 version of magnetic contract
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
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
42 // clause cancel(sellerSig: Signature) {
43 // verify checkTxSig(sellerKey, sellerSig)
44 // unlock valueAmount of valueAsset
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)
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())
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)
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)
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)
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)
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)
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)
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()