anchor/assets/js/17.29eac49f.js

1 line
22 KiB
JavaScript

(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{410:function(t,a,s){"use strict";s.r(a);var e=s(29),n=Object(e.a)({},(function(){var t=this,a=t.$createElement,s=t._self._c||a;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"a-minimal-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#a-minimal-example"}},[t._v("#")]),t._v(" A Minimal Example")]),t._v(" "),s("p",[t._v("Here, we introduce Anchor's core syntax elements and project workflow. This tutorial assumes all\n"),s("RouterLink",{attrs:{to:"/getting-started/installation.html"}},[t._v("prerequisites")]),t._v(" are installed.")],1),t._v(" "),s("h2",{attrs:{id:"clone-the-repo"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#clone-the-repo"}},[t._v("#")]),t._v(" Clone the Repo")]),t._v(" "),s("p",[t._v("To get started, clone the repo.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" clone https://github.com/project-serum/anchor\n")])])]),s("p",[t._v("Next, checkout the tagged branch of the same version of the anchor cli you have installed.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("git")]),t._v(" checkout tags/"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("version"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n")])])]),s("p",[t._v("Change directories to the "),s("a",{attrs:{href:"https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0",target:"_blank",rel:"noopener noreferrer"}},[t._v("example"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("cd")]),t._v(" anchor/examples/tutorial/basic-0\n")])])]),s("p",[t._v("And install any additional JavaScript dependencies:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("yarn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v("\n")])])]),s("h2",{attrs:{id:"starting-a-localnet"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#starting-a-localnet"}},[t._v("#")]),t._v(" Starting a Localnet")]),t._v(" "),s("p",[t._v("In a separate terminal, start a local network. If you're running solana\nfor the first time, generate a wallet.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("solana-keygen new\n")])])]),s("p",[t._v("Then run")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("solana-test-validator\n")])])]),s("p",[t._v("Then, shut it down.")]),t._v(" "),s("p",[t._v("The test validator will be used when testing Anchor programs. Make sure to turn off the validator before you begin testing Anchor programs.")]),t._v(" "),s("details",{staticClass:"custom-block details"},[s("summary",[t._v("DETAILS")]),t._v(" "),s("p",[t._v("As you'll see later, starting a localnet manually like this is not necessary when testing with Anchor,\nbut is done for educational purposes in this tutorial.")])]),t._v(" "),s("h2",{attrs:{id:"defining-a-program"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#defining-a-program"}},[t._v("#")]),t._v(" Defining a Program")]),t._v(" "),s("p",[t._v("We define the minimum viable program as follows.")]),t._v(" "),s("div",{staticClass:"language-rs extra-class"},[s("pre",{pre:!0,attrs:{class:"language-rs"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("anchor_lang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),t._v("prelude"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token macro property"}},[t._v("declare_id!")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token attribute attr-name"}},[t._v("#[program]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("mod")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token module-declaration namespace"}},[t._v("basic_0")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("use")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("::")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("fn")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-definition function"}},[t._v("initialize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ctx"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Context")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Initialize")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("->")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Result")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Ok")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token attribute attr-name"}},[t._v("#[derive(Accounts)]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pub")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token type-definition class-name"}},[t._v("Initialize")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("p",[s("code",[t._v("#[program]")]),t._v(" First, notice that a program is defined with the "),s("code",[t._v("#[program]")]),t._v(' attribute, where each\ninner method defines an RPC request handler, or, in Solana parlance, an "instruction"\nhandler. These handlers are the entrypoints to your program that clients may invoke, as\nwe will see soon.')])]),t._v(" "),s("li",[s("p",[s("code",[t._v("Context<Initialize>")]),t._v(" The first parameter of "),s("em",[t._v("every")]),t._v(" RPC handler is the "),s("code",[t._v("Context")]),t._v(" struct, which is a simple\ncontainer for the currently executing "),s("code",[t._v("program_id")]),t._v(" generic over\n"),s("code",[t._v("Accounts")]),t._v("--here, the "),s("code",[t._v("Initialize")]),t._v(" struct.")])]),t._v(" "),s("li",[s("p",[s("code",[t._v("#[derive(Accounts)]")]),t._v(" The "),s("code",[t._v("Accounts")]),t._v(" derive macro marks a struct containing all the accounts that must be\nspecified for a given instruction. To understand Accounts on Solana, see the\n"),s("a",{attrs:{href:"https://docs.solana.com/developing/programming-model/accounts",target:"_blank",rel:"noopener noreferrer"}},[t._v("docs"),s("OutboundLink")],1),t._v(".\nIn subsequent tutorials, we'll demonstrate how an "),s("code",[t._v("Accounts")]),t._v(" struct can be used to\nspecify constraints on accounts given to your program. Since this example doesn't touch any\naccounts, we skip this (important) detail.")])])]),t._v(" "),s("h2",{attrs:{id:"building-and-emitting-an-idl"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#building-and-emitting-an-idl"}},[t._v("#")]),t._v(" Building and Emitting an IDL")]),t._v(" "),s("p",[t._v("After creating a program, you can use the "),s("code",[t._v("anchor")]),t._v(" CLI to build and emit an IDL, from which clients\ncan be generated.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("anchor build\n")])])]),s("details",{staticClass:"custom-block details"},[s("summary",[t._v("DETAILS")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("build")]),t._v(" command is a convenience combining two steps.")]),t._v(" "),s("ol",[s("li",[s("code",[t._v("cargo build-bpf")])]),t._v(" "),s("li",[s("code",[t._v("anchor idl parse -f program/src/lib.rs -o target/idl/basic_0.json")]),t._v(".")])])]),t._v(" "),s("p",[t._v("Once run, you should see your build artifacts, as usual, in your "),s("code",[t._v("target/")]),t._v(" directory. Additionally,\na "),s("code",[t._v("target/idl/basic_0.json")]),t._v(" file is created. Inspecting its contents you should see")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"version"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"0.1.0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"basic_0"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"instructions"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"initialize"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"accounts"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"args"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("From this file a client can be generated. Note that this file is created by parsing the "),s("code",[t._v("src/lib.rs")]),t._v("\nfile in your program's crate.")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),s("p",[t._v("If you've developed on Ethereum, the IDL is analogous to the "),s("code",[t._v("abi.json")]),t._v(".")])]),t._v(" "),s("h2",{attrs:{id:"deploying"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#deploying"}},[t._v("#")]),t._v(" Deploying")]),t._v(" "),s("p",[t._v("Once built, we can deploy the program by running")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("anchor deploy\n")])])]),s("p",[t._v("Take note of the program's deployed address. We'll use it next.")]),t._v(" "),s("h2",{attrs:{id:"generating-a-client"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generating-a-client"}},[t._v("#")]),t._v(" Generating a Client")]),t._v(" "),s("p",[t._v("Now that we've built a program, deployed it to a local cluster, and generated an IDL,\nwe can use the IDL to generate a client to speak to our on-chain program. For example,\nsee "),s("a",{attrs:{href:"https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0/client.js",target:"_blank",rel:"noopener noreferrer"}},[t._v("client.js"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read the generated IDL.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" idl "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"fs"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("readFileSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./target/idl/basic_0.json"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"utf8"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Address of the deployed program.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" programId "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("anchor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("web3"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("PublicKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"<YOUR-PROGRAM-ID>"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate the program client from IDL.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" program "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("anchor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Program")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("idl"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" programId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Execute the RPC.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" program"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initialize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")])])])]),s("p",[t._v("Notice how we dynamically created the "),s("code",[t._v("initialize")]),t._v(" method under\nthe "),s("code",[t._v("rpc")]),t._v(" namespace.")]),t._v(" "),s("p",[t._v("Now, make sure to plugin your program's address into "),s("code",[t._v("<YOUR-PROGRAM-ID>")]),t._v(" (a mild\nannoyance that we'll address next). In order to run the client, you'll also need the path\nto your wallet's keypair you generated when you ran "),s("code",[t._v("solana-keygen new")]),t._v("; you can find it\nby running")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("solana config get keypair\n")])])]),s("p",[t._v("Once you've got it, run the client with the environment variable "),s("code",[t._v("ANCHOR_WALLET")]),t._v(" set to\nthat path, e.g.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("ANCHOR_WALLET")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("YOUR-KEYPAIR-"),s("span",{pre:!0,attrs:{class:"token environment constant"}},[t._v("PATH")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" node client.js\n")])])]),s("p",[t._v("You just successfully created a client and executed a transaction on your localnet.")]),t._v(" "),s("h2",{attrs:{id:"workspaces"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#workspaces"}},[t._v("#")]),t._v(" Workspaces")]),t._v(" "),s("p",[t._v("So far we've seen the basics of how to create, deploy, and make RPCs to a program, but\ndeploying a program, copy and pasting the address, and explicitly reading\nan IDL is all a bit tedious, and can easily get out of hand the more tests and the more\nprograms you have. For this reason, we introduce the concept of a workspace.")]),t._v(" "),s("p",[t._v("Inspecting "),s("a",{attrs:{href:"https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0/tests/basic-0.js",target:"_blank",rel:"noopener noreferrer"}},[t._v("tests/basic-0.js"),s("OutboundLink")],1),t._v(", we see the above example can be reduced to")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Read the deployed program from the workspace.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" program "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" anchor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("workspace"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Basic0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Execute the RPC.")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" program"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("rpc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initialize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")])])])]),s("p",[t._v("The "),s("code",[t._v("workspace")]),t._v(" namespace provides access to all programs in the local project and is\nautomatically updated to reflect the latest deployment, making it easy to change\nyour program, update your JavaScript, and run your tests in a fast feedback loop.")]),t._v(" "),s("div",{staticClass:"custom-block tip"},[s("p",{staticClass:"custom-block-title"},[t._v("NOTE")]),t._v(" "),s("p",[t._v("For now, the workspace feature is only available when running the "),s("code",[t._v("anchor test")]),t._v(" command,\nwhich will automatically "),s("code",[t._v("build")]),t._v(", "),s("code",[t._v("deploy")]),t._v(", and "),s("code",[t._v("test")]),t._v(" all programs against a localnet\nin one command.")])]),t._v(" "),s("p",[t._v("Finally, we can run the test. Don't forget to kill the local validator started earlier.\nWe won't need to start one manually for any future tutorials.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("anchor "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v("test")]),t._v("\n")])])]),s("h2",{attrs:{id:"next-steps"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#next-steps"}},[t._v("#")]),t._v(" Next Steps")]),t._v(" "),s("p",[t._v("We've introduced the basic syntax of writing programs in Anchor along with a productive\nworkflow for building and testing. However, programs aren't all that interesting without\ninteracting with persistent state. We'll cover that next.")])])}),[],!1,null,null,null);a.default=n.exports}}]);