├── LICENSE ├── static ├── .nojekyll ├── CNAME ├── logos.tar.gz ├── img │ ├── confio_logo.png │ ├── deuslabs_logo.png │ ├── logo_stacked.png │ ├── oraichain_logo.jpg │ ├── cryptonics_logo.png │ ├── favicon.svg │ ├── logo.svg │ └── logo_dark.svg ├── nft_marketplace.jpeg └── CosmWasm_Brand_Guidelines.pdf ├── .dockerignore ├── cw_plus_versions.json ├── docs_versions.json ├── media ├── _category_.json └── assets.md ├── tutorials ├── _category_.json ├── storage │ ├── _category_.json │ ├── AVL-tree-wBalance_K.svg.png │ ├── key-value-store.md │ └── state-modeling.md ├── frontend-dapp │ ├── _category_.json │ ├── assets │ │ └── frontend-dapp │ │ │ ├── login.png │ │ │ ├── balance-cw20.png │ │ │ ├── balance-error.png │ │ │ └── balance-native.png │ ├── bootstrap-dapp.md │ ├── intro.md │ ├── cosmicdapp-design.md │ └── cosmicdapp-logic.md ├── hijack-escrow │ ├── _category_.json │ ├── intro.md │ └── edit-escrow-hints.md ├── name-service │ ├── _category_.json │ └── intro.md ├── simple-option │ ├── _category_.json │ ├── next-steps.md │ ├── setup.md │ ├── intro.md │ └── testing.md ├── governance.md └── videos-workshops.md ├── docs ├── 05-actor-model │ └── _category_.json ├── 04-smart-contracts │ ├── 02-message │ │ ├── _category_.json │ │ ├── 01-message.md │ │ └── 02-submessage.md │ ├── 03-state │ │ ├── _category_.json │ │ ├── 02-simple-state.md │ │ └── 03-complex-state.md │ ├── 10-frontend_app │ │ ├── _category_.json │ │ ├── assets │ │ │ └── frontend-dapp │ │ │ │ ├── login.png │ │ │ │ ├── balance-cw20.png │ │ │ │ ├── balance-error.png │ │ │ │ └── balance-native.png │ │ ├── 04-bootstrap-dapp.md │ │ ├── 01-introduction.md │ │ ├── 03-cosmicdapp-design.md │ │ └── 02-cosmicdapp-logic.md │ ├── _category_.json │ ├── 09-deployment.md │ ├── 04-entry-points.md │ ├── 08-compilation.md │ ├── 05-query.md │ ├── 12-code-pinning.md │ ├── 06-events.md │ ├── 07-math.md │ ├── 14-sudo.md │ ├── 10-verify.md │ ├── 03-result-option.md │ └── 11-migration.md ├── 06-tutorials │ ├── _category_.json │ └── 01-cosmwasm-ide.md ├── 03-architecture │ ├── _category_.json │ ├── 05-serialization.md │ ├── 01-multichain.md │ ├── 03-addresses.md │ ├── 04-query.md │ └── 02-actor.md ├── 02-getting-started │ ├── _category_.json │ ├── 06-next-steps.md │ ├── 01-intro.md │ ├── 04-compile-contract.md │ ├── 03-setting-env.md │ └── 02-installation.md └── 01-intro.md ├── archived-github-workflows ├── link_checker_config.json └── workflows │ ├── link_checker.yml │ └── main.yml ├── babel.config.js ├── README.md ├── .editorconfig ├── crowdin.yml ├── src ├── theme │ └── NavbarItem.js ├── pages │ ├── deprecated.md │ └── chat.jsx └── css │ └── custom.scss ├── .gitignore ├── CONTRIBUTION.md ├── package.json └── docusaurus.config.js /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/CNAME: -------------------------------------------------------------------------------- 1 | docs.cosmwasm.com 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | */node_modules 2 | *.log 3 | -------------------------------------------------------------------------------- /cw_plus_versions.json: -------------------------------------------------------------------------------- 1 | [ 2 | "0.9.0" 3 | ] 4 | -------------------------------------------------------------------------------- /docs_versions.json: -------------------------------------------------------------------------------- 1 | [ 2 | "0.16", 3 | "0.14" 4 | ] 5 | -------------------------------------------------------------------------------- /media/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Category", 3 | "position": 1 4 | } 5 | -------------------------------------------------------------------------------- /tutorials/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Learn", 3 | "position": 5 4 | } 5 | -------------------------------------------------------------------------------- /tutorials/storage/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Storage", 3 | "position": 4 4 | } 5 | -------------------------------------------------------------------------------- /static/logos.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/logos.tar.gz -------------------------------------------------------------------------------- /docs/05-actor-model/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Actor model", 3 | "collapsed": false 4 | } 5 | -------------------------------------------------------------------------------- /tutorials/frontend-dapp/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Frontend dApp", 3 | "position": 5 4 | } 5 | -------------------------------------------------------------------------------- /tutorials/hijack-escrow/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Hijack Escrow", 3 | "position": 1 4 | } 5 | -------------------------------------------------------------------------------- /tutorials/name-service/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Name Service", 3 | "position": 4 4 | } 5 | -------------------------------------------------------------------------------- /tutorials/simple-option/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Simple Option", 3 | "position": 2 4 | } 5 | -------------------------------------------------------------------------------- /archived-github-workflows/link_checker_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "aliveStatusCodes": [200, 206, 429] 3 | } 4 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/02-message/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Message", 3 | "position": 2 4 | } 5 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/03-state/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "State", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /static/img/confio_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/img/confio_logo.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Frontend App", 3 | "position": 9 4 | } 5 | -------------------------------------------------------------------------------- /docs/06-tutorials/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tutorials", 3 | "position": 6, 4 | "collapsed": false 5 | } -------------------------------------------------------------------------------- /static/img/deuslabs_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/img/deuslabs_logo.png -------------------------------------------------------------------------------- /static/img/logo_stacked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/img/logo_stacked.png -------------------------------------------------------------------------------- /static/img/oraichain_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/img/oraichain_logo.jpg -------------------------------------------------------------------------------- /static/nft_marketplace.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/nft_marketplace.jpeg -------------------------------------------------------------------------------- /static/img/cryptonics_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/img/cryptonics_logo.png -------------------------------------------------------------------------------- /docs/03-architecture/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Architecture", 3 | "position": 3, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/02-getting-started/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Getting Started", 3 | "position": 2, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Smart Contracts", 3 | "position": 4, 4 | "collapsed": false 5 | } 6 | -------------------------------------------------------------------------------- /static/CosmWasm_Brand_Guidelines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/static/CosmWasm_Brand_Guidelines.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated (in 2023) CosmWasm documentation 2 | 3 | Up-to-date documentation can be found here: https://cosmwasm.github.io/ 4 | -------------------------------------------------------------------------------- /tutorials/storage/AVL-tree-wBalance_K.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/tutorials/storage/AVL-tree-wBalance_K.svg.png -------------------------------------------------------------------------------- /tutorials/frontend-dapp/assets/frontend-dapp/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/tutorials/frontend-dapp/assets/frontend-dapp/login.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | -------------------------------------------------------------------------------- /tutorials/frontend-dapp/assets/frontend-dapp/balance-cw20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/tutorials/frontend-dapp/assets/frontend-dapp/balance-cw20.png -------------------------------------------------------------------------------- /tutorials/frontend-dapp/assets/frontend-dapp/balance-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/tutorials/frontend-dapp/assets/frontend-dapp/balance-error.png -------------------------------------------------------------------------------- /tutorials/frontend-dapp/assets/frontend-dapp/balance-native.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/tutorials/frontend-dapp/assets/frontend-dapp/balance-native.png -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/login.png -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/balance-cw20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/balance-cw20.png -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/balance-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/balance-error.png -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/balance-native.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CosmWasm/docs-deprecated/HEAD/docs/04-smart-contracts/10-frontend_app/assets/frontend-dapp/balance-native.png -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | project_id: '467072' 2 | api_token_env: 'CROWDIN_PERSONAL_TOKEN' 3 | preserve_hierarchy: true 4 | files: [ 5 | # JSON translation files 6 | { 7 | source: '/i18n/en/**/*', 8 | translation: '/i18n/%two_letters_code%/**/%original_file_name%', 9 | }, 10 | ] 11 | -------------------------------------------------------------------------------- /media/assets.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: intro 3 | title: Media 4 | slug: / 5 | displayed_sidebar: null 6 | --- 7 | 8 | ## Brand guidelines 9 | 10 | The guidelines can be viewed in .pdf format following this [link](/CosmWasm_Brand_Guidelines.pdf). 11 | 12 | ## Logos 13 | 14 | You can download the logos in PNG and SVG format by clicking on this [link](/logos.tar.gz). 15 | -------------------------------------------------------------------------------- /archived-github-workflows/workflows/link_checker.yml: -------------------------------------------------------------------------------- 1 | name: Check Markdown links 2 | 3 | on: 4 | schedule: 5 | # Run Monday at 12PM 6 | - cron: "* * * * 1" 7 | 8 | jobs: 9 | markdown-link-check: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@master 13 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 14 | with: 15 | use-quiet-mode: 'yes' 16 | use-verbose-mode: 'yes' 17 | config-file: '.github/link_checker_config.json' 18 | -------------------------------------------------------------------------------- /src/theme/NavbarItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import OriginalNavBarItem from '@theme-original/NavbarItem'; 3 | import { useLocation } from '@docusaurus/router'; 4 | 5 | export default function NavbarItem(props) { 6 | const { docsPluginId, type } = props 7 | const { pathname } = useLocation() 8 | 9 | if (type === 'docsVersionDropdown' && pathname.search(new RegExp(`/${docsPluginId}/`, 'g')) === -1) { 10 | return null 11 | } 12 | 13 | return ( 14 | <> 15 | 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /static/img/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/pages/deprecated.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Deprecated 3 | decscription: Deprecation info 4 | --- 5 | 6 | # This CosmWasm documentation is deprecated 7 | 8 | This CosmWasm documentation was not updated for a long time, and it got deprecated. Please refer to other sources: 9 | 10 | * [CosmWasm Book](https://book.cosmwasm.com/) 11 | * [Sylvia Book](https://cosmwasm.github.io/sylvia-book/index.html) 12 | * [CosmWasm Academy](https://academy.cosmwasm.com/) 13 | * [awesome-cosmwasm](https://github.com/CosmWasm/awesome-cosmwasm) 14 | * [cosmwasm-std documentation](https://docs.rs/cosmwasm-std/) 15 | * [Last version of this documentation sources before deprecation](https://github.com/InterWasm/docs/tree/archive) 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | 3 | .DS_Store 4 | .vscode 5 | .idea 6 | *.iml 7 | *.code-workspace 8 | .changelog 9 | 10 | node_modules 11 | .yarn 12 | 13 | .eslintcache 14 | 15 | yarn-error.log 16 | build 17 | coverage 18 | .docusaurus 19 | .cache-loader 20 | types 21 | test-website 22 | 23 | packages/docusaurus/lib/ 24 | packages/docusaurus-*/lib/* 25 | !packages/docusaurus-1.x/lib/* 26 | packages/docusaurus-1.x/lib/core/metadata.js 27 | packages/docusaurus-1.x/lib/core/MetadataBlog.js 28 | packages/docusaurus-*/lib-next/ 29 | 30 | website/netlifyDeployPreview/* 31 | !website/netlifyDeployPreview/index.html 32 | !website/netlifyDeployPreview/_redirects 33 | 34 | website-1.x-migrated 35 | 36 | i18n/**/* 37 | 38 | .netlify 39 | -------------------------------------------------------------------------------- /tutorials/simple-option/next-steps.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Next Steps 6 | 7 | We covered a lot of essentials of CosmWasm in this tutorial/workshop combo. We have more reading and learning resources 8 | for you: 9 | 10 | - [Getting Started](https://docs.cosmwasm.com/docs/1.0/getting-started/intro), best starter docs. 11 | - [cw-examples](https://github.com/InterWasm/cw-contracts), simple smart contract examples. 12 | - [cosmwasm-plus](https://docs.cosmwasm.com/dev-academy/dao-governance/what-is-a-dao/#cosmwasm-and-governance), production grade smart contracts. 13 | 14 | And don't forget to join the [CosmWasm Discord](https://docs.cosmwasm.com/chat). 15 | 16 | Happy to answer all your questions and see deploy contract messages racing for to be the first in the transaction. 17 | -------------------------------------------------------------------------------- /tutorials/frontend-dapp/bootstrap-dapp.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Bootstrap dApp 6 | 7 | There are two approaches to bootstrap a new dApp: as a lerna package in the monorepo or as a standalone app. 8 | 9 | ## Monorepo template {#monorepo-template} 10 | 11 | With this approach, we'll create another lerna package in the `packages/` directory that will use the local `logic` 12 | and `design` packages as dependencies. 13 | 14 | For that, you only need to copy the `_template` directory into `packages/` and rename it to `balance-checker`: 15 | 16 | ```shell 17 | git clone https://github.com/CosmWasm/dApps.git 18 | cd dApps 19 | cp -r _template packages/balance-checker 20 | ``` 21 | 22 | In the next section we'll start by customizing it to our needs. 23 | 24 | ## Standalone template {#standalone-template} 25 | 26 | 👷 Coming soon! 27 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/04-bootstrap-dapp.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Bootstrap dApp 6 | 7 | There are two approaches to bootstrap a new dApp: as a [Lerna](https://lerna.js.org/) package in the monorepo or as a 8 | standalone app. 9 | 10 | ## Monorepo template {#monorepo-template} 11 | 12 | With this approach, we'll create another lerna package in the `packages/` directory that will use the local `logic` 13 | and `design` packages as dependencies. 14 | 15 | For that, you only need to copy the `_template` directory into `packages/` and rename it to `balance-checker`: 16 | 17 | ```shell 18 | git clone https://github.com/CosmWasm/dApps.git 19 | cd dApps 20 | cp -r _template packages/balance-checker 21 | ``` 22 | 23 | In the next section we'll start by customizing it to our needs. 24 | 25 | ## Standalone template {#standalone-template} 26 | 27 | 👷 Coming soon! 28 | -------------------------------------------------------------------------------- /src/pages/chat.jsx: -------------------------------------------------------------------------------- 1 | import React, {useEffect} from "react"; 2 | import Layout from '@theme/Layout'; 3 | 4 | function RedirectChat() { 5 | 6 | useEffect(() => { 7 | window.location.href = "https://discord.gg/cPjEnPd"; 8 | }, []); 9 | 10 | return ( 11 | 12 |
13 |
14 |
15 |

Redirecting to the CosmWasm community 16 | chat 17 | …

18 |

If this doesn't work, click 19 | here. 20 |

