@@ -29,6 +29,7 @@ use clarity::vm::database::{
29
29
RollbackWrapperPersistedLog , STXBalance , NULL_BURN_STATE_DB , NULL_HEADER_DB ,
30
30
} ;
31
31
use clarity:: vm:: errors:: Error as InterpreterError ;
32
+ use clarity:: vm:: events:: { STXEventType , STXMintEventData } ;
32
33
use clarity:: vm:: representations:: SymbolicExpression ;
33
34
use clarity:: vm:: types:: { PrincipalData , QualifiedContractIdentifier , Value } ;
34
35
use clarity:: vm:: { ClarityVersion , ContractName } ;
@@ -42,7 +43,8 @@ use crate::chainstate::stacks::boot::{
42
43
BOOT_CODE_COST_VOTING_TESTNET as BOOT_CODE_COST_VOTING , BOOT_CODE_POX_TESTNET , COSTS_2_NAME ,
43
44
COSTS_3_NAME , POX_2_MAINNET_CODE , POX_2_NAME , POX_2_TESTNET_CODE , POX_3_MAINNET_CODE ,
44
45
POX_3_NAME , POX_3_TESTNET_CODE , POX_4_CODE , POX_4_NAME , SIGNERS_BODY , SIGNERS_DB_0_BODY ,
45
- SIGNERS_DB_1_BODY , SIGNERS_NAME , SIGNERS_VOTING_BODY , SIGNERS_VOTING_NAME ,
46
+ SIGNERS_DB_1_BODY , SIGNERS_NAME , SIGNERS_VOTING_BODY , SIGNERS_VOTING_NAME , SIP_031_BODY ,
47
+ SIP_031_NAME ,
46
48
} ;
47
49
use crate :: chainstate:: stacks:: db:: { StacksAccount , StacksChainState } ;
48
50
use crate :: chainstate:: stacks:: events:: { StacksTransactionEvent , StacksTransactionReceipt } ;
@@ -57,6 +59,8 @@ use crate::util_lib::boot::{boot_code_acc, boot_code_addr, boot_code_id, boot_co
57
59
use crate :: util_lib:: db:: Error as DatabaseError ;
58
60
use crate :: util_lib:: strings:: StacksString ;
59
61
62
+ pub const SIP_031_INITIAL_MINT : u128 = 200_000_000_000_000 ;
63
+
60
64
///
61
65
/// A high-level interface for interacting with the Clarity VM.
62
66
///
@@ -1617,10 +1621,89 @@ impl<'a> ClarityBlockConnection<'a, '_> {
1617
1621
tx_conn. epoch = StacksEpochId :: Epoch32 ;
1618
1622
} ) ;
1619
1623
1620
- // TODO: SIP-031 setup (minting and transfer to the boot contract)
1624
+ let mut receipts = vec![ ] ;
1625
+
1626
+ let boot_code_account = self
1627
+ . get_boot_code_account( )
1628
+ . expect( "FATAL: did not get boot account" ) ;
1629
+
1630
+ let mainnet = self . mainnet;
1631
+ let tx_version = if mainnet {
1632
+ TransactionVersion :: Mainnet
1633
+ } else {
1634
+ TransactionVersion :: Testnet
1635
+ } ;
1636
+
1637
+ let boot_code_address = boot_code_addr( mainnet) ;
1638
+ let boot_code_auth = boot_code_tx_auth( boot_code_address. clone( ) ) ;
1639
+
1640
+ // SIP-031 setup (deploy of the boot contract, minting and transfer to the boot contract)
1641
+ let sip_031_contract_id = boot_code_id( SIP_031_NAME , mainnet) ;
1642
+ let payload = TransactionPayload :: SmartContract (
1643
+ TransactionSmartContract {
1644
+ name: ContractName :: try_from( SIP_031_NAME )
1645
+ . expect( "FATAL: invalid boot-code contract name" ) ,
1646
+ code_body: StacksString :: from_str( SIP_031_BODY )
1647
+ . expect( "FATAL: invalid boot code body" ) ,
1648
+ } ,
1649
+ Some ( ClarityVersion :: Clarity3 ) ,
1650
+ ) ;
1651
+
1652
+ let sip_031_contract_tx =
1653
+ StacksTransaction :: new( tx_version. clone( ) , boot_code_auth, payload) ;
1654
+
1655
+ let mut sip_031_initialization_receipt = self . as_transaction( |tx_conn| {
1656
+ // initialize with a synthetic transaction
1657
+ debug!( "Instantiate {} contract" , & sip_031_contract_id) ;
1658
+ let receipt = StacksChainState :: process_transaction_payload(
1659
+ tx_conn,
1660
+ & sip_031_contract_tx,
1661
+ & boot_code_account,
1662
+ ASTRules :: PrecheckSize ,
1663
+ None ,
1664
+ )
1665
+ . expect( "FATAL: Failed to process .sip031 contract initialization" ) ;
1666
+ receipt
1667
+ } ) ;
1668
+
1669
+ if sip_031_initialization_receipt. result != Value :: okay_true( )
1670
+ || sip_031_initialization_receipt. post_condition_aborted
1671
+ {
1672
+ panic!(
1673
+ "FATAL: Failure processing sip031 contract initialization: {:#?}" ,
1674
+ & sip_031_initialization_receipt
1675
+ ) ;
1676
+ }
1677
+
1678
+ let recipient = PrincipalData :: Contract ( boot_code_id( SIP_031_NAME , mainnet) ) ;
1679
+
1680
+ self . as_transaction( |tx_conn| {
1681
+ tx_conn
1682
+ . with_clarity_db( |db| {
1683
+ db. increment_ustx_liquid_supply( SIP_031_INITIAL_MINT )
1684
+ . map_err( |e| e. into( ) )
1685
+ } )
1686
+ . expect( "FATAL: `SIP-031 initial mint` overflowed" ) ;
1687
+ StacksChainState :: account_credit(
1688
+ tx_conn,
1689
+ & recipient,
1690
+ u64 :: try_from( SIP_031_INITIAL_MINT )
1691
+ . expect( "FATAL: transferred more STX than exist" ) ,
1692
+ ) ;
1693
+ } ) ;
1694
+
1695
+ let event = STXEventType :: STXMintEvent ( STXMintEventData {
1696
+ recipient,
1697
+ amount: SIP_031_INITIAL_MINT ,
1698
+ } ) ;
1699
+ sip_031_initialization_receipt
1700
+ . events
1701
+ . push( StacksTransactionEvent :: STXEvent ( event) ) ;
1702
+
1703
+ receipts. push( sip_031_initialization_receipt) ;
1621
1704
1622
1705
debug!( "Epoch 3.2 initialized" ) ;
1623
- ( old_cost_tracker, Ok ( vec! [ ] ) )
1706
+ ( old_cost_tracker, Ok ( receipts ) )
1624
1707
} )
1625
1708
}
1626
1709
0 commit comments