stacksgov / sips Goto Github PK
View Code? Open in Web Editor NEWCommunity-submitted Stacks Improvement Proposals (SIPs)
Community-submitted Stacks Improvement Proposals (SIPs)
The current implementation only allows one commitment per address. This prevents users from:
@hstove to add more 🙏🏼
The prefix byte for standard and contract post-condition principals does not appear to be documented.
Standard principals:
0x02
Contract principals:
0x03
For Transaction Signing and Verifying the spec says
If this is a single-signature spending condition, then set the fee rate and nonce to 0, set the public key encoding byte to Compressed, and set the signature bytes to 0 (note that the address is preserved).
I started to implement my versions of verifyBegin()
and verifyOrigin()
(as in @stacks/transactions
) and noticed that the public key encoding byte is copied for standard single-sig transactions, not set to compressed.
As the ecosystem grows we see more and more NFT contracts that can be minted not only with plain STX but also with different FT (ie. CityCoins). Each have a slightly different function name and signature. I think we can do better.
There should be a trait that defines unified interface which can be used to mint new NFT with STX and any SIP-010 compliant FT. Such trait could look like this:
(use-trait sip-010-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
(define-trait (
;; mints 1 NFT using supplied FT as tender
(mint-with (<sip-010-trait>) (response bool uint))
;; mints X NFTs using supplied FT as tender
(mint-many-with (uint <sip-010-trait>) (response bool uint))
;; returns minting price in supplied FT
(get-mint-price-in (<sip-010-trait>) (response uint uint))
))
And to make it work also for STX we could define global wrapped STX SIP-010 compliant FT that is not issuing new token, but uses plain STX:
(impl-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
(define-read-only (get-balance (owner principal))
(ok (stx-get-balance owner))
)
(define-read-only (get-decimals)
(ok u6)
)
(define-read-only (get-name)
(ok "Wrapped STX")
)
(define-read-only (get-symbol)
(ok "WSTX")
)
(define-read-only (get-token-uri)
(ok (some u"https://www.stacks.co"))
)
(define-read-only (get-total-supply)
(ok stx-liquid-supply)
)
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
(begin
(try! (stx-transfer? amount sender recipient))
(match memo to-print (print to-print) 0x)
(ok true)
)
)
Very similar approach can be used by NFT marketplaces to define unified interface for listing/buying NFTs for STX and any SIP-010 compliant FT.
Now that we have more active CABs reviewing SIP-015 it would be good to reduce this work back to a consistent template that all CABs can use.
PRs for SIP-015 minutes:
The formatting is very close across all three, and the Economics CAB included a generic template file in their submission.
Given that we have a TEMPLATE.MD
for the CAB formation, it'd be great to also create one for meeting minutes using that as a starting point.
Some things that come to mind for me, and open to feedback on what works best for the CABs.
2022-10-31-sip-015.md
15:00 - 16:00 UTC
We can revisit this after all the PRs are merged in, and ideally set something up for the next SIP so it's even easier!
There should be a well-defined type depth that determines how deep any structured type can be. In the reference implementation, this is defined by clarity::vm::types::MAX_TYPE_DEPTH
, which is 32.
In the current implementation, stackers would have to skip one cycle after a previous commitment. This is happening because the STX tokens from a previous commitment will unlock after the prepare phase of the next cycle.
SIP 018 defines how any structured messages should be signed.
There should be a SIP that defines the message structure for sign-in with stacks that users can sign and services, web apps, off-chain entities accept as authentication.
In adherence with this grant from cohort 18, I set out to discover the “best” way to setup a multi-NFT -> FT staking experience in an attempt to template, standardize & submit a SIP.
After ~6 months of solo & collaborative research, I’ve come to the conclusion that submitting a SIP around this experience is ill-advisedill-advised at this current time. Below, I’ll walk-through the core reasons why I believe it’s inappropriate followed by generalized “interesting” findings that may or may not be relevant to the community at large.
1. “Staking” Is An Unspecific Term
During my research, I found it incredibly hard to find internal or community consensus on how we define staking. Is it when a trusted source has control of your asset (custodial)? Is it when transferring and/or listing is blocked? Or is staking simply a synonym for ownership? Upon closer inspection, each of these definitions are ill-suited for standardization.
If we define staking solely as a matter of custody - that is, when someone has custody of your asset in exchange for rewards - how does that differ from lending? Moreover, if we define staking as ownership but with contract restrictions on transfer or listing, we're faced with a number of unclear choices. Should we define staking as ownership only when transfer is impossible? Or when listing (which isn’t in SIP09…) is impossible? Or both? Why? Broken down, this is merely ownership with arbitrary obstacles to access. Which leads us to the last definition: simple ownership. Perhaps we should define staking simply as ownership & as the response to (get-owner …)? On principal that seems the most accurate & by in-turn, anticlimactic since it suggest the right label for staking is “rewarded ownership.”
While I was conducting technical research, the ambiguity surrounding the definition of staking did not particularly concern me since the templated solutions addressed all three definitions. However, during the collaborative phase, when we presented our SIP & drafted it up for review, it became apparent how problematic this ambiguity was for the entire SIP basis. The lack of clarity around the definition of staking served as a major red flag.
2. Accommodating For Both Old & New NFTs
The creation of a SIP focused on staking also presents a challenge when it comes to accommodating all NFTs, ie existing & new. Unless there is a community consensus on the "ownership" definition of staking, all existing NFTs require custodial staking. While it is possible to accommodate custodial staking, it is substandard as it means forgoing custody of an asset, which is sub-optimal. However, this trade-off on it’s own is likely acceptable.
Yet the issue isn't just with old NFTs being substandard, but also with new NFTs requiring changes to accommodate non-custodial staking. If this SIP were submitted & accepted, new NFTs would need to alter their transfer & listing functions to allow for non-custodial staking. While it is simple to add the necessary lines for non-custodial staking, requiring all new NFTs to consider this logic feels like an inappropriate encroachment on SIP-09 when it’s specifically teams building out ecosystems that’ll likely opt-into this architecture.
3. There Are Larger NFT Update Priorities
On that last point, accommodating for a nearly-universal (though not officially part of the SIP), function like (list-in-ustx …) raised another issue: why prioritize a SIP for staking over a SIP for non-custodial marketplace functions? Almost every NFT launched these days has the following non-custodial functions: (list-in-ustx …), (unlist-in-ustx …), & (buy-in-ustx …). Maybe there is a day in the future where we consider an overall update to SIP-09 with optional features like non-custodial marketplace & staking functions, but on it’s own staking has a very weak argument for a standalone SIP.
For all of these reasons, after finishing two templates, an analysis & a SIP presentation, I couldn’t convincingly submit a SIP that’d cross the threshold for
1. What’s The Best Template For NFT(s) -> FT Staking?
After examining two different architecture options, I came to the conclusion that the monolith model for staking, while suitable for individual teams, is not a viable option for standardization due to its poor security. Since this model accommodates NFT with custodial staking on a single contract, it becomes a vulnerable target for bad actors, particularly if the contract whitelists multiple collections. Moreover, with a single .staking contract, an owner can only stake to one ecosystem at a time. For example, if you have a CrashPunk and both CrashPunks and Bitcoin Monkeys offer staking rewards for CrashPunks, you would have to choose one team to stake with. Overall, while the monolith model may be "safe" for teams to implement, it is not recommended and certainly not worthy of a network standard.
In contrast, the star model is a much more attractive candidate for the architecture of a staking-based SIP. As outlined in the report, this model requires a "staker-helper" contract deployed for each NFT added to a staking collection. While this approach does require two sets of trait definitions and the deployment of multiple contracts (since each NFT requires an "NFT-helper"), it does address most of the concerns found in the monolith model.
2. Nested Traits Are Possible!
This was unbeknownst to me, but regardless of whether this SIP is submitted/accepted/rejected I was wonderfully surprised to learn that nested traits, as long as their defined in the same file, work! Specifically, in the Star model, in the sip-16 contract (16 is just an accidental placeholder number for this experiment), you can see the following signature in the stake-main trait:
;; Add whitelisted collection (add-whitelisted-collection (<stake-helper>) (response bool uint))
"stake-helper" is another trait also defined in that same file, ergo a trait defined & used within the definition of another trait! I haven’t quite wrapped my head around what traits of traits implies for possible future standards & dynamic contract calls but it’s something worth thinking about at length.
3. Weird Clarity Behavior With Traits
My last significant discovery is that working with traits beyond the simplest form (i.e., a single parameter) is arduous, complex, & counterintuitive. Two specific scenarios demonstrate this:
I faced both of these issues while constructing the Monolith and Star models, particularly when attempting to enhance user experience by adding "many" functions such as "stake-many," "stake-all," "claim-many," "claim-all," "unstake-many," and "unstake-all." I eventually overcame these bugs using awkward workarounds (like including brute-forcing functions with over 25+ optional trait parameters), but it was apparent that such an approach was unsuitable for a standard. This problem, which we can generalize as trait type-casting, requires, in my opinion, a decision in a following Clarity upgrade.
As I came across these problems, I did see threads & issues referring to other people running into them. Some think we shouldn’t support sequences of traits; some think we should. Either way, I think this is a discussion the community needs to have because as it stands the behavior isn’t encouraged, but it isn’t actively discouraged either - at some point, it follows that we must either support this behavior and correct the type-casting, or completely prohibit it at the language level.
And that’s it! As mentioned throughout you can find the Monolith template, Star template, analysis & SIP community presentation linked here. It’s a shame this fell short of a SIP standard but I wanted to share the fruits of the research anyway - feel free to reach out for any questions, concerns or if you want to implement!
Will close after a month of non-activity.
There should a standard that defines a schema for non-fungible tokens using SIP-009
SIP-005 states:
Note that if a transaction contains a token-transfer payload, it MUST
have only a standard authorization field. It cannot be sponsored.
However, the chain confirms a sponsored stx transfer:
The motivation for the specification in SIP 5 is not clear and the chain works without the specified restriction on sponsored transaction. Therefore, the specification should be adjusted and the paragraph removed.
In the current implementation, stackers will continue to see their tokens locked even if they don't qualify for a reward slot. This could happen on various occasions, for instance:
It would be great if tokens were not locked up if they are not eligible for rewards
This sips is about standardizing smart contract functions that enables digital assets to contain ability to participate in an open, decentralized market place.
Owners of NFTs (SIP9) and FTs (SIP10) should be able to list and unlist their token. Buyers should be able to buy the assets from the owner.
A simple trait would look like this:
(use-trait commission-trait .commisions.trait)
(define-trait tradable
(
;; announce listing to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; must send a list event
;; @param id; identifier of NFT or amount of FTs
;; @param price: of sale in micro STX
;; @param commission: action to happen after sale
(list-asset (uint uint <commission-trait>) (response bool uint))
;; announce delisting to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; must send a delist event
;; @param id; identifier of NFT or amount of FTs
(unlist-asset (uint) (response bool uint))
;; buy and announce delisting to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; commission must match the one set during listing
;; must send a delist event
;; @param id; identifier of NFT or amount of FTs
;; @param commission: action to happen after sale
(buy-asset (uint <commission-trait>) (response bool uint))
)
)
(define-trait commission
(
;; additional action after a sale happened
;; must return `(ok true)` on success, never `(ok false)`
;; @param id; identifier of NFT
;; @param price: of sale in micro STX
(pay (uint uint) (response bool uint))
)
)
Marketplaces would observe the list, unlist events and update their inventory accordingly. They act mainly off-chain.
Commission allows to implement royalties for artist on NFTs or fee for marketplaces or different sales mechanims like auctions.
See title
Currently, at least 50K needs to be committed. If we get more flexibility in regards to the number of commitments a single address can make (#8), it would be beneficial to low the threshold per the commitment. This could enable users to "top off" their locked up tokens and account for future increases in the threshold for reward slots (for instance, if someone locked tokens for 12 cycles).
The initial proposal (by @hstove) for a lower threshold was 10K.
As part of a recent Stacks grant the Ecosystem DAO will be displaying more information about SIPs through an external website.
An example can be seen here, although the link may change as a large part of this is still under development 🙂
Since the website data is served via what's available in the GitHub API, there were some open questions around what tags should be represented and used to help make the information easier to go through.
In the current interface GitHub issues = SIP Suggestions and GitHub pull requests (PRs) = SIP Proposals.
Issues don't contain any labels right now save some old Stacks 2.1
stuff, what would be the best way we could break them up and make them easier to digest? Do they fall into natural categories?
https://github.com/stacksgov/sips/issues
Pull requests are labeled based on SIP status, which is helpful, but should we also add labels for considerations and other SIP-related definitions?
https://github.com/stacksgov/sips/pulls
Open Q: should we define this structure in the README or similar?
Tagging @Hero-Gamer and issue #79 to get the discussion started 🎉
Topic: Improving Stacks Mining & Decentralization - Session 1
SIP call # 0 – Friday 06/17/22
Video recording: https://www.youtube.com/watch?v=hECBnr7gXK8&ab_channel=StacksCommunity
Topic: Improving Stacks Mining & Decentralization - Session 2
SIP call # 1 – Thursday 06/23/22
Video recording: https://www.youtube.com/watch?v=ACGLjXsNNnY&ab_channel=StacksCommunity
Topic: Introduction to SIP calls and SIP processes + SIP voting mechanism
SIP call # 2 Agenda – Friday 07/01/22 (11:00am EDT)
ARCHIVE
Hi all, there was a request to post weekly SIP meeting agendas ahead of time. I'll post the agenda for tomorrow's meeting here but am wondering: should we post all agendas within this issue (for the sake of simplicity) or open a new issue for every agenda?
Tagging @Hero-Gamer here too. Personally leaning toward using just one issue, though I realize that could get messy. We could also use the Forum instead if GitHub doesn't feel like the right place for this.
Weekly Community SIP Call Agenda – 07/01/22 (11:00am EDT)
Note: This is currently the standard format for calls, but we anticipate it changing as the SIP process evolves. For example, once consideration advisory boards begin to review SIPs more actively, we will likely make more time for their commentary during these calls. If you have any suggestions or feedback for how to improve these meetings, please don't hesitate to share!
No SIP exists describing how arbitrary messages are signed.
Specifics such as what the prefix is, and what encoding is used should be described. EIP-712
, for example, has an arbitrary message section.
The current prefix follows the same format as EIP-712
, with Stacks in place of Ethereum.
"\x17Stacks Signed Message:\n" ‖ len(message) ‖ message
The need for this SIP comes from issues that've arisen migrating to a single prefix: See hirosystems/stacks.js#1328.
In migrating to a new prefix, some apps have seen breaking changes. Were this described in a SIP, a more structured, community-driven approach to changes would've been required.
cc/ @friedger @markmhx @MarvinJanssen @pradel @Hero-Gamer
There are many efforts to use Bitcoin addresses and Stacks addresses interchangeably as they are just a different encoding of the same public key, e.g. using Bitcoins transactions to transfer NFTs between Stacks addresses.
There are open questions e.g. which addresses should be shown in wallets (leather-io/extension#2402) and how addresses of utxo based chains and account based chains can be used together.
Hi all, this post is to document the MONTHLY SC update call, agenda & notes.
For the weekly call notes please see this Github post: #79
cc: @jcnelson @GinaAbrams @jennymith
Link to Forum post: https://forum.stacks.org/t/15-monthly-sc-sip-call-steering-committee-community-update-01-september-2022/13748
Topic: Steering Committee September Community Update
SIP call # 15 Agenda – Friday 09/30/22 (11:00am EDT) - 34 attendees
Notes from the call
Video recording: TBC
Upcoming SIP Calls:
7th Oct - Independent Developer reviewing 2.1 Upgrade from @ Codex https://twitter.com/codexbtc
Useful links:
As per previous discussions (see Paper doc), @friedger will create a proposal for a non-fungible token standard.
I'm creating this to keep track of the conversations
Hi all, appreciate for opening such consideration panel for the wider community to participate.
Just would like to express my interest in this particular CAB.
Let me know if it is possible :)
Thanks. CC: @jcnelson
I propose that a (twist on) Harberger Tax be used for allocating BNS domain names, which could be more fair, and generate higher fees on Stacks as compared to the flat fee model that it has today.
In a typical Harberger Tax, the owner of the property (in our case a BNS name) self-assesses the value of their ownership and pays a recurring tax that is some percentage of that assessed value. The problem with having just one self assessed price is that it ignores the fact that there is a time component to prices and can ultimately require owners to self-assess a price that is just too high for them to pay for them to have any strong guarantee that the name won't be bought up from underneath them—which could cause real harm. See this post advocating against a Harberger Tax for ENS. The concerns presented in the post are valid, but I believe can be addressed by the following structure:
If instead of just self-assessing one scalar price for the domain name, the owner specifies a price as a function of time (t) and pays a weighted average percentage of the output of that function as the tax. The price at time (t) is what someone needs to pay the owner to take control of the domain name at that time (t). t is now, t + 1 is the next block, so on and so forth.
This allows an owner to specify a high price for the control of their name in the immediate/short term and incrementally step down the price as (t) gets further into the future, thus lowering the overall tax amount for the owner and giving them a strong assurance of ownership in the short term.
Owners can price the short term takeover at a price where they'd be happy to relinquish control, and at a minimum know whether or not someone is trying to take control of their domain name at any time in the future and can thus buy themselves time to make a decision about what to do.
For instance I could set the price of my domain name to $1 million for the first day then drop it down to $1k for all time after that. I'd be happy if someone wants to take control of my name right away for $1 million, and if they try to take control of it for $1k at t + 2 days and on, then I at least have bought myself a day before control is transferred over and can decide if I want to revalue and thus keep control, or allow the sale to go through. In this example, at a 2% tax rate, the yearly tax I would pay for this valuation function would be: $1,000,000 * (.02 / 365) + $1,000 * (.02 * 364/365) = $75.
Looking forward to feedback and some constructive criticism on this and whether or not others think something along this line can be viable.
In the current implementation, coinbase rewards are only able to be sent to STX addresses.
For example, mining pools controlled by smart contracts (like Pool³) currently have to have the rewards sent to the contract from the pool, putting unnecessary trust in the mining pool and increasing transaction fees.
If the rewards could be sent directly to the contract in charge of managing payouts, this would be beneficial.
Claiming the land grab :)
I gave this a preliminary SIP number (not sure if I am allowed or the CAB determines it) but we can change it, I like to have something here asap because it makes it easy to refer to the document. I choose 029 (because they do not have be in order (paraphrasing Jude) and to signal the relationship to SIP009.
I have texted briefly about how to write this draft with Friedger and dant before structuring it this way. It could have also been four separate traits/standards but they belong together and Friedger and Dan thought this would be the better way.
This is the first time I share my draft, feedback is needed and I will also need help from a dev to handle the technical feedback.
I have also included some questions myself starting with "werner:" feel free to comment here if you know more.
I would like to get this standard ratified so it can also be integrated into BNSv2
See my draft here (I am not sure how to send it properly as a PR):
https://github.com/no314/stx-fan/blob/main/sips-ip/sip-029_extending-tokens.md
This property is crucial to understanding how the system incentivizes liveness in the face of high mining costs.
I want to record the following here after discussing the ideas for a BNS marketplace with @friedger and @dantrevino . Some community members have shown an interest in trading BNS names and people frequently ask for one on the telegram channels.
The difficulty to make a marketplace contract for BNS names currently arises from the fact that a principle can hold a maximum of one name.
Proposed solution: If we could allow a contract to wrap a BNS name and 'deactivate' it for the purpose of trading it that would make it developer and user friendlier to make a marketplace for BNS names.
-- perhaps a bit like an expired name, which an address apparently can hold several of, but only one can be active.
Questions
Steering Committee is defined in SIP-000 however I can't find membership information. It would be good to list the SC members.
The README should provide a reasonable first step in the process of submitting a SIP, such as suggesting starting by posting a new issue here with an initial proposal for the SIP.
SIP 000 provides an high-level overview of the SIP process but not a practical first step. The SIPS README in the sips directory suggests that New SIPs may be submitted via pull request. Having to submit a pull request as a first step sets the bar high for engaging with the SIP process, which @GinaAbrams argues in issue #73 already has a high barrier to entry for folks that don't use GitHub day in and day out.
Posting a brief proposal for a new SIP in the issue tracker will lower the barrier to entry and open for further onboarding and hand-holding (if required).
Details: hstove/stacks-fungible-token#1
Now that we have more and more people looking at SIPs, we need a consistent workflow that's easy to use but adheres to SIP-000.
Since GitHub is the main medium we're using for the SIPs, I propose the following approach:
Draft
status via a PRAccepted
Recommended
Activation-in-Progress
and the README.At that point we should probably merge it as it would update the README on the main branch, which shows both activation-in-progress and ratified SIPs.
Then a separate PR could be created (by SC, or maybe by others in the groups above) that changes the status to Ratified
and updates the README once it's finalized.
Another way to look at this:
Draft
-> Accepted
-> Recommended
-> Activation-in-Progress
Activation-in-Progress
Activation-in-Progress
to Ratified
Curious if others have thoughts on this, the SIPs below have parts of the process in place, and once we settle on a structure we can document it either through a SIP, somewhere in this repo as a doc, or both.
There should be a standard describing the style of API used by wallet clients.
@friedger pushed a draft SIP a while back describing the existing wallet API. Though, more recently, there's been some discussion about moving away from the existing JWT-style API towards something more consistent with other ecosystems, like an RPC style API.
I suggest a SIP that describes a feature-agnostic RPC API that works cross-platform: Web Extensions, mobile apps, CLIs etc, similar to that of EIP-1102
.
This SIP describes a simpler standard for apps to interface with wallet clients.
This proposal outlines a uniform manner with which apps can interface with wallet clients.
It recommends to minimise the surface area of available APIs, and makes design decisions similar to those in other crypto ecosystems.
No standard exists describing how apps interact with Stacks-compatible wallets. Presently, ecosystem wallets adhere to an undocumented set of commands that wallets should implement. A well-documented API, that’s familiar to developers from other ecosystems, benefits both app and wallet developers.
The purpose of this SIP is to describe the outline of an API that can support multiple environments including, but not limited to, Web Extensions, mobile wallets, CLIs etc. It does not describe the individual methods that clients may commonly support.
Two methods are described. The methods can be typed such that the return value corresponds to the method name passed.
request
request(method: string, params?: object[]): Promise<T>
A request
method is accepted by clients, following the JSON RPC standard
Example
const accounts = await Provider.request('stx_requestAccounts');
listen
listen(event: string): Observable<T>
A listen
method accepts an event parameter. It returns an Observable
, following the TC39 specification, that consumers can subscribe and unsubscribe to.
Example
Provider.listen('networkChange').subscribe(network => toast('Switched network'))
https://eips.ethereum.org/EIPS/eip-1102
https://eips.ethereum.org/EIPS/eip-1474
https://eips.ethereum.org/EIPS/eip-2255
Wallet clients should continue to support the existing methods until a time where a sufficient majority of apps adhere to the new standard. They may warn developers of the newer format, encouraging developer to migrate.
This SIP is considered activated when at least two wallet clients support this API.
Happy to work on this with anyone that wants to collaborate.
cc/ @janniks @yknl @markmhx @fbwoolf @edu-stx
Edit: March 2023 update
With the suggestions/ideas from this SIP @janniks and I have started http://btckit.org, which aims to push this effort and form a community-driven, wallet-agnostic standard.
Hey Stacks fam! I wanted to start a discussion around the governance process and specifically a high barrier to entry for folks that don't use GitHub day in and day out. A core part of any community's governance is access to information and clear paths for engaging. Recent experiences in exploring the SIP posting process have highlighted the nuances of posting SIPs that make it difficult for the broader community to participate, and I wanted to start this discussion to propose that the current process should be reconsidered.
See the instructions listed here:
Submitting a Pull Request Pull requests are welcomed and encouraged!
Please follow this general procedure:
Fork/clone the repository
Create a new branch related to the PR: git checkout -b my-branch-name
Make changes and push to your fork
Submit a pull request for review
While this may be straightforward to some, for the rest of us it creates extra friction right off the bat where research is needed before even considering posting a SIP. When Ethereum Improvement Proposals and Helium Improvement Proposals are in the discussion and discovery phase, discussions happen in real time (added to meeting agendas) and not through PRs on GitHub.
My proposal to the community is that formal communications on SIPs should be able to happen on the Stacks Forum and in meetings (maybe the Weekly Stacks Blockchain Engineering Calls) ahead of SIPs being formally posted as PRs to GitHub. This would make it a lot easier to engage with and digest content without the barrier to entry.
What do others think?
There should be a standard that defines
As per previous discussions (see Paper doc), @psq will create a proposal for a fungible token standard.
I'm creating this to keep track of the conversations
I believe that as a community we should have clear coding standards and guidelines that we want to be followed by developers when they work on clarity contracts.
I drafted something like that for Syvita guild, and we could use it as a starting point.
Using language reserved keywords (data types, function names and keywords) in any other context than they were design for is prohibited.
For example:
;; BAD
(define-map MyMap
{ block-height: uint }
{ len: uint}
)
;; GOOD
(define-map MyMap
{ stx-block-height: uint }
{ length: uint}
)
Constants have to be declared in all upper case with underscore separators.
For example:
(define-constant CONTRACT_OWNER tx-sender)
(define-constant ERR_UNAUTHORIZED (err "Unauthorized!"))
Local and persisted variables have to be declared in camelCase. For example:
(define-data-var blockSize uint u128)
(let
(
(firstVar (+ 1 10))
(secondVar (pow u2 u8))
)
(ok (call-function firstVar secondVar))
)
Maps have to be declared in PascaCase. Key tuple definition and Map tuple definition should be declared in separate lines and follow tuples standard. For example:
(define-map UserRoles
{user: principal}
{
roles: uint,
isActive: bool
}
)
To save space and reduce execution costs both key and value can be declared as unnamed data types.
For example:
(define-map UserId
principal
uint
)
(define-map UserRoles
principal
{
roles: uint,
isActive: bool
}
)
Tuples have to be declared using curlybracket notation. Each tuple key have to be defined in separate line and follow local and persisted variables standard. For example:
{
user: tx-sender,
roles: u1,
group: "A",
membersCount: 123
}
Functions have to be declared in all lower case with dash separators. Function parameters should follow local and persisted variable standards For example:
(define-read-only (is-root (userName (buff 50)))
(ok true)
)
(define-read-only (is-member (userId uint) (groupId uint))
(false)
)
Custom errors should be defined as constants unsigned integers greater than 100, to be easily distinguishable from errors raised by build in functions. Name of each error should start with ERR_
followed by clear description of error.
For example:
(define-constant ERR_UNAUTHORIZED u401)
(define-public (some-function)
(asserts! (is-eq tx-sender contract-caller)
(err ERR_UNAUTHORIZED)
)
)
Parenthesis should be closed in the same line if line is very short or at the same level as they were opened if what is inside parenthesis is more complex. For example
;; BAD
(define-public (do-something-cool (userId uint))
(let
((firstVar (+ 1 10))
(secondVar (pow u2 u8)))
(ok (call-function firstVar secondVar))))
;; GOOD
(define-public (do-something-cool (userId uint))
(let
(
(firstVar (+ 1 10))
(secondVar (pow u2 u8))
)
(ok (call-function firstVar secondVar))
)
)
There should a trait for digital assets that are transferable. The trait should work for the two native fungible and non-fungible assets. It should be some kind the smallest common denominator between NFTs (sip-9 like assets) and FTs (sip-10 like assets).
Testing if the webhook is feeding this to Discord.
SIP-005 doesn't contain any mention of the string clarity values, used here in stacks.js.
StringASCII = 0x0d,
StringUTF8 = 0x0e,
The Clarity Value Representation should contain documentation for these.
This was mentioned by @neithanmo of Zondax, working on the Ledger integration.
During the last Clarity WG on 6/11/2024 call we discussed traits for SIP-009 and SIP-010, and there was some confusion over whether everyone has to use the same trait reference or if someone can use a duplicate.
Pulling from my memory, it should be possible to use a trait deployed at your own address as long as the trait contains the same code as the SIP-009 and SIP-010 traits on mainnet.
In practice there may have been some challenges with this:
This older PR added the trait definitions to each SIP, which are now out of date for testnet following the reset.
Tagging @obycode and @setzeus for additional reseearch and input to start!
Also @jcnelson time permitting - I remember we've discussed this topic in past blockchain meetings!
Officially expressing my interest here!
We need to add string-utf8
and string-ascii
to the Types
subsection under Clarity Type System
.
We should also update the information in Library Support and Syntactic Sugar
, which seems outdated now.
Also expressing interest in this working group
There should be a SIP that defines smart contract functions that enables an open, decentralized market place for digital assets. These assets must implement the operable
trait (#52).
Owners of operable assets should be able to list and unlist their token. Buyers should be able to buy the assets from the owner.
The marketplace
trait can be implemented as part of the asset contract (usually not recommended) or as an independent contract.
A simple trait would look like this:
(use-trait commission-trait .commisions.trait)
(define-trait marketplace
(
;; announce listing to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; must send a list event
;; @param id; identifier of NFT or amount of FTs
;; @param price: of sale in micro STX
;; @param commission: action to happen after sale
(list-in-ustx (uint uint <commission-trait>) (response bool uint))
;; announce delisting to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; must send a delist event
;; @param id; identifier of NFT or amount of FTs
(unlist-in-ustx (uint) (response bool uint))
;; buy and announce delisting to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; commission must match the one set during listing
;; must send a delist event
;; @param id; identifier of NFT or amount of FTs
;; @param commission: action to happen after sale
(buy-in-ustx (uint <commission-trait>) (response bool uint))
;; read-only function defining the asset
(get-asset () (response {fq-contract: string, asset-class: string} uint))
)
)
(define-trait commission
(
;; additional action after a sale happened, usually a fee transfer for marketplaces
;; must return `(ok true)` on success, never `(ok false)`
;; @param id; identifier of NFT
;; @param price: of sale in micro STX
(pay (uint uint) (response bool uint))
)
)
As commission-traits
can call any functions in the name of the tx-sender, it is important that a web app only offers commission contracts that are well understood. In particular, appropriate post-conditions have to be created.
If asset contracts want to control trades they have to restrict which operators are approved. Note, that royalties to an artist of an NFT can be part of the commission if agreed with the marketplace. They can also be implemented in the NFT directly.
Loopbom
https://github.com/radicleart/clarity-market
Megapont Ape Club
https://explorer.stacks.co/txid/SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.megapont-ape-club-nft?chain=mainnet
There should be a SIP that define extensions that can be implemented by SIP-9 and SIP-10(?) assets. These extension should use the uint
parameter either as id or as amount.
This trait is compatible with SIP-9, but not with SIP-10.
The function transfer-memo
is the corresponding function to stx-transfer-memo?
defined in Stacks 2.1.
define-trait transferable
(
;; Transfer from the sender to a new principal
;; must return `(ok true)` on success, never `(ok false)`
;; @param id-or-amount; identifier of NFT or amount of FTs
;; @param sender: owner of asset
;; @param recipient: new owner of asset after tx
(transfer (uint principal principal) (response bool uint))
;; Transfer from the sender to a new principal
;; must return `(ok true)` on success, never `(ok false)`
;; must emit an event with `memo`
;; @param id-or-amount; identifier of NFT or amount of FTs
;; @param sender: owner of asset
;; @param recipient: new owner of asset after tx
;; @param memo: message attached to the transfer
(transfer-memo (uint principal principal (buff 34) (response bool uint))
Example contract: https://github.com/MarvinJanssen/stx-atomic-swap/blob/master/stx/contracts/sip009-sip010-htlc.clar
This trait should be implemented by transferable asset contracts. It provides functions to defined operators that are approved to transfer assets in the name of the user. Examples of operators are trusted marketplaces.
In #40, some proposals have been made to improve the security of these functions
as-contract?
calls: #40 (comment)See also radicleart/clarity-market#6
define-trait operable
(
;; set approval for an operator to handle a specified id or amount of the asset
;; must return `(ok true)` on success, never `(ok false)`
;; @param id-or-amount; identifier of NFT or amount of FTs
;; @param operator: principal that wants top operate the asset
;; @param bool: if true operator can transfer id or up to amount
(set-approved (uint principal bool) (response bool uint))
;; read-only function to return the current status of given operator
;; if returned `(ok true)` the operator can transfer the NFT with the given id or up to the requested amount of FT
;; @param id-or-amount; identifier of NFT or amount of FTs
;; @param operator: principal that wants top operate the asset
;; @param bool: if true operator can transfer id or up to amount
(is-approved (uint principal) (response bool uint))
https://github.com/radicleart/clarity-market/blob/main/contracts/loopbomb.clar#L195
As raised as a need with hirosystems/connect#283
I propose a SIP to specify a slice
function for Clarity, building on the proposal in clarity-lang/reference#42 expanded with the insights of stacks-network/stacks-core#3149. There is a prototype implementation of such a function in the next branch that can be improved on.
Questions like this are asked now and again.
I used to run a stacks node on a couple of low-power cleanly installed Windows PC's, https://docs.stacks.co. The previous tutorial would explain the minute steps to install all the dependencies, download the stacks node software and then the command to run it.
That info is no longer available. If you search for "run stacks node" we find:
https://docs.stacks.co/docs/nodes-and-miners/run-a-node
Is running it in docker mandatory or can users still take steps to run it on Linux, Windows or MacOS without? If that is still possible I would love to see those step by steps. If not feel free to explain why that is, or why perhaps it is not recommended. We can let users know when we see the questions come up again. @wileyj
I think it would be great if it is super easy for users to install the node software with a single click, is there any chance of that, creating an executable that installs the dependencies and then runs the node?
Users already running a bitcoin node with Umbrel have shown an interest to run a Stacks node alongside on their Raspberry Pi. The Umbrel store has recently added the option to add apps from "community app stores", could the Stacks Foundation run such a store with an option to install the Stacks node?
Sidenote: Perhaps lnswap app can be added in the same store, it wasn't accepted in the official store getumbrel/umbrel#1315 (comment)
There is currently no single reference for traits defined by the Stacks Improvement Process.
A document maintained in this repo which lists recommended trait contracts already deployed will be helpful to new and existing developers.
SIPs 009 and 010 reference a deployed mainnet trait contract but not testnet versions. Versions for testnet are included below along with the new SIP-013 standard which is deployed on testnet but not yet ratified.
SIP-009
SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait
SIP-010
SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait
SIP-013 not yet ratified / deployed
SIP-009
ST1NXBK3K5YYMD6FD41MVNP3JS1GABZ8TRVX023PT.nft-trait.nft-trait
SIP-010
ST1NXBK3K5YYMD6FD41MVNP3JS1GABZ8TRVX023PT.sip-010-trait-ft-standard.sip-010-trait
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.