{"id":236473,"date":"2024-06-26T02:31:00","date_gmt":"2024-06-26T02:31:00","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2024\/06\/26\/comprehensive-guide-to-launching-a-dapp-on-injective\/"},"modified":"2025-06-25T17:16:09","modified_gmt":"2025-06-25T17:16:09","slug":"comprehensive-guide-to-launching-a-dapp-on-injective","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2024\/06\/26\/comprehensive-guide-to-launching-a-dapp-on-injective\/","title":{"rendered":"Comprehensive Guide to Launching a dApp on Injective"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<figure class=\"figure mt-2\">&#13;<br \/>\n                        <a href=\"https:\/\/image.blockchain.news:443\/features\/052E732CDC0184391FF0A028CC1D40A3A21073F8765712CD8FA1350C21CF9589.jpg\">&#13;<br \/>\n                            <img decoding=\"async\" class=\"rounded\" src=\"https:\/\/image.blockchain.news:443\/features\/052E732CDC0184391FF0A028CC1D40A3A21073F8765712CD8FA1350C21CF9589.jpg\" alt=\"Comprehensive Guide to Launching a dApp on Injective\"\/>&#13;<br \/>\n&#13;<br \/>\n                        <\/a>&#13;<br \/>\n                    <\/figure>\n<p>Developers are at the heart of the Injective  (INJ)ecosystem. With a diverse range of dApps spanning Web3 finance, Injective offers something for everyone. If you\u2019ve been following the Injective ecosystem and want to learn more about creating your first dApp on Injective, this guide is for you.<\/p>\n<h2>Installing <code>injectived<\/code><\/h2>\n<p><code>injectived<\/code> is the CLI tool used to interact with the Injective network. You can use the <code>injectived<\/code> CLI to compile, deploy, and interact with Injective smart contracts, run your own node, and more. Before installing it, ensure you have <a rel=\"nofollow\" href=\"https:\/\/rustup.rs\/?ref=blog.injective.com\"><code>rustup<\/code><\/a> along with recent versions of <code>rustc<\/code> and <code>cargo<\/code> installed. Currently, testing can be done with Rust v1.58.1+.<\/p>\n<p>Additionally, you need to install the <code>wasm32-unknown-unknown<\/code> target and the <code>cargo-generate<\/code> Rust crate.<\/p>\n<p>You can check versions via the following commands:<\/p>\n<pre><code>rustc --version\ncargo --version\nrustup target list --installed<\/code><\/pre>\n<p>If <code>wasm32<\/code> is not listed, run this command:<\/p>\n<p><code>rustup target add wasm32-unknown-unknown<\/code><\/p>\n<p>To install <code>cargo-generate<\/code>, run:<\/p>\n<pre><code>cargo install cargo-generate<\/code><\/pre>\n<p>To install <code>injectived<\/code> on your machine, you have two options: install it from the binary or from source. For complete instructions on both methods, see <a rel=\"nofollow\" href=\"https:\/\/docs.injective.network\/develop\/tools\/injectived\/install?ref=blog.injective.com\">Install Injectived<\/a>.<\/p>\n<h2>Your First Smart Contract<\/h2>\n<p>A smart contract can be considered an instance of a singleton object whose internal state is persisted on the blockchain. Users can trigger state changes or query the contract&#8217;s state by sending JSON messages. These JSON messages are different from Injective messages such as <code>MsgSend<\/code> and <code>MsgExecuteContract<\/code>.<\/p>\n<p>As a smart contract developer, your job is to define three functions that compose your smart contract&#8217;s interface:<\/p>\n<ul>\n<li><code>instantiate()<\/code>: a constructor called during contract instantiation to provide the initial state<\/li>\n<li><code>execute()<\/code>: called when a user wants to invoke a method on the smart contract<\/li>\n<li><code>query()<\/code>: called when a user wants to retrieve data from the smart contract<\/li>\n<\/ul>\n<p>In our <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/59b9fed82864103eb704a58d20ddb4bf94c69787\/src\/msg.rs?ref=blog.injective.com\">sample counter contract<\/a>, we will implement one <code>instantiate<\/code>, one <code>query<\/code>, and two <code>execute<\/code> methods.<\/p>\n<h3>Counter Template<\/h3>\n<p>In your working directory, launch your smart contract with the recommended folder structure and build options by running the following commands:<\/p>\n<pre><code>cargo generate --git https:\/\/github.com\/CosmWasm\/cw-template.git --branch 1.0 --name my-first-contract\ncd my-first-contract<\/code><\/pre>\n<p>This template will provide you with the basic boilerplate and structure for a smart contract. In the <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/ea3b781447a87f052e4b8308d5c73a30481ed61f\/src\/contract.rs?ref=blog.injective.com\">src\/contract.rs<\/a> file you will find that the standard CosmWasm entry points <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/ea3b781447a87f052e4b8308d5c73a30481ed61f\/src\/contract.rs?ref=blog.injective.com#L15\">instantiate()<\/a>, <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/ea3b781447a87f052e4b8308d5c73a30481ed61f\/src\/contract.rs?ref=blog.injective.com#L35\">execute()<\/a>, and <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/ea3b781447a87f052e4b8308d5c73a30481ed61f\/src\/contract.rs?ref=blog.injective.com#L72\">query()<\/a> are properly exposed and connected.<\/p>\n<h3>State<\/h3>\n<p>State handles the database where smart contract data is stored and accessed.<\/p>\n<p>The <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/ea3b781447a87f052e4b8308d5c73a30481ed61f\/src\/state.rs?ref=blog.injective.com\">starting template<\/a> has the following basic state, a singleton struct <code>State<\/code> containing:<\/p>\n<ul>\n<li><code>count<\/code>, a 32-bit integer that <code>execute()<\/code> messages will interact by increasing or resetting it.<\/li>\n<li><code>owner<\/code>, the sender address of the <code>MsgInstantiateContract<\/code>, which determines if certain execution messages are permitted.<\/li>\n<\/ul>\n<h3>InstantiateMsg<\/h3>\n<p><code>InstantiateMsg<\/code> is provided to the contract when a user instantiates a contract on the blockchain through a <code>MsgInstantiateContract<\/code>. This message supplies the contract with its configuration as well as its initial state.<\/p>\n<p>On Injective, uploading a contract&#8217;s code and instantiating a contract are separate events, unlike on Ethereum. This separation allows a small set of vetted contract archetypes to exist as multiple instances sharing the same base code, but be configured with different parameters (imagine one canonical ERC20, and multiple tokens that use its code).<\/p>\n<h3>ExecuteMsg<\/h3>\n<p><code>ExecuteMsg<\/code> is a JSON message passed to the <code>execute()<\/code> function through a <code>MsgExecuteContract<\/code>. Unlike <code>InstantiateMsg<\/code>, <code>ExecuteMsg<\/code> can exist as several different types of messages to account for the various types of functions that a smart contract can expose to users. The <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/59b9fed82864103eb704a58d20ddb4bf94c69787\/src\/msg.rs?ref=blog.injective.com#L9\"><code>ExecuteMsgs<\/code><\/a>: <code>Increment<\/code> and <code>Reset<\/code>.<\/p>\n<ul>\n<li><code>Increment<\/code> has no input parameter and increases the value of count by 1.<\/li>\n<li><code>Reset<\/code> takes a 32-bit integer as a parameter and resets the value of count to the input parameter.<\/li>\n<\/ul>\n<h3>QueryMsg<\/h3>\n<p>The <code>GetCount<\/code> query message has no parameters and returns the <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/cw-counter\/blob\/59b9fed82864103eb704a58d20ddb4bf94c69787\/src\/msg.rs?ref=blog.injective.com#L16\">count<\/a> value.<\/p>\n<h3>Unit test<\/h3>\n<p>Unit tests should be run as the first line of assurance before deploying the code on-chain. They are quick to execute and can provide helpful backtraces on failures with the <code>RUST_BACKTRACE=1<\/code> flag:<\/p>\n<pre><code>cargo unit-test \/\/ run this with RUST_BACKTRACE=1 for helpful backtraces<\/code><\/pre>\n<p>You can find the unit test implementation at <code>src\/contract.rs<\/code><\/p>\n<h3>Building the Contract<\/h3>\n<p>Now that we understand and have tested the contract, we can run the following command to build the contract. This will check for any preliminary errors before we optimize the contract in the next step.<\/p>\n<pre><code>cargo wasm<\/code><\/pre>\n<p>Next, we must optimize the contract in order to ready the code for upload to the chain.<\/p>\n<p>CosmWasm has <a rel=\"nofollow\" href=\"https:\/\/github.com\/CosmWasm\/optimizer?ref=blog.injective.com\">rust-optimizer<\/a>, an optimizing compiler that produces a small and consistent build output. The easiest method to use the tool is through a published Docker image\u2014check <a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/cosmwasm\/rust-optimizer\/tags?ref=blog.injective.com\">here<\/a> for the latest x86 version, or <a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/cosmwasm\/rust-optimizer-arm64\/tags?ref=blog.injective.com\">here<\/a> for the latest ARM version. With Docker running, use the following command to mount the contract code to <code>\/code<\/code> and optimize the output (you can use an absolute path instead of <code>$(pwd)<\/code> if you don&#8217;t want to cd to the directory first):<\/p>\n<p>For x86:<\/p>\n<pre><code>docker run --rm -v \"$(pwd)\":\/code \\\n  --mount type=volume,source=\"$(basename \"$(pwd)\")_cache\",target=\/code\/target \\\n  --mount type=volume,source=registry_cache,target=\/usr\/local\/cargo\/registry \\\n  cosmwasm\/rust-optimizer:0.12.12<\/code><\/pre>\n<p>For ARM64:<\/p>\n<pre><code>docker run --rm -v \"$(pwd)\":\/code \\\n  --mount type=volume,source=\"$(basename \"$(pwd)\")_cache\",target=\/code\/target \\\n  --mount type=volume,source=registry_cache,target=\/usr\/local\/cargo\/registry \\\n  cosmwasm\/rust-optimizer-arm64:0.12.12<\/code><\/pre>\n<p>This produces an <code>artifacts<\/code> directory with a <code>PROJECT_NAME.wasm<\/code> and a <code>checksums.txt<\/code> file containing the <code>SHA256<\/code> hash of the Wasm file. The Wasm file is compiled deterministically, meaning anyone else running the same Docker image on the same Git commit should get an identical file with the same <code>SHA256<\/code> hash.<\/p>\n<h3>Upload the Wasm Contract<\/h3>\n<p>As mentioned above, Wasm smart contracts are uploaded via the <code>injectived<\/code> CLI. To proceed, initialize and fund an account with test funds (see <a rel=\"nofollow\" href=\"https:\/\/docs.injective.network\/develop\/guides\/injective-101\/your-first-contract?ref=blog.injective.com#install-injectived\">here<\/a> for instructions). Once that is done, enter the following command to upload the contract:<\/p>\n<pre><code># inside the \"injective-core-staging\" container, or from the contract directory if running injectived locally\nyes 12345678 | injectived tx wasm store artifacts\/my_first_contract.wasm \\\n--from=$(echo $INJ_ADDRESS) \\\n--chain-id=\"injective-888\" \\\n--yes --fees=1000000000000000inj --gas=2000000 \\\n--node=https:\/\/k8s.testnet.tm.injective.network:443<\/code><\/pre>\n<p>Next, enter your address on the Injective <a rel=\"nofollow\" href=\"https:\/\/testnet.explorer.injective.network\/?ref=blog.injective.com\">Testnet Explorer<\/a> and look for a transaction with the <code>txhash<\/code> returned from storing the code on-chain. The transaction type should be <code>MsgStoreCode<\/code>.<\/p>\n<p>And voil\u00e0! You have successfully created and uploaded your first smart contract on Injective. For more information and context around each step, see <a rel=\"nofollow\" href=\"https:\/\/docs.injective.network\/develop\/guides\/injective-101\/your-first-contract?ref=blog.injective.com\">here<\/a>.<\/p>\n<h2>Build a Front End<\/h2>\n<p>While it is possible to interact with your contract through the Injective CLI, this is not ideal for most dApp users. A web UI can provide a much better experience. A web UI can provide a much better experience. Rather than sending transaction messages through <code>injectived<\/code>, we can abstract away the complexity and provide the user with two buttons\u2014one to increment the count and one to reset the count.<\/p>\n<p>For example, see the <a rel=\"nofollow\" href=\"https:\/\/injective-simple-cosmwasm-sc.netlify.app\/?ref=blog.injective.com\">counter website example<\/a>. A high level guide on developing the front end using Vue and the Injective TypeScript SDK can be found in <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/injective-simple-sc-counter-ui\/tree\/master\/nuxt?ref=blog.injective.com\">injective-simple-sc-counter\/nuxt<\/a>. For a React implementation, see <a rel=\"nofollow\" href=\"https:\/\/github.com\/InjectiveLabs\/injective-simple-sc-counter-ui\/tree\/master\/next?ref=blog.injective.com\">injective-simple-sc-counter-ui\/next<\/a>.<\/p>\n<p>Now, interacting with the contract is as simple as clicking a button and signing with a wallet such as MetaMask (ensure the account is set to Ethereum Goerli Testnet to avoid a chain ID mismatch error).<\/p>\n<p>And just like that, you have built your first dApp on Injective!<\/p>\n<h3>About Injective<\/h3>\n<p>Injective is a lightning fast interoperable layer one blockchain optimized for building the premier Web3 finance applications. Injective provides developers with powerful plug-and-play modules for creating unmatched dApps. INJ is the native asset that powers Injective and its rapidly growing ecosystem. Injective is incubated by Binance and is backed by prominent investors such as Jump Crypto, Pantera and Mark Cuban.<\/p>\n<p><a rel=\"nofollow\" href=\"https:\/\/injective.com\/?ref=blog.injective.com\">Website<\/a> | <a rel=\"nofollow\" href=\"https:\/\/t.me\/joininjective?ref=blog.injective.com\">Telegram<\/a> | <a rel=\"nofollow\" href=\"https:\/\/discord.gg\/injective?ref=blog.injective.com\">Discord<\/a> | <a rel=\"nofollow\" href=\"https:\/\/blog.injectiveprotocol.com\/?ref=blog.injective.com\">Blog<\/a> | <a rel=\"nofollow\" href=\"https:\/\/www.twitter.com\/@InjectiveLabs?ref=blog.injective.com\">Twitter<\/a> | <a rel=\"nofollow\" href=\"https:\/\/blog.injective.com\/learn\/\">Learn<\/a> | <a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/channel\/UCN99m0dicoMjNmJV9mxioqQ?ref=blog.injective.com\">Youtube<\/a> | <a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/injectiveprotocol\">Facebook<\/a> | <a rel=\"nofollow\" href=\"https:\/\/www.linkedin.com\/company\/injective-protocol\/?ref=blog.injective.com\">LinkedIn<\/a> | <a rel=\"nofollow\" href=\"https:\/\/www.reddit.com\/r\/injective\/?ref=blog.injective.com\">Reddit<\/a> | <a rel=\"nofollow\" href=\"https:\/\/www.instagram.com\/injectivelabs\/?ref=blog.injective.com\">Instagram<\/a> | <a rel=\"nofollow\" href=\"http:\/\/eepurl.com\/hcrjwP?ref=blog.injective.com\">Orbit Newsletter<\/a><\/p>\n<p><span><i>Image source: Shutterstock<\/i><\/span>                    <!-- Divider --><\/p>\n<p>                    <!-- Divider --><\/p>\n<p>                    <!-- Author info START --><br \/>\n                    <!-- Author info END --><br \/>\n                    <!-- Divider -->\n                <\/div>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><script async src=\"\/\/www.instagram.com\/embed.js\"><\/script><br \/>\n<br \/>[ad_2]<br \/>\n<br \/><a href=\"https:\/\/blockchain.news\/news\/comprehensive-guide-launching-dapp-injective\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] &#13; &#13; &#13; &#13; &#13; Developers are at the heart of the Injective (INJ)ecosystem. With a diverse range of dApps spanning Web3 finance, Injective<\/p>\n","protected":false},"author":1,"featured_media":236474,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[171],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/236473"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=236473"}],"version-history":[{"count":0,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/236473\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/236474"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=236473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=236473"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=236473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}