21 |
22 |
23 |
24 |
25 |
26 | ); 27 | } 28 | 29 | export default RedirectChat; 30 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/09-deployment.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 9 3 | --- 4 | 5 | # Deployment 6 | 7 | When compiling is complete (it may take a while) `cd` into the `artifacts` directory. `ls` should show you binaries for 8 | the contract. 9 | 10 | In the following examples, remember to switch `` for the name of the binary you just compiled. 11 | 12 | ## Store using the CLI 13 | 14 | Using `wasmd` you can now store it on the blockchain: 15 | 16 | ```sh 17 | wasmd tx wasm store .wasm --from --chain-id --gas auto 18 | ``` 19 | 20 | You will need the code id of the contract. For this, you can look in the JSON output for the `code_id` value. If you 21 | would prefer to capture this as a shell variable, instead the previous upload step you can instead do: 22 | 23 | ```sh 24 | cd artifacts 25 | RES=$(wasmd tx wasm store .wasm --from --chain-id= --gas auto -y) 26 | CODE_ID=$(echo $RES | jq -r '.logs[0].events[0].attributes[-1].value') 27 | ``` 28 | 29 | You will then be able to use `$CODE_ID` in commands when working with the contract for the remainder of your session. 30 | -------------------------------------------------------------------------------- /tutorials/frontend-dapp/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Introduction 6 | 7 | In this tutorial you will learn how to build a [CosmJS](https://github.com/cosmos/cosmjs) based dApp. The example dApp 8 | will be a balance checker that will allow you to see your native tokens and the CW20 tokens of the contract with the 9 | address you enter. 10 | 11 | ## Views {#views} 12 | 13 | It will look like this: 14 | 15 | ### Login {#login} 16 | 17 | ![image](assets/frontend-dapp/login.png) 18 | 19 | ### Native balance {#native-balance} 20 | 21 | ![image](assets/frontend-dapp/balance-native.png) 22 | 23 | ### Balance of a CW20 contract {#balance-of-a-cw20-contract} 24 | 25 | ![image](assets/frontend-dapp/balance-cw20.png) 26 | 27 | ### Error for address with no contract {#error-for-address-with-no-contract} 28 | 29 | ![image](assets/frontend-dapp/balance-error.png) 30 | 31 | ## Setup environment {#setup-environment} 32 | 33 | We recommend to use [Visual Studio Code](https://code.visualstudio.com) but this tutorial should be easily followed with 34 | any other text editor. 35 | 36 | You should download the latest release of the [`CosmWasm/dApps`](https://github.com/CosmWasm/dApps) monorepo using your 37 | preferred method. 38 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/01-introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Introduction 6 | 7 | In this tutorial you will learn how to build a [CosmJS](https://github.com/cosmos/cosmjs) based dApp. The example dApp 8 | will be a balance checker that will allow you to see your native tokens and the CW20 tokens of the contract with the 9 | address you enter. 10 | 11 | ## Views {#views} 12 | 13 | It will look like this: 14 | 15 | ### Login {#login} 16 | 17 | ![image](assets/frontend-dapp/login.png) 18 | 19 | ### Native balance {#native-balance} 20 | 21 | ![image](assets/frontend-dapp/balance-native.png) 22 | 23 | ### Balance of a CW20 contract {#balance-of-a-cw20-contract} 24 | 25 | ![image](assets/frontend-dapp/balance-cw20.png) 26 | 27 | ### Error for address with no contract {#error-for-address-with-no-contract} 28 | 29 | ![image](assets/frontend-dapp/balance-error.png) 30 | 31 | ## Setup environment {#setup-environment} 32 | 33 | We recommend to use [Visual Studio Code](https://code.visualstudio.com) but this tutorial should be easily followed with 34 | any other text editor. 35 | 36 | You should download the latest release of the [`CosmWasm/dApps`](https://github.com/CosmWasm/dApps) monorepo using your 37 | preferred method. 38 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/04-entry-points.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Entry points 6 | 7 | Entry points, or _handlers_ are where messages or queries are handled by the contract. 8 | 9 | All three of the functions we will be talking about are explicitly flagged as entry points, and excluded from being 10 | bundled in the library: 11 | 12 | ```rust 13 | #[cfg_attr(not(feature = "library"), entry_point)] 14 | pub fn instantiate( 15 | deps: DepsMut, 16 | _env: Env, 17 | _info: MessageInfo, 18 | msg: InstantiateMsg, 19 | ) -> Result { 20 | // ...etc 21 | } 22 | ``` 23 | 24 | These handlers are: 25 | 26 | 1. Instantiate messages, as defined by the `InstantiateMsg` struct, are handled by `instantiate`. 27 | 2. Messages, as defined by the `ExecuteMsg` enum, are handled by the `execute` function, using a 28 | pattern-matching `match` statement. 29 | 3. Queries, as defined by the `QueryMsg` enum, are handled by the `query` function, using a pattern-match. 30 | 31 | `execute` and `query` must exhaustively match every variant in the enums they handle, while `instantiate` only has to 32 | deal with the struct it is passed. 33 | 34 | Typically, `instantiate` and `execute` have the type `Result`, while `query` 35 | has `StdResult` due to the underlying Cosmos SDK `Querier`. 36 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/08-compilation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 8 3 | --- 4 | 5 | # Compilation 6 | 7 | Before your contract can be used, it has to be compiled, and then stored on chain. 8 | 9 | The easiest way of compiling is of course with `cargo`. 10 | 11 | ```sh 12 | cargo wasm 13 | ``` 14 | 15 | This is sufficient for dev use. However, this will not be optimised, and in production gas costs matter. It's possible 16 | to strip unnecessary code and produce a more lean build like so: 17 | 18 | ```sh 19 | RUSTFLAGS='-C link-arg=-s' cargo wasm 20 | ``` 21 | 22 | In most cases, however, you will want to use the optimiser docker image. Note that you might need to change the paths in 23 | the snippet below to better fit your code paths. 24 | 25 | ```sh 26 | sudo docker run --rm -v "$(pwd)":/code \ 27 | --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ 28 | --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ 29 | cosmwasm/workspace-optimizer:0.12.4 30 | ``` 31 | 32 | On Windows, you can use the following command instead 33 | ```powershell 34 | docker run --rm -v ${pwd}:/code ` 35 | --mount type=volume,source="$("$(Split-Path -Path $pwd -Leaf)")_cache",target=/code/target ` 36 | --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry ` 37 | cosmwasm/rust-optimizer:0.12.11 38 | ``` 39 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/03-state/02-simple-state.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Simple State 6 | 7 | State is where the smart contract works with saving and retrieving data. You can think of it much like a database 8 | interaction layer in a traditional application. 9 | 10 | The most simple way of writing state is by writing a single item. 11 | 12 | For example, in the `cw20-base` contract, `TokenInfo` is written when the contract is instantiated. 13 | 14 | First, a `TokenInfo` type is declared in `state.rs`: 15 | 16 | ```rust 17 | #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] 18 | #[serde(rename_all = "snake_case")] 19 | pub struct TokenInfo { 20 | pub name: String, 21 | pub symbol: String, 22 | pub decimals: u8, 23 | pub total_supply: Uint128, 24 | pub mint: Option, 25 | } 26 | ``` 27 | 28 | Then the storage is initialized: 29 | 30 | ```rust 31 | pub const TOKEN_INFO: Item = Item::new("token_info"); 32 | ``` 33 | 34 | In the contract, we see in the `instantiate` function how data can be saved to this: 35 | 36 | ```rust 37 | let data = TokenInfo { 38 | name: msg.name, 39 | symbol: msg.symbol, 40 | decimals: msg.decimals, 41 | total_supply, 42 | mint, 43 | }; 44 | TOKEN_INFO.save(deps.storage, & data) ?; 45 | ``` 46 | 47 | Here's the [code context](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/src/contract.rs#L90). 48 | -------------------------------------------------------------------------------- /tutorials/hijack-escrow/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Introduction 6 | 7 | Throughout the [Getting Started](https://docs.cosmwasm.com/1.0/getting-started/intro) section we demonstrated the essential procedure that is required to use CosmWasm smart contracts: setup, compilation, deployment and interaction. We will take it one step further and edit the [Escrow Contract](https://github.com/InterWasm/cw-contracts/tree/main/contracts/escrow) in a way that enables a thief to hijack the funds saved in the contract. Before starting, make sure you read and followed the steps in the [Getting Started](https://docs.cosmwasm.com/1.0/getting-started/intro) section. 8 | 9 | :::tip Reminder 10 | The Rust plugins for the [recommended development environments](https://docs.cosmwasm.com/1.0/getting-started/installation#setting-up-your-ide) look for a Cargo.toml file in the root directory of your project workspace, and only parse rust code referenced by this Cargo.toml file (listed as a workspace, or imported by `src/lib.rs`). 11 | The [`cw-examples`](https://github.com/CosmWasm/cw-examples) repository does not have a `Cargo.toml` file in the project root folder, but rather has one in each example contract sub-directory. To ensure proper IDE support when working on this example, you should only open the `escrow` directory in your preferred IDE and not the project root folder. In general, a good practice is to have one window open for each rust project, rooted in the same directory as its `Cargo.toml` file. 12 | ::: 13 | -------------------------------------------------------------------------------- /CONTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # Contribution 2 | 3 | > This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ## Installation 6 | 7 | ```console 8 | yarn install 9 | ``` 10 | 11 | ## Local Development 12 | 13 | ```console 14 | yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live 18 | without having to restart the server. 19 | 20 | ## Build 21 | 22 | ```console 23 | yarn build 24 | ``` 25 | 26 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 27 | 28 | ## Auto Deployment 29 | 30 | Merges to `main` branch will automatically be deployed at https://docs.cosmwasm.com 31 | 32 | ## Adding New Page 33 | 34 | - [/docs](docs) contains next CosmWasm documentation. Version follows cosmwasm-std. 35 | - [/docs_versioned_docs](docs_versioned_docs) contains old and current versions CosmWasm documentation. Version follows 36 | cosmwasm-std. 37 | - [/tutorials](tutorials) contains unversioned cosmwasm tutorials. 38 | - [/cw-plus](cw-plus) contains cosmwasm-plus documentation. It is listed under dApps. 39 | 40 | Create a markdown page under related category, and put order information as header. 41 | ``` 42 | --- 43 | sidebar_position: 3 44 | --- 45 | ``` 46 | The documentation will be shown automatically. 47 | 48 | ## Creating New Category 49 | 50 | Create a now folder, and write category information under `_category_.json` 51 | It will be listed on the website. 52 | -------------------------------------------------------------------------------- /tutorials/simple-option/setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Setup 6 | 7 | 8 | 9 | ## Coding Environment {#coding-environment} 10 | 11 | ### Rust and IDE {#rust-and-ide} 12 | 13 | This section is a summary 14 | of [Getting Started / Installation and Setting Up Environment](https://docs.cosmwasm.com/0.14/getting-started/installation). 15 | You can go to the doc, 16 | setup rust and preferred IDE then and come back here. We recommend using Intellij IDEA. 17 | 18 | ## Project Starter {#project-starter} 19 | 20 | Project starter template repo is there for spinning new smart contract quickly. With one command, project layout, boiler 21 | plate, git, and even Circle CI for auto testing/formatting/linting will be set up. Cool huh. Here is the 22 | repo: [cosmwasm-template](https://github.com/CosmWasm/cosmwasm-template) 23 | 24 | Assuming you have a followed section above, then the following should get you a new repo to start a contract: 25 | 26 | First, install **cargo-generate**. Unless you did that before, run this line now: 27 | 28 | `cargo install cargo-generate --features vendored-openssl` 29 | 30 | Now, use it to create your new contract. Go to the folder in which you want to place it and run: 31 | 32 | `cargo generate --git https://github.com/CosmWasm/cosmwasm-template.git --name simple-option` 33 | 34 | Initialize git repo: 35 | 36 | ```shell 37 | git add . 38 | git commit -m "Initial generation from cosmwasm-template" 39 | ``` 40 | 41 | Great, workstation is ready. 42 | -------------------------------------------------------------------------------- /archived-github-workflows/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Docs Deployment 2 | 3 | on: 4 | pull_request: 5 | branches: main 6 | push: 7 | branches: main 8 | 9 | jobs: 10 | checks: 11 | if: github.event_name != 'push' 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v1 15 | - uses: actions/setup-node@v1 16 | with: 17 | node-version: '18.x' 18 | - name: Test Build 19 | run: | 20 | if [ -e yarn.lock ]; then 21 | yarn install --frozen-lockfile 22 | elif [ -e package-lock.json ]; then 23 | npm ci 24 | else 25 | npm i 26 | fi 27 | npm run build 28 | 29 | gh-release: 30 | if: github.event_name != 'pull_request' 31 | runs-on: ubuntu-latest 32 | timeout-minutes: 10 33 | steps: 34 | - uses: actions/checkout@v1 35 | - uses: actions/setup-node@v1 36 | with: 37 | node-version: '18.x' 38 | - uses: webfactory/ssh-agent@v0.5.3 39 | with: 40 | ssh-private-key: ${{ secrets.GH_PAGES_DEPLOY }} 41 | - name: Release to GitHub Pages 42 | env: 43 | USE_SSH: true 44 | GIT_USER: git 45 | CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} 46 | run: | 47 | git config --global user.email "actions@github.com" 48 | git config --global user.name "gh-actions" 49 | if [ -e yarn.lock ]; then 50 | yarn install --frozen-lockfile 51 | elif [ -e package-lock.json ]; then 52 | npm ci 53 | else 54 | npm i 55 | fi 56 | npm run crowdin:sync 57 | npm run deploy 58 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "0.2.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus write-heading-ids & docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids", 15 | "crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download --verbose" 16 | }, 17 | "dependencies": { 18 | "@crowdin/cli": "3", 19 | "@docusaurus/core": "2.2.0", 20 | "@docusaurus/plugin-client-redirects": "2.2.0", 21 | "@docusaurus/plugin-sitemap": "2.2.0", 22 | "@docusaurus/preset-classic": "2.2.0", 23 | "@mdx-js/react": "^1.6.21", 24 | "@svgr/webpack": "^5.5.0", 25 | "clsx": "^1.1.1", 26 | "docusaurus-plugin-sass": "^0.2.0", 27 | "file-loader": "^6.2.0", 28 | "react": "^17.0.1", 29 | "react-dom": "^17.0.1", 30 | "react-router": "^5.2.0", 31 | "react-router-dom": "^5.2.0", 32 | "sass": "^1.35.1", 33 | "url-loader": "^4.1.1" 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.5%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | }, 47 | "devDependencies": { 48 | "crowdin": "^3.5.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tutorials/name-service/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | --- 4 | 5 | # Introduction 6 | 7 | The Cosmos SDK has [a good standard tutorial](https://tutorials.cosmos.network/academy/3-my-own-chain/cosmwasm.html#compile-a-smart-contract), 8 | which builds out a sample name service application. To provide a nice transition for existing SDK developers, we will 9 | demonstrate implementing the same application using CosmWasm. This is a useful tutorial to demonstrate basic concepts 10 | and applying the skills that you learned in the introduction. We will also be producing another tutorial for deploying 11 | and using an ERC20 contract, which may be more familiar to those coming from an Ethereum background. 12 | 13 | ## Goal {#goal} 14 | 15 | As in the [original tutorial](https://tutorials.cosmos.network/academy/3-my-own-chain/cosmwasm.html#compile-a-smart-contract), you will build a 16 | functional application running on [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/). In this case we will 17 | use [`cosmwasm`](https://github.com/CosmWasm/cosmwasm) to deploy a rust contract rather than develop a native go module. 18 | In the process, learn the basic concepts and structures of CosmWasm. The example will showcase how quickly and easily 19 | customize a [default Cosmos SDK application](https://github.com/CosmWasm/wasmd) using CosmWasm smart contracts. 20 | 21 | By the end of this tutorial you will have a functional `nameservice` application, a mapping of strings to other 22 | strings (`map[string]string`). This is similar to [Namecoin](https://namecoin.org/), [ENS](https://ens.domains/) 23 | , [IOV](https://iov.one), or [Handshake](https://handshake.org/), which all model the traditional DNS 24 | systems (`map[domain]zonefile`). Users will be able to buy unused names, or sell/trade their name. 25 | 26 | **Coming Soon** 27 | -------------------------------------------------------------------------------- /docs/02-getting-started/06-next-steps.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Next Steps 6 | 7 | This is a very simple example for the name service contract we developed, but it should show you what is possible, limited only by the wasm code you upload and the json messages you send. The next step is the 8 | [Hijack Escrow tutorial](/tutorials/hijack-escrow/intro) where you will edit a smart contract to put a backdoor that enables a thief to steal funds. 9 | 10 | - [Videos and Workshops](/tutorials/videos-workshops): We curated some video and workshop resources you can take a look 11 | at. 12 | - [Learn](/tutorials/simple-option/intro) will demonstrate developing smart contracts from zero to production with step 13 | by step explanations, code snippets, scripts and more. 14 | * [Dev Academy](/dev-academy/intro) provides structured learning content for CosmWasm smart contracts and clients. 15 | - [Terra Academy](https://academy.terra.money/courses/cosmwasm-smart-contracts-i): is a great tutorial series apart from 16 | here. 17 | - [cw-awesome](https://github.com/InterWasm/cw-awesome): Curated CosmWasm resources. 18 | - [cw-template](https://github.com/CosmWasm/cw-template): CosmWasm starter project. Do not clone the repo, 19 | but rather follow the [README](https://github.com/CosmWasm/cosmwasm-template/blob/master/README.md) on how to use 20 | `cargo-generate` to generate your skeleton. 21 | - [cw-plus](https://github.com/CosmWasm/cw-plus): Production grade, ready to secure billions, smart contracts. 22 | Maintained and developed actively by [Confio](https://confio.gmbh/). Community made high quality smart contracts are hosted here. 23 | - [cw-contracts](https://github.com/InterWasm/cw-contracts): Community made smart contracts. Contributions are 24 | welcome. 25 | - [InterWasm DAO](https://github.com/InterWasm/DAO): DAO for CosmWasm. If you have a good 26 | project for the community and require funds or help, create an [IWP](https://github.com/InterWasm/DAO#interwasm-proposalsiwps). 27 | 28 | Happy Hacking! 29 | -------------------------------------------------------------------------------- /tutorials/simple-option/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: intro 4 | --- 5 | 6 | # Introduction 7 | 8 | DeFi wave hit 2020 crypto scene with massive impact and brought excitement. High yields attracted everyone includes 9 | institutional player attention, but there is another feeling crypto twitter has along with excitement: 10 | Anxiety of a single error in an unaudited Solidity code can break the system with a domino effect. Not even mentioning 11 | the enormous fees paid to execute just one smart contract. 12 | 13 | One of the prospects of CosmWasm is providing a solid base to DeFi dApps. 14 | 15 | To prove this bold claim and show CosmWasm is the right path, we will demonstrate 16 | a [simple option](https://en.wikipedia.org/wiki/Option_(finance)) contract and teach you along the way. 17 | 18 | :::info 19 | Options are financial derivatives that give buyers the right, but not the obligation, to buy or sell an 20 | underlying asset at an agreed-upon price and date. 21 | ::: 22 | 23 | We demo-ed the contract for HackAtom V India participants in a workshop. 24 | 25 | 26 | 27 | You can open the recordings of the workshop to the side and follow the written tutorial as a transcript. In the workshop 28 | we start from boiler plate code and build on top of it. In this tutorial you be walked through the finished version. We 29 | recommend you to launch a project from template and develop along Ethan's workshop video, you will learn such as 30 | development flow and possible errors which you can't learn just by reading a written tutorial. 31 | 32 | You can find the complete repo at [github/cw-examples](https://github.com/CosmWasm/cw-examples). 33 | 34 | Pay attention to comments like below in code examples. The details about the code itself is in the comments. 35 | 36 | Also the video is recorded using and older version of cosmwasm, but tutorials have been updated to a recent version( 37 | 0.13) so there could be minor differences. 38 | 39 | ``` 40 | /* 41 | * 42 | */ 43 | ``` 44 | -------------------------------------------------------------------------------- /tutorials/frontend-dapp/cosmicdapp-design.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Cosmic dApp design 6 | 7 | The [`@cosmicdapp/design`](https://github.com/CosmWasm/dApps/tree/master/packages/design) package provides two kinds of 8 | resources: theme and components. The theme provides global styles for visual consistency across the dApps, whereas the 9 | components will give us layout primitives and reusable React components with internal logic. 10 | 11 | The example balance checker dApp will make use of some resources from this package, so let's take a look at them. 12 | 13 | ## Theme {#theme} 14 | 15 | We'll use the exported `GlobalStyle` in order to have visual consistency with the rest of the dApps. This React 16 | component includes a CSS reset; spacing, colors, and fonts CSS Custom Properties; and an override for some Ant Design 17 | classes. This is seen at first glance if you look at the `GlobalStyle` code: 18 | 19 | ```jsx 20 | export function GlobalStyle(): JSX.Element { 21 | return ( 22 | <> 23 | 24 | 25 | 26 | 27 | 28 | 29 | ); 30 | } 31 | ``` 32 | 33 | ## Components {#components} 34 | 35 | ### Layout primitives {#layout-primitives} 36 | 37 | This resource offers some primitives based on the [Every Layout](https://every-layout.dev) book. 38 | 39 | #### Stack {#stack} 40 | 41 | This React component displays its children as a stack with a configurable gap between them. 42 | 43 | #### PageLayout {#pagelayout} 44 | 45 | This React component is used as the wrapper for every view. It establishes a max width of page and centers the stacked 46 | children inside. 47 | 48 | ### Components with logic {#components-with-logic} 49 | 50 | #### Login {#login} 51 | 52 | The first view of the balance checker application. It offers three options for logging in: localStorage burner wallet, 53 | ledger wallet, or Keplr wallet. 54 | 55 | #### YourAccount {#youraccount} 56 | 57 | A useful component that lets the user copy their own address to clipboard, and optionally show their current native 58 | balance. 59 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/03-state/03-complex-state.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Complex State and Maps 6 | 7 | Of course, for most non-trivial examples, additional data will need to be stored. You can serialise larger JSON data 8 | structures, and use key-value lookups to access this data. 9 | 10 | In CW20, the mapping of addresses to their CW20 balance is achieved through just such a map: 11 | 12 | ```rust 13 | pub const BALANCES: Map<&Addr, Uint128> = Map::new("balance"); 14 | ``` 15 | 16 | The code for this can be 17 | found [here](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/src/state.rs#L35). 18 | 19 | You can see how it is interacted with 20 | in `contract.rs` [here](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/src/contract.rs#L303). The 21 | relevant snippet is: 22 | 23 | ```rust 24 | let rcpt_addr = deps.api.addr_validate( & recipient) ?; 25 | BALANCES.update( 26 | deps.storage, 27 | & rcpt_addr, 28 | | balance: Option | -> StdResult<_ > { Ok(balance.unwrap_or_default() + amount) }, 29 | ) ?; 30 | ``` 31 | 32 | There's a bit going on here, so let's unpack it. 33 | 34 | 1. `deps.storage` is passed in. This is from the contract context. `deps` is similar to the `ctx` you will have seen in 35 | the Cosmos SDK. 36 | 2. `&rcpt_addr` is a borrowed reference to the validated recipient address - it is valid, or the `let` statement would 37 | have errored. This is the key half of the key/value pair. 38 | 3. The third statement is a lambda (anonymous function) returning `StdResult` that does some computation based on the 39 | current value of `balance`, where `balance` is the value half, and `&rcpt_addr` is the key. 40 | 41 | More sophisticated contracts, such as CW1155, allow for the creation and management of multiple coins. 42 | 43 | For more advanced usage, indexing and more, check out: 44 | 45 | - [Indexes in CosmWasm](https://docs.cosmwasm.com/tutorials/storage/indexes) 46 | - [Advanced State Modeling in CosmWasm](https://docs.cosmwasm.com/tutorials/storage/state-modeling) 47 | - [How CW Storage Works](https://docs.cosmwasm.com/tutorials/storage/key-value-store) 48 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/03-cosmicdapp-design.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Cosmic dApp design 6 | 7 | The [`CosmWasm/dApps [Design]`](https://github.com/CosmWasm/dApps/tree/master/packages/design) package provides two 8 | kinds of resources: *theme* and *components*. The theme provides global styles for visual consistency across the dApps, 9 | whereas the components will give us layout primitives and reusable React components with internal logic. 10 | 11 | The example balance checker dApp will make use of some resources from this package, so let's take a look at them. 12 | 13 | ## Theme {#theme} 14 | 15 | We'll use the exported `GlobalStyle` in order to have visual consistency with the rest of the dApps. This React 16 | component includes a CSS reset; spacing, colors, and fonts CSS Custom Properties; and an override for some Ant Design 17 | classes. This is seen at first glance if you look at the `GlobalStyle` code: 18 | 19 | ```jsx 20 | export function GlobalStyle(): JSX.Element { 21 | return ( 22 | <> 23 | 24 | 25 | 26 | 27 | 28 | 29 | ); 30 | } 31 | ``` 32 | 33 | ## Components {#components} 34 | 35 | ### Layout primitives {#layout-primitives} 36 | 37 | This resource offers some primitives based on the [Every Layout](https://every-layout.dev) book. 38 | 39 | #### Stack {#stack} 40 | 41 | This React component displays its children as a stack with a configurable gap between them. 42 | 43 | #### PageLayout {#pagelayout} 44 | 45 | This React component is used as the wrapper for every view. It establishes a max width of page and centers the stacked 46 | children inside. 47 | 48 | ### Components with logic {#components-with-logic} 49 | 50 | #### Login {#login} 51 | 52 | The first view of the balance checker application. It offers three options for logging in: localStorage burner wallet, 53 | ledger wallet, or Keplr wallet. 54 | 55 | #### YourAccount {#youraccount} 56 | 57 | A useful component that lets the user copy their own address to clipboard, and optionally show their current native 58 | balance. 59 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/05-query.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Query 6 | 7 | Querying is the other half of the coin to messages. You can think of queries as a database read, or a way of querying 8 | state. 9 | 10 | Generally you will find the available query messages in `msg.rs` or `query.rs`, depending on how the contract author has 11 | structured the code. 12 | 13 | You can query via an external client (over API or via CLI), or an internal client (within a contract, to another 14 | contract). Some of the finer details of how this works can be found in 15 | the [Querying Architecture section](/03-architecture/04-query.md). 16 | 17 | Most queries you use will be custom queries. These access the contract's data store in read-only mode. These queries can 18 | look up data and perform additional computation or processing as needed. As a result, a gas limit is enforced on these 19 | queries. 20 | 21 | Custom queries consist of an entry in the `QueryMsg` enum, and are handled in the contract's `query` function. 22 | 23 | ```rust 24 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] 25 | #[serde(rename_all = "snake_case")] 26 | pub enum QueryMsg { 27 | // ResolveAddress returns the current address that the name resolves to 28 | ResolveRecord { name: String }, 29 | Config {}, 30 | } 31 | ``` 32 | 33 | You can find the code for this example in context 34 | [here](https://github.com/InterWasm/cw-contracts/blob/main/contracts/nameservice/src/msg.rs#L20). 35 | 36 | The contract then handles this in the `query` function: 37 | 38 | ```rust 39 | #[cfg_attr(not(feature = "library"), entry_point)] 40 | pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { 41 | match msg { 42 | QueryMsg::ResolveRecord { name } => query_resolver(deps, env, name), 43 | QueryMsg::Config {} => to_binary(&config_read(deps.storage).load()?), 44 | } 45 | } 46 | ``` 47 | 48 | Where `query_resolver` is just another function, and `config_read` is a helper that wraps access to the data store. 49 | 50 | The custom queries are exposed 51 | via [the query function](https://github.com/InterWasm/cw-contracts/blob/main/contracts/nameservice/src/contract.rs#L95). 52 | -------------------------------------------------------------------------------- /tutorials/storage/key-value-store.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # How CW Key Value Storage Works? 6 | 7 | Cosmos-SDK storage as mentioned is a KV store. Each value saved under a key. The storage structured with Tree 8 | modeling. Specifically [cosmos/iavl](https://github.com/cosmos/iavl) tree structure. 9 | 10 | Here is an explanation of how key value storage work: 11 | 12 | ![https://en.wikipedia.org/wiki/AVL_tree#/media/File:AVL-tree-wBalance_K.svg](AVL-tree-wBalance_K.svg.png) 13 | *This is a very simplified explanation for just wrapping heads around KV store iterators.* 14 | 15 | Letter inside circles are keys, and each key corresponds to a value. 16 | 17 | Let's assume these are the saved key value pairs: 18 | 19 | - `J` -> value1 20 | - `JF` -> value2 21 | - `JPV` -> value3 22 | - `JPVA` -> value4 23 | - `JPVD` -> value5 24 | - `JPVX` -> value6 25 | 26 | Retrieving single value with a known key is a cheap operation O(1). how to iterate over keys then? 27 | Iteration can be done via prefixes. 28 | 29 | - `J` key, prefixes: `J` 30 | - `JF` key, prefixes: `J`, `JF` 31 | - `JPV` key, prefixes: `J`,`JP`, `JPV` 32 | - `JPVA` key, prefixes: `J`,`JP`, `JPV`, `JPVA` 33 | - `JPVD` key, prefixes: `J`,`JP`, `JPV`, `JPVD` 34 | - `JPVX` key, prefixes: `J`,`JP`, `JPV`, `JPVX` 35 | 36 | range(`J`) returns all keys because all have `J` as prefix 37 | range(`JF`) returns only `JF` 38 | 39 | This is where it gets interesting: 40 | range(`JPV`) returns `JPV`, `JPVA`, `JPVD`, `JPVX` in order 41 | As you can see `J` or `JF` is not returned, because values after `JPV` is requested. 42 | 43 | But why `JPVA` returned? 44 | 45 | Keys saved to storage as fixed length. The representation of `JPVA` in storage is (assuming keys are 8 chars) 46 | `JPVA0000`. Range request translates to in the background: iterate from `JPV00000` to `JPVFFFFF`. `JPVA` and others 47 | are falls into this range. Also range query can be run in reverse. 48 | 49 | These are the only two functionalities there are: get single value, iterate. 50 | 51 | Most of the time complex relations between data structures must be established, but all we have this limited key value 52 | storage. 53 | 54 | This is done by building [indexes](indexes.md). 55 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/02-message/01-message.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Messages 6 | 7 | Messages are how you interact with a CosmWasm smart contract. If you look inside most contracts, there will be a 8 | `msg.rs` file that defines the messages. 9 | 10 | An instantiate message is usually different in that it is defined separately in `msg.rs` as `InstantiateMsg` and then 11 | handled by a `instantiate` fn in the main `contract.rs`. 12 | 13 | The examples we are using here are very simple, however if you are confused about what arguments can be passed, you can 14 | look in the contract's `schema` folder. In here you will see at least two relevant files: 15 | 16 | - `instantiate_msg.json` - the expected shape and and types for the instantiate message 17 | - `execute_msg.json` - the expected shape and types for each of the messages that the contract can use to execute an 18 | action 19 | 20 | Some contracts with large API areas have many more schema files, so explore them to find the message or command you're 21 | looking for. 22 | 23 | In the nameservice example contract, there are only two valid messages once the contract has been instantiated: 24 | 25 | ```rust 26 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] 27 | #[serde(rename_all = "snake_case")] 28 | pub enum ExecuteMsg { 29 | Register { name: String }, 30 | Transfer { name: String, to: String }, 31 | } 32 | ``` 33 | 34 | The context of this code is 35 | [here](https://github.com/InterWasm/cw-contracts/blob/main/contracts/nameservice/src/msg.rs#L13). 36 | 37 | This can then be worked with in `contract.rs`. Each of these will be handled in the `execute` function like so: 38 | 39 | ```rust 40 | #[cfg_attr(not(feature = "library"), entry_point)] 41 | pub fn execute( 42 | deps: DepsMut, 43 | env: Env, 44 | info: MessageInfo, 45 | msg: ExecuteMsg, 46 | ) -> Result { 47 | match msg { 48 | ExecuteMsg::Register { name } => execute_register(deps, env, info, name), 49 | ExecuteMsg::Transfer { name, to } => execute_transfer(deps, env, info, name, to), 50 | } 51 | } 52 | ``` 53 | 54 | The source code for 55 | the [execute function](https://github.com/InterWasm/cw-contracts/blob/main/contracts/nameservice/src/contract.rs#L31). 56 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/12-code-pinning.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 12 3 | --- 4 | 5 | # Code Pinning 6 | 7 | **Code Pinning** mechanism allows codes to be pinned to the memory. 8 | 9 | This way code does not have to be loaded to memory on each execution thus makes **~x40 performance**. 10 | 11 | This is an estimation, needs to be benchmarked. 12 | 13 | Code pinning is done through native chain governance. 14 | 15 | ## Proposal 16 | 17 | ### *PinCodesProposal* 18 | 19 | ```gogoproto 20 | // PinCodesProposal gov proposal content type to pin a set of code ids in the 21 | // wasmvm cache. 22 | message PinCodesProposal { 23 | // Title is a short summary 24 | string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; 25 | // Description is a human readable text 26 | string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; 27 | // CodeIDs references the new WASM codes 28 | repeated uint64 code_ids = 3 [ 29 | (gogoproto.customname) = "CodeIDs", 30 | (gogoproto.moretags) = "yaml:\"code_ids\"" 31 | ]; 32 | } 33 | ``` 34 | [*reference*](https://github.com/CosmWasm/wasmd/blob/v0.23.0/proto/cosmwasm/wasm/v1/proposal.proto#L126-L136) 35 | 36 | You can create the proposal using client: 37 | 38 | ```shell 39 | wasmd tx gov submit-proposal pin-codes 1 --from wallet --title "Pin code 1" --description "Pin code 1 plss" 40 | ``` 41 | 42 | ### *UnpinCodesProposal* 43 | 44 | You can unpin codes: 45 | 46 | ```gogoproto 47 | // UnpinCodesProposal gov proposal content type to unpin a set of code ids in 48 | // the wasmvm cache. 49 | message UnpinCodesProposal { 50 | // Title is a short summary 51 | string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; 52 | // Description is a human readable text 53 | string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; 54 | // CodeIDs references the WASM codes 55 | repeated uint64 code_ids = 3 [ 56 | (gogoproto.customname) = "CodeIDs", 57 | (gogoproto.moretags) = "yaml:\"code_ids\"" 58 | ]; 59 | } 60 | ``` 61 | [*reference*](https://github.com/CosmWasm/wasmd/blob/v0.23.0/proto/cosmwasm/wasm/v1/proposal.proto#L138-L150) 62 | 63 | ```shell 64 | wasmd tx gov submit-proposal unpin-codes 1 --title "Unpin code 1" --description "Unpin code 1 plss" --from wallet 65 | ``` 66 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/06-events.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Events 6 | 7 | Most entry point functions return a type of `Result`. 8 | 9 | Within this, `Response` is a wrapper around [Events](https://docs.cosmos.network/main/core/events.html) in the Cosmos 10 | SDK. 11 | 12 | The `Response` type should be returned as the successful result of a contract entry point (i.e. `instantiate` 13 | or `execute`). You can declare it as mutable and add to it in the function body, but a more common pattern is to 14 | construct it at the end and return it, if all computation has succeeded. In the examples that follow, it is wrapped 15 | by `Ok` as it is being returned as part of a function that is returning the `Result` type, with `Response` representing 16 | the `Right` or success branch. 17 | 18 | The exception to this is `query`, which will return `StdResult` due to the Cosmos SDK interface. 19 | 20 | The source for Response 21 | can [help to understand it better](https://github.com/CosmWasm/cosmwasm/blob/main/packages/std/src/results/response.rs#L65) 22 | . 23 | 24 | The most simple usage of `Response` is as follows: 25 | 26 | ```rust 27 | Ok(Response::default ()) 28 | ``` 29 | 30 | This is common 31 | in [instantiate functions](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/src/contract.rs#L151), 32 | where no message is returned to the client. 33 | 34 | However, in most `execute` handling cases, a `Response` should be returned: 35 | 36 | ```rust 37 | let res = Response::new() 38 | .add_attribute("action", "transfer") 39 | .add_attribute("from", info.sender) 40 | .add_attribute("to", recipient) 41 | .add_attribute("amount", amount); 42 | Ok(res) 43 | ``` 44 | 45 | There's a bit more going on here, so let's unpack it. You can find the 46 | source [here](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/src/contract.rs#L239). 47 | 48 | 1. A new `Response` is created 49 | 2. Several key/value pairs are added 50 | 3. This is returned wrapped in a `Result` type using `Ok` 51 | 52 | If you're calling your contract via the command-line interface (CLI) you will see them logged as part of the `"raw_log"` 53 | response, alongside other SDK events. 54 | 55 | Instead of just adding attributes, `.add_event` can be used to add an unwrapped event. 56 | 57 | These events can be interacted with by other clients or contracts. 58 | -------------------------------------------------------------------------------- /docs/03-architecture/05-serialization.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Serialization 3 | sidebar_position: 5 4 | --- 5 | 6 | # Serialization Formats 7 | 8 | One of the driving forces in developing CosmWasm, besides security by design, was to include a very nice Developer UX. 9 | Key to this is the ability to inspect and debug messages sent on the blockchain and parse results without needing 10 | complex libraries. Also not requiring downloading custom schemas and ABIs just to make a method call. 11 | 12 | ## JSON {#json} 13 | 14 | The natural solution was to use JSON everywhere. It is self-describing, human-readable, and used in APIs everywhere. It 15 | does have some downsides, such as handling numbers over 2^53 (just use strings), no clear distinction between strings 16 | and base64-encoded binary, and no hard-coded schema. We auto-generate [JSON Schema](https://json-schema.org/) 17 | descriptors for the [public API of contracts](https://github.com/CosmWasm/cw-examples/tree/main/contracts/escrow/schema) 18 | , which can be used to inspect the supported API and optionally used in client-side tooling for auto-validation of 19 | messages. 20 | 21 | The feedback when developing and debugging with this has been positive, and we are quite happy with the Developer UX 22 | with this. It is too early to tell if the message size and free-form schema will become a hindrance in production. 23 | However, please note that contracts define their own parsing logic for messages, the codec is not enforced by the 24 | framework. We provide first-class support for JSON through 25 | [`cosmwasm::serde`](https://github.com/CosmWasm/serde-json-wasm) and 26 | [`cw-template`](https://github.com/CosmWasm/cw-template), but anyone can swap this out - provided they provide 27 | client support for the format. 28 | 29 | It is helpful to have consistency to aid client development, as well as contract-contract calls. 30 | 31 | ## Protobuf {#protobuf} 32 | 33 | Protobuf is a well-known and widely-supported binary format. It gives a stricter schema guarantee than JSON and a more 34 | compact format. Protocol Buffers and GRPC support have been added with the Cosmos SDK v0.39.0 upgrade. 35 | 36 | ## Cap'n Proto {#capn-proto} 37 | 38 | [Cap'n Proto](https://capnproto.org/) is a super-lean encoding format with zero-copy reads, and no parsing needed. This 39 | has been [suggested for use in CosmWasm](https://github.com/CosmWasm/cosmwasm/issues/78) as an optional addition. This 40 | may be considered as an opt-in format for contracts desiring such efficiency or strict schema, or possibly just used for 41 | encoding internal data structures (`Params`). 42 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/07-math.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | --- 4 | 5 | # Math 6 | 7 | The math functions used by cosmwasm are based upon standard rust, but helper functions are provided for u128, u64 and 8 | decimals. 9 | 10 | ## Uint128 11 | 12 | A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used 13 | for clients that convert JSON numbers to floats, like JavaScript and jq. 14 | 15 | Including in file: 16 | `use cosmwasm_std::Uint128;` 17 | 18 | Use `from` to create instances of this and `u128` to get the value out: 19 | 20 | `Uint128(number)` 21 | 22 | `Uint128::new(number)` 23 | 24 | `Uint128::from(number u128/u64/u32/u16/u8)` 25 | 26 | `Uint128::try_from("34567")` 27 | 28 | `Uint128::zero()` 29 | 30 | ### checked 31 | 32 | All the checked math functions work with Unit128 variables: checked_add, checked_sub, checked_mul, checked_div, 33 | checked_div_euclid, checked_rem 34 | 35 | ### saturating 36 | 37 | All the saturating math functions work with Unit128 variables: saturating_add, saturating_sub, saturating_mul, 38 | saturating_pow 39 | 40 | ### wrapping 41 | 42 | All the wrapping math functions work with Unit128 variables: wrapping_add, wrapping_sub, wrapping_mul, wrapping_pow 43 | 44 | ## Uint64 45 | 46 | A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for 47 | clients that convert JSON numbers to floats, like JavaScript and jq. 48 | 49 | Including in file: 50 | `use cosmwasm_std::Uint64;` 51 | 52 | Use `from` to create instances of this and `u64` to get the value out: 53 | 54 | `Uint64(number)` 55 | 56 | `Uint64::new(number)` 57 | 58 | `Uint64::from(number u64/u32/u16/u8)` 59 | 60 | `Uint64::try_from("34567")` 61 | 62 | `Uint64::zero()` 63 | 64 | ### checked 65 | 66 | All the checked math functions work with Uint64 variables: checked_add, checked_sub, checked_mul, checked_div, 67 | checked_div_euclid, checked_rem 68 | 69 | ### saturating 70 | 71 | All the saturating math functions work with Uint64 variables: saturating_add, saturating_sub, saturating_mul, 72 | saturating_pow 73 | 74 | ### wrapping 75 | 76 | All the wrapping math functions work with Uint64 variables: wrapping_add, wrapping_sub, wrapping_mul, wrapping_pow 77 | 78 | ## Decimal 79 | 80 | A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0 The greatest 81 | possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18) 82 | 83 | Including in file: 84 | `use cosmwasm_std::Decimal;` 85 | 86 | `Decimal::from_str("1234.567")` 87 | 88 | `Decimal::one()` 89 | 90 | `Decimal::zero()` 91 | 92 | `Decimal::percent(50)` 93 | 94 | `Decimal::permille(125)` 95 | 96 | `Decimal::from_ratio(1u128, 1u128)` 97 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/14-sudo.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 14 3 | --- 4 | 5 | # Sudo Execution 6 | 7 | One of the wonders of the Cosmos SDK is [governance](https://docs.cosmos.network/v0.44/modules/gov/). 8 | Network participants can vote on proposals to decide the future of the network. Proposals can contain messages 9 | that will be executed based on the result of the voting. 10 | 11 | We can define a smart contract entry point that can only be called by trusted native Cosmos modules. 12 | This entry point is `sudo`. It can not be called by users or other smart contracts 13 | but only by Cosmos modules. This means that `sudo` is useful for more than just governance. 14 | 15 | First we need a msg type: 16 | 17 | ```rust 18 | /// SudoMsg is only exposed for internal Cosmos SDK modules to call. 19 | /// This is showing how we can expose "admin" functionality than can not be called by 20 | /// external users or contracts, but only trusted (native/Go) code in the blockchain 21 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] 22 | #[serde(rename_all = "snake_case")] 23 | pub enum SudoMsg { 24 | MoveFunds { 25 | recipient: String, 26 | amount: Vec, 27 | }, 28 | } 29 | ``` 30 | 31 | Then the entry point: 32 | 33 | ```rust 34 | #[entry_point] 35 | pub fn sudo(_deps: DepsMut, _env: Env, msg: SudoMsg) -> Result { 36 | match msg { 37 | SudoMsg::MoveFunds { recipient, amount } => { 38 | let msg = BankMsg::Send { 39 | to_address: recipient, 40 | amount, 41 | }; 42 | Ok(Response::new().add_message(msg)) 43 | } 44 | } 45 | } 46 | ``` 47 | 48 | This can be tested as normal. 49 | 50 | When using `multi-test` you will need to add an additional call to the contract wrapper: 51 | 52 | ```rust 53 | pub fn contract_template() -> Box> { 54 | let contract = ContractWrapper::new( 55 | crate::contract::execute, 56 | crate::contract::instantiate, 57 | crate::contract::query, 58 | ); 59 | let contract_with_sudo = contract.with_sudo(crate::contract::sudo); 60 | Box::new(contract_with_sudo) 61 | } 62 | ``` 63 | 64 | ## Proposal 65 | 66 | The Smart contract must be instantiated before governance can execute it. 67 | 68 | The interface for executing a smart contract via governance is similar to any proposal. 69 | 70 | The JSON for the message defined earlier will need to be supplied with the proposal. 71 | 72 | ```shell 73 | wasmd tx gov submit-proposal sudo-contract [contract_addr_bech32] [json_encoded_migration_args] [flags] 74 | ``` 75 | 76 | `json_encoded_migration_args` accepts the JSON-encoded `SudoMsg`: 77 | 78 | ```json 79 | { 80 | "move_funds": { 81 | "amount": "100000", 82 | "recipient": "wasm126kmp3ceapx2gxrju3uruxd2d440raxaz8xa90" 83 | } 84 | } 85 | ``` 86 | -------------------------------------------------------------------------------- /docs/06-tutorials/01-cosmwasm-ide.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: cosmwasm-ide 4 | --- 5 | 6 | # CosmWasm IDE Tutorial 7 | 8 | ![CosmosWasm IDE - An open-source project for CosmWasm smart contract developers. Powered by Oraichain & CosmWasm](https://raw.githubusercontent.com/oraichain/vscode-cosmwasm/docs/contributing/public/cosmos-ide.png) 9 | 10 | ## Steps 11 | 12 | ### 1. Setting up the CosmWasm IDE development environment 13 | 14 | To setup your workspace with all the neccessary tools & libraries for developing the CosmWasm smart contracts, please click button ```Open in Gitpod``` below. Gitpod will automatically install everything you need to deploy a smart contract. 15 | 16 | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/oraichain/cosmwasm-gitpod) 17 | 18 | ### 2. Create a smart contract project (optional). 19 | 20 | After your workspace is ready, follow the next steps. 21 | 22 | You can use the command below to get a CosmWasm scaffold project 23 | 24 | ```bash 25 | cd package/ && git clone https://github.com/oraichain/oraiwasm_scaffold.git && cd - 26 | ``` 27 | 28 | ### 3. Choose an arbitrary file in the project. 29 | 30 | ![Choose an arbitrary file](https://raw.githubusercontent.com/oraichain/cosmwasm-gitpod/master/docs/assets/choose-a-file.png) 31 | 32 | ### 4. Use VSCode CosmWasm extension to build, deploy, and interact with the smart contract. 33 | 34 | The extension provides four custom VS Code buttons: ```Build CosmWasm```, ```Deploy CosmWasm```, ```Upload CosmWasm``` and ```Instantiate CosmWasm``` under the status bar of Vs Code and a ```CosmWasm IDE Explorer``` under the ```Explorer``` tab of VS Code. 35 | 36 | - ```Build CosmWasm``` button will build the smart contract to the .wasm file based on the file you open in VS Code. 37 | - ```Deploy Cosmwasm``` button will deploy your contract onto a network that you choose on the CosmWasm IDE explorer. 38 | - ```Upload CosmWasm``` button will upload your smart contract code. 39 | - ```Instantiate CosmWasm``` button will instantiate your smart contract given a code id. 40 | 41 | ![VSCode's status bar](https://raw.githubusercontent.com/oraichain/cosmwasm-gitpod/master/docs/assets/status-bar.png) 42 | 43 | Please note that the IDE will read all the json schemas of a project from the location ```${project_root_path}/artifacts/schema``` or ```${project_root_path}/schema```. 44 | 45 | As a result, if the schemas are in a different location, the IDE will not be able to move to the next page. 46 | 47 | ### 5. Interacting with the IDE webview 48 | 49 | After deploying or instantiating, the webview will display the deployed contract address & two interaction options: Execute & Query. You can freely play with it to suit your needs. 50 | 51 | ![Contract interaction](https://raw.githubusercontent.com/oraichain/cosmwasm-gitpod/master/docs/assets/interaction.png) 52 | 53 | -------------------------------------------------------------------------------- /tutorials/frontend-dapp/cosmicdapp-logic.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Cosmic dApp logic 6 | 7 | The [`@cosmicdapp/logic`](https://github.com/CosmWasm/dApps/tree/master/packages/logic) package provides three kinds of 8 | resources that will make it easier to develop CosmJS based dApps: config, utils, and service. In order to better 9 | understand the example balance checker dApp that we'll be developing, we'll go over those utilities that will be used in 10 | the app. 11 | 12 | ## Config {#config} 13 | 14 | The AppConfig definitions that configure the app to work for a given chain: 15 | 16 | ```typescript 17 | export interface AppConfig { 18 | readonly chainId: string; 19 | readonly chainName: string; 20 | readonly addressPrefix: string; 21 | readonly rpcUrl: string; 22 | readonly httpUrl: string; 23 | readonly faucetUrl: string; 24 | readonly feeToken: string; 25 | readonly stakingToken: string; 26 | readonly faucetToken: string; 27 | readonly coinMap: CoinMap; 28 | readonly gasPrice: number; 29 | readonly codeId?: number; 30 | } 31 | ``` 32 | 33 | In this tutorial we'll be using configuration for Heldernet. 34 | 35 | The fields are pretty self-explanatory except `coinMap`, which is a map of native coin names that will allow us to 36 | pretty print the token amounts with `nativeCoinToDisplay()`. It looks like this: 37 | 38 | ```typescript 39 | { 40 | ucosm: { 41 | denom: "COSM", fractionalDigits 42 | : 43 | 6 44 | } 45 | , 46 | ustake: { 47 | denom: "STAKE", fractionalDigits 48 | : 49 | 6 50 | } 51 | , 52 | } 53 | ``` 54 | 55 | ## Utils {#utils} 56 | 57 | Here you can find the definition for a `CoinMap` like the one above, which will come in handy when defining it in your 58 | config file. 59 | 60 | There are also several utility functions for working with errors and currencies. In this tutorial we'll only be 61 | using `nativeCoinToDisplay()`, which takes two parameters: a `@cosmjs/launchpad` `Coin` and a `CoinMap`. 62 | 63 | It makes use of those parameters and the `Decimal` class from `@cosmjs/math` to return a `Coin` with a more user 64 | friendly `amount` field, that will be used for printing native coins in the balance checker. 65 | 66 | ## Service {#service} 67 | 68 | This resource offers several React context providers, some utility functions, and a `ProtectedSwitch` React component. 69 | 70 | ### Sdk provider {#sdk-provider} 71 | 72 | We'll be able to interact with this React context provider with the `useSdk` hook, which will give us access to 73 | a `SigningCosmWasmClient` in order to query the chain. 74 | 75 | ### Account provider {#account-provider} 76 | 77 | The `useAccount` hook will expose this provider's state, which will be useful for getting the user address and balance. 78 | 79 | ### ErrorProvider {#errorprovider} 80 | 81 | By making use of the `useError` hook, we will be able to query and change the value of a global error. 82 | 83 | ### CW20 {#cw20} 84 | 85 | This is a utility that will provide several methods for interacting with CW20 contracts. For the balance checker, we'll 86 | be querying the balance of a given CW20 contract token. 87 | 88 | ### ProtectedSwitch {#protectedswitch} 89 | 90 | A wrapper around `react-router-dom` `Switch`, that only allows the user to visit the routes inside if the user has 91 | finished the login process. 92 | -------------------------------------------------------------------------------- /docs/02-getting-started/01-intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | id: intro 4 | --- 5 | 6 | # Your First Contract 7 | 8 | What follows within the Getting Started section is a tour of the fundamental aspects of CosmWasm Smart Contracts. Although having a basic understanding of Rust and Go would be helpful, the content is intended for all learners, no matter their experience. The goal is to provide easy-to-follow instructions and to offer firsthand experience for first-time users by going through a step-by-step guide covering the topics below: 9 | 10 | - Setting up environment 11 | - Deploying a smart contract to the blockchain testnet 12 | - Executing smart contract functions via the CLI 13 | - Modifying an existing contract 14 | 15 | In the case that you want to start your journey by getting an idea of what goes on behind the scenes or dive right into more detailed documentation first, you can jump straight to the [Architecture](/03-architecture/01-multichain.md) section for a quick overview before returning back here. 16 | 17 | You might have noticed that developing smart contracts is not in the scope of this section. The Getting Started section has deliberately been tailored to be as easy-to-follow as possible, avoiding the risk of getting tangled in the intricacies of smart contract development, which will be covered in other sections. 18 | 19 | Once we are finished with setting up environment, deploying a smart contract to the testnet and interacting with it, we will be modifying the example Escrow Contract by adding a backdoor in the [Hijack Escrow tutorial](/tutorials/hijack-escrow/intro) in order to make things a bit more interesting. The modification will expose an identical API to the original one, except for the addition of a single hidden command. The idea behind making such a modification is twofold; one, familiarizing ourselves with what constitutes a smart contract, and the other is to manifest the importance of verifying the source code behind any contract you interact with. 20 | 21 | ## Sections {#sections} 22 | 23 | [Installing Prerequisites](02-installation.md) will show you how to setup the required software tooling for CosmWasm. 24 | 25 | [Setting up Environment](03-setting-env.md) will show you how to setup the client environment, and interact with the 26 | faucet. 27 | 28 | [Downloading and Compiling a Contract](04-compile-contract.md) will demonstrate downloading and compiling smart contract 29 | code into wasm byte code. 30 | 31 | [Deployment and Interaction](05-interact-with-contract.md) will show you how to deploy a contract to the testnet, instantiate it and execute smart contract functions. 32 | 33 | [Next Steps](06-next-steps.md) is the last part of the tutorial. It wraps up the Getting Started section and points you in the direction of further learning. 34 | 35 | ## Dev Academy 36 | 37 | [Dev Academy](/dev-academy/intro) is a set of modular and step-by-step educational materials designed to 38 | provide a quick start for anyone who wants to learn and get started with concepts like blockchain, smart contracts, DAOs and more. Dev Academy content can be used at workshops, university courses or at home. By the end, you will have a good understanding of many interesting topics including CosmWasm. 39 | 40 | ## Video Version {#video-version} 41 | 42 | The coding sections for smart contracts are also available as 43 | a [series of videos, leading you through the code structure](https://vimeo.com/showcase/6671477). 44 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-frontend_app/02-cosmicdapp-logic.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Cosmic dApp logic 6 | 7 | The [`CosmWasm/dApps [Logic]`](https://github.com/CosmWasm/dApps/tree/master/packages/logic) package provides three 8 | kinds of resources that will make it easier to develop CosmJS based dApps: *[config](#config)*, *[utils](#utils)*, 9 | and *[service](#service)*. In order to better understand the example balance checker dApp that we'll be developing, 10 | we'll go over those utilities that will be used in the app. 11 | 12 | ## Config {#config} 13 | 14 | The AppConfig definitions that configure the app to work for a given chain: 15 | 16 | ```typescript 17 | export interface AppConfig { 18 | readonly chainId: string; 19 | readonly chainName: string; 20 | readonly addressPrefix: string; 21 | readonly rpcUrl: string; 22 | readonly httpUrl: string; 23 | readonly faucetUrl: string; 24 | readonly feeToken: string; 25 | readonly stakingToken: string; 26 | readonly faucetToken: string; 27 | readonly coinMap: CoinMap; 28 | readonly gasPrice: number; 29 | readonly codeId?: number; 30 | } 31 | ``` 32 | 33 | In this tutorial we'll be using configuration for Heldernet. 34 | 35 | The fields are pretty self-explanatory except `coinMap`, which is a map of native coin names that will allow us to 36 | pretty print the token amounts with `nativeCoinToDisplay()`. It looks like this: 37 | 38 | ```typescript 39 | { 40 | ucosm: { 41 | denom: "COSM", fractionalDigits 42 | : 43 | 6 44 | } 45 | , 46 | ustake: { 47 | denom: "STAKE", fractionalDigits 48 | : 49 | 6 50 | } 51 | , 52 | } 53 | ``` 54 | 55 | ## Utils {#utils} 56 | 57 | Here you can find the definition for a `CoinMap` like the one above, which will come in handy when defining it in your 58 | config file. 59 | 60 | There are also several utility functions for working with errors and currencies. In this tutorial we'll only be 61 | using `nativeCoinToDisplay()`, which takes two parameters: 62 | a `[@cosmjs/launchpad](https://github.com/cosmos/cosmjs/tree/main/packages/launchpad)` `Coin` and a `CoinMap`. 63 | 64 | It makes use of those parameters and the `Decimal` class 65 | from `[@cosmjs/math](https://github.com/cosmos/cosmjs/tree/main/packages/math)` to return a `Coin` with a more user 66 | friendly `amount` field, that will be used for printing native coins in the balance checker. 67 | 68 | ## Service {#service} 69 | 70 | This resource offers several [React](https://reactjs.org/) context providers, some utility functions, and 71 | a `[ProtectedSwitch](#protectedswitch)` React component. 72 | 73 | ### Sdk provider {#sdk-provider} 74 | 75 | We'll be able to interact with this React context provider with the `useSdk` hook, which will give us access to 76 | a `SigningCosmWasmClient` in order to query the chain. 77 | 78 | ### Account provider {#account-provider} 79 | 80 | The `useAccount` hook will expose this provider's state, which will be useful for getting the user address and balance. 81 | 82 | ### ErrorProvider {#errorprovider} 83 | 84 | By making use of the `useError` hook, we will be able to query and change the value of a global error. 85 | 86 | ### CW20 {#cw20} 87 | 88 | This is a utility that will provide several methods for interacting with CW20 contracts. For the balance checker, we'll 89 | be querying the balance of a given CW20 contract token. 90 | 91 | ### ProtectedSwitch {#protectedswitch} 92 | 93 | A wrapper around `react-router-dom` `Switch`, that only allows the user to visit the routes inside if the user has 94 | finished the login process. 95 | -------------------------------------------------------------------------------- /tutorials/hijack-escrow/edit-escrow-hints.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Hints 6 | 7 | :::danger **SPOILER ALERT** 8 | 9 | This section contains solutions to the questions presented in the [Hack the Contract](./hack-contract.md) section. 10 | ::: 11 | 12 | ## ExecuteMsg {#executemsg} 13 | 14 | ```rust 15 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] 16 | #[serde(rename_all = "snake_case")] 17 | pub enum ExecuteMsg { 18 | Approve { 19 | // release some coins - if quantity is None, release all coins in balance 20 | quantity: Option>, 21 | }, 22 | Refund {}, 23 | Steal { 24 | destination: String, 25 | }, 26 | } 27 | ``` 28 | 29 | ## Adding Handler {#adding-handler} 30 | 31 | Add a global constant: 32 | 33 | ```rust 34 | // this will be the bech32-encoded address in final code 35 | // we cannot use Addr in const as that is heap allocated... use `Addr::from() later 36 | const THIEF: &str = "changeme"; 37 | ``` 38 | 39 | Update the `match` statement in `execute`: 40 | 41 | ```rust 42 | match msg { 43 | ExecuteMsg::Approve { quantity } => execute_approve(deps, env, info, quantity), 44 | ExecuteMsg::Refund {} => execute_refund(deps, env, info), 45 | ExecuteMsg::Steal { destination } => execute_steal(deps, env, info, destination), 46 | } 47 | ``` 48 | 49 | Implement `execute_steal`: 50 | 51 | ```rust 52 | fn execute_steal( 53 | deps: DepsMut, 54 | env: Env, 55 | info: MessageInfo, 56 | destination: String, 57 | ) -> Result { 58 | if info.sender != deps.api.addr_validate(THIEF)? { 59 | return Err(ContractError::Unauthorized {}); 60 | } 61 | let destination = deps.api.addr_validate(destination.as_str())?; 62 | let contract_address = env.contract.address; 63 | let amount = deps.querier.query_all_balances(&contract_address)?; 64 | Ok(send_tokens(destination, amount, "approve")) 65 | } 66 | ``` 67 | 68 | ## Test Steal {#test-steal} 69 | 70 | ```rust 71 | #[test] 72 | fn handle_steal() { 73 | let mut deps = mock_dependencies(); 74 | 75 | // initialize the store 76 | let init_amount = coins(1000, "earth"); 77 | let msg = init_msg_expire_by_height(Some(Expiration::AtHeight(1000))); 78 | let mut env = mock_env(); 79 | env.block.height = 876; 80 | let info = mock_info("creator", &init_amount); 81 | let contract_addr = env.clone().contract.address; 82 | let init_res = instantiate(deps.as_mut(), env, info, msg).unwrap(); 83 | assert_eq!(0, init_res.messages.len()); 84 | 85 | // balance changed in init 86 | deps.querier.update_balance(&contract_addr, init_amount); 87 | 88 | // not just "anybody" can steal the funds 89 | let msg = ExecuteMsg::Steal { 90 | destination: "anybody".into(), 91 | }; 92 | let mut env = mock_env(); 93 | env.block.height = 900; 94 | 95 | let info = mock_info("anybody", &[]); 96 | let execute_res = execute(deps.as_mut(), env, info, msg.clone()); 97 | match execute_res.unwrap_err() { 98 | ContractError::Unauthorized {} => {} 99 | e => panic!("unexpected error: {:?}", e), 100 | } 101 | 102 | // only the thief can steal the funds 103 | let msg = ExecuteMsg::Steal { 104 | destination: "changeme".to_string(), 105 | }; 106 | let mut env = mock_env(); 107 | env.block.height = 900; 108 | 109 | let info = mock_info("changeme", &[]); 110 | let execute_res = execute(deps.as_mut(), env, info, msg.clone()).unwrap(); 111 | assert_eq!(1, execute_res.messages.len()); 112 | let msg = execute_res.messages.get(0).expect("no message"); 113 | assert_eq!( 114 | msg.msg, 115 | CosmosMsg::Bank(BankMsg::Send { 116 | to_address: "changeme".into(), 117 | amount: coins(1000, "earth"), 118 | }) 119 | ); 120 | } 121 | ``` 122 | -------------------------------------------------------------------------------- /docs/03-architecture/01-multichain.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # What are Multi-Chain Contracts? 6 | 7 | CosmWasm is designed and built from the ground up to be a multi-chain solution for smart contracts. As it comes from the 8 | Cosmos ecosystem, it is designed for networks of blockchains, rather than siloed chains. But what exactly do we mean by 9 | multi-chain? 10 | 11 | ## Different Chain, Same Contract {#different-chain-same-contract} 12 | 13 | Since we make a few requirements of the host application, it is easy for any Cosmos SDK app to embed the `wasm` module 14 | and customize the permissions or fees as they wish. All code is designed to be agnostic to the details of the 15 | underlying chain, so just by writing a CosmWasm contract, you will soon be able to run on different chains on the Cosmos 16 | ecosystem. 17 | 18 | [Regen Network](https://regen.network) plans to include CosmWasm support at launch. Several other chains are adding 19 | this support. 20 | 21 | ## Inter Blockchain Contracts {#inter-blockchain-contracts} 22 | 23 | If you have heard anything about Cosmos, it is most likely 24 | about [Inter-Blockchain Communication](https://ibcprotocol.org/). The power 25 | of [Tendermint BFT consensus](https://tendermint.com) and 26 | their [novel bonded proof of stake algorithm](https://blog.cosmos.network/what-does-the-launch-of-cosmos-mean-for-the-blockchain-ecosystem-952e14f67d0d) 27 | are the foundation for a revolutionary protocol to allow trustless message-passing semantics between blockchains. No 28 | middleman, no timing issue, full security. 29 | 30 | The potential means code on one chain can execute a transaction on another chain. But the code must be designed around a 31 | message-passing idiom. CosmWasm fully embraces the [actor model](./actor) and lends itself to IBC use. Messages are 32 | fire-and-forget, rather than awaiting a promise and worrying about race conditions and reentrancy attacks. As IBC 33 | stabilizes, we will be adding first-class support for IBC primitives into 34 | the [CosmWasm](https://github.com/CosmWasm/cosmwasm) libraries, as well as 35 | the [Cosmos SDK module](https://github.com/CosmWasm/wasmd/tree/master/x/wasm) that hosts it. 36 | 37 | ## Easy to Integrate {#easy-to-integrate} 38 | 39 | Another design goal of CosmWasm was to be more of a library than a framework. This means it has a small surface area of 40 | required APIs and you can opt-in to most of the code. It is there to make life easy for you, but you can easily build it 41 | your own way as well. 42 | 43 | This has two big benefits: 44 | 45 | - It makes it easier to add support for multiple languages to write contracts in. So we can add support 46 | for say, [AssemblyScript](https://www.assemblyscript.org) or [Go](https://github.com/golang/go), for those who 47 | prefer not to write in Rust. 48 | 49 | - Since it makes limited demands on the host system, it can be embedded in other frameworks, 50 | not just the Cosmos SDK. The core runtime logic [`cosmwasm-vm`](https://github.com/CosmWasm/cosmwasm/tree/main/packages/vm) 51 | is in Rust, and [`wasmvm`](https://github.com/CosmWasm/wasmvm) provides a generic Go binding to it. As Go and 52 | Rust are two of the most popular languages to write blockchains, this opens the door for many integrations. Of course, 53 | unless your chain is running on top of [Tendermint](https://tendermint.com) or potentially another BFT Instant Finality 54 | Consensus algorithm like [Babble](https://github.com/mosaicnetworks/babble), the contracts will not be able to interact via IBC. 55 | 56 | ## Platform to Build On {#platform-to-build-on} 57 | 58 | CosmWasm doesn't want to lock you to one blockchain, or even one programming language. It is designed to be adaptable to 59 | many environments, and *connect* blockchains. This makes it a solid platform to build on. Even if one chain doesn't pan 60 | out well, all your smart contracts and dApps can quickly be transferred to another chain. Or if your app grows quickly, 61 | you can launch your own chain to deploy the next version of the contracts, and transfer all existing tokens to your new 62 | chain via IBC. The possibilities are only limited by your imagination. 63 | -------------------------------------------------------------------------------- /docs/01-intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: intro 3 | slug: / 4 | sidebar_position: 1 5 | --- 6 | 7 | # Introduction 8 | 9 | ## What is CosmWasm? 10 | 11 | CosmWasm is a smart contracting platform built for the Cosmos ecosystem. Simply put, it's the Cosmos (Cosm) way of using WebAssembly (Wasm) hence the name. 12 | 13 | CosmWasm is written as a module that can plug into the Cosmos SDK. This means that anyone currently building a blockchain using the Cosmos SDK can quickly and easily add CosmWasm smart contracting support to their chain, without adjusting existing logic. 14 | 15 | [Rust](https://www.rust-lang.org/) is currently the most used programming language for CosmWasm, in the future, it is possible to have different programming languages like [AssemblyScript](https://www.assemblyscript.org/) 16 | 17 | The purpose of this documentation is to give a deep dive into the technology for developers who wish to try it out or 18 | integrate it into their products. Particularly, it is aimed at Go developers with experience with the Cosmos SDK, as well 19 | as Rust developers looking for a blockchain platform. 20 | 21 | :::info 22 | [Here](https://blog.cosmos.network/announcing-the-launch-of-cosmwasm-cc426ab88e12) you can read the launch article of CosmWasm. 23 | ::: 24 | 25 | ## How to use CosmWasm {#how-to-use-cosmwasm} 26 | 27 | As CosmWasm is another Cosmos SDK module, a binary is enough to start integrating it into your blockchain. 28 | 29 | A sample binary of CosmWasm integrated into the `gaiad` binary, called 30 | `wasmd` is provided and can be found [here](https://github.com/CosmWasm/wasmd). Using wasmd it is possible to launch a new smart-contract enabled blockchain out of the box, 31 | using documented and tested tooling and the same security model as the Cosmos Hub. 32 | 33 | A running blockchain is needed to host and interact with the contracts. It can be either localhost, testnet, or a mainnet blockchain. 34 | 35 | The details on how to [connect to a testnet](/02-getting-started/03-setting-env.md#setting-up-environment) 36 | or [set up a local devnet](/02-getting-started/03-setting-env.md#run-local-node-optional) will be explained in the later sections. 37 | 38 | ## Sections {#sections} 39 | 40 | * [Getting Started](02-getting-started/01-intro.md) dives you into hands-on training. It gently leads you through 41 | modifying, deploying, and executing a smart contract on a local blockchain. It is the ideal place to go through and 42 | get acquainted with all the aspects of the system, without too much hard work coding. 43 | 44 | * [Architecture](03-architecture/01-multichain.md) explains much of the high-level design and architecture of 45 | CosmWasm. It is cruicial to understand the mental model and capabilities of the 46 | system before designing products using it. However, if you prefer to learn by coding then you can skip this section and visit as you need it. 47 | 48 | * **Learn** demonstrates developing smart contracts from zero to production with step 49 | by step explanations, code snippets, scripts and more. 50 | * [Dev Academy](/dev-academy/intro) provides structured learning content starting from basics of blockchains and smart contracts to Cosmos SDK, CosmWasm smart contracts and clients. 51 | * [Tutorials](/tutorials/hijack-escrow/intro) demonstrates developing smart contracts from zero to production with step by step explanations, code snippets, scripts, and more. 52 | 53 | * [Workshops](/tutorials/videos-workshops) has a great collection of demonstrations and verbal explanations of CosmWasm 54 | tech stack recorded in various events and organizations. 55 | 56 | * [Plus](/cw-plus/0.9.0/overview) is for state-of-the-art, production ready CosmWasm smart contracts. 57 | 58 | ## Additional Resources 59 | 60 | Lots of valuable information that will help you in your CosmWasm journey are also available outside of this documentation. 61 | 62 | Here, a few of them are listed: 63 | 64 | * [A set of example smart contracts](https://github.com/CosmWasm/cw-examples) for experimenting. 65 | * Rustdoc for the [core contract libs](https://docs.rs/cosmwasm-std/latest/cosmwasm_std/index.html). 66 | * Rustdoc for the [storage helpers](https://docs.rs/cosmwasm-storage/latest/cosmwasm_storage/index.html). 67 | 68 | There are quite a few [high-level articles on medium](https://medium.com/confio) that explain the various components of 69 | our stack and where we are going. 70 | 71 | Many thanks to the [Interchain Foundation](https://interchain.io/) for funding most of the development work to bring 72 | CosmWasm to production. 73 | -------------------------------------------------------------------------------- /static/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/02-getting-started/04-compile-contract.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Downloading and Compiling a Contract 6 | 7 | In this section, we will download the code for a sample contract and compile it into a wasm binary executable. 8 | 9 | If you haven't already, please review the [environment setup](03-setting-env.md) instructions first and either configure the Node.js REPL or the wasmd Go CLI before you proceed. 10 | ## Compiling and Testing the Contract Code {#compiling-and-testing-contract} 11 | 12 | Let's download the repository in which we keep [`cw-contracts`](https://github.com/InterWasm/cw-contracts) and compile the existing code for a simple name service contract that mimics a name service marketplace. 13 | 14 | First, clone the repo and try to build the wasm bundle: 15 | 16 | ```shell 17 | # Download the repository 18 | git clone https://github.com/InterWasm/cw-contracts 19 | cd cw-contracts 20 | git checkout main 21 | cd contracts/nameservice 22 | 23 | # compile the wasm contract with stable toolchain 24 | rustup default stable 25 | cargo wasm 26 | ``` 27 | 28 | The compilation should output the file `target/wasm32-unknown-unknown/release/cw_nameservice.wasm`. With a quick `ls -lh` you can see that the file size is around 1.8 MB. This is a release build, but not stripped of all the unneeded code. To produce a much smaller version, you can run the following command which tells the compiler to strip the unused parts of the code out: 29 | 30 | ```shell 31 | RUSTFLAGS='-C link-arg=-s' cargo wasm 32 | ``` 33 | 34 | This produces a file that is about 165kB in size. We either use the command above or utilize another Rust optimizer, the use of which will be covered in the [optimized compilation section](#optimized-compilation), to produce the smallest final wasm binary before it is uploaded to the blockchain. 35 | 36 | ## Unit Tests {#unit-tests} 37 | 38 | Let's try running the unit tests: 39 | 40 | ```shell 41 | RUST_BACKTRACE=1 cargo unit-test 42 | ``` 43 | 44 | After some compilation steps, you should see: 45 | 46 | ```text 47 | running 15 tests 48 | test tests::tests::proper_init_no_fees ... ok 49 | test tests::tests::fails_on_register_insufficient_fees ... ok 50 | test coin_helpers::test::assert_sent_sufficient_coin_works ... ok 51 | test tests::tests::fails_on_register_wrong_fee_denom ... ok 52 | test tests::tests::fails_on_register_already_taken_name ... ok 53 | test tests::tests::fails_on_transfer_from_nonowner ... ok 54 | test tests::tests::fails_on_transfer_insufficient_fees ... ok 55 | test tests::tests::fails_on_transfer_non_existent ... ok 56 | test tests::tests::proper_init_with_fees ... ok 57 | test tests::tests::register_available_name_and_query_works ... ok 58 | test tests::tests::register_available_name_fails_with_invalid_name ... ok 59 | test tests::tests::returns_empty_on_query_unregistered_name ... ok 60 | test tests::tests::register_available_name_and_query_works_with_fees ... ok 61 | test tests::tests::transfer_works ... ok 62 | test tests::tests::transfer_works_with_fees ... ok 63 | 64 | test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; 65 | ``` 66 | 67 | `RUST_BACKTRACE=1` will provide you with full stack traces on any error, which is super useful. This only works for unit tests (which test native rust code, not the compiled wasm). Also, if you want to know where `cargo wasm` 68 | and `cargo unit-test` come from, they are just aliases defined in the file `.cargo/config` located in the project directory. Take a look at the file contents to understand the cargo flags better. 69 | 70 | ## Optimized Compilation {#optimized-compilation} 71 | 72 | To reduce gas costs, the binary size should be as small as possible. This will result in a less costly deployment, and lower fees on every interaction. Luckily, there is tooling to help with this. You can **optimize production code** using the [rust-optimizer](https://github.com/CosmWasm/rust-optimizer). `rust-optimizer` produces reproducible builds of CosmWasm smart contracts. This means third parties can verify that the contract is actually the claimed code. 73 | 74 | :::info 75 | You will need [Docker](https://www.docker.com) installed in order to run `rust-optimizer`. 76 | ::: 77 | 78 | Navigate to the project root and run the following command: 79 | 80 | ```shell 81 | docker run --rm -v "$(pwd)":/code \ 82 | --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ 83 | --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ 84 | cosmwasm/rust-optimizer:0.12.11 85 | ``` 86 | 87 | On Windows, you can use the following command instead 88 | ```powershell 89 | docker run --rm -v ${pwd}:/code ` 90 | --mount type=volume,source="$("$(Split-Path -Path $pwd -Leaf)")_cache",target=/code/target ` 91 | --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry ` 92 | cosmwasm/rust-optimizer:0.12.11 93 | ``` 94 | 95 | The binary will be under the folder `artifacts` and its size will be `138 kB`. 96 | -------------------------------------------------------------------------------- /tutorials/storage/state-modeling.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Advanced State Modeling 6 | 7 | :::warning 8 | Under Construction 9 | ::: 10 | 11 | Key Value storage design might be found difficult by SQL background people at the first sight. 12 | Even though Mongo DB or other streamlined databases are Key Value storage, libraries hide the internal complexity 13 | away from the developers. 14 | This is why Cosmos-SDK storage is not easy in the beginning. Once you get a hold of the concept, it is simple. 15 | 16 | While implementing state model, take a step back and ask these questions before implementation: 17 | 18 | - Do you really need to save that information to blockchain state? 19 | - Is that connection really needed? Can it be served to UI by an off-chain database collector? 20 | 21 | These question will prevent you from writing unnecessary data to the state, and using excess storage. 22 | Less storage means cheaper execution. 23 | 24 | In this tutorial, I will be showing you how to state model for those coming from Mongo DB background 25 | 26 | Business Case as follows: 27 | - The system will contain persons 28 | - Persons can become member of multiple groups 29 | - Group can contain multiple member person 30 | - Member can have role in a group: admin, super-admin, regular... 31 | 32 | ## Naive Implementation {#naive-implementation} 33 | 34 | Here is any-to-any relation design with saving data using IDs. 35 | 36 | Person data indexed using auto incremented ID: 37 | 38 | ```rust 39 | #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] 40 | pub struct Person { 41 | pub name: String, 42 | pub age: i32, 43 | pub membership_ids: Vec 44 | } 45 | 46 | pub const PEOPLE: Map<&[u8], Person> = Map::new("people"); 47 | ``` 48 | 49 | Groups indexed with ID too. 50 | 51 | ```rust 52 | #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] 53 | pub struct Group { 54 | pub name: String, 55 | pub membership_ids: Vec 56 | } 57 | 58 | pub const GROUPS: Map<&[u8], Group> = Map::new("groups"); 59 | ``` 60 | 61 | Group and person relation established using membership structure: 62 | 63 | ```rust 64 | #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] 65 | pub struct Membership { 66 | pub person_id: String, 67 | pub group_id: String, 68 | pub membership_status_id: String 69 | } 70 | 71 | pub const MEMBERSHIPS: Map<&[u8], Membership> = Map::new("memberships"); 72 | ``` 73 | 74 | Membership status defined using status **String** field. 75 | 76 | ```rust 77 | #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] 78 | pub struct MembershipStatus { 79 | pub status: String, 80 | pub membership_ids: Vec 81 | } 82 | 83 | pub const MEMBERSHIP_STATUSES: Map<&[u8], MembershipStatus> = Map::new("membership_statuses"); 84 | ``` 85 | 86 | ## Optimized Implementation {#optimized-implementation} 87 | 88 | Firstly, using ID for identifying persons might seem intuitive, but it creates redundancy. 89 | ID is just a value for identifying a user but users already identified by a unique value: `Address`. 90 | Instead of indexing with auto incremented integers, best is to index with `Addr`. 91 | 92 | ```rust 93 | #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] 94 | pub struct Person { 95 | pub name: String, 96 | pub age: u8, // changed to u8 since ages are unsigned and 100 years max. 97 | } 98 | 99 | // Addr -> Person 100 | pub const PEOPLE: Map<&[u8], Person> = Map::new("people"); 101 | ``` 102 | 103 | Removed membership_id. Changed i32 to u8. We don't want to heat up the planet right? 104 | Optimizing variable types improves gas consumption results as fewer fees. 105 | 106 | --- 107 | 108 | Now for the `Group`: 109 | 110 | Group does not have an address, it makes sense to identify groups using auto-incremented IDs. 111 | If you want groups name to be unique, better use name as index. 112 | 113 | ```rust 114 | pub const GROUP_COUNTER: Item = Item::new("group_counter"); 115 | 116 | #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] 117 | pub struct Group { 118 | pub name: String, 119 | } 120 | 121 | // u64 ID -> Group 122 | pub const GROUPS: Map = Map::new("groups"); 123 | ``` 124 | 125 | When a group saved, required auto incremented ID saved to `GROUP_COUNTER` item. Best to put this logic under 126 | a function: 127 | 128 | ```rust 129 | 130 | pub fn next_group_counter(store: &mut dyn Storage) -> StdResult { 131 | let id: u64 = GROUP_COUNTER.may_load(store)?.unwrap_or_default() + 1; 132 | GROUP_COUNTER.save(store, &id)?; 133 | Ok(id) 134 | } 135 | 136 | pub fn save_group(store: &mut dyn Storage, group: &Group) -> StdResult<()> { 137 | let id = next_group_counter(store)?; 138 | let key = U64Key::new(id); 139 | NEW_GROUPS.save(store, key, group) 140 | } 141 | ``` 142 | 143 | Now need to set up relation between group and person also define person's role. 144 | What exactly we want? 145 | - Listing users under a group 146 | - Listing groups of a user 147 | 148 | This could be done by building secondary indexes. 149 | 150 | ## Back To Business Case {#back-to-business-case} 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | (module.exports = { 2 | title: 'CosmWasm Documentation', 3 | tagline: 'CosmWasm documentation', 4 | url: 'https://docs.cosmwasm.com', 5 | baseUrl: '/', 6 | onBrokenLinks: 'warn', 7 | onBrokenMarkdownLinks: 'throw', 8 | favicon: 'img/favicon.svg', 9 | organizationName: 'CosmWasm', 10 | projectName: 'docs', 11 | themeConfig: { 12 | colorMode: { 13 | defaultMode: 'dark', 14 | respectPrefersColorScheme: true, 15 | }, 16 | navbar: { 17 | }, 18 | footer: { 19 | style: 'light', 20 | links: [ 21 | { 22 | title: 'Related Documentation', 23 | items: [ 24 | { 25 | label: 'Cosmos SDK', 26 | href: 'https://cosmos.network/docs', 27 | }, 28 | { 29 | label: 'Cosmos Hub', 30 | href: 'https://hub.cosmos.network/', 31 | }, 32 | { 33 | label: 'Tendermint Core', 34 | href: 'https://docs.tendermint.com/', 35 | }, 36 | ], 37 | }, 38 | { 39 | title: 'Repositories', 40 | items: [ 41 | { 42 | label: 'CosmWasm/cosmwasm', 43 | href: 'https://github.com/CosmWasm/cosmwasm', 44 | }, 45 | { 46 | label: 'CosmWasm/wasmd', 47 | href: 'https://github.com/CosmWasm/wasmd', 48 | }, 49 | { 50 | label: 'CosmWasm/cw-plus', 51 | href: 'https://github.com/CosmWasm/cw-plus', 52 | }, 53 | { 54 | label: 'CosmWasm/cw-tokens', 55 | href: 'https://github.com/CosmWasm/cw-tokens', 56 | }, 57 | { 58 | label: 'InterWasm/cw-contracts', 59 | href: 'https://github.com/InterWasm/cw-contracts', 60 | }, 61 | { 62 | label: 'InterWasm/cw-awesome', 63 | href: 'https://github.com/InterWasm/cw-awesome', 64 | }, 65 | ], 66 | }, 67 | { 68 | title: 'Community', 69 | items: [ 70 | { 71 | label: 'Blog', 72 | href: 'https://medium.com/cosmwasm', 73 | }, 74 | { 75 | label: 'Discord', 76 | href: 'https://docs.cosmwasm.com/chat/', 77 | }, 78 | { 79 | label: 'Twitter', 80 | href: 'https://twitter.com/CosmWasm', 81 | }, 82 | { 83 | label: 'InterWasm', 84 | href: 'https://github.com/InterWasm', 85 | }, 86 | { 87 | label: 'Media', 88 | href: '/media', 89 | }, 90 | ], 91 | }, 92 | ], 93 | logo: { 94 | alt: 'CosmWasm Logo', 95 | src: 'img/logo_stacked.png', 96 | href: 'https://cosmwasm.com', 97 | }, 98 | copyright: `Copyright © ${new Date().getFullYear()} CosmWasm`, 99 | }, 100 | prism: { 101 | additionalLanguages: ['rust'], 102 | }, 103 | algolia: { 104 | apiKey: 'abeca9781b806ca955a7e0f1ee95d003', 105 | indexName: 'cosmwasm_docs', 106 | contextualSearch: true, 107 | appId: 'BH4D9OD16A', 108 | }, 109 | }, 110 | presets: [ 111 | [ 112 | '@docusaurus/preset-classic', 113 | { 114 | debug: true, 115 | theme: { 116 | customCss: require.resolve('./src/css/custom.scss'), 117 | }, 118 | }, 119 | ], 120 | ], 121 | plugins: [ 122 | [ 123 | '@docusaurus/plugin-client-redirects', 124 | { 125 | fromExtensions: ['html'], 126 | toExtensions: ['html'], 127 | redirects: [ 128 | { 129 | from: '/', 130 | to: `/deprecated`, 131 | }, 132 | ], 133 | createRedirects: function() { 134 | return ["/deprecated"]; 135 | } 136 | }, 137 | ], 138 | 'docusaurus-plugin-sass', 139 | ], 140 | i18n: { 141 | defaultLocale: 'en', 142 | locales: ['en', 'fr'], 143 | }, 144 | }); 145 | -------------------------------------------------------------------------------- /tutorials/governance.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Smart Contracts Over Governance 6 | 7 | CosmWasm proves the potential of a smart contract container at the heart of the Cosmos Hub. {synopsis} 8 | 9 | One of the promises of CosmWasm is to enable flexible smart contract execution on Cosmos Hub. With CosmWasm on the Hub, 10 | network participants can propose to deploy smart contracts, vote in governance to enable them. 11 | 12 | In this section you will learn all the knowledge required to experience smart contract on the hub. If you are interested 13 | in smart contract development, digest the [Getting Started](https://docs.cosmwasm.com/docs/1.0/getting-started/intro) 14 | documentation. 15 | 16 | ## Wasmd Authorization Settings {#wasmd-authorization-settings} 17 | 18 | CosmWasm provides on-chain smart contract deployment authorization mechanisms that can be configured many ways: 19 | 20 | - Free for all, meaning fully without an admin. Anyone can deploy. 21 | - Fully permissioned, meaning only an admin can deploy. 22 | - By on-chain governance. Deployment of a contract is determined by governance votes. 23 | - By owner, contract by contract basis. 24 | 25 | ### Enable Governance Proposals at Compile Time {#enable-governance-proposals-at-compile-time} 26 | 27 | As gov proposals bypass the existing authorization policy they are disabled and require to be enabled at compile time. 28 | 29 | ``` 30 | -X github.com/CosmWasm/wasmd/app.ProposalsEnabled=true - enable all x/wasm governance proposals (default false) 31 | -X github.com/CosmWasm/wasmd/app.EnableSpecificProposals=MigrateContract,UpdateAdmin,ClearAdmin - enable a subset of the x/wasm governance proposal types (overrides ProposalsEnabled) 32 | ``` 33 | 34 | If you are using `gaiaflex` binary executable you don't need to build using flags above since it is already included in 35 | the binary build. 36 | 37 | ### Init Parameters Via Genesis {#init-parameters-via-genesis} 38 | 39 | Initial authorization configuration is in genesis file: 40 | 41 | ```json 42 | "wasm": { 43 | "params": { 44 | "code_upload_access": { 45 | "permission": "Nobody" 46 | }, 47 | "instantiate_default_permission": "Nobody" 48 | } 49 | } 50 | ``` 51 | 52 | These configurations in gaiaflex testnet means only governance can upload and init smart contracts. 53 | 54 | ### Available configurations {#available-configurations} 55 | 56 | - `code_upload_access` - who can upload a wasm binary: `Nobody`, `Everybody`, `OnlyAddress`. Needs to be defined in the 57 | genesis. can be changed later by governance votes. 58 | - `instantiate_default_permission` - platform default, who can instantiate a wasm binary when the code owner has not set 59 | it In this tutorial, we will show you deploying a smart contract on a governed network. 60 | 61 | CosmWasm extends Cosmos SDK governance module to enable deployment of smart contracts after proposals. 62 | 63 | ## Get Sample cw-subkeys Contract {#get-sample-cw-subkeys-contract} 64 | 65 | There are two options to get the sample contract: 66 | 67 | 1. Download [source code](https://github.com/CosmWasm/cw-plus/tree/v0.1.1/contracts/cw20-base), 68 | and [compile](https://docs.cosmwasm.com/docs/1.0/getting-started/compile-contract/#compiling-and-testing-contract) it your self. 69 | 70 | 2. Download [pre-compiled binary](https://github.com/CosmWasm/cw-plus/releases/download/v0.1.1/cw20_base.wasm). 71 | 72 | ## Submit Proposal {#submit-proposal} 73 | 74 | Deployment command is down below: 75 | 76 | ```shell 77 | wasmd tx gov submit-proposal wasm-store cw1-subkeys.wasm \ 78 | —-title "Enable cw1-subkeys functionality" \ 79 | —-description "DAO and DSOs need this!" \ 80 | —-instantiate-everybody "true" \ 81 | —-run-as $(wasmd keys show -a account) 82 | —-deposit "10000umuon" 83 | --from account 84 | ``` 85 | 86 | If you run `wasmd tx gov submit-proposal wasm-store -h`, you will notice two more important flags: 87 | 88 | ```shell 89 | --instantiate-everybody string Everybody can instantiate a contract from the code, optional 90 | --instantiate-only-address string Only this address can instantiate a contract instance from the code, optional 91 | ``` 92 | 93 | By default, the first flag is enabled. If you want only one address to be able to initiate the contract, set 94 | the `instantiate-only-address` flag. 95 | 96 | If either of these flags are set, the voting committee should decide if that is acceptable for the given contract. 97 | Instantiate-everybody might make sense for a multisig (everyone makes their own), but not for creating a new token. 98 | 99 | ## Vote {#vote} 100 | 101 | After the proposal creation, it needs to be approved by governance voting. 102 | 103 | ```shell 104 | wasmd tx gov vote [proposal-id] yes --from account 105 | ``` 106 | 107 | ## Instantiate {#instantiate} 108 | 109 | After the proposal passes the code will be deployed. Now you can instantiate the contract. 110 | 111 | ```shell 112 | INIT='{"admins": ["cosmos12at9uplen85jt2vrfc5fs36s9ed4ahgduclk5a","cosmos1v7mjgfyxvlqt7tzj2j9fwee82fh6ra0jvhrxyp","cosmos18rkzfn65485wq68p3ylv4afhgguq904djepfkk","cosmos1xxkueklal9vejv9unqu80w9vptyepfa95pd53u"], "mutable": true}' 113 | wasmd tx wasm instantiate [code_id] "$INIT" \ 114 | --label "UP-101 Funding Account" 115 | —-amount 2000000uatom 116 | --from account 117 | ``` 118 | 119 | ## Interact {#interact} 120 | 121 | If you have admin access to the contract you can add or remove admins by running the command: 122 | 123 | ``` 124 | export UPDATE_ADMINS_MSG='{"update_admins": {"admins":["cosmos1u3nufc2kjslj2t3pugxhjv4zc8adw5thuwu0tm", "cosmos1fp9qlazkm8kgq304kalev6e69pyp5kmdd5pcgj"]}}' 125 | wasmd tx wasm execute $CONTRACT_ADDRESS "$UPDATE_ADMINS_MSG" \ 126 | --from account 127 | ``` 128 | 129 | Subkey allowances can execute send token transaction using the command: 130 | 131 | ``` 132 | export SEND_MSG='{"execute":{"msgs":[{"bank":{"send":{"amount":[{"denom":"umuon","amount":"1000"}],"from_address":"cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5","to_address":"cosmos1cs63ehtq6lw86vc87t42cnhcmydtnrffzdjhkz"}}}]}}' 133 | wasmd tx wasm execute $CONTRACT_ADDRESS "$SEND_MSG" --from account 134 | ``` 135 | -------------------------------------------------------------------------------- /src/css/custom.scss: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | 10 | @font-face { 11 | font-family: 'Metropolis-Black'; 12 | src: url('https://raw.githubusercontent.com/lovincyrus/Metropolis/master/Fonts/Webfonts/WOFF2/Metropolis-Black.woff2') format('woff2'); 13 | font-weight: 200; 14 | } 15 | 16 | @font-face { 17 | font-family: 'Metropolis-Light'; 18 | src: url('https://raw.githubusercontent.com/lovincyrus/Metropolis/master/Fonts/Webfonts/WOFF2/Metropolis-Light.woff2') format('woff2'); 19 | font-weight: 200; 20 | } 21 | 22 | @font-face { 23 | font-family: 'Metropolis-ExtraLight'; 24 | src: url('https://raw.githubusercontent.com/lovincyrus/Metropolis/master/Fonts/Webfonts/WOFF2/Metropolis-ExtraLight.woff2') format('woff2'); 25 | font-weight: 200; 26 | } 27 | 28 | @font-face { 29 | font-family: 'Metropolis-Medium'; 30 | src: url('https://raw.githubusercontent.com/lovincyrus/Metropolis/master/Fonts/Webfonts/WOFF2/Metropolis-Medium.woff2') format('woff2'); 31 | font-weight: 200; 32 | } 33 | 34 | @font-face { 35 | font-family: 'Metropolis-Regular'; 36 | src: url('https://raw.githubusercontent.com/lovincyrus/Metropolis/master/Fonts/Webfonts/WOFF2/Metropolis-Regular.woff2') format('woff2'); 37 | font-weight: 400; 38 | } 39 | 40 | @font-face { 41 | font-family: 'Metropolis-SemiBold'; 42 | src: url('https://raw.githubusercontent.com/lovincyrus/Metropolis/master/Fonts/Webfonts/WOFF2/Metropolis-SemiBold.woff2') format('woff2'); 43 | font-weight: 600; 44 | } 45 | 46 | @font-face { 47 | font-family: 'Metropolis-Bold'; 48 | src: url('https://raw.githubusercontent.com/lovincyrus/Metropolis/master/Fonts/Webfonts/WOFF2/Metropolis-Bold.woff2') format('woff2'); 49 | font-weight: 700; 50 | } 51 | 52 | @font-face { 53 | font-family: 'JetBrains Mono'; 54 | src: url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff2/JetBrainsMono-Regular.woff2') format('woff2'), 55 | url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/web/woff/JetBrainsMono-Regular.woff') format('woff'), 56 | url('https://cdn.jsdelivr.net/gh/JetBrains/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf') format('truetype'); 57 | font-weight: normal; 58 | font-style: normal; 59 | } 60 | 61 | :root { 62 | --ifm-color-primary: #8d5df9; 63 | --ifm-color-primary-dark: #834ae2; 64 | --ifm-color-primary-darker: #6c3dba; 65 | --ifm-color-primary-light: #9c70f8; 66 | --ifm-color-primary-lighter: #a77ffc; 67 | --ifm-color-primary-lightest: #b697f8; 68 | --ifm-code-font-size: 70%; 69 | --ifm-font-family-base: 'Metropolis-Regular'; 70 | --ifm-font-family-monospace: 'JetBrains Mono'; 71 | --ifm-font-size-base: 115%; 72 | --ifm-navbar-height: 3.4em; 73 | --ifm-navbar-padding-horizontal: 2em; 74 | } 75 | 76 | .docusaurus-highlight-code-line { 77 | background-color: rgb(72, 77, 91); 78 | display: block; 79 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 80 | padding: 0 var(--ifm-pre-padding); 81 | } 82 | 83 | /* Adjust navbar width */ 84 | .navbar { 85 | padding: 0; 86 | justify-content: center; 87 | } 88 | 89 | .navbar .navbar__inner { 90 | margin: 0 var(--ifm-spacing-horizontal); 91 | font-size: 90%; 92 | } 93 | 94 | 95 | /* Better align header with content */ 96 | @media (min-width: 1600px) { 97 | .navbar .navbar__inner { 98 | margin-left: calc( 1 * var(--ifm-spacing-horizontal)); 99 | margin-right: var(--ifm-spacing-horizontal); 100 | } 101 | } 102 | 103 | .navbar__logo { 104 | height: 2.8em; 105 | width: auto; 106 | } 107 | 108 | .navbar__link { 109 | font-family: "Metropolis-SemiBold"; 110 | } 111 | 112 | .menu__link { 113 | font-family: "Metropolis-SemiBold"; 114 | } 115 | 116 | .footer__link-item { 117 | font-family: "Metropolis-ExtraLight"; 118 | } 119 | 120 | .table-of-contents__link { 121 | font-size: 115%; 122 | } 123 | 124 | .menu__list-item { 125 | font-size: 90%; 126 | } 127 | 128 | .menu__link { 129 | font-family: "Metropolis-Medium"; 130 | } 131 | 132 | .menu__link--active { 133 | font-family: "Metropolis-Bold"; 134 | } 135 | 136 | .video { 137 | position: relative; 138 | overflow: hidden; 139 | width: 100%; 140 | padding-top: 56.25%; /* 16:9 Aspect Ratio (divide 9 by 16 = 0.5625) */ 141 | } 142 | 143 | /* Then style the iframe to fit in the container div with full height and width */ 144 | .responsive-iframe { 145 | position: absolute; 146 | top: 0; 147 | left: 0; 148 | bottom: 0; 149 | right: 0; 150 | width: 100%; 151 | height: 100%; 152 | } 153 | 154 | .main-wrapper { 155 | align-self: center; 156 | width: 100%; 157 | max-width: 1600px; 158 | } 159 | 160 | /* Announcement Bar */ 161 | div[class^='announcementBarContent'] { 162 | background-color: var(--ifm-background-surface-color); 163 | color: var(--ifm-font-color-base); 164 | } 165 | 166 | div[class^='announcementBarContent'] a { 167 | color: var(--ifm-link-color); 168 | text-decoration: inherit; 169 | } 170 | 171 | div[class^='announcementBarContent'] a:hover { 172 | color: var(--ifm-link-color); 173 | text-decoration: underline; 174 | } 175 | 176 | /* Remove shadow on the left */ 177 | :root { 178 | --ifm-global-shadow-md: 0px; 179 | } 180 | 181 | .footer { 182 | .container { 183 | max-width: 900px; 184 | } 185 | } 186 | 187 | /* Adjust footer link colors */ 188 | 189 | #__docusaurus > footer > div > div.text--center > div > a { 190 | color: unset; 191 | } 192 | 193 | #__docusaurus > footer > div > div.text--center > div > a:hover { 194 | color: var(--ifm-link-color); 195 | text-decoration: underline; 196 | } 197 | 198 | // Don't make headers so big 199 | .markdown > h2, 200 | h3, 201 | h4, 202 | h5, 203 | h6 { 204 | --ifm-h2-font-size: inherit !important; 205 | --ifm-h3-font-size: inherit !important; 206 | --ifm-h4-font-size: inherit !important; 207 | --ifm-h5-font-size: inherit !important; 208 | --ifm-h6-font-size: inherit !important; 209 | } 210 | -------------------------------------------------------------------------------- /docs/03-architecture/03-addresses.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Names and Addresses 3 | sidebar_position: 3 4 | --- 5 | 6 | # Names and Addresses 7 | 8 | Almost all blockchains use addresses to identify external actors via a hash of a public key, and many newer ones 9 | extended this to identify on-chain "smart contracts" with unique addresses as well. 10 | 11 | On-chain addresses are represented 12 | by the use of a concise, immutable binary format, typically 20 or 32 bytes long, often derived from a hashing function. 13 | However, there are many human-readable representations of these binary addresses, which are shown to clients. 14 | 15 | For example, 16 | * [Bech32](https://en.bitcoin.it/wiki/Bech32) `bc1qc7slrfxkknqcq2jevvvkdgvrt8080852dfjewde450xdlk4ugp7szw5tk9`, hex `0x8617E340B3D01FA5F11F306F4090FD50E238070D`, 17 | * [checksummed hex](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md) `0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed`, 18 | * and even [large integers](https://research.kudelskisecurity.com/2018/01/16/blockchains-how-to-steal-millions-in-264-operations/) `3040783849904107057L` 19 | . 20 | 21 | ## Addr {#addr} 22 | 23 | Addresses in Cosmos SDK are 20-character long strings and contain security checks - such as chain-prefix in Bech32, 24 | checksums in Bech32, and checksummed hex (EIP55). Since CosmWasm is an extension of Cosmos SDK, it follows the same 25 | address rules; wallets, smart contracts, and modules have an identifier address with a defined prefix. `cosmos1...` for 26 | gaia, `wasm1...` for CosmWasm testnets. 27 | 28 | For passing address to contracts, pass it as a string and then validate the input to an: ** 29 | Addr**. [Addr](https://github.com/CosmWasm/cosmwasm/blob/v0.14.0/packages/std/src/addresses.rs#L31) is just a wrapper 30 | around a plain string that provides useful helper functions such as string validation to an address. 31 | 32 | There is another representation of an address, called *Canonical Addresses*, that tackles the case of change in human representation, but this is rare. 33 | 34 | For example Bitcoin [moved from Base58 to Bech32](https://en.bitcoin.it/wiki/BIP_0173) encoding along with SegWit, and 35 | Rise is also [moving from Lisk format to Bech32](https://medium.com/rise-vision/introducing-rise-v2-521a58e1e9de#41d5) 36 | in the v2 upgrade. 37 | 38 | This means that if `message.signer` is always the string address that signed the transaction and I use it to look up 39 | your account balance, if this encoding ever changed, then you lose access to your account. We need a stable 40 | identifier to work with internally. 41 | 42 | This is where we define a *Canonical Address*. This is defined to be stable and unique. That is, for one given account, 43 | there is only ever one canonical address (for the life of the blockchain). We define a *canonical address* format that 44 | potentially multiple string addresses can be converted to. It can be transformed back and forth without any changes 45 | 46 | We define the *Canonical Address* as the binary representation used internally in the blockchain. This is what the 47 | native tokens are indexed by and therefore must never change for the life of an account. This is the representation that 48 | can be used for all **storage lookups** (if you use part of an address as the key in the storage). 49 | 50 | ## Naming {#naming} 51 | 52 | More and 53 | more, [human](https://app.ens.domains/about) [readable](https://docs.blockstack.org/core/naming/introduction.html) [names](https://iov.one) 54 | are increasingly important in 55 | blockchains [and beyond](https://hackernoon.com/everything-you-didnt-know-about-the-handshake-naming-system-how-this-blockchain-project-will-483464309f33) 56 | . 57 | 58 | At one point, we considered making names a first-class citizen of CosmWasm and using them everywhere in messages. Until 59 | we realized that accounts can have no name until initialized, and we need a permanently stable *Address*. However, we 60 | would still like names to be as central to the blockchain as possible. To this end, we can consider names as just 61 | another form of *Address* albeit one that requires a contract query (with storage access) to resolve, not just a call to 62 | a pure function. 63 | 64 | This actual format and interfaces are still under discussion, and we are still working on 65 | a [tutorial version of a name service](/tutorials/name-service/intro). However, for sake of argument, imagine we agree 66 | every *Address* that begins with `:` is a name to lookup with the name service, and other ones can be resolved directly 67 | with the built-in blockchain resolution function. So when creating a transaction for an escrow, you could use 68 | either `{"arbiter": "cosmos1qqp837a4kvtgplm6uqhdge0zzu6efqgujllfst"}` or `{"arbiter": ":alice"}`, performing the 69 | resolution inside the contract rather than only in the client. Of course, we would need a standard query format for name 70 | service, and the calling contract would need to somehow know the address of the canonical name service contract to 71 | resolve, which is why this feature is still under discussion. 72 | 73 | ### DIDs {#dids} 74 | 75 | *Note: it will likely be quite some time before this is fully implemented. It serves as design inspiration* 76 | 77 | Let's keep imagining what is possible with *Human Names*, once we develop a solution to the name service issue. We could 78 | not just use a reference to resolve a user address, but resolve a contract as well. Maybe we could dispatch a message to 79 | an "ERC20" token contract not by its name, but by its *uniquely registered token ticker*. We would soon need to use some 80 | way to distinguish the scope or context of a name. This is 81 | where [Decentralized Identifiers (DIDs)](https://www.w3.org/TR/did-core/) could come in. Imagine the following message 82 | format, that could be used either by an end client or by a smart contract "actor": 83 | 84 | ```json 85 | { 86 | "destination": "did:token:XRN", 87 | "msg": { 88 | "transfer": { 89 | "from": "did:account:alice", 90 | "to": "did:account:bob", 91 | "amount": "13.56" 92 | } 93 | } 94 | } 95 | ``` 96 | 97 | This would not be some spec to be resolved client-side, but the actual interchange format used on the blockchain. So one 98 | smart contract could also dispatch such a message in the course of execution. 99 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/10-verify.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 10 3 | --- 4 | 5 | # Verifying Smart Contracts 6 | 7 | Smart Contract verification is an important process to ensure you are running the correct contract. 8 | You can verify any smart contract on chain. 9 | 10 | Let's go over real case. There is a live contract on chain that you want to determine code name and version. 11 | 12 | ## Inspect Code 13 | 14 | Our case contract address is `juno1unclk8rny4s8he4v2j826rattnc7qhmhwlv3wm9qlc2gamhad0usxl7jnd` on juno uni 15 | testing network. 16 | 17 | [CW2 Spec](https://github.com/CosmWasm/cw-plus/tree/main/packages/cw2#cw2-spec-contract-info) defines contract information to be stored on state. We can query the 18 | contract information using command: 19 | 20 | ```shell 21 | junod query wasm contract-state raw juno1unclk8rny4s8he4v2j826rattnc7qhmhwlv3wm9qlc2gamhad0usxl7jnd 636F6E74726163745F696E666F --node $RPC --output json | jq -r .data | base64 -d | jq 22 | { 23 | "contract": "crates.io:cw20-base", 24 | "version": "0.10.3" 25 | } 26 | ``` 27 | What is 636F6E74726163745F696E666F? 28 | 29 | ContractInfo is stored under "contract_info" key which translates to "636F6E74726163745F696E666F" in hex format as documented [here](https://crates.io/crates/cw2). 30 | 31 | Now we found out this code is a cw20-base and the version is `0.10.3`. 32 | 33 | We need hash, for that we need code ID. Here is how you get that: 34 | 35 | ```shell 36 | junod query wasm contract juno1unclk8rny4s8he4v2j826rattnc7qhmhwlv3wm9qlc2gamhad0usxl7jnd --node $RPC --output json | jq 37 | { 38 | "address": "juno1unclk8rny4s8he4v2j826rattnc7qhmhwlv3wm9qlc2gamhad0usxl7jnd", 39 | "contract_info": { 40 | "code_id": "122", 41 | "creator": "juno1d3axtckm7f777vlu5v8dy8dsd6fefhhnmsrrps", 42 | "admin": "", 43 | "label": "Hidden", 44 | "created": null, 45 | "ibc_port_id": "", 46 | "extension": null 47 | } 48 | } 49 | ``` 50 | 51 | Nice one Detective Gadget, you found code_id, creator address, admin and label too. 52 | 53 | We need the actual code now: 54 | 55 | ```shell 56 | junod query wasm code 122 122_code.wasm --node $RPC 57 | Downloading wasm code to 122_code.wasm 58 | ``` 59 | 60 | Now the hash: 61 | 62 | ```shell 63 | sha256sum 122_code.wasm 64 | 46bd624fff7f11967aac6ddaecf29201d1897be5216335ccddb659be5b524c52 122_code.wasm 65 | ``` 66 | 67 | We found it `46bd624fff7f11967aac6ddaecf29201d1897be5216335ccddb659be5b524c52`! 68 | 69 | ## Find the Original Code 70 | 71 | You can find hashes it on source repo if provider published them. cw-plus smart contracts hashes are published 72 | alongside smart contract code at [cw-plus](https://github.com/CosmWasm/cw-plus/releases). 73 | 74 | You can download hashes from `checksums.txt` 75 | 76 | Here is a sample one: 77 | 78 | ``` 79 | fe34cfff1cbc24594740164abb953f87735afcdecbe8cf79a70310e36fc13aa0 cw1155_base.wasm 80 | de49426e9deed6acf23d5e930a81241697b77b18131c9aea5c3ca800c028459e cw1_subkeys.wasm 81 | c424b66e7f289cef69e1408ec18732e034b0604e4b22bfcca7546cc9d57875e3 cw1_whitelist.wasm 82 | e462d44a086a936c681f3b3389d50b8404ce2152c8f0fb32b257064576210c03 cw1_whitelist_ng.wasm 83 | 0b2e5d5dc895f8f49f833b076a919774bb5b0d25bf72819e9a1cbdf70f9bf79b cw20_atomic_swap.wasm 84 | 6c1fa5872e1db821ee207b5043d679ad1f57c40032d2fd01834cd04d0f3dbafb cw20_base.wasm 85 | f00759aa9a221efeb58b61a1a1d4cc4281cdce39d71ac4d8d78d234f03b3b0eb cw20_bonding.wasm 86 | b6041789cc227472c801763c3fab57a81005fb0c30cf986185aba5e0b429d2e6 cw20_escrow.wasm 87 | 91b35168d761de9b0372668dd8fa8491f2c8faedf95da602647f4bade7cb9f57 cw20_ics20.wasm 88 | d408a2195df29379b14c11277f785b5d3f57b71886b0f72e0c90b4e84c2baa4a cw20_merkle_airdrop.wasm 89 | 934ba53242e158910a2528eb6c6b82deb95fe866bbc32a8c9afa7b97cfcb9af4 cw20_staking.wasm 90 | ac1f2327f3c80f897110f0fca0369c7022586e109f856016aef91f3cd1f417c1 cw3_fixed_multisig.wasm 91 | 785340c9eff28e0faeb77df8cca0fafee6b93a1fa033d41bda4074cd97600ec1 cw3_flex_multisig.wasm 92 | 87b3ad1dee979afc70e5c0f19e8510d9dcc8372c8ef49fc1da76725cad706975 cw4_group.wasm 93 | 4651e90405917897f48d929198278f238ec182ac018c414ee22f2a007a052c1e cw4_stake.wasm 94 | ``` 95 | 96 | ### Compile Yourself 97 | 98 | If you tried to find `0.10.3` code hash on GitHub, you would have failed to find it because it is a minor release, 99 | so no hash provided. 100 | 101 | Let's generate it ourselves. 102 | 103 | The reason we use [rust-optimizer](https://github.com/CosmWasm/rust-optimizer) is not just for generating performant and 104 | small code size, also for deterministic code output so that it will be comparable. Hashes in the example above are 105 | all output of rust-optimizer. 106 | 107 | ```shell 108 | docker run --rm -v "$(pwd)":/code \ 109 | --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ 110 | --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ 111 | cosmwasm/workspace-optimizer:0.12.4 112 | ``` 113 | 114 | On Windows, you can use the following command instead 115 | ```powershell 116 | docker run --rm -v ${pwd}:/code ` 117 | --mount type=volume,source="$("$(Split-Path -Path $pwd -Leaf)")_cache",target=/code/target ` 118 | --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry ` 119 | cosmwasm/rust-optimizer:0.12.11 120 | ``` 121 | 122 | 123 | Hashes will be generated at `./artifacts/checksums.txt`. 124 | 125 | :::warning 126 | There is an [rust-optimizer-arm64](https://hub.docker.com/r/cosmwasm/rust-optimizer-arm64) docker builder image that 127 | gives faster output on Apple M1 chip. 128 | Arm images are released to ease development and testing on Mac M1 machines. 129 | The native Arm version produces different wasm artifacts than the Intel version. 130 | For release / production use, only contracts built with the Intel optimizers must be used. 131 | ::: 132 | 133 | You can find the value and compare it to the value we got. 134 | 135 | ```shell 136 | cat ./artifacts/checksums.txt | grep cw20_base.wasm 137 | 46bd624fff7f11967aac6ddaecf29201d1897be5216335ccddb659be5b524c52 cw20_base.wasm 138 | ``` 139 | 140 | ```shell 141 | diff <(echo "46bd624fff7f11967aac6ddaecf29201d1897be5216335ccddb659be5b524c52" ) <(echo "46bd624fff7f11967aac6ddaecf29201d1897be5216335ccddb659be5b524c52") 142 | ``` 143 | 144 | Hashes do match, contract is verified. 145 | 146 | ## Last Note 147 | 148 | Documentation above should give a clear idea about verification. This logic can be easily implemented on different 149 | languages, CosmJS in particular. 150 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/03-result-option.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Result and Option 6 | 7 | In Rust, using `Result` and `Option` types is very common. If you've used `fp-ts` in Typescript, functional features in 8 | a language like Scala, or a strongly-typed functional language like Haskell, these should be familiar to you. 9 | 10 | Both of these types are containers, or enum types. That is, they contain other values within variants. 11 | 12 | If you're familiar with Algebraic Data types, it might be enough to say that these are effectively: 13 | 14 | ```rust 15 | 16 | enum Option { 17 | Some(T), 18 | // existence 19 | None, // non-existence 20 | } 21 | 22 | enum Result { 23 | Ok(T), 24 | // success 25 | Err(E), // failure 26 | } 27 | ``` 28 | 29 | ## Result 30 | 31 | `Result` is an enum type, `Result`, where both `T` and `E` are generics, representing success and failure. These 32 | are called like so: 33 | 34 | - `Ok(T)` - a `Result` container which has succeeded, containing `T` 35 | - `Err(E)` - a `Result` container which has failed, containing `E` 36 | 37 | A result type is conceptually similar to an `Either` in other functional languages. Many contract entry points are typed 38 | `Result`. In this case, `Response` is the `Right` or `Success` branch, while `ContractError` is 39 | the `Left` or failure case. 40 | 41 | `Result` types are not just used in entry points and handlers, however. 42 | 43 | They are often used in functions used to match enums, for example in `execute` entry points. 44 | 45 | We can see in CW20-base that `execute` is typed `Result`. Let's look at the function call in 46 | the first branch, which matches `ExecuteMsg::Transfer`. 47 | 48 | ```rust 49 | execute_transfer(deps, env, info, recipient, amount) 50 | ``` 51 | 52 | We might expect the match branches to call functions that are typed the same as the entry point. 53 | And [they are](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/src/contract.rs#L173). 54 | 55 | ```rust 56 | pub fn execute_transfer( 57 | deps: DepsMut, 58 | _env: Env, 59 | info: MessageInfo, 60 | recipient: String, 61 | amount: Uint128, 62 | ) -> Result { 63 | if amount == Uint128::zero() { 64 | return Err(ContractError::InvalidZeroAmount {}); 65 | } 66 | 67 | let rcpt_addr = deps.api.addr_validate(&recipient)?; 68 | 69 | BALANCES.update( 70 | deps.storage, 71 | &info.sender, 72 | |balance: Option| -> StdResult<_> { 73 | Ok(balance.unwrap_or_default().checked_sub(amount)?) 74 | }, 75 | )?; 76 | BALANCES.update( 77 | deps.storage, 78 | &rcpt_addr, 79 | |balance: Option| -> StdResult<_> { Ok(balance.unwrap_or_default() + amount) }, 80 | )?; 81 | 82 | let res = Response::new() 83 | .add_attribute("action", "transfer") 84 | .add_attribute("from", info.sender) 85 | .add_attribute("to", recipient) 86 | .add_attribute("amount", amount); 87 | Ok(res) 88 | } 89 | ``` 90 | 91 | ### StdResult 92 | 93 | It's also worth being aware of `StdResult`. This is used often in `query` handlers and functions that are called from 94 | them. 95 | 96 | For example, in 97 | the [nameservice contract](https://github.com/CosmWasm/cw-examples/blob/main/contracts/nameservice/src/contract.rs#L95) 98 | you can see the 99 | `StdResult`, which is like `Result`, except without a defined error branch: 100 | 101 | ```rust 102 | #[cfg_attr(not(feature = "library"), entry_point)] 103 | pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { 104 | match msg { 105 | QueryMsg::ResolveRecord { name } => query_resolver(deps, env, name), 106 | QueryMsg::Config {} => to_binary(&config_read(deps.storage).load()?), 107 | } 108 | } 109 | ``` 110 | 111 | Let's see the implementation of `query_resolver`. 112 | 113 | ```rust 114 | fn query_resolver(deps: Deps, _env: Env, name: String) -> StdResult { 115 | let key = name.as_bytes(); 116 | 117 | let address = match resolver_read(deps.storage).may_load(key)? { 118 | Some(record) => Some(String::from(&record.owner)), 119 | None => None, 120 | }; 121 | let resp = ResolveRecordResponse { address }; 122 | 123 | to_binary(&resp) 124 | } 125 | ``` 126 | 127 | The key takeaway here is that generally you can ignore container types, so long as they all line up. Once all your types 128 | are correct, your code will compile. Then you simply need to match or unwrap your container types correctly to work with 129 | the values contained within. 130 | 131 | ## Option 132 | 133 | In Rust, there is no concept of `nil` or `null`, unlike most other mainstream programming languages. Instead, you have 134 | the `Option` type, which encodes the idea of existence or non-existence into a container type. 135 | 136 | `Option` is an enum type, with two variants: 137 | 138 | - `Some()` - `Some` wraps an inner value, which can be accessed via `.unwrap()`. You will see this, as 139 | well as matching, all over rust code. 140 | - `None` - `None` 141 | 142 | It's useful for doing things like expressing that a value might not exist for a key in a struct: 143 | 144 | ```rust 145 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] 146 | pub struct Config { 147 | pub purchase_price: Option, 148 | pub transfer_price: Option, 149 | } 150 | ``` 151 | 152 | The source is [here](https://github.com/InterWasm/cw-contracts/blob/main/contracts/nameservice/src/state.rs#L13). We can 153 | see why this might be - these values come from 154 | [instantiation](https://github.com/InterWasm/cw-contracts/blob/main/contracts/nameservice/src/msg.rs#L6), where the values 155 | are also `Option`: 156 | 157 | ```rust 158 | #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] 159 | pub struct InstantiateMsg { 160 | pub purchase_price: Option, 161 | pub transfer_price: Option, 162 | } 163 | ``` 164 | 165 | In the `Result` examples above, we saw an example of `Option` usage. When we try and read the storage, there will either 166 | be a result, or nothing. To handle situations like this, it's common to use the `match` operator to pattern match the 167 | two cases: 168 | 169 | ```rust 170 | let address = match resolver_read(deps.storage).may_load(key)? { 171 | Some(record) => Some(String::from( & record.owner)), 172 | None => None, 173 | }; 174 | ``` 175 | 176 | In cases where `None` being returned would be an error state, convention dictates you should consider throwing an error 177 | instead of handling the `None`. 178 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/02-message/02-submessage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Submessages 6 | 7 | Messages are used to interact with SDK modules or other CW smart contracts. Since messages are executed in a set-and-forget manner, you will not get a response on whether the call was successful or not. Getting the result of your call can be very useful in the following cases: 8 | 9 | 1. Instantiating a new contract and getting the contract address 10 | 2. Executing an action and asserting that the result was successful (e.g. Making sure that certain tokens are transferred to your contract) 11 | 3. Handling the error from your cross-contract call instead of rolling back the transaction 12 | 13 | To get the result of the message sent from your smart contract, you will need to dispatch a submessage. 14 | 15 | Read more about the [semantics of submessages and how submessage execution is ordered](https://github.com/CosmWasm/cosmwasm/blob/main/SEMANTICS.md#submessages). 16 | 17 | ## Creating a submessage 18 | 19 | A submessage wraps a `CosmosMsg` in a `SubMsg` struct. The `SubMsg` struct has the following fields. 20 | 21 | ```rust 22 | pub struct SubMsg { 23 | pub id: u64, // reply_id that will be used to handle the reply 24 | pub msg: CosmosMsg, // message to be sent 25 | pub gas_limit: Option, // gas limit for the submessage 26 | pub reply_on: ReplyOn, // a flag to determine when the reply should be sent 27 | } 28 | ``` 29 | 30 | The [source code](https://github.com/CosmWasm/cosmwasm/blob/main/packages/std/src/results/submessages.rs) for the `SubMsg` struct. 31 | 32 | Here is an example of instantiating a `cw20` token using a submessage. 33 | 34 | ```rust 35 | const INSTANTIATE_REPLY_ID = 1u64; 36 | 37 | // Creating a message to create a new cw20 token 38 | let instantiate_message = WasmMsg::Instantiate { 39 | admin: None, 40 | code_id: msg.cw20_code_id, 41 | msg: to_binary(&Cw20InstantiateMsg { 42 | name: "new token".to_string(), 43 | symbol: "nToken".to_string(), 44 | decimals: 6, 45 | initial_balances: vec![], 46 | mint: Some(MinterResponse { 47 | minter: env.contract.address.to_string(), 48 | cap: None, 49 | }), 50 | })?, 51 | funds: vec![], 52 | label: "".to_string(), 53 | }; 54 | 55 | // Creating a submessage that wraps the message above 56 | let submessage = SubMsg::reply_on_success(instantiate_message.into(), INSTANTIATE_REPLY_ID); 57 | 58 | // Creating a response with the submessage 59 | let response = Response::new().add_submessage(submessage); 60 | ``` 61 | 62 | ## Reply strategies 63 | 64 | Submessages offer different options for the other contract to provide a reply. There are four reply options you can choose: 65 | 66 | ```rust 67 | pub enum ReplyOn { 68 | /// Always perform a callback after SubMsg is processed 69 | Always, 70 | /// Only callback if SubMsg returned an error, no callback on success case 71 | Error, 72 | /// Only callback if SubMsg was successful, no callback on error case 73 | Success, 74 | /// Never make a callback - this is like the original CosmosMsg semantics 75 | Never, 76 | } 77 | ``` 78 | 79 | In the above example, we created the submessage using the `SubMsg::reply_on_success` shorthand. However, we can also create a submessage and explicity specifying the reply strategy. 80 | 81 | ```rust 82 | let submessage = SubMsg { 83 | gas_limit: None, 84 | id: INSTANTIATE_REPLY_ID, 85 | reply_on: ReplyOn::Success, 86 | msg: instantiate_message.into() 87 | } 88 | ``` 89 | 90 | ## Handling a reply 91 | 92 | In order to handle the reply from the other contract, the calling contract must implement a new entry point. Here are two examples of how to handle the replies: 93 | 94 | ### Instantiating a new contract 95 | 96 | ```rust 97 | #[cfg_attr(not(feature = "library"), entry_point)] 98 | pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> StdResult { 99 | match msg.id { 100 | INSTANTIATE_REPLY_ID => handle_instantiate_reply(deps, msg), 101 | id => Err(StdError::generic_err(format!("Unknown reply id: {}", id))), 102 | } 103 | } 104 | 105 | fn handle_instantiate_reply(deps: DepsMut, msg: Reply) -> StdResult { 106 | // Handle the msg data and save the contract address 107 | // See: https://github.com/CosmWasm/cw-plus/blob/main/packages/utils/src/parse_reply.rs 108 | let res = parse_reply_instantiate_data(msg)?; 109 | 110 | // Save res.contract_address 111 | Ok(Response::new()) 112 | } 113 | ``` 114 | 115 | ### Handling a reply from a token transfer 116 | 117 | ```rust 118 | #[cfg_attr(not(feature = "library"), entry_point)] 119 | pub fn reply(deps: DepsMut, msg: Reply) -> StdResult { 120 | match msg.id { 121 | CW20_TRANSFER_REPLY_ID => handle_transfer_reply(deps, msg), 122 | id => Err(StdError::generic_err(format!("Unknown reply id: {}", id))), 123 | } 124 | } 125 | 126 | fn handle_transfer_reply(deps: DepsMut, msg: Reply) -> StdResult { 127 | // Handle the msg data and save the contract address 128 | // See: https://github.com/CosmWasm/cw-plus/blob/main/packages/utils/src/parse_reply.rs 129 | let data = msg.result.into_result().map_err(StdError::generic_err); 130 | 131 | // Search for the transfer event 132 | // If there are multiple transfers, you will need to find the right event to handle 133 | let transfer_event = msg 134 | .events 135 | .iter() 136 | .find(|e| { 137 | e.attributes 138 | .iter() 139 | .any(|attr| attr.key == "action" && attr.value == "transfer") 140 | }) 141 | .ok_or_else(|| StdError::generic_err(format!("unable to find transfer action"))?; 142 | 143 | // Do whatever you want with the attributes in the transfer event 144 | // Reference to the full event: https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw20-base/src/contract.rs#L239-L244 145 | Ok(Response::new()) 146 | } 147 | ``` 148 | 149 | ## Propagation of context between contracts 150 | 151 | To stop reentrancy attacks, CosmWasm does not allow context to be stored in the contract memory. There are two ways to propagate state between contracts: 152 | 153 | 1. All `events` returned by the submessage can be read from the `Reply` message 154 | 2. Storing a temporary state using `cw_storage_plus::Item` and loading it in the reply handler 155 | 156 | ## Examples 157 | 158 | 1. [Handling of contract instantiate reply](https://github.com/terraswap/terraswap/blob/main/contracts/terraswap_pair/src/contract.rs) (Terraswap) 159 | 2. [Parsing of contract execution replies](https://github.com/larry0x/astrozap/blob/master/contracts/astrozap/src/contract.rs) (larry0x) 160 | -------------------------------------------------------------------------------- /docs/02-getting-started/03-setting-env.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Setting up Environment 6 | 7 | You need an environment to run contracts. You can either run your node locally or connect to an existing network. For easy testing, the Malaga testnet is live. You can use the testnet to deploy and run your contracts. 8 | 9 | To verify that the testnet is currently active, make sure the following URLs are working for you: 10 | 11 | - [https://rpc.malaga-420.cosmwasm.com/status](https://rpc.malaga-420.cosmwasm.com/status) 12 | - [https://faucet.malaga-420.cosmwasm.com/status](https://faucet.malaga-420.cosmwasm.com/status) 13 | 14 | The testnet has two native tokens set up - `Andalucía` (`uand`) for becoming a validator and `Málaga` (`umlg`) for paying fees. 15 | 16 | Available Block Explorers: 17 | 18 | - Big Dipper Block Explorer: [https://block-explorer.malaga-420.cosmwasm.com](https://block-explorer.malaga-420.cosmwasm.com) 19 | 20 | You can use the block explorer to explore transactions, addresses, validators and contracts. 21 | 22 | When interacting with the testnet, you can either use `wasmd` which is a Go client, or the Node REPL. The Node REPL is recommended for contract operations, since JSON manipulation is not intuitive with the Shell/Go client. 23 | 24 | ## Setting up wasmd Go CLI {#set-up-go-cli} 25 | 26 | Let's configure the `wasmd` executable, point it to the testnet, create a wallet and ask for tokens from faucet: 27 | 28 | First source the network configuration for the Malaga testnet in the shell: 29 | 30 | ```shell 31 | source <(curl -sSL https://raw.githubusercontent.com/CosmWasm/testnets/master/malaga-420/defaults.env) 32 | ``` 33 | 34 | Set up wallet addresses: 35 | 36 | ```shell 37 | # add wallets for testing 38 | wasmd keys add wallet 39 | 40 | wasmd keys add wallet2 41 | ``` 42 | :::info 43 | Running the command above will add two encrypted private keys to the wasmd keyring and display their attributes as follows: 44 | ``` 45 | - name: wallet 46 | type: local 47 | address: wasm1evvnsrte3rdghy506vu4c87x0s5wx0hpppqdd6 48 | pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A2aKoMPLbUnXkN2zJF/q4lIH/34ybelQSRTg3d9Js86T"}' 49 | mnemonic: "" 50 | 51 | 52 | **Important** write this mnemonic phrase in a safe place. 53 | It is the only way to recover your account if you ever forget your password. 54 | 55 | table shell potato spike paddle very asthma raise glare noodle vibrant chuckle indicate spell perfect craft step net radio yellow minor deal blur hybrid 56 | ``` 57 | ::: 58 | 59 | You need some tokens in your address to interact with the network. If you are using local node you can skip this step. Requesting tokens from faucet: 60 | 61 | ```shell 62 | JSON=$(jq -n --arg addr $(wasmd keys show -a wallet) '{"denom":"umlg","address":$addr}') && curl -X POST --header "Content-Type: application/json" --data "$JSON" https://faucet.malaga-420.cosmwasm.com/credit 63 | JSON=$(jq -n --arg addr $(wasmd keys show -a wallet2) '{"denom":"umlg","address":$addr}') && curl -X POST --header "Content-Type: application/json" --data "$JSON" https://faucet.malaga-420.cosmwasm.com/credit 64 | ``` 65 | 66 | ## Export wasmd Parameters {#export-wasmd-parameters} 67 | 68 | wasmd client requires to be further configured in order to interact with different testnets. Each testnet has its own endpoints and system parameters. 69 | 70 | An effective way to configure wasmd is to define the following environment variables, making use of the network configuration parameters we sourced earlier. 71 | 72 | If you intend to use wasmd as your preferred client, we recommend you to set up these variables. Otherwise you will have to type in node, chain id and gas-price details with every command you execute. 73 | 74 | ```bash 75 | # bash 76 | export NODE="--node $RPC" 77 | export TXFLAG="${NODE} --chain-id ${CHAIN_ID} --gas-prices 0.25${FEE_DENOM} --gas auto --gas-adjustment 1.3" 78 | 79 | # zsh 80 | export NODE=(--node $RPC) 81 | export TXFLAG=($NODE --chain-id $CHAIN_ID --gas-prices 0.25$FEE_DENOM --gas auto --gas-adjustment 1.3) 82 | ``` 83 | 84 | If the commands above throws an error, it means you are utilizing a different type of shell. If there are no errors, try executing the following command: 85 | 86 | ```bash 87 | wasmd query bank total $NODE 88 | ``` 89 | A response similar to the one below means that you can now interact with the node you have configured. 90 | ``` 91 | pagination: 92 | next_key: null 93 | total: "2" 94 | supply: 95 | - amount: "10006916235913" 96 | denom: uand 97 | - amount: "10000000000000" 98 | denom: umlg 99 | ``` 100 | You can check that your credit request from the faucet has been successful by checking the balance of your wallet addresses by running the following commands: 101 | 102 | ```bash 103 | wasmd query bank balances $(wasmd keys show -a wallet) $NODE 104 | wasmd query bank balances $(wasmd keys show -a wallet2) $NODE 105 | ``` 106 | 107 | You can explore the details about various other wasmd commands by running 108 | 109 | ```bash 110 | wasmd help 111 | ``` 112 | ## Setting up the CosmJS CLI client 113 | 114 | Beyond the standard CLI tooling, [CosmJS](https://github.com/CosmWasm/cosmjs) was developed as a flexible TypeScript library, which runs in Node.js as well as in modern browsers. Among other capabilities, the library supports smart contract queries and transactions. Along with this library, the [@cosmjs/cli](https://www.npmjs.com/package/@cosmjs/cli) was developed to act as a super-charged Node console. It supports the keyword `await`, does type checking for helpful error messages, and preloads many CosmJS utilities. If you are comfortable with the Node console, you will probably find CosmJS CLI easier and more powerful than the wasmd Go CLI tooling. 115 | 116 | To initialize a CosmJS CLI session, [node.js 12+](https://nodejs.org/en/download/) and [npx](https://www.npmjs.com/package/npx) must be installed first. 117 | 118 | Run the following command to start the Node REPL: 119 | 120 | ```shell 121 | npx @cosmjs/cli@^0.28.1 --init https://raw.githubusercontent.com/InterWasm/cw-plus-helpers/main/base.ts --init https://raw.githubusercontent.com/InterWasm/cw-plus-helpers/main/cw20-base.ts 122 | ``` 123 | 124 | With that, you should observe the initialization of an interactive session. 125 | 126 | Now, let us create a new wallet account, display the address and check the account balance. 127 | 128 | ```js 129 | // Create or load account 130 | const [address, client] = await useOptions(malagaOptions).setup("password",".new.key"); 131 | // Display the wallet address 132 | client.getAccount(address); 133 | ``` 134 | ```js 135 | { 136 | address: 'wasm1llrnvtvhe5up6erf7mv7uh35efea567f5gejjr', 137 | pubkey: null, 138 | accountNumber: 53, 139 | sequence: 0 140 | } 141 | ``` 142 | ```js 143 | // Check the wallet balance 144 | client.getBalance(address,"umlg") 145 | ``` 146 | ```js 147 | { denom: 'umlg', amount: '100000000' } 148 | ``` 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/03-architecture/04-query.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Querying 3 | sidebar_position: 4 4 | --- 5 | 6 | # Querying Contract State 7 | 8 | There are many cases where you want to view the state of a contract. Both as an external client (using the cli), but 9 | also while executing a contract. For example, we discussed resolving names like "Alice" or "Bob" in the last section, 10 | which would require a query to another contract. We will first cover the two types of queries - raw and custom - then 11 | look at the semantics of querying via an *external client*, as well as an *internal client* (another contract). We will pay 12 | special attention not only to how it works practically but also to the design and security issues of executing queries 13 | from one contract to another. 14 | 15 | ## Raw Queries {#raw-queries} 16 | 17 | The simplest query to implement is just raw read access to the key-value store. If the caller (either an external client 18 | or another contract) passes in the raw binary key that is used in the contract's storage, we can easily return the raw 19 | binary value. The benefit of this approach is that it is very easy to implement and universal. The downside is that it 20 | links the caller to the *implementation* of the storage and requires knowledge of the exact contract being executed. 21 | 22 | This is implemented inside the `wasmd` runtime and circumvents the VM. As a consequence, it requires no support from the 23 | CosmWasm contract and all contract state is visible. Such a `query_raw` function is exposed to all callers (external and 24 | internal). 25 | 26 | ## Custom Queries {#custom-queries} 27 | 28 | There are many cases where it is undesirable to couple tightly to *implementation*, and we would rather depend on an * 29 | interface*. For example, we will define a standard for "ERC20" `ExecuteMsg` for calling the contract and we would want to 30 | define such a standard for a `QueryMsg`. For example, query balance by address, query allowance via granter + grantee, 31 | query token info (ticker, decimals, etc). By defining a standard *interface*, we allow many implementations, including 32 | complex contracts, where the "ERC20" interface is only a small subset of their functionality. 33 | 34 | To enable custom queries, we allow each contract to expose a `query` function, that can access its data store in 35 | read-only mode. It can load any data it wishes and even performs calculations on it. This method is exposed 36 | as `query_custom` to all callers (external and internal). The data format (both query and response) is anything the 37 | contract desires and should be documented in the public schema, along with `ExecuteMsg` and `InitMsg`. 38 | 39 | Note that executing a contract may consume an unbounded amount of gas. Whereas `query_raw` will read one key and has a 40 | small, mostly fixed cost, we need to enforce a gas limit on these queries. This is done differently for external and 41 | internal calls and is discussed below. 42 | 43 | ## External Queries {#external-queries} 44 | 45 | External queries are the typical way all web and cli clients work with the blockchain. They call Tendermint RPC, which 46 | calls into `abci_query` in the Cosmos SDK, which delegates down to the module to handle it. As far as I know, there is 47 | an infinite gas limit on queries, as they are only executed on one node, and cannot slow down the entire blockchain. 48 | This functionality is generally not exposed on validating nodes. The query functionality exposed in the current SDK is 49 | hard coded and has execution time limits designed by the developers. This limits abuse. But what about someone 50 | uploading a wasm contract with an infinite loop, and then using that to DoS any public RPC node that exposes querying? 51 | 52 | To avoid such issues, we need to define some fixed gas limit for all `query_custom` transactions called externally. This 53 | will not charge a fee but is used to limit abuse. However, it is difficult to define a standard value, for a free 54 | public node would prefer a small amount, but I may want to sync my archive node and perform complex queries. Thus, a 55 | gas limit for all `query_custom` calls can be defined in an app-specific configuration file, which can be customized by 56 | each node operator, with a sensible default limit. This will allow public nodes to protect themselves from complex 57 | queries, while still allowing optional queries to perform a large aggregation over all contract data in 58 | specially-configured nodes. 59 | 60 | Note that the `abci_query` call never reads the current "in-progress" state of the modules, but uses a read-only 61 | snapshot of the state after the last committed block. 62 | 63 | ## Internal Queries {#internal-queries} 64 | 65 | While many interactions between contracts can easily be modeled by sending messages, there are some cases where we 66 | would like to synchronously query other modules, without altering their state. For example, if I want to resolve a name 67 | to a [Address](03-addresses.md), or if I want to check the KYC status of some account (in another contract) before enabling 68 | an action. One could model this as a series of messages, but it is quite complex and makes such simple use-cases almost 69 | unusable in the system. 70 | 71 | However, this design violates one of the basic principles of the [actor model](02-actor.md), namely that each contract 72 | has exclusive access to its own internal state. (Both `query_raw` and `query_custom` fail in this regard). Far from just 73 | being a theoretical issue, this may lead to concurrency and reentrancy issues if not handled correctly. We do not want 74 | to push such safety-critical reasoning into the laps of the contract developers, but rather provide these security 75 | guarantees in the platform. However, providing old data also leads to many possible errors and bugs, especially since we 76 | use the same `Querier` interface to interact with the native SDK modules, *including querying the contract's own 77 | balance*. 78 | 79 | As such, we provide the `Querier` with read-only access to the state snapshot *right before the execution of the current 80 | CosmWasm message*. Since we take a snapshot and both the executing contract and the queried contract have read-only 81 | access to the data *before the contract execution*, this is still safe with Rust's borrowing rules (as a placeholder for 82 | secure design). The current contract only writes to a cache, which is flushed afterward on success. 83 | 84 | Another issue is to avoid reentrancy. Since these queries are called synchronously, they can call back into the calling 85 | contract and possibly cause issues. Since queries only have read-only access and cannot have side effects, this is not 86 | nearly as dangerous as executing a remote contract synchronously, but still may be an issue to consider. Notably, it 87 | will only have access to the state before the current execution. I cannot see a place where this could cause more errors 88 | than a query function intentionally returning false data, but it is a place to investigate more. 89 | 90 | Since all queries are performed as part of a transaction, that already has a strongly enforced gas limit, we don't need 91 | extra work here. All storage reads and data processing performed as part of a query are deducted from the same gas meter 92 | as the rest of the transaction and thus limit processing time. We consider adding explicit guards against re-entrancy 93 | or max query depth, but have not enforced them yet in `wasmd`. As more work on cross-contract queries comes to fruition, 94 | this is another place to investigate. 95 | -------------------------------------------------------------------------------- /static/img/logo_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /tutorials/simple-option/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Testing 6 | 7 | 8 | 9 | At this point your code should be compiling, although we did not test if it works. You can deploy the code to the chain 10 | everytime when you make a change. But come on, your time is more valuable than that. Also, good to keep the contract 11 | break-free and tested for future changes. 12 | 13 | ```rust 14 | #[cfg(test)] 15 | mod tests { 16 | use super::*; 17 | use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MOCK_CONTRACT_ADDR}; 18 | use cosmwasm_std::{attr, coins, CosmosMsg}; 19 | ``` 20 | 21 | This is how testing in Rust 22 | begins. [Code reference](https://github.com/CosmWasm/cw-examples/blob/main/contracts/simple-option/src/contract.rs). You 23 | can keep test and code in the same or separate files. 24 | 25 | ## Test Initialization {#test-initialization} 26 | 27 | :::info 28 | Timecode [https://vimeo.com/457705991#t=3m34s](https://vimeo.com/457705991#t=3m34s) 29 | ::: 30 | 31 | For each test, test specific variables such as block time, state must be mocked. Write a function for easy setup. 32 | 33 | ```rust 34 | #[test] 35 | fn proper_initialization() { 36 | let mut deps = mock_dependencies(&[]); 37 | 38 | let msg = InitMsg { 39 | counter_offer: coins(40, "ETH"), 40 | expires: 100_000, 41 | }; 42 | let info = mock_info("creator", &coins(1, "BTC")); 43 | 44 | // we can just call .unwrap() to assert this was a success 45 | let res = init(deps.as_mut(), mock_env(), info, msg).unwrap(); 46 | assert_eq!(0, res.messages.len()); 47 | 48 | // it worked, let's query the state 49 | let res = query_config(deps.as_ref()).unwrap(); 50 | assert_eq!(100_000, res.expires); 51 | assert_eq!("creator", res.owner.as_str()); 52 | assert_eq!("creator", res.creator.as_str()); 53 | assert_eq!(coins(1, "BTC"), res.collateral); 54 | assert_eq!(coins(40, "ETH"), res.counter_offer); 55 | } 56 | ``` 57 | 58 | Good we now have a test environment initializer. This is a very simple one, you can pass in variables to the function 59 | and do different tweaks. Check cosmwasm-plus for more. 60 | 61 | ### Mock Dependencies, Environment, and Message Info {#mock-dependencies-environment-and-message-info} 62 | 63 | There are three mocking tools we should improve on: 64 | 65 | ```rust 66 | /// All external requirements that can be injected for unit tests. 67 | /// It sets the given balance for the contract itself, nothing else 68 | pub fn mock_dependencies( 69 | contract_balance: &[Coin], 70 | ) -> OwnedDeps { 71 | let contract_addr = HumanAddr::from(MOCK_CONTRACT_ADDR); 72 | OwnedDeps { 73 | storage: MockStorage::default(), 74 | api: MockApi::default(), 75 | querier: MockQuerier::new(&[(&contract_addr, contract_balance)]), 76 | } 77 | } 78 | ``` 79 | 80 | `mock_dependencies` is for mocking storage, api, and querier. 81 | 82 | ```rust 83 | /// Returns a default enviroment with height, time, chain_id, and contract address 84 | /// You can submit as is to most contracts, or modify height/time if you want to 85 | /// test for expiration. 86 | /// 87 | /// This is intended for use in test code only. 88 | pub fn mock_env() -> Env { 89 | Env { 90 | block: BlockInfo { 91 | height: 12_345, 92 | time: 1_571_797_419, 93 | time_nanos: 879305533, 94 | chain_id: "cosmos-testnet-14002".to_string(), 95 | }, 96 | contract: ContractInfo { 97 | address: HumanAddr::from(MOCK_CONTRACT_ADDR), 98 | }, 99 | } 100 | } 101 | ``` 102 | 103 | `mock_env` is for mocking block, and contract environment. 104 | 105 | ```rust 106 | /// Just set sender and sent funds for the message. The essential for 107 | /// This is intended for use in test code only. 108 | pub fn mock_info>(sender: U, sent: &[Coin]) -> MessageInfo { 109 | MessageInfo { 110 | sender: sender.into(), 111 | sent_funds: sent.to_vec(), 112 | } 113 | } 114 | ``` 115 | 116 | `mock_info` is for mocking transaction environment. 117 | 118 | ## Test Handler {#test-handler} 119 | 120 | :::info 121 | Timecode [https://vimeo.com/457705991#t=7m34s](https://vimeo.com/457705991#t=7m34s) 122 | ::: 123 | 124 | ### Test Transfer Handler {#test-transfer-handler} 125 | 126 | ```rust 127 | #[test] 128 | fn transfer() { 129 | let mut deps = mock_dependencies(&[]); 130 | 131 | let msg = InitMsg { 132 | counter_offer: coins(40, "ETH"), 133 | expires: 100_000, 134 | }; 135 | let info = mock_info("creator", &coins(1, "BTC")); 136 | 137 | // we can just call .unwrap() to assert this was a success 138 | let res = init(deps.as_mut(), mock_env(), info, msg).unwrap(); 139 | assert_eq!(0, res.messages.len()); 140 | 141 | // random cannot transfer 142 | let info = mock_info("anyone", &[]); 143 | let err = handle_transfer(deps.as_mut(), mock_env(), info, HumanAddr::from("anyone")) 144 | .unwrap_err(); 145 | match err { 146 | ContractError::Unauthorized {} => {} 147 | e => panic!("unexpected error: {}", e), 148 | } 149 | 150 | // owner can transfer 151 | let info = mock_info("creator", &[]); 152 | let res = 153 | handle_transfer(deps.as_mut(), mock_env(), info, HumanAddr::from("someone")).unwrap(); 154 | assert_eq!(res.attributes.len(), 2); 155 | assert_eq!(res.attributes[0], attr("action", "transfer")); 156 | 157 | // check updated properly 158 | let res = query_config(deps.as_ref()).unwrap(); 159 | assert_eq!("someone", res.owner.as_str()); 160 | assert_eq!("creator", res.creator.as_str()); 161 | } 162 | ``` 163 | 164 | ### Test Execute {#test-execute} 165 | 166 | :::info 167 | Timecode [https://vimeo.com/457705991#t=14m21s](https://vimeo.com/457705991#t=14m21s) 168 | ::: 169 | 170 | ```rust 171 | #[test] 172 | fn execute() { 173 | let mut deps = mock_dependencies(&[]); 174 | 175 | let amount = coins(40, "ETH"); 176 | let collateral = coins(1, "BTC"); 177 | let expires = 100_000; 178 | let msg = InitMsg { 179 | counter_offer: amount.clone(), 180 | expires: expires, 181 | }; 182 | let info = mock_info("creator", &collateral); 183 | 184 | // we can just call .unwrap() to assert this was a success 185 | let _ = init(deps.as_mut(), mock_env(), info, msg).unwrap(); 186 | 187 | // set new owner 188 | let info = mock_info("creator", &[]); 189 | let _ = handle_transfer(deps.as_mut(), mock_env(), info, HumanAddr::from("owner")).unwrap(); 190 | 191 | // random cannot execute 192 | let info = mock_info("creator", &amount); 193 | let err = handle_execute(deps.as_mut(), mock_env(), info).unwrap_err(); 194 | match err { 195 | ContractError::Unauthorized {} => {} 196 | e => panic!("unexpected error: {}", e), 197 | } 198 | 199 | // expired cannot execute 200 | let info = mock_info("owner", &amount); 201 | let mut env = mock_env(); 202 | env.block.height = 200_000; 203 | let err = handle_execute(deps.as_mut(), env, info).unwrap_err(); 204 | match err { 205 | ContractError::OptionExpired { expired } => assert_eq!(expired, expires), 206 | e => panic!("unexpected error: {}", e), 207 | } 208 | 209 | // bad counter_offer cannot execute 210 | let msg_offer = coins(39, "ETH"); 211 | let info = mock_info("owner", &msg_offer); 212 | let err = handle_execute(deps.as_mut(), mock_env(), info).unwrap_err(); 213 | match err { 214 | ContractError::CounterOfferMismatch { 215 | offer, 216 | counter_offer, 217 | } => { 218 | assert_eq!(msg_offer, offer); 219 | assert_eq!(amount, counter_offer); 220 | } 221 | e => panic!("unexpected error: {}", e), 222 | } 223 | 224 | // proper execution 225 | let info = mock_info("owner", &amount); 226 | let res = handle_execute(deps.as_mut(), mock_env(), info).unwrap(); 227 | assert_eq!(res.messages.len(), 2); 228 | assert_eq!( 229 | res.messages[0], 230 | CosmosMsg::Bank(BankMsg::Send { 231 | from_address: MOCK_CONTRACT_ADDR.into(), 232 | to_address: "creator".into(), 233 | amount, 234 | }) 235 | ); 236 | assert_eq!( 237 | res.messages[1], 238 | CosmosMsg::Bank(BankMsg::Send { 239 | from_address: MOCK_CONTRACT_ADDR.into(), 240 | to_address: "owner".into(), 241 | amount: collateral, 242 | }) 243 | ); 244 | 245 | // check deleted 246 | let _ = query_config(deps.as_ref()).unwrap_err(); 247 | } 248 | ``` 249 | 250 | Now run the tests: 251 | 252 | ```shell 253 | cargo test 254 | ``` 255 | 256 | If all green, the code will run work on chain. 257 | -------------------------------------------------------------------------------- /docs/02-getting-started/02-installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Installing Prerequisites 6 | In this section, we will set up our machine and install the prerequisites for developing, deploying and interacting with smart contracts on Cosmos SDK chains. 7 | ## Go {#go} 8 | You can set up Go following the [official documentation](https://github.com/golang/go/wiki#working-with-go). The 9 | latest versions of `wasmd` require go version `v1.18+`. 10 | ## Rust {#rust} 11 | Assuming you have never worked with Rust, you will first need to install some tooling. The standard approach is to use `rustup` to maintain dependencies and handle updating multiple versions of `cargo` and `rustc`, which you will be using. 12 | ### Installing Rust in Linux and Mac {#installing-rust-in-linux-and-mac} 13 | First, [install rustup](https://rustup.rs/). Once installed, make sure you have the wasm32 target: 14 | 15 | ```shell 16 | rustup default stable 17 | cargo version 18 | # If this is lower than 1.55.0+, update 19 | rustup update stable 20 | 21 | rustup target list --installed 22 | rustup target add wasm32-unknown-unknown 23 | ``` 24 | 25 | :::info 26 | *wasm32-unknown-unknown* states the target specification, and is called "target triple" consisting of three strings separated by hyphens. Strings represent **architecture**, **vendor**, and **operating system** respectively. *unknown* means there is no specifications for the target and the application is more flexible. 27 | 28 | Read the [rust docs](https://rust-lang.github.io/rfcs/0131-target-specification.html#detailed-design) for a more detailed explanation. 29 | ::: 30 | 31 | 32 | ### Installing Rust in Windows 10 {#installing-rust-in-windows-10} 33 | First, download and execute `rustup-init.exe` from [rustup.rs](https://rustup.rs/) 34 | or [rust-lang.org](https://www.rust-lang.org/tools/install). 35 | 36 | If requested, manually download and install Visual C++ Build Tools 2019, 37 | from https://visualstudio.microsoft.com/visual-cpp-build-tools/ . Make sure "Windows 10 SDK" and "English language pack" 38 | are selected. 39 | 40 | Continue running `rustup-init.exe`, and proceed with the installation. 41 | 42 | Optionally: 43 | 44 | - Download and install [gvim](https://www.vim.org/download.php#pc), and modify the environment variables to add \ to 45 | the PATH. 46 | - Download and install [git for windows](https://git-scm.com/download/win). Modify the environment variables to add \\bin to PATH. 47 | - Turn on Developer Mode (Settings -> Update and Security: For Developers) and enable Device Discovery, to be able to access the Windows 10 server through ssh (https://www.ctrl.blog/entry/how-to-win10-ssh-service.html#section-mssshserv-enable). 48 | 49 | Install the wasm32 target: 50 | 51 | ```shell 52 | rustup default stable 53 | cargo version 54 | # If this is lower than 1.55.0, update 55 | rustup update stable 56 | 57 | rustup target list --installed 58 | rustup target add wasm32-unknown-unknown 59 | ``` 60 | ## wasmd {#wasmd} 61 | `wasmd` is the backbone of the CosmWasm platform. It is the implementation of a Cosmos zone with wasm smart contracts enabled. 62 | 63 | The code was forked from the `cosmos/gaia` repository as a basis, then x/wasm was added and many gaia-specific files were cleaned up. However, the wasmd binary should function just like gaiad except for the addition of the x/wasm module. As such, `wasmd` have all the same features (plus WASM smart contracts obviously). If you'd like to learn more about accessing those features take a look at the [Gaia docs](https://github.com/cosmos/gaia/tree/main/docs/hub-tutorials). If you'd like to learn more about getting started with the Cosmos SDK in general, take a look at the series of [Tutorials](https://tutorials.cosmos.network/) that show how to build custom modules for application-specific blockchains. 64 | 65 | Run the following commands to install `wasmd`: 66 | 67 | ```shell 68 | git clone https://github.com/CosmWasm/wasmd.git 69 | cd wasmd 70 | # If you are updating wasmd, first update your local repository by fetching the remote tags available 71 | git fetch --tags 72 | # replace the v0.27.0 with the most stable version on https://github.com/CosmWasm/wasmd/tags (or look at `git tag`) 73 | git checkout v0.27.0 74 | make install 75 | 76 | # verify the installation 77 | wasmd version 78 | ``` 79 | :::info 80 | * If you are on a Windows machine and `make` software is not preinstalled in the OS, install it following the instructions [here](https://stackoverflow.com/questions/32127524/how-to-install-and-use-make-in-windows). 81 | 82 | * `make install` will copy `wasmd` to `$HOME/go/bin` by default. Still, if you have any problems with the installation of `wasmd`, check your `PATH` and make sure it includes `$HOME/go/bin`. 83 | ::: 84 | ## Setting up command-line tools {#setting-up-command-line-tools} 85 | We will be using a few command-line tools extensively: 86 | ```shell 87 | apt install jq curl 88 | ``` 89 | ## Setting up your IDE {#setting-up-your-ide} 90 | We will need a good IDE for developing smart contracts with Rust. The following development environments are highly recommended and coupling them with the corresponding Rust plugins will help you learn the syntax, especially if you have no prior experience. 91 | 92 | * [VSCode](https://code.visualstudio.com/download) is the best supported environment for RLS (Rust Language Server) and coupled with the Use the [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) extension instead (The previous plugin, [RLS for VSCode](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust), is deprecated.), it makes use of the rust compiler to type-check all your code on each save. This gives the same error messages as the actual compiler would and highlights the errors, but it can be a bit slow to respond (as it runs the compiler). It is a solid option, particularly if you are used to VSCode. 93 | 94 | * The other option is [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download/) along with the [IntelliJ Rust](https://intellij-rust.github.io/) plugin, which has fast support for inline language features. In particular, it shows the inferred types of variables, which can be very helpful, especially when working with (nested) generics. It catches most syntax errors very quickly, but not all of them. This means sometimes you have to look at compile failures to find the errors. It is highly recommended, more so, if you are coming from another IntelliJ product (eg. Goland). 95 | 96 | There are other editors out there with varying degrees of Rust support. However, unless you have a strong preference for another editor (e.g., Sublime, Emacs, Vim) trying one of the two above is recommended, especially if you are new to Rust. Once you are confident in the language, you can always use another editor and customize it to your liking. 97 | 98 | [CosmWasm IDE](https://github.com/oraichain/cw-vscode) 99 | 100 | CosmWasm IDE is a tool that simplifies CosmWasm smart contract development & deployment processes. It integrates with Gitpod & Keplr to create a simple yet powerful environment to build, deploy, and interact with CosmWasm smart contracts through default and custom networks using CosmWasm. With Gitpod, CosmWasm developers can develop smart contracts on the browser, and it is well maintained. The tool is currently maintained by Oraichain & CosmWasm. 101 | 102 | #### Components 103 | 104 | The CosmWasm IDE consists of three sub-repositories: 105 | 106 | - [CosmWasm Gitpod](https://github.com/oraichain/cosmwasm-gitpod) serves as a Gitpod builder which automatically builds a complete development environment including Rust installation, VS Code browser, crucial VS Code extensions, and is fully compatible with the Keplr wallet. With this repository, CosmWasm developers will not have to worry about spending hours installing tools & libraries, and they also feel secure when deploying contracts using Keplr. 107 | 108 | - [CosmWasm IDE extension](https://github.com/oraichain/cw-vscode) is a VS Code extension which integrates all the important functionalities related to building & deploying CosmWasm smart contracts through simple button clicks. 109 | 110 | - [CosmWasm IDE extension webview](https://github.com/oraichain/cw-ide-webview) is a React application that lies on top of the CosmWasm IDE Extension. It is responsible for connecting with the Keplr wallet and displaying inputs to deploy & interact with smart contracts. It also allows adding custom networks. 111 | 112 | For more information, please visit the repositories on GitHub. You can also find a tutorial for CosmWasm IDE [here](https://docs.cosmwasm.com/docs/1.0/tutorials/cosmwasm-ide) or through the official [Oraichain documentation site](https://docs.orai.io/developers/cosmwasm-ide/tutorial-01). 113 | -------------------------------------------------------------------------------- /docs/03-architecture/02-actor.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Actor Model 3 | sidebar_position: 2 4 | --- 5 | 6 | # Actor Model for Contract Calls 7 | 8 | The [actor model](https://en.wikipedia.org/wiki/Actor_model) is a design pattern, used to build reliable, distributed 9 | systems. The fundamental points are that each `Actor` has exclusive access to its own internal state and that `Actors` 10 | cannot call each other directly. Instead, they dispatch messages over some `Dispatcher` (that maintains the state of the 11 | system and maps addresses to code and storage). Fundamentally the `Actor` pattern can be encapsulated in this interface: 12 | 13 | ```rust 14 | pub trait Actor { 15 | fn handle(msgPayload: &[u8]) -> Vec; 16 | } 17 | 18 | pub struct Msg { 19 | pub destination: Vec, 20 | pub payload: Vec, 21 | } 22 | ``` 23 | 24 | This is the basic model that was used to model contracts in CosmWasm. You can see the same influence in the 25 | function: 26 | 27 | ```rust 28 | pub fn handle(store: &mut T, params: Params, msg: Vec) -> Result 29 | ``` 30 | The response contains `Vec` and a little metadata. `store` is access to the contract's internal state. And `params` is some 31 | global immutable context. So, just a little bit of syntax around the same design. From this basic design, a few other 32 | useful aspects can be derived: 33 | 34 | - First, there is a **loose coupling** between Actors, limited to the format of the data packets (the recipient must 35 | support a superset of what you send). There are no complex API or function pointers to pass around. This is much like 36 | using REST or RPC calls as a boundary between services, which is a scalable way to compose systems from many vendors. 37 | 38 | - Secondly, each `Actor` can effectively run on its own thread, with its own queue. This both enables concurrency (which 39 | we don't make use of in CosmWasm... yet), and **serialized execution** within each actor (which we do rely upon). This 40 | means that the `Handle` method above cannot be executed in the middle of a previously executed `Handle` 41 | call. `Handle` is a synchronous call and returns before the `Actor` can process the next message. This feature is 42 | what [protects us from reentrancy by design](./smart-contracts#avoiding-reentrancy-attacks). 43 | 44 | :::info 45 | The contract can access other contracts state directly - such technique is called raw querying. However, contract 46 | can never write to others contracts state. 47 | ::: 48 | 49 | Another important aspect related to CosmWasm is **locality**. That is, actors can only communicate with other actors ** 50 | whose address they previously received**. We will go more into depth on [names and addresses](./addresses) on the next 51 | page, but the key point is that for two actors to communicate, an external message (from the contract creator, or 52 | potentially a user) must be sent to the actor. This is a flexible way to set up topologies in a distributed manner. The 53 | only thing that must be hard-coded is the data format to pass to such addresses. Once some standard interfaces are 54 | established (like ERC20, ERC721, ENS, etc), then we can support composability between large classes of contracts, with 55 | different backing codes, but sharing a common API. 56 | 57 | ## Security Benefits {#security-benefits} 58 | 59 | By enforcing **private internal state**, a given contract can guarantee all valid transitions in its internal state. 60 | This is in contrast to the capabilities model used in Cosmos SDK, where trusted modules are passed a `StoreKey` in their 61 | constructor, which allows *full read and write access to the other module's storage*. In the Cosmos SDK, we can audit 62 | the modules before calling them, and safely pass in such a powerful set of rights at compile time. However, there are no 63 | compile-time checks in a smart contract system and we need to produce stricter boundaries between contracts. This allows 64 | us to comprehensively reason over all possible transitions in a contract's state (and use quick-check-like methods to 65 | test it). 66 | 67 | As mentioned above, **serialized execution** prevents all concurrent execution of a contract's code. This is like an 68 | automatic mutex over the entire contract code. This is exactly the issue that one of the most common Ethereum attacks, 69 | reentrancy, makes use of. Contract A calls into contract B, which calls back into contract A. There may be local changes 70 | in memory in contract A from the first call (eg. deduct a balance), which are not yet persisted, so the second call can 71 | use the outdated state a second time (eg. authorize sending a balance twice). By enforcing serialized execution, the 72 | contract will write all changes to storage before exiting and have a proper view when the next message is processed. 73 | 74 | ## Atomic Execution {#atomic-execution} 75 | 76 | One problem with sending messages is atomically committing a state change over two contracts. There are many cases where 77 | we want to ensure that all returned messages were properly processed before committing our state. There are ideas like " 78 | three-phase-commit" is used in distributed databases, but since in the normal case, all actors are living in the same 79 | binary, we can handle this in the `Keeper`. Before executing a Msg that came from an external transaction, we create a 80 | SavePoint of the global data store, and pass in a subset to the first contract. We then execute all returned messages 81 | inside the same sub-transaction. If all messages succeed, then we can commit the sub-transaction. If any fails (or we 82 | run out of gas), we abort execution and roll back the state to before the first contract was executed. 83 | 84 | This allows us to optimistically update code, relying on rollback for error handling. For example, if an exchange matches 85 | a trade between two "ERC20" tokens, it can make the offer fulfilled and return two messages to move token A to the 86 | buyer and token B to the seller. (ERC20 tokens use a concept of allowance, so the owner "allows" the exchange to move up 87 | to X tokens from their account). When executing the returned messages, it turns out that the buyer doesn't have 88 | sufficient token B (or provided an insufficient allowance). This message will fail, causing the entire sequence to be 89 | reverted. Transaction failed, the offer was not marked as fulfilled, and no tokens changed hands. 90 | 91 | While many developers may be more comfortable thinking about directly calling the other contract in their execution path 92 | and handling the errors, you can achieve almost all the same cases with such an *optimistic update and return* approach. 93 | And there is no room for making mistakes in the contract's error handling code. 94 | 95 | ## Dynamically Linking Host Modules {#dynamically-linking-host-modules} 96 | 97 | The aspects of **locality** and **loose coupling** means that we don't even need to link to other CosmWasm contracts. We 98 | can send messages to anything the Dispatcher has an address for. For example, we can return a `SendMsg`, which will be 99 | processed by the native `x/bank` module in Cosmos SDK, moving native tokens. As we define standard interfaces for 100 | composability, we can define interfaces to call into core modules (bond and unbond your stake...), and then pass in the 101 | address to the native module in the contract constructor. 102 | 103 | ## Inter Blockchain Messaging {#inter-blockchain-messaging} 104 | 105 | Since the Actor model doesn't attempt to make synchronous calls to another contract but just returns a message "to be 106 | executed", it is a nice match for making cross-chain contract calls using [IBC](https://cosmos.network/ibc). The only 107 | caveat here is that the *atomic execution* guarantee we provided above no longer applies here. The other call will not 108 | be called by the same dispatcher, so we need to store an intermediate state in the contract itself. That means a state 109 | that cannot be changed until the result of the IBC call is known, then can be safely applied or reverted. 110 | 111 | For example, if we want to move tokens from chain A to chain B, we would first prepare a send: 112 | 113 | 1. Contract A reduces the token supply of the sender 114 | 2. Contract A creates an "escrow" of those tokens linked to the IBC message id, sender, and receiving chain. 115 | 3. Contract A commits state and returns a message to initiate an IBC transaction to chain B. 116 | 4. If the IBC send part fails, then the contract is atomically reverted as above. 117 | 118 | After some time, a "success" or "error"/"timeout" message is returned from the IBC module to the token contract: 119 | 120 | 1. Contract A validates the message came from the IBC handler (authorization) and refers to a known IBC message ID it 121 | has in escrow. 122 | 2. If it was a success, the escrow is deleted and the escrowed tokens are placed in an account for "Chain B" (meaning 123 | that only a future IBC message from Chain B may release them). 124 | 3. If it was an error, the escrow is deleted and the escrowed tokens are returned to the account of the original sender. 125 | 126 | You can imagine a similar scenario working for cases like moving NFT ownership, cross-chain staking, etc. We will expand 127 | on these possibilities and provide tooling to help make proper design once the IBC code in Cosmos SDK is stabilized (and 128 | included in a release), but the contract design is made with this in mind. 129 | -------------------------------------------------------------------------------- /tutorials/videos-workshops.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Videos and Workshops 6 | 7 | Here are the videos, events, workshops that can feed your learning hunger for CosmWasm! 8 | 9 | ## Beginner Level {#beginner-level} 10 | 11 | ### Introduction to CosmWasm. CW1-subkeys Development, Deployment and Interaction {#introduction-to-cosmwasm-cw1-subkeys-development-deployment-and-interaction} 12 | 13 | *Date: September 12, 2020* 14 | 15 | ### Basic Layout of Smart Contract {#basic-layout-of-smart-contract} 16 | 17 |
18 | 19 |
20 | 21 | ### Contract development flow w/permissions to subkey contract {#contract-development-flow-wpermissions-to-subkey-contract} 22 | 23 |
24 | 26 |
27 | 28 | ### Contract interaction using CosmJS and smart contract helpers {#contract-interaction-using-cosmjs-and-smart-contract-helpers} 29 | 30 |
31 | 32 |
33 | 34 | ### Hackatom HCMC: CosmWasm/CosmJS zero to hero {#hackatom-hcmc-cosmwasmcosmjs-zero-to-hero} 35 | 36 |
37 | 38 |
39 | 40 | ## Advanced Level {#advanced-level} 41 | 42 | ### Code With US {#code-with-us} 43 | 44 | *Date: June 29, 2020* 45 | 46 | Custom token workshop 47 | 48 |
49 | 51 |
52 | 53 | ### Contract Composition Workshop - August 26, 2020 {#contract-composition-workshop---august-26-2020} 54 | 55 | *Date: August 26, 2020* 56 | 57 | In this workshop, we chose the topic ¨Contract composition deep dive¨ as per our poll result. 58 | 59 | 1) We will show the basic staking derivative 60 | 2) And demonstrate how to wrap it in a CW20 token 61 | 3) Then we could use that token to interact with other contracts. 62 | 63 | ### Deep Dive Part 1 - CosmWasm template {#deep-dive-part-1---cosmwasm-template} 64 | 65 |
66 | 67 |
68 | 69 | ### Deep Dive Part 2 - CW1 Subkeys {#deep-dive-part-2---cw1-subkeys} 70 | 71 |
72 | 73 |
74 | 75 | ### Deep Dive Part 3 - CW20 Staking features {#deep-dive-part-3---cw20-staking-features} 76 | 77 |
78 | 79 |
80 | 81 | ### Building Multi-chain Smart-Contracts Using CosmWasm - HackAtom V India Workshop {#building-multi-chain-smart-contracts-using-cosmwasm---hackatom-v-india-workshop} 82 | 83 | *Date: September 14, 2020* 84 | 85 | #### Intro {#intro} 86 | 87 |
88 | 89 |
90 | 91 | #### Setup Coding Environment {#setup-coding-environment} 92 | 93 |
94 | 95 |
96 | 97 | #### Smart Contract Components and Development {#smart-contract-components-and-development} 98 | 99 |
100 | 101 |
102 | 103 | #### Smart Contract Testing {#smart-contract-testing} 104 | 105 |
106 | 107 |
108 | 109 | ### State modeling & Buckets {#state-modeling--buckets} 110 | 111 | *Date: September 29, 2020* 112 | 113 | #### Part 1 {#part-1} 114 | 115 |
116 | 117 |
118 | 119 | #### Part 2 {#part-2} 120 | 121 |
122 | 123 |
124 | 125 | ### Quadratic Funding with CosmWasm {#quadratic-funding-with-cosmwasm} 126 | 127 | #### Part 1 QF concept & implementing logic {#part-1-qf-concept--implementing-logic} 128 | 129 |
130 | 131 |
132 | 133 | #### Part 2 QF Smart Contract Helper& Execution {#part-2-qf-smart-contract-helper-execution} 134 | 135 |
136 | 137 |
138 | 139 | ### Path to IBC {#path-to-ibc} 140 | 141 |
142 | 143 |
144 | 145 | ### CosmWasm/CosmJS dApps - Zero to Hero {#cosmwasmcosmjs-dapps---zero-to-hero} 146 | 147 | *Date: Oct 16, 2020* 148 | 149 |
150 | 151 |
152 | 153 | ### Multi contract testing {#multi-contract-testing} 154 | 155 | *Date: Feb 14, 2021* 156 | 157 |
158 | 159 |
160 | 161 | ### CosmWasm & IBC: Cross Chain Contracts {#cosmwasm--ibc-cross-chain-contracts} 162 | 163 | *Date: Feb 24, 2021* 164 | 165 |
166 | 167 |
168 | 169 | ### CosmWasm: Submessages {#cosmwasm-submessages} 170 | 171 |
172 | 173 |
174 | 175 | ## Presentations {#presentations} 176 | 177 | ### CosmWasm presentation at Cosmos Ecosystem Summit (15/01/21) {#cosmwasm-presentation-at-cosmos-ecosystem-summit-150121} 178 | 179 |
180 | 182 |
183 | 184 | ### Whiteboard Series with NEAR | Ep: 38 Ethan Frey from CosmWasm {#whiteboard-series-with-near--ep-38-ethan-frey-from-cosmwasm} 185 | 186 |
187 | 189 |
190 | 191 | ### Introducción al Ecosistema Cosmos, CosmWasm y presentación del Riddlethon {#introducción-al-ecosistema-cosmos-cosmwasm-y-presentación-del-riddlethon} 192 | 193 | 194 |
195 | 197 |
198 | 199 | ### Riddlethon I: Ask Me Anything about Confio & CosmWasm {#riddlethon-i-ask-me-anything-about-confio--cosmwasm} 200 | 201 |
202 | 204 |
205 | -------------------------------------------------------------------------------- /docs/04-smart-contracts/11-migration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 11 3 | --- 4 | 5 | # Migration 6 | 7 | Migration is the process through which a given smart contracts code can be swapped out or 'upgraded'. 8 | 9 | CosmWasm made contract migration a first-class experience. When instantiating a contract, there is an optional admin field that you can set. If it is left empty, the contract is immutable. If it is set (to an external account or governance contract), that account can trigger a migration. The admin can also change admin or even make the contract fully immutable after some time. However, when we wish to migrate from contract A to contract B, contract B needs to be aware somehow of how the state was encoded. 10 | 11 | This is where CW2 specification comes in. It specifies one special `Singleton` to be stored on disk by all contracts on instantiate. When the migrate function is called, then the new contract can read that data and see if this is an expected contract we can migrate from. And also contain extra version information if we support multiple migrate paths. 12 | 13 | Working with CW2 is quite straightforward in that, as a smart contract developer you need only perform a couple of steps. 14 | 15 | The CW2 Spec provides a `set_contract_version` which should be used in instantiate to store the original version of a contract. It is important to also `set_contract_version` as a part of the `pub fn migrate(...)` logic this time (as opposed to `instantiate`) for the contract version to be updated after a succesful migration. 16 | 17 | ```rust 18 | const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); 19 | const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); 20 | 21 | 22 | #[cfg_attr(not(feature = "library"), entry_point)] 23 | pub fn instantiate(deps: DepsMut, env: Env, info: MessageInfo, msg: InstantiateMsg) -> Response { 24 | // Use CW2 to set the contract version, this is needed for migrations 25 | set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; 26 | } 27 | ``` 28 | 29 | Additionally, `get_contract_version` is provided in CW2 which can and should be used in the `migrate` function of the contract when you need to know the previous version of the contract. Both methods work on a `Item` data structure from `cw_storage_plus` which operates over this object: 30 | 31 | ```rust 32 | #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] 33 | pub struct ContractVersion { 34 | /// contract is the crate name of the implementing contract, eg. `crate:cw20-base` 35 | /// we will use other prefixes for other languages, and their standard global namespacing 36 | pub contract: String, 37 | /// version is any string that this implementation knows. It may be simple counter "1", "2". 38 | /// or semantic version on release tags "v0.7.0", or some custom feature flag list. 39 | /// the only code that needs to understand the version parsing is code that knows how to 40 | /// migrate from the given contract (and is tied to it's implementation somehow) 41 | pub version: String, 42 | } 43 | ``` 44 | 45 | ## Setting up a contract for migrations 46 | 47 | Performing a contract migration is a three step process. First, you must write a newer version of the contract you wish to update. Second, you can upload the new code as you did before, but don’t instantiate it. Third, you use a dedicated [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.20.0/proto/cosmwasm/wasm/v1/tx.proto#L94-L104) transaction to point this contract to use the new code. And you are done! 48 | 49 | During the migration process, the migrate function defined on the new code is executed, never the one from the old code. Both the source and the destination `code_id`'s may be migratable, but it is necessary that the new code has a `migrate` function defined and properly exported as an `entry_point`: #[cfg_attr(not(feature = "library"), entry_point)]. 50 | 51 | The `migrate` function itself, exposes the ability to make any granular changes needed to the State, akin to a database migration or any other things you might want to do. 52 | 53 | If the migrate function returns an error, the transaction aborts, all state changes are reverted and the migration is not performed. 54 | 55 | Provided below are a few variants on migrations you could do ranging from a very simple one, to a more restricted one by code iD and type. 56 | 57 | ### Basic Contract Migration 58 | 59 | This migration will be the most common you may see. It simply is used to swap out the code of a contract. Safety checks may not be performed if you do not also use `cw2::set_contract_version`. 60 | 61 | ```rust 62 | const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); 63 | const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); 64 | 65 | #[entry_point] 66 | pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { 67 | // No state migrations performed, just returned a Response 68 | Ok(Response::default()) 69 | } 70 | ``` 71 | 72 | ### Restricted Migration by code version and name 73 | 74 | This migration is a more complete and restricted example where the `cw2` package is used and the `migrate` function ensures that: 75 | 76 | - We are migrating from the same type of contract; checking its name 77 | - We are upgrading from an older version of the contract; checking its version 78 | 79 | ```rust 80 | const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); 81 | const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); 82 | 83 | #[entry_point] 84 | pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { 85 | let ver = cw2::get_contract_version(deps.storage)?; 86 | // ensure we are migrating from an allowed contract 87 | if ver.contract != CONTRACT_NAME { 88 | return Err(StdError::generic_err("Can only upgrade from same type").into()); 89 | } 90 | // note: better to do proper semver compare, but string compare *usually* works 91 | #[allow(clippy::cmp_owned)] 92 | if ver.version >= CONTRACT_VERSION { 93 | return Err(StdError::generic_err("Cannot upgrade from a newer version").into()); 94 | } 95 | 96 | // set the new version 97 | cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; 98 | 99 | // do any desired state migrations... 100 | 101 | Ok(Response::default()) 102 | } 103 | ``` 104 | 105 | ### Migrate which updates the version only if newer 106 | 107 | This migration is a less restrictive example than above. In this case the `cw2` package is used and the `migrate` function ensures that: 108 | 109 | - If the contract version has incremented from the stored one, perform needed migrations but store the new contract version 110 | - Uses Semver instead of String compare 111 | 112 | ```rust 113 | const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); 114 | const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); 115 | 116 | #[entry_point] 117 | pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { 118 | let version: Version = CONTRACT_VERSION.parse()?; 119 | let storage_version: Version = get_contract_version(deps.storage)?.version.parse()?; 120 | 121 | if storage_version < version { 122 | set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; 123 | 124 | // If state structure changed in any contract version in the way migration is needed, it 125 | // should occur here 126 | } 127 | Ok(Response::default()) 128 | } 129 | ``` 130 | 131 | This example uses Semver to help with version checks, you would also need to add the semver dependency to your cargo deps: 132 | 133 | ```toml 134 | [dependencies] 135 | semver = "1" 136 | ``` 137 | 138 | And also implement Semver custom errors for your contract package: 139 | 140 | ```rust 141 | #[derive(Error, Debug, PartialEq)] 142 | pub enum ContractError { 143 | 144 | #[error("Semver parsing error: {0}")] 145 | SemVer(String), 146 | 147 | } 148 | impl From for ContractError { 149 | fn from(err: semver::Error) -> Self { 150 | Self::SemVer(err.to_string()) 151 | } 152 | } 153 | ``` 154 | 155 | ### Using migrate to update otherwise immutable state 156 | 157 | This example shows how a migration can be used to update a value that generally should not be changed. This allows for the immutable value to be changed only during a migration if that functionality is needed by your team. 158 | 159 | ```rust 160 | #[entry_point] 161 | pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { 162 | let data = deps 163 | .storage 164 | .get(CONFIG_KEY) 165 | .ok_or_else(|| StdError::not_found("State"))?; 166 | let mut config: State = from_slice(&data)?; 167 | config.verifier = deps.api.addr_validate(&msg.verifier)?; 168 | deps.storage.set(CONFIG_KEY, &to_vec(&config)?); 169 | 170 | Ok(Response::default()) 171 | } 172 | ``` 173 | 174 | In the above example, our `MigrateMsg` has a `verifier` field which contains the new value for our contracts `verifier` field located in the State. Provided your contract does not also expose an `UpdateState` or something like `UpdateVerifier` ExecuteMsgs then this provides the only method to change the `verifier` value. 175 | 176 | ### Using migrations to 'burn' a contract 177 | 178 | Migrations can also be used to completely abandon an old contract and burn its state. This has varying uses but in the event you need it you can find an example [here](https://github.com/CosmWasm/cosmwasm/blob/main/contracts/burner/src/contract.rs#L20): 179 | 180 | ```rust 181 | #[entry_point] 182 | pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult { 183 | // delete all state 184 | let keys: Vec<_> = deps 185 | .storage 186 | .range(None, None, Order::Ascending) 187 | .map(|(k, _)| k) 188 | .collect(); 189 | let count = keys.len(); 190 | for k in keys { 191 | deps.storage.remove(&k); 192 | } 193 | 194 | // get balance and send all to recipient 195 | let balance = deps.querier.query_all_balances(env.contract.address)?; 196 | let send = BankMsg::Send { 197 | to_address: msg.payout.clone(), 198 | amount: balance, 199 | }; 200 | 201 | let data_msg = format!("burnt {} keys", count).into_bytes(); 202 | 203 | Ok(Response::new() 204 | .add_message(send) 205 | .add_attribute("action", "burn") 206 | .add_attribute("payout", msg.payout) 207 | .set_data(data_msg)) 208 | } 209 | 210 | ``` 211 | 212 | In the above example, when the migration occurs the State is completely deleted. Additionally all the balance of contract is send to a nominated `payout` address provided in the `MigrationMsg`. In this case all funds are drained and all state removed effectively burning the contract. 213 | 214 | ## Platform Specific Variations 215 | 216 | Different chains and hubs in the Cosmos ecosystem may have some variations on how migrations are done on their respective networks. This section will attempt to outline those. 217 | 218 | ### Terra 219 | 220 | Terra has some specific differences in how they manage migrations. Firstly; the contract must have been set as migratable on instantiation. The contract needs to have an admin for migratability similar to the standard procedure for migrations. 221 | Specifically migration in this case for Terra refers to swapping out the code id for a new one that is considered 'compatible' (CW2 helps with this). [Source](https://github.com/terra-money/terrain#migrating-cosmwasm-contracts-on-terra). 222 | 223 | > Note: In Terra, it is also possible to migrate a code_id across chains (COL4->5 for example). This operation is atomic and can only be performed once. Its intention is to migrate your code to the new chain and preserve its old code ID. This process helps to prevent downstream breakages of other contracts on the new network which depend on your old code ID. 224 | > Example command for migrating across chains : 225 | > 226 | > ```rust 227 | > terrad tx wasm store ./{code.wasm} --from {keyname} \ 228 | > --migrate-code-id {codeID} 229 | > ``` 230 | --------------------------------------------------------------------------------