16
16
17
17
use std:: cmp;
18
18
use std:: collections:: BTreeMap ;
19
+ use std:: sync:: LazyLock ;
19
20
21
+ use clarity:: types:: Address ;
20
22
use clarity:: vm:: analysis:: CheckErrors ;
21
23
use clarity:: vm:: ast:: ASTRules ;
22
24
use clarity:: vm:: clarity:: { Error as ClarityError , TransactionConnection } ;
@@ -34,6 +36,8 @@ use serde::Deserialize;
34
36
use stacks_common:: codec:: StacksMessageCodec ;
35
37
use stacks_common:: types:: chainstate:: { StacksAddress , StacksBlockId } ;
36
38
use stacks_common:: util:: hash:: { hex_bytes, to_hex} ;
39
+ #[ cfg( test) ]
40
+ use stacks_common:: util:: tests:: TestFlag ;
37
41
38
42
use crate :: burnchains:: { Burnchain , PoxConstants } ;
39
43
use crate :: chainstate:: burn:: db:: sortdb:: SortitionDB ;
@@ -77,7 +81,8 @@ pub const SIGNERS_BODY: &str = std::include_str!("signers.clar");
77
81
pub const SIGNERS_DB_0_BODY : & str = std:: include_str!( "signers-0-xxx.clar" ) ;
78
82
pub const SIGNERS_DB_1_BODY : & str = std:: include_str!( "signers-1-xxx.clar" ) ;
79
83
pub const SIGNERS_VOTING_BODY : & str = std:: include_str!( "signers-voting.clar" ) ;
80
- pub const SIP_031_BODY : & str = std:: include_str!( "sip-031.clar" ) ;
84
+ /// Not public - be sure to use [make_sip_031_body]
85
+ const SIP_031_BODY : & str = std:: include_str!( "sip-031.clar" ) ;
81
86
82
87
pub const COSTS_1_NAME : & str = "costs" ;
83
88
pub const COSTS_2_NAME : & str = "costs-2" ;
@@ -90,6 +95,22 @@ pub const BOOT_TEST_POX_4_AGG_KEY_FNAME: &str = "aggregate-key";
90
95
91
96
pub const MINERS_NAME : & str = "miners" ;
92
97
98
+ /// The initial recipient address for SIP-031 on mainnet.
99
+ /// TODO: replace with actual address
100
+ pub const SIP_031_MAINNET_ADDR : LazyLock < StacksAddress > = LazyLock :: new ( || {
101
+ StacksAddress :: from_string ( "SP1A2K3ENNA6QQ7G8DVJXM24T6QMBDVS7D0TRTAR5" ) . unwrap ( )
102
+ } ) ;
103
+
104
+ /// The initial recipient address for SIP-031 on testnet.
105
+ /// TODO: replace with actual address
106
+ pub const SIP_031_TESTNET_ADDR : LazyLock < StacksAddress > = LazyLock :: new ( || {
107
+ StacksAddress :: from_string ( "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM" ) . unwrap ( )
108
+ } ) ;
109
+
110
+ #[ cfg( test) ]
111
+ pub static TEST_SIP_031_ADDR : LazyLock < TestFlag < Option < StacksAddress > > > =
112
+ LazyLock :: new ( TestFlag :: default) ;
113
+
93
114
pub mod docs;
94
115
95
116
lazy_static ! {
@@ -139,6 +160,40 @@ fn make_testnet_cost_voting() -> String {
139
160
)
140
161
}
141
162
163
+ #[ cfg( test) ]
164
+ pub fn get_sip_031_recipient_addr ( is_mainnet : bool ) -> StacksAddress {
165
+ if is_mainnet {
166
+ SIP_031_MAINNET_ADDR . clone ( )
167
+ } else {
168
+ TEST_SIP_031_ADDR
169
+ . get ( )
170
+ . unwrap_or ( SIP_031_TESTNET_ADDR . clone ( ) )
171
+ }
172
+ }
173
+
174
+ #[ cfg( not( test) ) ]
175
+ pub fn get_sip_031_recipient_addr ( is_mainnet : bool ) -> StacksAddress {
176
+ if is_mainnet {
177
+ SIP_031_MAINNET_ADDR . clone ( )
178
+ } else {
179
+ SIP_031_TESTNET_ADDR . clone ( )
180
+ }
181
+ }
182
+
183
+ /// Generate the contract body for the SIP-031 contract.
184
+ ///
185
+ /// When on mainnet, only the constant [SIP_031_MAINNET_ADDR] is used.
186
+ /// Otherwise, on testnet, you can provide a configurable address.
187
+ pub fn make_sip_031_body ( is_mainnet : bool ) -> String {
188
+ let addr = get_sip_031_recipient_addr ( is_mainnet) . to_string ( ) ;
189
+
190
+ SIP_031_BODY . replacen (
191
+ "(define-data-var recipient principal tx-sender)" ,
192
+ & format ! ( "(define-data-var recipient principal '{})" , addr) ,
193
+ 1 ,
194
+ )
195
+ }
196
+
142
197
pub fn make_contract_id ( addr : & StacksAddress , name : & str ) -> QualifiedContractIdentifier {
143
198
QualifiedContractIdentifier :: new (
144
199
StandardPrincipalData :: from ( addr. clone ( ) ) ,
@@ -2631,7 +2686,7 @@ pub mod test {
2631
2686
)
2632
2687
(begin
2633
2688
;; take the stx from the tx-sender
2634
-
2689
+
2635
2690
(unwrap-panic (stx-transfer? amount-ustx tx-sender this-contract))
2636
2691
2637
2692
;; this contract stacks the stx given to it
@@ -5847,5 +5902,34 @@ pub mod test {
5847
5902
}
5848
5903
}
5849
5904
5905
+ #[ test]
5906
+ fn test_sip031_addrs ( ) {
5907
+ assert_eq ! (
5908
+ SIP_031_MAINNET_ADDR . to_string( ) ,
5909
+ "SP1A2K3ENNA6QQ7G8DVJXM24T6QMBDVS7D0TRTAR5"
5910
+ ) ;
5911
+ assert_eq ! (
5912
+ SIP_031_TESTNET_ADDR . to_string( ) ,
5913
+ "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM"
5914
+ ) ;
5915
+
5916
+ assert_eq ! (
5917
+ get_sip_031_recipient_addr( true ) ,
5918
+ SIP_031_MAINNET_ADDR . clone( )
5919
+ ) ;
5920
+ assert_eq ! (
5921
+ get_sip_031_recipient_addr( false ) ,
5922
+ SIP_031_TESTNET_ADDR . clone( )
5923
+ ) ;
5924
+
5925
+ let transient = StacksAddress :: from ( StandardPrincipalData :: transient ( ) . clone ( ) ) ;
5926
+ TEST_SIP_031_ADDR . set ( Some ( transient. clone ( ) ) ) ;
5927
+ assert_eq ! ( get_sip_031_recipient_addr( false ) , transient. clone( ) ) ;
5928
+ assert_eq ! (
5929
+ get_sip_031_recipient_addr( true ) ,
5930
+ SIP_031_MAINNET_ADDR . clone( )
5931
+ ) ;
5932
+ }
5933
+
5850
5934
// TODO: need Stacking-rejection with a BTC address -- contract name in OP_RETURN? (NEXT)
5851
5935
}
0 commit comments