Skip to content

Commit 3c68635

Browse files
committed
sip-031 boot contract setup
1 parent c3a015e commit 3c68635

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

stackslib/src/chainstate/stacks/boot/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub const POX_4_NAME: &str = "pox-4";
6363
pub const SIGNERS_NAME: &str = "signers";
6464
pub const SIGNERS_VOTING_NAME: &str = "signers-voting";
6565
pub const SIGNERS_VOTING_FUNCTION_NAME: &str = "vote-for-aggregate-public-key";
66+
pub const SIP_031_NAME: &str = "sip-031";
6667
/// This is the name of a variable in the `.signers` contract which tracks the most recently updated
6768
/// reward cycle number.
6869
pub const SIGNERS_UPDATE_STATE: &str = "last-set-cycle";
@@ -76,6 +77,7 @@ pub const SIGNERS_BODY: &str = std::include_str!("signers.clar");
7677
pub const SIGNERS_DB_0_BODY: &str = std::include_str!("signers-0-xxx.clar");
7778
pub const SIGNERS_DB_1_BODY: &str = std::include_str!("signers-1-xxx.clar");
7879
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");
7981

8082
pub const COSTS_1_NAME: &str = "costs";
8183
pub const COSTS_2_NAME: &str = "costs-2";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
(define-data-var recipient principal 'ST000000000000000000002AMW42H)
2+
3+
(define-public (update-recipient (new-recipient principal)) (begin
4+
(asserts! (is-eq tx-sender (var-get recipient)) (err u101))
5+
(var-set recipient new-recipient)
6+
(ok true)
7+
)) ;; Returns (response bool uint)
8+
9+
(define-read-only (get-recipient) (ok (var-get recipient))) ;; Returns (response principal uint)
10+
11+
(define-public (claim) (ok true) ) ;; Returns (response uint uint)

stackslib/src/clarity_vm/clarity.rs

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use clarity::vm::database::{
2929
RollbackWrapperPersistedLog, STXBalance, NULL_BURN_STATE_DB, NULL_HEADER_DB,
3030
};
3131
use clarity::vm::errors::Error as InterpreterError;
32+
use clarity::vm::events::{STXEventType, STXMintEventData};
3233
use clarity::vm::representations::SymbolicExpression;
3334
use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, Value};
3435
use clarity::vm::{ClarityVersion, ContractName};
@@ -42,7 +43,8 @@ use crate::chainstate::stacks::boot::{
4243
BOOT_CODE_COST_VOTING_TESTNET as BOOT_CODE_COST_VOTING, BOOT_CODE_POX_TESTNET, COSTS_2_NAME,
4344
COSTS_3_NAME, POX_2_MAINNET_CODE, POX_2_NAME, POX_2_TESTNET_CODE, POX_3_MAINNET_CODE,
4445
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,
4648
};
4749
use crate::chainstate::stacks::db::{StacksAccount, StacksChainState};
4850
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
5759
use crate::util_lib::db::Error as DatabaseError;
5860
use crate::util_lib::strings::StacksString;
5961

62+
pub const SIP_031_INITIAL_MINT: u128 = 200_000_000_000_000;
63+
6064
///
6165
/// A high-level interface for interacting with the Clarity VM.
6266
///
@@ -1617,10 +1621,89 @@ impl<'a> ClarityBlockConnection<'a, '_> {
16171621
tx_conn.epoch = StacksEpochId::Epoch32;
16181622
});
16191623

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);
16211704

16221705
debug!("Epoch 3.2 initialized");
1623-
(old_cost_tracker, Ok(vec![]))
1706+
(old_cost_tracker, Ok(receipts))
16241707
})
16251708
}
16261709

testnet/stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ use crate::{tests, BitcoinRegtestController, BurnchainController, Config, Config
128128
pub static POX_4_DEFAULT_STACKER_BALANCE: u64 = 100_000_000_000_000;
129129
pub static POX_4_DEFAULT_STACKER_STX_AMT: u128 = 99_000_000_000_000;
130130

131+
use clarity::vm::database::STXBalance;
132+
use stacks::chainstate::stacks::boot::SIP_031_NAME;
133+
use stacks::clarity_vm::clarity::SIP_031_INITIAL_MINT;
134+
131135
use crate::clarity::vm::clarity::ClarityConnection;
132136

133137
lazy_static! {
@@ -12802,6 +12806,44 @@ fn test_sip_031_activation() {
1280212806

1280312807
assert_eq!(epoch_version, Some(StacksEpochId::Epoch32));
1280412808

12809+
// check if sip-031 boot contract has been deployed
12810+
let sip_031_boot_contract_exists = chainstate.with_read_only_clarity_tx(
12811+
&sortdb
12812+
.index_handle_at_block(&chainstate, &latest_stacks_block_id)
12813+
.unwrap(),
12814+
&latest_stacks_block_id,
12815+
|conn| {
12816+
conn.with_clarity_db_readonly(|db| {
12817+
db.has_contract(&boot_code_id(SIP_031_NAME, naka_conf.is_mainnet()))
12818+
})
12819+
},
12820+
);
12821+
12822+
assert_eq!(sip_031_boot_contract_exists, Some(true));
12823+
12824+
// check if sip-031 boot contract has a balance of 200_000_000 STX
12825+
let sip_031_boot_contract_balance = chainstate.with_read_only_clarity_tx(
12826+
&sortdb
12827+
.index_handle_at_block(&chainstate, &latest_stacks_block_id)
12828+
.unwrap(),
12829+
&latest_stacks_block_id,
12830+
|conn| {
12831+
conn.with_clarity_db_readonly(|db| {
12832+
db.get_account_stx_balance(&PrincipalData::Contract(boot_code_id(
12833+
SIP_031_NAME,
12834+
naka_conf.is_mainnet(),
12835+
)))
12836+
})
12837+
},
12838+
);
12839+
12840+
assert_eq!(
12841+
sip_031_boot_contract_balance,
12842+
Some(Ok(STXBalance::Unlocked {
12843+
amount: SIP_031_INITIAL_MINT
12844+
}))
12845+
);
12846+
1280512847
coord_channel
1280612848
.lock()
1280712849
.expect("Mutex poisoned")

0 commit comments

Comments
 (0)