Skip to content
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
31bb550
feat: add Clarity 5 SIP (epoch 3.4)
brice-stacks Jan 27, 2026
0bcd7a0
fix: make `from-consensus-buff?` change Clarity-gated
brice-stacks Jan 27, 2026
05a058c
feat: add `from-consensus-buff?` PR
brice-stacks Jan 27, 2026
ae7c06b
fix: stack depth change must be epoch-gated
brice-stacks Jan 27, 2026
5deeaaa
Merge branch 'main' into clarity-5
brice-stacks Feb 2, 2026
b399e6e
chore: add link to SIP-035 and clarify errors
brice-stacks Feb 3, 2026
fc8aec0
chore: improve wording
brice-stacks Feb 6, 2026
6f90472
add forum link
brice-stacks Feb 6, 2026
4284fa9
set SIP number
brice-stacks Feb 11, 2026
e9b47af
adjust file structure for new SIP number
brice-stacks Feb 11, 2026
d4ab493
add explanation of `burn-block-height` bug
brice-stacks Feb 11, 2026
4b158fe
add ame-contract rait use to SIP
brice-stacks Feb 11, 2026
ff022aa
add hard fork label
brice-stacks Feb 11, 2026
0b1c173
remove extraneous comma
brice-stacks Feb 13, 2026
9f9c619
remove issue from titles
brice-stacks Feb 13, 2026
e5af10d
chore: minor changes from review
brice-stacks Feb 17, 2026
ffbbbbd
feat: add contract call with constant
brice-stacks Feb 21, 2026
c48933e
fix: add `stx-account` and `stx-get-balance` to `at-block` bug
brice-stacks Feb 27, 2026
9ba2867
chore: updated activation section for vote
brice-stacks Feb 27, 2026
85ccf1b
Set status to accepted
wileyj Mar 5, 2026
8fb11a0
feat: add `sip-address` script
brice-stacks Mar 5, 2026
9de700b
Revert "feat: add `sip-address` script"
brice-stacks Mar 5, 2026
e68faee
add voting information
brice-stacks Mar 9, 2026
abadf17
Move to Activation-In-Progress
wileyj Mar 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 201 additions & 0 deletions sips/sip-039/sip-039-clarity5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Preamble

SIP Number: 039

Title: Clarity 5: Fixing known issues in Clarity

Author(s):

- Brice Dobry <brice@stackslabs.com>

Status: Activation-In-Progress

Consideration: Governance, Technical

Type: Consensus

Layer: Consensus (hard fork)

Created: 2025-01-16

License: BSD-2-Clause

Sign-off:

Discussions-To:

- https://forum.stacks.org/t/clarity-5-and-epoch-3-4/18659

# Abstract

This version of Clarity is being proposed solely to address and resolve
documented issues with existing functionality, specifically those that require a
hard-fork to change. The implementation for this SIP should only resolve
problems in the current Clarity implementation or make beneficial changes to
under-specified aspects of the Clarity language and virtual machine (VM).

# Copyright

This SIP is made available under the terms of the BSD-2-Clause license,
available at https://opensource.org/licenses/BSD-2-Clause. This SIP’s copyright
is held by the Stacks Open Internet Foundation.

# Introduction

This SIP intends to solve the known issues in the implementation of the Clarity
VM, without making any changes to the intended behavior of the Clarity language.

# Specification

## Resolve the discrepancy in `secp256r1-verify` described in SIP-035

In Clarity 5 and above, `secp256r1-verify` will no longer double-hash its input.
See [SIP-035](./sips/sip-035/sip-secp256r1-verify.md) for details.

## Runtime error when passing an empty buffer to `from-consensus-buff?`

