@hazbase/simplicity 0.0.5 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +645 -148
- package/dist/cli.js +2125 -159
- package/dist/client/SimplicityClient.d.ts +64 -290
- package/dist/client/SimplicityClient.js +65 -23
- package/dist/core/executor.js +67 -92
- package/dist/core/outputBinding.d.ts +61 -0
- package/dist/core/outputBinding.js +552 -0
- package/dist/core/schnorr.d.ts +5 -0
- package/dist/core/schnorr.js +34 -0
- package/dist/core/types.d.ts +553 -1
- package/dist/docs/definitions/bond-anchor.simf +19 -0
- package/dist/docs/definitions/bond-definition.json +10 -0
- package/dist/docs/definitions/bond-descriptor-bound-settlement-machine.simf +144 -0
- package/dist/docs/definitions/bond-issuance-anchor.simf +26 -0
- package/dist/docs/definitions/bond-issuance-state-partial-redemption.json +18 -0
- package/dist/docs/definitions/bond-issuance-state-redeemed.json +18 -0
- package/dist/docs/definitions/bond-issuance-state.json +12 -0
- package/dist/docs/definitions/bond-redemption-state-machine.simf +118 -0
- package/dist/docs/definitions/bond-redemption-transition.simf +41 -0
- package/dist/docs/definitions/bond-script-bound-settlement-machine.simf +142 -0
- package/dist/docs/definitions/fund-capital-call-open.simf +82 -0
- package/dist/docs/definitions/fund-capital-call-refund-only.simf +33 -0
- package/dist/docs/definitions/fund-capital-call-state.json +11 -0
- package/dist/docs/definitions/fund-definition.json +8 -0
- package/dist/docs/definitions/fund-distribution-claim.simf +57 -0
- package/dist/docs/definitions/recursive-delay-direct-next.simf +60 -0
- package/dist/docs/definitions/recursive-delay-optional.simf +88 -0
- package/dist/docs/definitions/recursive-delay-required.simf +72 -0
- package/dist/docs/definitions/recursive-delay.simf +83 -0
- package/dist/docs/definitions/recursive-policy-transfer-machine.simf +65 -0
- package/dist/domain/bond.d.ts +8583 -721
- package/dist/domain/bond.js +1272 -31
- package/dist/domain/bondSettlementValidation.d.ts +2 -0
- package/dist/domain/bondSettlementValidation.js +28 -0
- package/dist/domain/bondValidation.d.ts +6 -0
- package/dist/domain/bondValidation.js +65 -3
- package/dist/domain/fund.d.ts +2069 -0
- package/dist/domain/fund.js +1384 -0
- package/dist/domain/fundValidation.d.ts +122 -0
- package/dist/domain/fundValidation.js +635 -0
- package/dist/domain/policies.d.ts +1051 -0
- package/dist/domain/policies.js +1605 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +85 -21
- package/package.json +15 -2
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* LP distribution claim contract.
|
|
3
|
+
*
|
|
4
|
+
* Fund admin prepares the distribution state off-chain, then the LP claims the
|
|
5
|
+
* payout in a one-shot spend. Runtime output binding is optional.
|
|
6
|
+
*/
|
|
7
|
+
fn not(bit: bool) -> bool {
|
|
8
|
+
<u1>::into(jet::complement_1(<bool>::into(bit)))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
fn require_definition_anchor() {
|
|
12
|
+
let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
|
|
13
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
14
|
+
assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fn require_state_anchor() {
|
|
18
|
+
let anchored_state_hash: u256 = 0x{{STATE_HASH}};
|
|
19
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
20
|
+
assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fn require_output_shape(expected_output_hash: u256, expected_output_script_hash: u256, binding_mode: u8) {
|
|
24
|
+
match jet::eq_8(binding_mode, 1) {
|
|
25
|
+
true => {
|
|
26
|
+
let actual_output_hash: u256 = match jet::output_hash(0) {
|
|
27
|
+
Some(output_hash : u256) => output_hash,
|
|
28
|
+
None => panic!(),
|
|
29
|
+
};
|
|
30
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
31
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
32
|
+
assert!(jet::eq_256(actual_output_hash, expected_output_hash));
|
|
33
|
+
},
|
|
34
|
+
false => {
|
|
35
|
+
match jet::eq_8(binding_mode, 2) {
|
|
36
|
+
true => {
|
|
37
|
+
let actual_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
38
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
39
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
40
|
+
assert!(jet::eq_256(actual_output_script_hash, expected_output_script_hash));
|
|
41
|
+
},
|
|
42
|
+
false => {},
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fn main() {
|
|
49
|
+
require_definition_anchor();
|
|
50
|
+
require_state_anchor();
|
|
51
|
+
let expected_output_hash: u256 = witness::EXPECTED_PAYOUT_OUTPUT_HASH;
|
|
52
|
+
let expected_output_script_hash: u256 = witness::EXPECTED_PAYOUT_OUTPUT_SCRIPT_HASH;
|
|
53
|
+
let binding_mode: u8 = witness::OUTPUT_BINDING_MODE;
|
|
54
|
+
require_output_shape(expected_output_hash, expected_output_script_hash, binding_mode);
|
|
55
|
+
let lp: Pubkey = 0x{{LP_XONLY}};
|
|
56
|
+
jet::bip_0340_verify((lp, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
|
|
57
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Recursive delay policy direct-transfer state contract.
|
|
3
|
+
*
|
|
4
|
+
* This variant is used for 1tx required-mode transfers. The current recipient
|
|
5
|
+
* can spend only after the configured relative delay, and only into the next
|
|
6
|
+
* constrained output shape committed through witness values at execution time.
|
|
7
|
+
*/
|
|
8
|
+
fn not(bit: bool) -> bool {
|
|
9
|
+
<u1>::into(jet::complement_1(<bool>::into(bit)))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
fn require_definition_anchor() {
|
|
13
|
+
let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
|
|
14
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
15
|
+
assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fn require_state_anchor() {
|
|
19
|
+
let anchored_state_hash: u256 = 0x{{STATE_HASH}};
|
|
20
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
21
|
+
assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fn require_policy_hash_anchor() {
|
|
25
|
+
let anchored_policy_hash: u256 = 0x{{POLICY_HASH}};
|
|
26
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
27
|
+
assert!(not(jet::eq_256(anchored_policy_hash, zero_hash)));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fn require_required_mode() {
|
|
31
|
+
assert!(jet::eq_8({{PROPAGATION_MODE_8}}, 1));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn require_next_transition_witness(next_policy_hash: u256, next_output_descriptor_hash: u256) {
|
|
35
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
36
|
+
assert!(not(jet::eq_256(next_policy_hash, zero_hash)));
|
|
37
|
+
assert!(not(jet::eq_256(next_output_descriptor_hash, zero_hash)));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fn require_output_shape(expected_next_output_script_hash: u256) {
|
|
41
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
42
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
43
|
+
let actual_next_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
44
|
+
assert!(jet::eq_256(actual_next_output_script_hash, expected_next_output_script_hash));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fn main() {
|
|
48
|
+
require_definition_anchor();
|
|
49
|
+
require_state_anchor();
|
|
50
|
+
require_policy_hash_anchor();
|
|
51
|
+
require_required_mode();
|
|
52
|
+
let next_policy_hash: u256 = witness::NEXT_POLICY_HASH;
|
|
53
|
+
let next_output_descriptor_hash: u256 = witness::NEXT_OUTPUT_DESCRIPTOR_HASH;
|
|
54
|
+
let expected_next_output_script_hash: u256 = witness::EXPECTED_NEXT_OUTPUT_SCRIPT_HASH;
|
|
55
|
+
require_next_transition_witness(next_policy_hash, next_output_descriptor_hash);
|
|
56
|
+
require_output_shape(expected_next_output_script_hash);
|
|
57
|
+
jet::check_lock_distance({{LOCK_DISTANCE}});
|
|
58
|
+
let signer: Pubkey = 0x{{SIGNER_XONLY}};
|
|
59
|
+
jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
|
|
60
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Recursive delay policy state contract for optional / terminating propagation.
|
|
3
|
+
*
|
|
4
|
+
* The current recipient can spend only after the configured relative delay.
|
|
5
|
+
* In optional mode, callers may either exit plainly or provide witness values
|
|
6
|
+
* that bind the next constrained output script hash in the same transaction.
|
|
7
|
+
*/
|
|
8
|
+
fn not(bit: bool) -> bool {
|
|
9
|
+
<u1>::into(jet::complement_1(<bool>::into(bit)))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
fn require_definition_anchor() {
|
|
13
|
+
let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
|
|
14
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
15
|
+
assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fn require_state_anchor() {
|
|
19
|
+
let anchored_state_hash: u256 = 0x{{STATE_HASH}};
|
|
20
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
21
|
+
assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fn require_policy_hash_anchor() {
|
|
25
|
+
let anchored_policy_hash: u256 = 0x{{POLICY_HASH}};
|
|
26
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
27
|
+
assert!(not(jet::eq_256(anchored_policy_hash, zero_hash)));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fn require_next_transition_witness(next_policy_hash: u256, next_output_descriptor_hash: u256) {
|
|
31
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
32
|
+
assert!(not(jet::eq_256(next_policy_hash, zero_hash)));
|
|
33
|
+
assert!(not(jet::eq_256(next_output_descriptor_hash, zero_hash)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fn maybe_require_recursive_branch(
|
|
37
|
+
next_policy_hash: u256,
|
|
38
|
+
next_output_descriptor_hash: u256,
|
|
39
|
+
expected_next_output_hash: u256,
|
|
40
|
+
expected_next_output_script_hash: u256
|
|
41
|
+
) {
|
|
42
|
+
match jet::eq_8({{PROPAGATION_MODE_8}}, 2) {
|
|
43
|
+
true => {
|
|
44
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
45
|
+
match not(jet::eq_256(expected_next_output_script_hash, zero_hash)) {
|
|
46
|
+
true => {
|
|
47
|
+
require_next_transition_witness(next_policy_hash, next_output_descriptor_hash);
|
|
48
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
49
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
50
|
+
match not(jet::eq_256(expected_next_output_hash, zero_hash)) {
|
|
51
|
+
true => {
|
|
52
|
+
let actual_next_output_hash: u256 = match jet::output_hash(0) {
|
|
53
|
+
Some(output_hash : u256) => output_hash,
|
|
54
|
+
None => panic!(),
|
|
55
|
+
};
|
|
56
|
+
assert!(jet::eq_256(actual_next_output_hash, expected_next_output_hash));
|
|
57
|
+
},
|
|
58
|
+
false => {
|
|
59
|
+
let actual_next_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
60
|
+
assert!(jet::eq_256(actual_next_output_script_hash, expected_next_output_script_hash));
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
false => {},
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
false => {},
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fn main() {
|
|
72
|
+
require_definition_anchor();
|
|
73
|
+
require_state_anchor();
|
|
74
|
+
require_policy_hash_anchor();
|
|
75
|
+
let next_policy_hash: u256 = witness::NEXT_POLICY_HASH;
|
|
76
|
+
let next_output_descriptor_hash: u256 = witness::NEXT_OUTPUT_DESCRIPTOR_HASH;
|
|
77
|
+
let expected_next_output_hash: u256 = witness::EXPECTED_NEXT_OUTPUT_HASH;
|
|
78
|
+
let expected_next_output_script_hash: u256 = witness::EXPECTED_NEXT_OUTPUT_SCRIPT_HASH;
|
|
79
|
+
maybe_require_recursive_branch(
|
|
80
|
+
next_policy_hash,
|
|
81
|
+
next_output_descriptor_hash,
|
|
82
|
+
expected_next_output_hash,
|
|
83
|
+
expected_next_output_script_hash
|
|
84
|
+
);
|
|
85
|
+
jet::check_lock_distance({{LOCK_DISTANCE}});
|
|
86
|
+
let signer: Pubkey = 0x{{SIGNER_XONLY}};
|
|
87
|
+
jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
|
|
88
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Recursive delay policy state contract for required propagation.
|
|
3
|
+
*
|
|
4
|
+
* The current recipient can spend only after the configured relative delay,
|
|
5
|
+
* and only into the next constrained output shape supplied at execution time.
|
|
6
|
+
*/
|
|
7
|
+
fn not(bit: bool) -> bool {
|
|
8
|
+
<u1>::into(jet::complement_1(<bool>::into(bit)))
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
fn require_definition_anchor() {
|
|
12
|
+
let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
|
|
13
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
14
|
+
assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fn require_state_anchor() {
|
|
18
|
+
let anchored_state_hash: u256 = 0x{{STATE_HASH}};
|
|
19
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
20
|
+
assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
fn require_policy_hash_anchor() {
|
|
24
|
+
let anchored_policy_hash: u256 = 0x{{POLICY_HASH}};
|
|
25
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
26
|
+
assert!(not(jet::eq_256(anchored_policy_hash, zero_hash)));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fn require_required_mode() {
|
|
30
|
+
assert!(jet::eq_8({{PROPAGATION_MODE_8}}, 1));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fn require_next_transition_witness(next_policy_hash: u256, next_output_descriptor_hash: u256) {
|
|
34
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
35
|
+
assert!(not(jet::eq_256(next_policy_hash, zero_hash)));
|
|
36
|
+
assert!(not(jet::eq_256(next_output_descriptor_hash, zero_hash)));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
fn require_output_shape(expected_next_output_hash: u256, expected_next_output_script_hash: u256) {
|
|
40
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
41
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
42
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
43
|
+
match not(jet::eq_256(expected_next_output_hash, zero_hash)) {
|
|
44
|
+
true => {
|
|
45
|
+
let actual_next_output_hash: u256 = match jet::output_hash(0) {
|
|
46
|
+
Some(output_hash : u256) => output_hash,
|
|
47
|
+
None => panic!(),
|
|
48
|
+
};
|
|
49
|
+
assert!(jet::eq_256(actual_next_output_hash, expected_next_output_hash));
|
|
50
|
+
},
|
|
51
|
+
false => {
|
|
52
|
+
let actual_next_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
53
|
+
assert!(jet::eq_256(actual_next_output_script_hash, expected_next_output_script_hash));
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fn main() {
|
|
59
|
+
require_definition_anchor();
|
|
60
|
+
require_state_anchor();
|
|
61
|
+
require_policy_hash_anchor();
|
|
62
|
+
require_required_mode();
|
|
63
|
+
let next_policy_hash: u256 = witness::NEXT_POLICY_HASH;
|
|
64
|
+
let next_output_descriptor_hash: u256 = witness::NEXT_OUTPUT_DESCRIPTOR_HASH;
|
|
65
|
+
let expected_next_output_hash: u256 = witness::EXPECTED_NEXT_OUTPUT_HASH;
|
|
66
|
+
let expected_next_output_script_hash: u256 = witness::EXPECTED_NEXT_OUTPUT_SCRIPT_HASH;
|
|
67
|
+
require_next_transition_witness(next_policy_hash, next_output_descriptor_hash);
|
|
68
|
+
require_output_shape(expected_next_output_hash, expected_next_output_script_hash);
|
|
69
|
+
jet::check_lock_distance({{LOCK_DISTANCE}});
|
|
70
|
+
let signer: Pubkey = 0x{{SIGNER_XONLY}};
|
|
71
|
+
jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
|
|
72
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Recursive delay policy state contract.
|
|
3
|
+
*
|
|
4
|
+
* This contract commits the policy template hash, the concrete policy state hash,
|
|
5
|
+
* and a policy hash that binds recipient + params + propagation mode. The holder
|
|
6
|
+
* can spend only after the configured relative delay.
|
|
7
|
+
*
|
|
8
|
+
* In required propagation mode it also enforces a first hop into the generic
|
|
9
|
+
* recursive policy router machine, so the current state cannot directly exit to
|
|
10
|
+
* a plain address.
|
|
11
|
+
*/
|
|
12
|
+
fn not(bit: bool) -> bool {
|
|
13
|
+
<u1>::into(jet::complement_1(<bool>::into(bit)))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
fn require_definition_anchor() {
|
|
17
|
+
let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
|
|
18
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
19
|
+
assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
fn require_state_anchor() {
|
|
23
|
+
let anchored_state_hash: u256 = 0x{{STATE_HASH}};
|
|
24
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
25
|
+
assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fn require_policy_hash_anchor() {
|
|
29
|
+
let anchored_policy_hash: u256 = 0x{{POLICY_HASH}};
|
|
30
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
31
|
+
assert!(not(jet::eq_256(anchored_policy_hash, zero_hash)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn require_router_machine_anchor() {
|
|
35
|
+
let router_machine_script_hash: u256 = 0x{{ROUTER_MACHINE_SCRIPT_HASH_256}};
|
|
36
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
37
|
+
match not(jet::eq_8({{PROPAGATION_MODE_8}}, 3)) {
|
|
38
|
+
true => assert!(not(jet::eq_256(router_machine_script_hash, zero_hash))),
|
|
39
|
+
false => {},
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fn require_required_machine_hop() {
|
|
44
|
+
match jet::eq_8({{REQUIRE_MACHINE_HOP_8}}, 1) {
|
|
45
|
+
true => {
|
|
46
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
47
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
48
|
+
let router_machine_script_hash: u256 = 0x{{ROUTER_MACHINE_SCRIPT_HASH_256}};
|
|
49
|
+
let next_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
50
|
+
assert!(jet::eq_256(router_machine_script_hash, next_output_script_hash));
|
|
51
|
+
},
|
|
52
|
+
false => {},
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fn require_optional_machine_hop_if_selected() {
|
|
57
|
+
match jet::eq_8({{PROPAGATION_MODE_8}}, 2) {
|
|
58
|
+
true => {
|
|
59
|
+
let router_machine_script_hash: u256 = 0x{{ROUTER_MACHINE_SCRIPT_HASH_256}};
|
|
60
|
+
let next_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
61
|
+
match jet::eq_256(router_machine_script_hash, next_output_script_hash) {
|
|
62
|
+
true => {
|
|
63
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
64
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
65
|
+
},
|
|
66
|
+
false => {},
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
false => {},
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fn main() {
|
|
74
|
+
require_definition_anchor();
|
|
75
|
+
require_state_anchor();
|
|
76
|
+
require_policy_hash_anchor();
|
|
77
|
+
require_router_machine_anchor();
|
|
78
|
+
require_required_machine_hop();
|
|
79
|
+
require_optional_machine_hop_if_selected();
|
|
80
|
+
jet::check_lock_distance({{LOCK_DISTANCE}});
|
|
81
|
+
let signer: Pubkey = 0x{{SIGNER_XONLY}};
|
|
82
|
+
jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
|
|
83
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Recursive policy transfer machine.
|
|
3
|
+
*
|
|
4
|
+
* This machine is generic for a given current policy state. The next policy hash
|
|
5
|
+
* and output descriptor commitments are supplied at execution time through witness
|
|
6
|
+
* values, while the current state still commits the router machine as the only
|
|
7
|
+
* allowed first hop in required propagation mode.
|
|
8
|
+
*/
|
|
9
|
+
fn not(bit: bool) -> bool {
|
|
10
|
+
<u1>::into(jet::complement_1(<bool>::into(bit)))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
fn require_definition_anchor() {
|
|
14
|
+
let anchored_definition_hash: u256 = 0x{{DEFINITION_HASH}};
|
|
15
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
16
|
+
assert!(not(jet::eq_256(anchored_definition_hash, zero_hash)));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fn require_state_anchor() {
|
|
20
|
+
let anchored_state_hash: u256 = 0x{{STATE_HASH}};
|
|
21
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
22
|
+
assert!(not(jet::eq_256(anchored_state_hash, zero_hash)));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fn require_policy_hash_anchor() {
|
|
26
|
+
let anchored_policy_hash: u256 = 0x{{POLICY_HASH}};
|
|
27
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
28
|
+
assert!(not(jet::eq_256(anchored_policy_hash, zero_hash)));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fn require_next_transition_witness(next_policy_hash: u256, next_output_descriptor_hash: u256) {
|
|
32
|
+
let zero_hash: u256 = 0x0000000000000000000000000000000000000000000000000000000000000000;
|
|
33
|
+
assert!(not(jet::eq_256(next_policy_hash, zero_hash)));
|
|
34
|
+
assert!(not(jet::eq_256(next_output_descriptor_hash, zero_hash)));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
fn require_output_shape(expected_next_output_hash: u256, expected_next_output_script_hash: u256, binding_mode: u8) {
|
|
38
|
+
assert!(jet::eq_32(jet::num_outputs(), 2));
|
|
39
|
+
assert!(unwrap(jet::output_is_fee(1)));
|
|
40
|
+
let actual_next_output_hash: u256 = match jet::output_hash(0) {
|
|
41
|
+
Some(output_hash : u256) => output_hash,
|
|
42
|
+
None => panic!(),
|
|
43
|
+
};
|
|
44
|
+
let actual_next_output_script_hash: u256 = unwrap(jet::output_script_hash(0));
|
|
45
|
+
|
|
46
|
+
match jet::eq_8(binding_mode, 0x01) {
|
|
47
|
+
true => assert!(jet::eq_256(actual_next_output_hash, expected_next_output_hash)),
|
|
48
|
+
false => assert!(jet::eq_256(actual_next_output_script_hash, expected_next_output_script_hash)),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fn main() {
|
|
53
|
+
require_definition_anchor();
|
|
54
|
+
require_state_anchor();
|
|
55
|
+
require_policy_hash_anchor();
|
|
56
|
+
let next_policy_hash: u256 = witness::NEXT_POLICY_HASH;
|
|
57
|
+
let next_output_descriptor_hash: u256 = witness::NEXT_OUTPUT_DESCRIPTOR_HASH;
|
|
58
|
+
let expected_next_output_hash: u256 = witness::EXPECTED_NEXT_OUTPUT_HASH;
|
|
59
|
+
let expected_next_output_script_hash: u256 = witness::EXPECTED_NEXT_OUTPUT_SCRIPT_HASH;
|
|
60
|
+
let binding_mode: u8 = witness::OUTPUT_BINDING_MODE;
|
|
61
|
+
require_next_transition_witness(next_policy_hash, next_output_descriptor_hash);
|
|
62
|
+
require_output_shape(expected_next_output_hash, expected_next_output_script_hash, binding_mode);
|
|
63
|
+
let signer: Pubkey = 0x{{SIGNER_XONLY}};
|
|
64
|
+
jet::bip_0340_verify((signer, jet::sig_all_hash()), witness::SIGNER_SIGNATURE)
|
|
65
|
+
}
|