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,20 @@ 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
+ pub const SIP_031_MAINNET_ADDR : LazyLock < StacksAddress > = LazyLock :: new ( || {
100
+ StacksAddress :: from_string ( "SM1Z6BP8PDKYKXTZXXSKXFEY6NQ7RAM7DAEAYR045" ) . unwrap ( )
101
+ } ) ;
102
+
103
+ /// The initial recipient address for SIP-031 on testnet.
104
+ pub const SIP_031_TESTNET_ADDR : LazyLock < StacksAddress > = LazyLock :: new ( || {
105
+ StacksAddress :: from_string ( "ST1QCN9YMXMJPJ0Y5EMR627FCWDXQWT1CRK9CWN23" ) . unwrap ( )
106
+ } ) ;
107
+
108
+ #[ cfg( test) ]
109
+ pub static TEST_SIP_031_ADDR : LazyLock < TestFlag < Option < StacksAddress > > > =
110
+ LazyLock :: new ( TestFlag :: default) ;
111
+
93
112
pub mod docs;
94
113
95
114
lazy_static ! {
@@ -139,6 +158,40 @@ fn make_testnet_cost_voting() -> String {
139
158
)
140
159
}
141
160
161
+ #[ cfg( test) ]
162
+ pub fn get_sip_031_recipient_addr ( is_mainnet : bool ) -> StacksAddress {
163
+ if is_mainnet {
164
+ SIP_031_MAINNET_ADDR . clone ( )
165
+ } else {
166
+ TEST_SIP_031_ADDR
167
+ . get ( )
168
+ . unwrap_or ( SIP_031_TESTNET_ADDR . clone ( ) )
169
+ }
170
+ }
171
+
172
+ #[ cfg( not( test) ) ]
173
+ pub fn get_sip_031_recipient_addr ( is_mainnet : bool ) -> StacksAddress {
174
+ if is_mainnet {
175
+ SIP_031_MAINNET_ADDR . clone ( )
176
+ } else {
177
+ SIP_031_TESTNET_ADDR . clone ( )
178
+ }
179
+ }
180
+
181
+ /// Generate the contract body for the SIP-031 contract.
182
+ ///
183
+ /// When on mainnet, only the constant [SIP_031_MAINNET_ADDR] is used.
184
+ /// Otherwise, on testnet, you can provide a configurable address.
185
+ pub fn make_sip_031_body ( is_mainnet : bool ) -> String {
186
+ let addr = get_sip_031_recipient_addr ( is_mainnet) . to_string ( ) ;
187
+
188
+ SIP_031_BODY . replacen (
189
+ "(define-data-var recipient principal tx-sender)" ,
190
+ & format ! ( "(define-data-var recipient principal '{addr})" ) ,
191
+ 1 ,
192
+ )
193
+ }
194
+
142
195
pub fn make_contract_id ( addr : & StacksAddress , name : & str ) -> QualifiedContractIdentifier {
143
196
QualifiedContractIdentifier :: new (
144
197
StandardPrincipalData :: from ( addr. clone ( ) ) ,
@@ -2631,7 +2684,7 @@ pub mod test {
2631
2684
)
2632
2685
(begin
2633
2686
;; take the stx from the tx-sender
2634
-
2687
+
2635
2688
(unwrap-panic (stx-transfer? amount-ustx tx-sender this-contract))
2636
2689
2637
2690
;; this contract stacks the stx given to it
@@ -5847,5 +5900,34 @@ pub mod test {
5847
5900
}
5848
5901
}
5849
5902
5903
+ #[ test]
5904
+ fn test_sip031_addrs ( ) {
5905
+ assert_eq ! (
5906
+ SIP_031_MAINNET_ADDR . to_string( ) ,
5907
+ "SM1Z6BP8PDKYKXTZXXSKXFEY6NQ7RAM7DAEAYR045"
5908
+ ) ;
5909
+ assert_eq ! (
5910
+ SIP_031_TESTNET_ADDR . to_string( ) ,
5911
+ "ST1QCN9YMXMJPJ0Y5EMR627FCWDXQWT1CRK9CWN23"
5912
+ ) ;
5913
+
5914
+ assert_eq ! (
5915
+ get_sip_031_recipient_addr( true ) ,
5916
+ SIP_031_MAINNET_ADDR . clone( )
5917
+ ) ;
5918
+ assert_eq ! (
5919
+ get_sip_031_recipient_addr( false ) ,
5920
+ SIP_031_TESTNET_ADDR . clone( )
5921
+ ) ;
5922
+
5923
+ let transient = StacksAddress :: from ( StandardPrincipalData :: transient ( ) . clone ( ) ) ;
5924
+ TEST_SIP_031_ADDR . set ( Some ( transient. clone ( ) ) ) ;
5925
+ assert_eq ! ( get_sip_031_recipient_addr( false ) , transient. clone( ) ) ;
5926
+ assert_eq ! (
5927
+ get_sip_031_recipient_addr( true ) ,
5928
+ SIP_031_MAINNET_ADDR . clone( )
5929
+ ) ;
5930
+ }
5931
+
5850
5932
// TODO: need Stacking-rejection with a BTC address -- contract name in OP_RETURN? (NEXT)
5851
5933
}
0 commit comments