Beginning in Clarity 5, computing the cost of passing an empty buffer to
`from-consensus-buff?` will no longer trigger a runtime error. Instead, the cost
will be charged appropriately, and the expression will return `none`, as
originally intended. See issue
[#6683](https://github.com/stacks-network/stacks-core/issues/6683).

## Bug inside `at-block` expressions

From issue [#6123](https://github.com/stacks-network/stacks-core/issues/6123):

> Epoch 3 introduced a bug which causes `burn-block-height` to always return the
> current burn block height, even if inside of an `at-block` expression. This
> should be fixed to behave as expected in the next hard-fork.

In addition to `burn-block-height`, it was also determined that this same error
effects `stx-account` and `stx-get-balance`. These two functions can return an
incorrect value inside of an `at-block` since the incorrect burn block height is
used to determine the locked status of the STX.

In Clarity 5 and above, `burn-block-height` will return the correct value when
used inside of an `at-block` expression.

## Increased stack depth

Currently, the Clarity VM limits the call stack of a transaction execution to a
depth of 64 and several user applications have been hitting this limit recently.
This value was not specified in any previous SIPs, but was chosen to constrain
memory usage by the VM. Upon further testing, it has been determined that this
value can safely be increased to 128 without imposing unreasonable requirements
on Stacks node runners. Effective in epoch 3.4, the stack depth will be set
to 128.

## Rejectable transactions

Several kinds of errors have been avoided in the Clarity VM via a soft-fork
mechanism, causing transactions that trigger these problematic situations to be
rejected, not allowed to be included in a block. This strategy is useful for
quickly patching issues without requiring a hard-fork. However, once the
soft-fork is in place, the next time a hard-fork is executed, these errors can
all be transitioned to errors that can be included in a block. This is much
better for the network, since not including a transaction in a block has several
downsides:

- Miners cannot charge a fee for processing the transaction
- Users may be confused as to why their transaction is not being included,
causing that transaction and all later transactions (with higher nonces) to
stall
- These unmineable transactions remain in the mempool, unprocessed, until they
age out

With the upgrade to epoch 3.4, all known reachable "rejectable" errors will
become includable errors.

## Allow trait use in same contract

Currently, a trait defined in a contract cannot be used at the top-level of that
contract. For example, the code below will result in a `NoSuchContract` error.

```clarity
(define-trait trait-1 (
(foo
()
(response int int)
)
))
(define-private (bar (F <trait-1>))
(unwrap-panic (contract-call? F foo))
)
(bar .c-foo)
```

This behavior is a bit surprising. Beginning in Clarity 5, this usage will be
supported. See issue
[6831](https://github.com/stacks-network/stacks-core/issues/6831).

## Allow `contract-call?` to constant

Effective in Clarity 2, the type-checker does not complain about using a
constant as the target of a `contract-call?`, for example:

```clarity
(define-constant MY_CONTRACT .contract-a)
(define-public (call-foo)
(contract-call? MY_CONTRACT foo)
)
```

Despite passing type-checking, this contract would fail during runtime, with an
error, `RuntimeCheckErrorKind::ContractCallExpectName`. This again is surprising
behavior. Beginning in epoch 3.4, this usage will be supported.

# Related Work

This SIP is focused on fixing consensus issues discovered in previous
implementations of Clarity, or improving behavior which is unspecified in prior
SIPs. The existing SIPs defining Clarity are:

- [SIP-002 (Clarity)](../sip-002/sip-002-smart-contract-language.md)
- [SIP-015 (Clarity 2)](../sip-015/sip-015-network-upgrade.md)
- [SIP-021 (Clarity 3)](../sip-021/sip-021-nakamoto.md)
- [SIP-033 (Clarity 4)](../sip-033/sip-033-clarity4.md)

# Backwards Compatibility

Clarity 5 will be implemented with these changes while maintaining backwards
compatibility for previous versions of Clarity. Existing contracts will continue
to execute with the existing behavior, but new contracts will default to
Clarity 5.

# Activation

In order for this SIP to activate, the following criteria must be met:

- At least 80 million stacked STX must vote, with at least 80% of all stacked
STX committed by voting must be in favor of the proposal (vote "yes").
- At least 80% of all liquid STX committed by voting must be in favor of the
proposal (vote "yes").

All STX holders vote by sending Stacks dust to the corresponding Stacks address
from the account where their Stacks are held (stacked or liquid). To simplify
things, users can create their votes by visiting the
[ballot.gg](https://ballot.gg/67a34537-0375-4046-a4b7-432e8dfd4eb3/1MP9LjMBZRKXWq3tRio6nGwFyUoboozEQx)
platform. Voting power is determined by a snapshot of the amount of STX (stacked
and unstacked) at the block height at which the voting started (preventing the
same STX from being transferred between accounts and used to effectively double
vote). The voting addresses are also shared below.

Solo stackers only can also vote by sending a bitcoin dust transaction (6000
sats) to the corresponding bitcoin address.

| Vote | Bitcoin | Stacks | ASCII Encoding | Msg |
| ---- | ------------------------------ | ----------------------------------- | ---------------------------------------- | ---------- |
| yes | 11111111111mdWK2VXcrA1eceSntcp | SP00000000001WPAWSDEDMQ0B9K76XTZ79N | 000000000000000000007965732d7369702d3339 | yes-sip-39 |
| no | 111111111111ACW5wa4RwyepZ84byy | SP000000000006WVSDEDMQ0B9K76JZVAKY | 00000000000000000000006e6f2d7369702d3339 | no-sip-39 |

If the SIP is approved, epoch 3.4 will activate at Bitcoin block height 943000,
targeting March 30, 2026.

# Reference Implementation

At the time of this writing, the following public implementations are available
so far:

- [`secp256r1-verify?` change](https://github.com/stacks-network/stacks-core/pull/6763)
- [`from-consensus-buff?` change](https://github.com/stacks-network/stacks-core/pull/6820)