Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Helpful references for writing Secret Network contracts as well as building full-stack Secret Networks dApps.
Use this link to see a sample voting contract and a line-by-line description of everything you need to know.
Use this link for a sealed-bid (secret) auction contract that makes use of SNIP-20 and a walkthrough of the contract.
For an even more advanced version of this stunning Secret Sealed Bid Auction app, you can refer to its enhanced Secret Auction Factory put in production.
The VueJS UI code is available here.
Guides about building on the Secret Network
Official Guides written by the community
Set up your environment and start writing contracts as fast as possible
More specific tutorials for different use cases
Guides and Tutorials by Figment
Creating my first secret contract
Tutorial by DarwinZero
Developing your first secret contract
Tutorial by DarwinZero
How to build a Keplr Staking Web App
Tutorial by validator Secure Secrets
Example of on-chain randomness based on encrypted inputs and state + video tutorial
This page is dedicated to community tutorials and code repositories that provide helpful references for writing Secret Network contracts as well as building full-stack Secret Networks dApps.
To master the SNIP-20 contract specifications, you can refer to these two key parts:
To master the SNIP-721 contract specifications for Non-Fungible Tokens (NFT), you can refer to these two key parts:
Here are some examples of additional Secret Contracts for reference:
We'll start by going through the basic components of a contract.
Instantiate - the logic that is ran once on initialization of the contract. This will usually be the initial conditions and configuration of the contract.
Execute - this is where the transactional logic resides. These are functions that modify contract data
Query - these are functions that are ran as read-only and cannot modify contract data
State - the long-term storage of the contract. By default, data used by contracts will be lost between transactions.
Each contract will contain these basic building blocks, with their logic being built around how they work.
Did you know? Executes require a transaction, which costs gas. Queries are free! This is why it is preferable to use queries when an action does not require modifying data.
Now we can move on to examining our contract, which solves the Millionaire's problem. We'll start by looking at the directory structure:
For the most part, we can expect the files to contain the following data:
contract.rs - will contain most of the business logic of the app
msg.rs - will contain the various interfaces and messages that are used to communicate with the contract
state.rs - will contain logic pertaining to data structures that are saved in the long-term storage (state)
cargo.toml - will contain metadata and detail the various libraries that the contract is using
Did you know? Contracts for Secret Network depend on forked versions of the standard CosmWasm dependencies
Before we jump into the code, we will go over the contract flow. We have to accept inputs from two different users, save their inputs, and expose a way to check which input is greater.
We end up with the following state machine:
This is a fairly naïve approach, but for the purposes of this example it is fairly straightforward. From looking at this state machine, we can expect that the implementation will contain (at minimum) the following methods:
Submit Input - allow the user to submit input. We'll also need the user to identify himself somehow so we can print out his identity if he is the winner.
Query Result - ask the contract which input is greater and return the id of the user whose input was greater
Reset - resets the state and start over
We'll note that Submit Input and Reset are both actions that require modifying contract data, so they will be executes. Similarly, Query Result is a read-only function, so it can be implemented (as the name suggests) as a query.
Now let's think about what data our contract will need to store. Each submit input method will require a separate transaction, so we need to save both the user data, and something to help keep track of which step we are on. This means that our state will look something like:
User data #1 - <User ID, Net Worth>
User data #2 - <User ID, Net Worth>
Step - <Initial/Got 1st/Done>
Further Reading: For simplicity we do not differentiate between a transaction and a message. In reality, the Cosmos-SDK defines each discrete interaction with the chain as a message. While a transaction is a higher-level object that can contain multiple messages
Alright, now we are armed with all the knowledge we need to dive into the code itself!
Entry points, or handlers are where messages or queries are handled by the contract - this is basically where all data coming into the contract ends up. We can see the different entry points based on the contract components we described.
The instantiate step is where we'll want to create a default contract state with our initial starting conditions to prepare the contract for accepting data. We're not depending on any input from the user in this step, so we can ignore all the function inputs.
Further Reading: The instantiate step is usually where contract ownership is defined, if the contract makes use of admin-only features
Let's look at this in the code:
Again, we'll ignore all the scary stuff and look only at lines 9 and 10.
On line #9 we're taking this yet unknown State data type and calling its default()
function.
On line #10 we're saving this State data structure to the contract storage. This means it will be available for us to read the next time the contract is called (from the execute or query entry-points). We can also see deps.storage
is being used as a function parameter. This gives us a clue as to what the deps
variable contains - objects that allow the contract to interact with functionality outside the contract code itself. Some examples of this are using long-term storage, calling efficient crypto APIs, or querying the blockchain state.
Did you know? The instantiate function can only be called once per contract when it is initialized
Since we want to understand what this strange State structure is, we can sort of guess that there might be some useful information in the state.rs file. And indeed here we find our definitions:
Do you even Rust? The #[derive] header tells the compiler to provide implementations for basic behaviour. For example, using _Default
_ will tell our compiler to generate the ::default()
function, which will allocate the structure and set all the values to their defaults (0 for a number, "" for a string, etc.)
Switching back to contract.rs we'll just dive right into our execute entry-point, since we already know what to expect
Do you even Rust? The match syntax is logically similar to switch-case that you might be familiar with from other languages
Do you even Rust? In Rust Enums can contain complex data types, which makes them especially useful for interface definitions
Yep, as we expect, ExecuteMsg
is just an enumeration of the different message types (and their parameters) that a user can send to the contract. The way this works in practice is that the user sends his data as a JSON object. This object then gets parsed and matched according to the definition in ExecuteMsg
. If the object does not match one of the enum types? The transaction will fail and get rejected!
Do you even Rust? Can you intuitively guess what #[derive(Serialize, Deserialize, PartialEq)] are used for? How about #[serde(rename_all = "snake_case")]?
Okay, time to zoom back in to contract.rs and take a look at our functions. The first one we will be looking at is try_submit_net_worth:
This is the main function that handles the logic of our contract. Although you can probably figure this out easily, we'll describe the logic you're seeing:
Read the current state of the contract from long-term storage
If we don't have any data, save user data as player#1 and set the state as Got1
If we already got the data for the first user, save user data as player#2 and set the state as Done
Save the new state in storage.
Super simple. Let's head over to the try_reset function
At this point I don't even have to explain to you what's going on here. We'll just note that the Response
object in this case returns something called an attribute. An attribute is a key-value pair that gets returned after a successful message that can help summarizing what happened. Attributes can even be indexed, queried and used as event triggers via WebSocket.
Now we have all the pieces in place. All that remains to be done is to look at how the result is queried by the user.
Let's see what the last contract component we haven't looked at - query - has for us:
At a glance, we see the same basic structure that we've seen in the Execute entry point. We can also guess that msg
and the QueryMsg
data type are functionally similar to the ExecuteMsg
type we've seen earlier. By now you'll know where this data type is defined, so you can go take a look at the definition and verify this assumption.
Looking a bit deeper, the to_binary
method sticks out as odd. We haven't seen this in our executes or the instantiate function. The reason for this is that queries are returned as binary data. Executes and the instantiate function return complex objects that are saved to the blockchain state, whereas queries are simple and only need to return the specific data the user cares about.
The last piece of the puzzle is the query_who_is_richer
function
Logically, this is super simple. Read the state, check which player has the most money, and return the result.
Do you even Rust? The astute reader will remember that player in this context is actually a complex data structure. How is it possible to call max(player1, player2) or to check if player1 == player2? It turns out you can actually implement the logic for equality and ordering yourself for structs. Head over to state.rs to see an example of that in action
The only thing worth noting is that the response is of the type RicherResponse
(we ignore the StdResult
wrapper - it is used to handle and include errors in the possible return types). RicherResponse
is a custom type that we defined (in msg.rs).
Usually, you will want to define a custom return type for each separate query, which makes data easier to process on the user side - we'll remember that while we talk about user queries for simplicity, in reality, the user will most likely be accessing data through some web application which will be handling both querying the contract and processing the response.
That's it! An entire Secret Contract from start to end. Thanks for taking the time to go through all of this guide (or even a small portion of it)! You should now have a good understanding of the building blocks of a contract not only on Secret Network, but for all blockchains that support CosmWasm.
- Winning projects from past Secret hackathons
- This is part of the . It is meant as an easy to understand first contract example that solves the Millionaire's Problem.
- Quick-start template to start developing Secret Contracts.
- Includes messages for frequently used permissioned functionality.
- Reference implementation of Secret Tokens.
- Reference Implementation of Private Multitokens.
- Reference implementation of Secret NFTs.
- Demonstrates how to use a parent contract to create offspring contracts.
- Example of a contract that can be uploaded to both secret and non-secret cosmwasm chains.
- Simple betting game on the outcome of a dice roll, with a video tutorial.
- Example of a voting contract.
- Template for launching NFT projects that need randomized minting.
- Verifies that an on-chain contract is indeed running a specific code. .
- A smart contract that receives tokens and distributes them to multiple addresses. .
- Get authorized to web3 places by proving you are the owner of an NFT. .
- A wallet that is collectively controlled by multiple accounts.
- Example how real-world data could be inserted on chain by validators.
.
- Demonstrates Vesting implementation
- These are the standard specifications and reference contract that implements the base standard required for fractionalized NFTs on Secret Network.
This section provides a detailed breakdown of a Secret smart contract known as . Going through this section won't require you to know Rust (though it would help), but instead we'll focus mostly on the logic, and how different components interact with each other.
, we can see these entry points defined in contract.rs -
As per usual, let's ignore all that#[derive]
stuff, and instead look at our data structures. We can see that our State
data structure contains the exact types that we expected when thinking about the of the contract. We'll also note that we chose to contain the user data in the Millionaire
struct.
Without understanding anything else, we can immediately see our 2 actions that we implemented here. We can also figure out that msg
is some data type that tells us what function we need to call.
**** we can see what ExecuteMsg
is defined as:
- a more in-depth Secret Contract guide
- everything you want to know about CosmWasm
- Building a web UI for a Secret Contract
Here all interaction SDKs are listed that are maintained for the Secret Network
Shade Protocol - Integrated Defi dApp with Stablecoin, lending, AMM and more.
Secret Blackjack - Secret multiplayer gaming example - be the first player among multiple opponents to empty your hand!
Secret Admirers - Video streaming dApp with privacy preserving features.
Private Voting - Private EVM cross-chain voting dApp deployed on Polygon testnet (source code).
Secret Lottery - Lottery dApp that returns a number between 1 and 1,000,000 using SecretVRF (source code).
Secret Business Cards - Business card dApp that uses Secret toolkit viewing keys to create permissioned business cards (source code).
Millionaire's Problem - Privately reveal whose networth is greater with Secret contracts (source code).
Mystic Skulls - Upgradable NFT collection with puzzles. Frontend.
Dreamscape - Multiplayer card game. Frontend.
SecretJack - BlackJack game.
SecretSwap - Decentralized Exchange of tokens and SCRT. Frontend.
Secret Vault - Simple Password Manager.
Decure - Customer review platform.
SecretHoldEm - Texas hold'em poker game.
The Secret Software Development Kit (SDK) in Python is a simple library toolkit for building software that can interact with the Secret blockchain and provides simple abstractions over core data structures, serialization, key management, and API request generation.
Written in Python offering extensive support libraries
Versatile support for key management solutions
Exposes the Secret Rest API through LCD/REST client
Written in C# / .NET 6 including MAUI Support.
Can be used in MAUI Apps on Android, iOS, Windows and Mac.
Provides simple abstractions over core data structures.
Supports every possible message and transaction type.
Exposes every possible query type.
Handles input/output encryption/decryption for Secret Contracts.
The SDK has a wallet built in and does not currently require / support external wallets.
Custom APIs / clients for specific smart contracts can be easily created and the additional packages for tokens / SNIP20 or NFT / SNIP721 (see below) can serve as an example for this.
In addition the following complementary packages are available, which act as a layer on top of the Secret.NET:
All packages are available via NuGet and can be easily installed nuget.exe
-CLI:
.NET Multi-platform App UI (.NET MAUI) is a cross-platform framework for creating native mobile and desktop apps with C# and XAML.
Using .NET MAUI, you can develop apps that can run on Android, iOS, macOS, and Windows from a single shared code-base.
.NET MAUI is open-source and is the evolution of Xamarin.Forms, extended from mobile to desktop scenarios, with UI controls rebuilt from the ground up for performance and extensibility.
Using .NET MAUI, you can create multi-platform apps using a single project, but you can add platform-specific source code and resources if necessary. One of the key aims of .NET MAUI is to enable you to implement as much of your app logic and UI layout as possible in a single code-base.
.NET MAUI is for developers who want to:
Write cross-platform apps in XAML and C#, from a single shared code-base in Visual Studio.
Share UI layout and design across platforms.
Share code, tests, and business logic across platforms.
A toolkit very similar to CosmJs that allows people to create and sign contract executions, integrate wallets and more.
See the full documentation, code and usage examples here:
Secret.NET (full port of the ) is a .NET SDK for writing applications that interact with the Secret Network blockchain.
You can find the source code and full version of the docs at
supports all methods of the of the .
supports all methods of the of the .
:
Secret.NET unfortunately cannot be connected to localsecret (Docker) yet, as the docker image currently does not provide an encrypted connection on gRPC-web port 9091. As far as I know, .NET cannot be connected to an unencrypted port via gRPC-web unless it offers HTTP/2 exclusively, which is not the case with localsecret (it also runs HTTP 1.1 on port 9091). See and .
Documentation for Secret.Js is separately hosted under:
A Kotlin multiplatform Encryption and REST client for Secret Network utilizing gRPC gateway endpoints.
Supported Features:
Contract Queries
Simulate Contract Execution To Estimate Gas
Contract Execution (MsgExecuteContract)
Contract Code Upload (MsgStoreCode)
Contract Instantiate (MsgInstantiateContract)
Contract Migrate (MsgMigrateContract)
Contract Update Admin (MsgUpdateAdmin)
Contract Clear Admin (MsgClearAdmin)
Bank Send (MsgSend)
Web: Delegate signing transactions to Kepler or Metamask browser wallets
Supported Targets:
JVM
js
iOS
macOS
TODO: linux
An experimental swift pacakge for use with iOS and macOS is available as well.
See the full documentation, code and usage examples here For help and questions please ask Luca Spinazzola from Eqoty Labs.
Shade protocol made their own JavaScript SDK to help people interact with specifically their Contracts. It serves as a great example for Contract Interaction or can be forked to make a similar SDK for your own application. https://github.com/securesecrets/shadejs
SecretNET.Token is a layer on top of the Secret.NET which supports all methods of the reference implementation of the SNIP20 contract.
nuget install SecretNET.Token
SecretNET.NFT is a layer on top of the Secret.NET which supports all methods of the reference implementation of the SNIP721 contract.
nuget install SecretNET.NFT
This is a group of tools that help you develop Smart contracts by skipping on boilerplate code.
This Rust package is a collection of sub-packages that contain common tools used in development of running on the .
While the packages in this repository are designed with Secret Network's runtime in mind, some of them may work well with the vanilla libraries and runtimes as well, or only require minimal modifications to be compatible with them.
See usage and docs at:
The following section will detail useful tools for developing Secret Contracts
This is a collection of specification and contracts designed for use on real networks. They are designed not just as examples, but to solve real-world use cases, and to provide a reusable basis to build many custom contracts.
Version by SCRT labs: https://github.com/scrtlabs/cw-plus
Version by Secure Secrets: https://github.com/securesecrets/cw-plus
Rebranded version by Secure Secrets: https://github.com/securesecrets/secret-plus-utils
Warning: Compatibility of with Secret Contracts may be limited due to the missing iterator function
Quick breakdown of additional tools to use for development
There are many tools created by various ecosystem contributors. These tools can be incredibly useful in different situations.
If you have a tool that you think could be added here, let us know on GitHub or Discord!
Collection of awesome things related to CosmWasm smart contracts.
https://github.com/scrtlabs/CosmWasm-Simulator - Simulator for CosmWasm transactions. Helpful when trying to debug on-chain behavior
Browser interface for smart contracts by btn.group
Monitor a validator on the Secret Network with an active telegram bot, email or phone call through Twilio
Tool to verify the WASM public binary of any contract against its source code. Make sure live contracts do what the Git repo says they do.
Fadroma (built by hack.bg) introduces core workflows for smart contract development and deployment on Cosmos-based platforms, specifically Secret Network! Fadroma helps developers avoid platform specific boilerplate code - automating the repetitive workflow steps by providing essential smart contract building blocks that empower developers to both maintain high development velocity and deliver a reliable product.
Fadroma is currently being developed as an in-house framework facilitating the Sienna Network project. In order to bring Fadroma to a larger developer audience, development hours are being dedicated to improving test coverage, documentation, stabilizing APIs, and ensuring compatibility with a wide range of use cases and underlying platforms.
Get started with Fadroma here: https://github.com/hackbg/fadroma/blob/stable/guide/basic-project-setup.md
The following is the list of some of the important initial feature of Fadroma - creating a unique and fluid development experience.
Fadroma Prelude - reexport of platform libraries, with added types for frequently used building blocks:
ContractLink
, a data type that contains a contract address and code hash
Humanize
and Canonize
- traits to convert structures that contain HumanAddr
to their CanonicalAddr
equivalent and vice versa
ViewingKey
and Permit
viewing key and permit with custom permissions
Uint256
- 256-bit equivalents of the CosmWasm numeric types, etc.
Fadroma Derive: a derive macro that generates boilerplate code like message definitions and dispatch init/handle/query functions, as well as wasm32 entry points - empowering contract creation out of separate subsystems.
Fadroma Components - implementations of frequently used smart contract functionality:
Fadroma Admin: TX sender-based admin auth
Fadroma VK: viewing key-based auth
Fadroma Permit: query permit-based auth
Fadroma Killswitch: pause or permanently disable contracts
Fadroma Token: A SNIP-20 implementation forked from the reference implementation and rebuilt as a trait.
This allows individual token contract functions to be overriden without having to copy the entire codebase.
Furthermore, it enables token functionality to be added to service contracts, obviating the need for a separate contract to represent the service token.
Fadroma Ensemble: fast integration testing of multiple smart contracts in Rust by mocking the CosmWasm API - useful for testing application logic when it is distributed among several contracts.and having them run instantaneously during development.
Fadroma Ops: Node.js-based operations framework for managing the smart contract lifecycle. Provides a rich vocabulary of classes for modeling your smart contract deployment workflow.
Fadroma Build: compile smart contracts from the working tree or a past point in Git history.
Fadroma Localnet: run a localnet for development,
Fadroma Receipts: keep track of uploads and instantiations. It is possible to update an existing deployment by specifying its id from the receipts and adding additional instances or executing messages all from code.
Fadroma Schema: generate TypeScript definitions from the JSON Schema exported by contracts.
Fadroma Bundle: Execute multiple messages in a single transaction or generate an unsigned transaction for manual multi-signing.
100% test coverage
Docker Compose integration for a portable development environment based on familiar tools.
Fadroma CLI: Command-line entrypoint for creating new projects and running default and custom management commands.
(init) Start a project
(add) Add contracts to it
(compile) Compile them
Polar is development framework for building secret contracts. The aim of the project is to make Secret contracts development process simple, efficient and scalable. User can focus on logic of secret contract and not much about further steps in development. It facilitates features such as initiating project repo from contract templates, easy compilation of contracts, deployment and contract testing framework.
For the full docs see: https://docs.arufaresearch.com/getting-started/
The Secret IDE is an all-inclusive environment for developing and deploying smart contracts on Secret Network. It's the best tool to get started with and the best tool to use, even if you're already a pro.
Currently, the Secret IDE is in public beta testing, and you can find all the information you need to get started with it here: https://github.com/digiline-io/Secret-IDE-Plugin
In this section we will provide examples to common usage patterns of Secret.NET
A local, instant, zero-config Secret Network blockchain.
LocalSecret is a complete Secret Network testnet and ecosystem containerized with Docker. It simplifies the way secret contract developers test their contracts in a sandbox before they deploy them on a testnet or mainnet.
LocalSecret comes preconfigured with opinionated, sensible defaults for standard testing environments. If other projects mention testing on LocalSecret, they are referring to the settings defined in this repo.
Easily modifiable world states
Quick to reset for rapid iterations
Simple simulations of different scenarios
Controllable validator behavior
Supported known architectures: x86_64, amd64
You've now officially created a local Secret Network testnet with chain-id secretdev-1
. 🎉
Your environment now contains:
You can also use docker run --rm
to launch LocalSecret. This will delete the container once you exit the terminal, but it also means that you can't edit the node's config as stopping the container automatically deletes it.
Here are some examples of how to use LocalSecret with secretcli
, secret.js
, and Keplr
.
To access secretcli
from inside the docker container:
To configure & test your local secretcli binary:
The environment variable SGX_MODE=SW
must be applied when using a local secretcli
binary.
To send some SCRT to the example secret address secret1e6mqxtwgaps7vz3qfa3fcekhh7a02hvfjvtqpt
we have to options:
The faucet drips 1000 SCRT at a time.
Inside the docker container there are accounts a
, b
, c
& d
that are pre-seeded with SCRT and can be used to send some to your address.
Connect to the chain through LocalSecret's LCD endpoint.
npm i secretjs
or yarn add secretjs
, then:
To add a custom chain to Keplr, use this code:
Different instances of LocalSecret need to be re-added to Keplr, so you need to first delete the old LocalSecret from Keplr and then re-run this^ code to add the current LocalSecret.
You can modify the node configuration of your validator in the ~/.secretd/config/config.toml
and ~/.secretd/config/app.toml
files inside the container.
To enter the docker container to access them, run:
You can then use commands like sed
& perl
to edit these files, or install text editors like vim
& nano
using apt install -y vim nano
.
To apply changes that are made to the config file, restart LocalSecret by running:
LocalSecret is often used alongside a script written with the secret.js as a convenient way to do integration tests. You can greatly improve the experience by speeding up the block time.
To decrease block times, run LocalSecret with the FAST_BLOCKS=true
environment varibale:
LocalSecret is pre-configured with one validator and 4 accounts with SCRT balances. You can import them into your own testing environment for easier prototyping.
Protocol | Endpoint | Usage |
---|
To complement this, when testing with secret.js you can lower broadcastCheckIntervalMs
to 100
from the default of 6000
().
Account | Address | Mnemonic |
---|
RPC | http://localhost:26657 |
|
gRPC-web | http://localhost:9091 |
|
SCRT Faucet | http://localhost:5000 | To get SCRT |
LCD | http://localhost:1317 |
|
a |
|
|
b |
|
|
c |
|
|
d |
|
|