1
1
2
2
3
+ from dataclasses import dataclass
3
4
from matt import NUMS_KEY
4
5
from matt .argtypes import BytesType , IntType , SignerType
5
6
from matt .btctools .common import sha256
6
- from matt .btctools .script import OP_ADD , OP_CHECKSIG , OP_DUP , OP_FROMALTSTACK , OP_ROT , OP_SHA256 , OP_SWAP , OP_TOALTSTACK , CScript
7
- from matt .contracts import ClauseOutput , StandardClause , StandardAugmentedP2TR , StandardP2TR
7
+ from matt .btctools .script import OP_ADD , OP_CHECKSIG , OP_DUP , OP_EQUAL , OP_FROMALTSTACK , OP_NOT , OP_PICK , OP_ROT , OP_SHA256 , OP_SWAP , OP_TOALTSTACK , OP_VERIFY , CScript
8
+ from matt .contracts import ClauseOutput , StandardClause , StandardAugmentedP2TR , StandardP2TR , ContractState
8
9
from matt .hub .fraud import Bisect_1 , Computer , Leaf
9
10
from matt .merkle import MerkleTree
10
11
from matt .script_helpers import check_input_contract , check_output_contract , drop , dup , merkle_root , older
16
17
# TODO: how to generalize what the contract does after the leaf? We should be able to compose clauses with some external code.
17
18
# Do we need "clause" algebra?
18
19
19
- # TODO: Augmented contracts should also specify the "encoder" for its data, so that callers don't have to worry
20
- # about handling Merkle trees by hand.
21
- # Might also be needed to define "higher order contracts" that can be used as a gadget, then provide a result
22
- # to some other contract provided by the caller.
23
-
24
20
class G256_S0 (StandardP2TR ):
25
21
def __init__ (self , alice_pk : bytes , bob_pk : bytes , forfait_timeout : int = 10 ):
26
22
self .alice_pk = alice_pk
27
23
self .bob_pk = bob_pk
28
24
self .forfait_timeout = forfait_timeout
29
25
26
+ g256_s1 = G256_S1 (alice_pk , bob_pk , forfait_timeout )
30
27
# witness: <bob_sig> <x>
31
28
choose = StandardClause (
32
29
name = "choose" ,
33
30
script = CScript ([
34
- OP_SHA256 , # sha256(x)
35
- * check_output_contract (G256_S1 ( alice_pk , bob_pk , forfait_timeout ) ),
31
+ * g256_s1 . State . encoder_script (),
32
+ * check_output_contract (g256_s1 ),
36
33
37
34
bob_pk ,
38
35
OP_CHECKSIG
@@ -41,42 +38,46 @@ def __init__(self, alice_pk: bytes, bob_pk: bytes, forfait_timeout: int = 10):
41
38
('bob_sig' , SignerType (bob_pk )),
42
39
('x' , IntType ()),
43
40
],
44
- next_output_fn = lambda args : [ClauseOutput (
41
+ next_outputs_fn = lambda args , _ : [ClauseOutput (
45
42
n = - 1 ,
46
- next_contract = G256_S1 ( alice_pk , bob_pk , forfait_timeout ) ,
47
- next_data = sha256 ( encode_wit_element ( args ['x' ]) )
43
+ next_contract = g256_s1 ,
44
+ next_state = g256_s1 . State ( x = args ['x' ])
48
45
)]
49
46
)
50
47
51
48
super ().__init__ (NUMS_KEY , choose )
52
49
53
50
54
51
class G256_S1 (StandardAugmentedP2TR ):
52
+ @dataclass
53
+ class State (ContractState ):
54
+ x : int
55
+
56
+ def encode (self ):
57
+ return sha256 (encode_wit_element (self .x ))
58
+
59
+ def encoder_script ():
60
+ return CScript ([OP_SHA256 ])
61
+
55
62
def __init__ (self , alice_pk : bytes , bob_pk : bytes , forfait_timeout ):
56
63
self .alice_pk = alice_pk
57
64
self .bob_pk = bob_pk
58
65
self .forfait_timeout = forfait_timeout
59
66
60
67
g256_s2 = G256_S2 (alice_pk , bob_pk , forfait_timeout )
61
68
62
- # reveal: <alice_sig> <r_a > <y> <sha256(x)>
69
+ # reveal: <alice_sig> <t_a > <y> <sha256(x)>
63
70
reveal = StandardClause (
64
71
name = "reveal" ,
65
72
script = CScript ([
66
73
OP_DUP ,
67
74
68
75
# check that the top of the stack is the embedded data
76
+ * self .State .encoder_script (),
69
77
* check_input_contract (),
70
78
71
- OP_TOALTSTACK ,
72
- OP_SHA256 ,
73
- OP_FROMALTSTACK ,
74
-
75
- # <alice_sig> <t_a> <sha256(y)> <sha256(x)>
76
- * merkle_root (3 ),
77
-
78
- # <alice_sig> <merkle_root(t_a, sha256(y), sha256(x))>
79
-
79
+ # <alice_sig> <t_a> <y> <x>
80
+ * g256_s2 .State .encoder_script (),
80
81
* check_output_contract (g256_s2 ),
81
82
82
83
alice_pk ,
@@ -86,12 +87,12 @@ def __init__(self, alice_pk: bytes, bob_pk: bytes, forfait_timeout):
86
87
('alice_sig' , SignerType (alice_pk )),
87
88
('t_a' , BytesType ()),
88
89
('y' , IntType ()),
89
- ('sha256_x ' , BytesType ()),
90
+ ('x ' , IntType ()),
90
91
],
91
- next_output_fn = lambda args : [ClauseOutput (
92
+ next_outputs_fn = lambda args , _ : [ClauseOutput (
92
93
n = - 1 ,
93
94
next_contract = g256_s2 ,
94
- next_data = MerkleTree ([ args ['t_a' ], sha256 ( encode_wit_element ( args ['y' ])), args ['sha256_x' ]]). root
95
+ next_state = g256_s2 . State ( t_a = args ['t_a' ], y = args ['y' ], x = args ['x' ])
95
96
)]
96
97
)
97
98
@@ -113,6 +114,21 @@ def __init__(self, alice_pk: bytes, bob_pk: bytes, forfait_timeout):
113
114
114
115
115
116
class G256_S2 (StandardAugmentedP2TR ):
117
+ @dataclass
118
+ class State (ContractState ):
119
+ t_a : bytes
120
+ y : int
121
+ x : bytes
122
+
123
+ def encode (self ):
124
+ return MerkleTree ([self .t_a , sha256 (encode_wit_element (self .y )), sha256 (encode_wit_element (self .x ))]).root
125
+
126
+ def encoder_script ():
127
+ return CScript ([
128
+ OP_TOALTSTACK , OP_SHA256 , OP_FROMALTSTACK , OP_SHA256 ,
129
+ * merkle_root (3 )
130
+ ])
131
+
116
132
def __init__ (self , alice_pk : bytes , bob_pk : bytes , forfait_timeout : int = 10 ):
117
133
self .alice_pk = alice_pk
118
134
self .bob_pk = bob_pk
@@ -133,27 +149,32 @@ def __init__(self, alice_pk: bytes, bob_pk: bytes, forfait_timeout: int = 10):
133
149
def leaf_factory (i : int ): return Leaf (alice_pk , bob_pk , Compute2x )
134
150
135
151
bisectg256_0 = Bisect_1 (alice_pk , bob_pk , 0 , 7 , leaf_factory , forfait_timeout )
136
- # start_challenge: <bob_sig> <t_a> <sha256(y) > <sha256(x) > <z> <t_b>
152
+ # start_challenge: <bob_sig> <t_a> <y > <x > <z> <t_b>
137
153
start_challenge = StandardClause (
138
154
name = "start_challenge" ,
139
155
script = CScript ([
140
156
OP_TOALTSTACK ,
141
- OP_SHA256 , OP_TOALTSTACK ,
142
157
143
- # <bob_sig> <t_a> <sha256(y)> <sha256(x)> --- <t_b> <sha256(z)>
158
+ # check that y != z
159
+ OP_DUP , 3 , OP_PICK , OP_EQUAL , OP_NOT , OP_VERIFY ,
160
+
161
+ OP_TOALTSTACK ,
162
+
163
+ # <bob_sig> <t_a> <y> <x> --- <t_b> <z>
144
164
145
- # verify the embedded data
146
165
* dup (3 ),
147
- * merkle_root (3 ),
166
+
167
+ # verify the embedded data
168
+ * self .State .encoder_script (),
148
169
* check_input_contract (),
149
170
150
- # <bob_sig> <t_a> <sha256(y) > <sha256(x) > --- <t_b> <sha256(z) >
151
- OP_SWAP ,
152
- # <bob_sig> <t_a> <sha256(x)> <sha256(y)> --- <t_b> <sha256(z) >
171
+ # <bob_sig> <t_a> <y > <x > --- <t_b> <z >
172
+ OP_SHA256 , OP_SWAP , OP_SHA256 ,
173
+ # <bob_sig> <t_a> <sha256(x)> <sha256(y)> --- <t_b> <z >
153
174
OP_ROT ,
154
175
# <bob_sig> <sha256(x)> <sha256(y)> <t_a> --- <t_b> <sha256(z)>
155
176
156
- OP_FROMALTSTACK ,
177
+ OP_FROMALTSTACK , OP_SHA256 ,
157
178
# <bob_sig> <sha256(x)> <sha256(y)> <t_a> <sha256(z)> --- <t_b>
158
179
OP_SWAP ,
159
180
# <bob_sig> <sha256(x)> <sha256(y)> <sha256(z)> <t_a> --- <t_b>
@@ -162,7 +183,7 @@ def leaf_factory(i: int): return Leaf(alice_pk, bob_pk, Compute2x)
162
183
163
184
# <bob_sig> <sha256(x)> <sha256(y)> <sha256(z)> <t_a> <t_b>
164
185
165
- * merkle_root ( 5 ),
186
+ * bisectg256_0 . State . encoder_script ( ),
166
187
* check_output_contract (bisectg256_0 ),
167
188
168
189
bob_pk ,
@@ -171,21 +192,21 @@ def leaf_factory(i: int): return Leaf(alice_pk, bob_pk, Compute2x)
171
192
arg_specs = [
172
193
('bob_sig' , SignerType (bob_pk )),
173
194
('t_a' , BytesType ()),
174
- ('sha256_y ' , BytesType ()),
175
- ('sha256_x ' , BytesType ()),
195
+ ('y ' , IntType ()),
196
+ ('x ' , IntType ()),
176
197
('z' , IntType ()),
177
198
('t_b' , BytesType ()),
178
199
],
179
- next_output_fn = lambda args : [ClauseOutput (
200
+ next_outputs_fn = lambda args , _ : [ClauseOutput (
180
201
n = - 1 ,
181
202
next_contract = bisectg256_0 ,
182
- next_data = MerkleTree ([
183
- args ['sha256_x' ] ,
184
- args ['sha256_y' ] ,
185
- sha256 (encode_wit_element (args ['z' ])),
186
- args ['t_a' ],
187
- args ['t_b' ],
188
- ]). root
203
+ next_state = bisectg256_0 . State (
204
+ h_i = sha256 ( encode_wit_element ( args ['x' ])) ,
205
+ h_j_plus_1_a = sha256 ( encode_wit_element ( args ['y' ])) ,
206
+ h_j_plus_1_b = sha256 (encode_wit_element (args ['z' ])),
207
+ t_i_j_a = args ['t_a' ],
208
+ t_i_j_b = args ['t_b' ],
209
+ )
189
210
)]
190
211
)
191
212
0 commit comments