123 lines
29 KiB
HTML
123 lines
29 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en-US">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>A Minimal Example | ⚓ Anchor</title>
|
|
<meta name="generator" content="VuePress 1.8.2">
|
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>⚓ </text></svg>">
|
|
<meta name="description" content="">
|
|
<meta name="theme-color" content="#3eaf7c">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
<link rel="preload" href="/anchor/assets/css/0.styles.21b321ec.css" as="style"><link rel="preload" href="/anchor/assets/js/app.130b905b.js" as="script"><link rel="preload" href="/anchor/assets/js/2.90291299.js" as="script"><link rel="preload" href="/anchor/assets/js/17.29eac49f.js" as="script"><link rel="prefetch" href="/anchor/assets/js/10.a81a7d6e.js"><link rel="prefetch" href="/anchor/assets/js/11.e20cdb5e.js"><link rel="prefetch" href="/anchor/assets/js/12.d30544e0.js"><link rel="prefetch" href="/anchor/assets/js/13.41fde578.js"><link rel="prefetch" href="/anchor/assets/js/14.8bf73db0.js"><link rel="prefetch" href="/anchor/assets/js/15.25c2e2bd.js"><link rel="prefetch" href="/anchor/assets/js/16.b6cb9e25.js"><link rel="prefetch" href="/anchor/assets/js/18.db5dc2ee.js"><link rel="prefetch" href="/anchor/assets/js/19.54c54ce4.js"><link rel="prefetch" href="/anchor/assets/js/20.873107aa.js"><link rel="prefetch" href="/anchor/assets/js/21.46f202de.js"><link rel="prefetch" href="/anchor/assets/js/3.397fd877.js"><link rel="prefetch" href="/anchor/assets/js/4.f90252b7.js"><link rel="prefetch" href="/anchor/assets/js/5.47891694.js"><link rel="prefetch" href="/anchor/assets/js/6.493f79e9.js"><link rel="prefetch" href="/anchor/assets/js/7.32936426.js"><link rel="prefetch" href="/anchor/assets/js/8.9fc829e7.js"><link rel="prefetch" href="/anchor/assets/js/9.525a5964.js">
|
|
<link rel="stylesheet" href="/anchor/assets/css/0.styles.21b321ec.css">
|
|
</head>
|
|
<body>
|
|
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/anchor/" class="home-link router-link-active"><!----> <span class="site-name">⚓ Anchor</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="https://book.anchor-lang.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
The Anchor Book
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://docs.rs/anchor-lang/latest/anchor_lang/" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Rust
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://project-serum.github.io/anchor/ts/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
TypeScript
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://github.com/project-serum/anchor" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
GitHub
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="https://book.anchor-lang.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
The Anchor Book
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://docs.rs/anchor-lang/latest/anchor_lang/" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
Rust
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://project-serum.github.io/anchor/ts/index.html" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
TypeScript
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://github.com/project-serum/anchor" target="_blank" rel="noopener noreferrer" class="nav-link external">
|
|
GitHub
|
|
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Getting Started</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/anchor/getting-started/introduction.html" class="sidebar-link">Introduction</a></li><li><a href="/anchor/getting-started/installation.html" class="sidebar-link">Installing Dependencies</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Teams</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/anchor/getting-started/projects.html" class="sidebar-link">Projects</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Tutorials</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/anchor/tutorials/tutorial-0.html" aria-current="page" class="active sidebar-link">A Minimal Example</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#clone-the-repo" class="sidebar-link">Clone the Repo</a></li><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#starting-a-localnet" class="sidebar-link">Starting a Localnet</a></li><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#defining-a-program" class="sidebar-link">Defining a Program</a></li><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#building-and-emitting-an-idl" class="sidebar-link">Building and Emitting an IDL</a></li><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#deploying" class="sidebar-link">Deploying</a></li><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#generating-a-client" class="sidebar-link">Generating a Client</a></li><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#workspaces" class="sidebar-link">Workspaces</a></li><li class="sidebar-sub-header"><a href="/anchor/tutorials/tutorial-0.html#next-steps" class="sidebar-link">Next Steps</a></li></ul></li><li><a href="/anchor/tutorials/tutorial-1.html" class="sidebar-link">Arguments and Accounts</a></li><li><a href="/anchor/tutorials/tutorial-2.html" class="sidebar-link">Account Constraints and Access Control</a></li><li><a href="/anchor/tutorials/tutorial-3.html" class="sidebar-link">Cross Program Invocations (CPI)</a></li><li><a href="/anchor/tutorials/tutorial-4.html" class="sidebar-link">Errors</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>CLI</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/anchor/cli/commands.html" class="sidebar-link">Commands</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Source Verification</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/anchor/getting-started/verification.html" class="sidebar-link">Verifiable Builds</a></li><li><a href="/anchor/getting-started/publishing.html" class="sidebar-link">Publishing Source</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="a-minimal-example"><a href="#a-minimal-example" class="header-anchor">#</a> A Minimal Example</h1> <p>Here, we introduce Anchor's core syntax elements and project workflow. This tutorial assumes all
|
|
<a href="/anchor/getting-started/installation.html">prerequisites</a> are installed.</p> <h2 id="clone-the-repo"><a href="#clone-the-repo" class="header-anchor">#</a> Clone the Repo</h2> <p>To get started, clone the repo.</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">git</span> clone https://github.com/project-serum/anchor
|
|
</code></pre></div><p>Next, checkout the tagged branch of the same version of the anchor cli you have installed.</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">git</span> checkout tags/<span class="token operator"><</span>version<span class="token operator">></span>
|
|
</code></pre></div><p>Change directories to the <a href="https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0" target="_blank" rel="noopener noreferrer">example<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token builtin class-name">cd</span> anchor/examples/tutorial/basic-0
|
|
</code></pre></div><p>And install any additional JavaScript dependencies:</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">yarn</span> <span class="token function">install</span>
|
|
</code></pre></div><h2 id="starting-a-localnet"><a href="#starting-a-localnet" class="header-anchor">#</a> Starting a Localnet</h2> <p>In a separate terminal, start a local network. If you're running solana
|
|
for the first time, generate a wallet.</p> <div class="language- extra-class"><pre class="language-text"><code>solana-keygen new
|
|
</code></pre></div><p>Then run</p> <div class="language- extra-class"><pre class="language-text"><code>solana-test-validator
|
|
</code></pre></div><p>Then, shut it down.</p> <p>The test validator will be used when testing Anchor programs. Make sure to turn off the validator before you begin testing Anchor programs.</p> <details class="custom-block details"><summary>DETAILS</summary> <p>As you'll see later, starting a localnet manually like this is not necessary when testing with Anchor,
|
|
but is done for educational purposes in this tutorial.</p></details> <h2 id="defining-a-program"><a href="#defining-a-program" class="header-anchor">#</a> Defining a Program</h2> <p>We define the minimum viable program as follows.</p> <div class="language-rs extra-class"><pre class="language-rs"><code><span class="token keyword">use</span> <span class="token namespace">anchor_lang<span class="token punctuation">::</span>prelude<span class="token punctuation">::</span></span><span class="token operator">*</span><span class="token punctuation">;</span>
|
|
<span class="token macro property">declare_id!</span><span class="token punctuation">(</span><span class="token string">"Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token attribute attr-name">#[program]</span>
|
|
<span class="token keyword">mod</span> <span class="token module-declaration namespace">basic_0</span> <span class="token punctuation">{</span>
|
|
<span class="token keyword">use</span> <span class="token keyword">super</span><span class="token punctuation">::</span><span class="token operator">*</span><span class="token punctuation">;</span>
|
|
<span class="token keyword">pub</span> <span class="token keyword">fn</span> <span class="token function-definition function">initialize</span><span class="token punctuation">(</span>_ctx<span class="token punctuation">:</span> <span class="token class-name">Context</span><span class="token operator"><</span><span class="token class-name">Initialize</span><span class="token operator">></span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token class-name">Result</span><span class="token operator"><</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">></span> <span class="token punctuation">{</span>
|
|
<span class="token class-name">Ok</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token attribute attr-name">#[derive(Accounts)]</span>
|
|
<span class="token keyword">pub</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Initialize</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
|
|
</code></pre></div><ul><li><p><code>#[program]</code> First, notice that a program is defined with the <code>#[program]</code> attribute, where each
|
|
inner method defines an RPC request handler, or, in Solana parlance, an "instruction"
|
|
handler. These handlers are the entrypoints to your program that clients may invoke, as
|
|
we will see soon.</p></li> <li><p><code>Context<Initialize></code> The first parameter of <em>every</em> RPC handler is the <code>Context</code> struct, which is a simple
|
|
container for the currently executing <code>program_id</code> generic over
|
|
<code>Accounts</code>--here, the <code>Initialize</code> struct.</p></li> <li><p><code>#[derive(Accounts)]</code> The <code>Accounts</code> derive macro marks a struct containing all the accounts that must be
|
|
specified for a given instruction. To understand Accounts on Solana, see the
|
|
<a href="https://docs.solana.com/developing/programming-model/accounts" target="_blank" rel="noopener noreferrer">docs<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.
|
|
In subsequent tutorials, we'll demonstrate how an <code>Accounts</code> struct can be used to
|
|
specify constraints on accounts given to your program. Since this example doesn't touch any
|
|
accounts, we skip this (important) detail.</p></li></ul> <h2 id="building-and-emitting-an-idl"><a href="#building-and-emitting-an-idl" class="header-anchor">#</a> Building and Emitting an IDL</h2> <p>After creating a program, you can use the <code>anchor</code> CLI to build and emit an IDL, from which clients
|
|
can be generated.</p> <div class="language-bash extra-class"><pre class="language-bash"><code>anchor build
|
|
</code></pre></div><details class="custom-block details"><summary>DETAILS</summary> <p>The <code>build</code> command is a convenience combining two steps.</p> <ol><li><code>cargo build-bpf</code></li> <li><code>anchor idl parse -f program/src/lib.rs -o target/idl/basic_0.json</code>.</li></ol></details> <p>Once run, you should see your build artifacts, as usual, in your <code>target/</code> directory. Additionally,
|
|
a <code>target/idl/basic_0.json</code> file is created. Inspecting its contents you should see</p> <div class="language-json extra-class"><pre class="language-json"><code><span class="token punctuation">{</span>
|
|
<span class="token property">"version"</span><span class="token operator">:</span> <span class="token string">"0.1.0"</span><span class="token punctuation">,</span>
|
|
<span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"basic_0"</span><span class="token punctuation">,</span>
|
|
<span class="token property">"instructions"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
|
|
<span class="token punctuation">{</span>
|
|
<span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"initialize"</span><span class="token punctuation">,</span>
|
|
<span class="token property">"accounts"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
|
|
<span class="token property">"args"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">]</span>
|
|
<span class="token punctuation">}</span>
|
|
</code></pre></div><p>From this file a client can be generated. Note that this file is created by parsing the <code>src/lib.rs</code>
|
|
file in your program's crate.</p> <div class="custom-block tip"><p class="custom-block-title">TIP</p> <p>If you've developed on Ethereum, the IDL is analogous to the <code>abi.json</code>.</p></div> <h2 id="deploying"><a href="#deploying" class="header-anchor">#</a> Deploying</h2> <p>Once built, we can deploy the program by running</p> <div class="language-bash extra-class"><pre class="language-bash"><code>anchor deploy
|
|
</code></pre></div><p>Take note of the program's deployed address. We'll use it next.</p> <h2 id="generating-a-client"><a href="#generating-a-client" class="header-anchor">#</a> Generating a Client</h2> <p>Now that we've built a program, deployed it to a local cluster, and generated an IDL,
|
|
we can use the IDL to generate a client to speak to our on-chain program. For example,
|
|
see <a href="https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0/client.js" target="_blank" rel="noopener noreferrer">client.js<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Read the generated IDL.</span>
|
|
<span class="token keyword">const</span> idl <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>
|
|
<span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"fs"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span><span class="token string">"./target/idl/basic_0.json"</span><span class="token punctuation">,</span> <span class="token string">"utf8"</span><span class="token punctuation">)</span>
|
|
<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token comment">// Address of the deployed program.</span>
|
|
<span class="token keyword">const</span> programId <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">anchor<span class="token punctuation">.</span>web3<span class="token punctuation">.</span>PublicKey</span><span class="token punctuation">(</span><span class="token string">"<YOUR-PROGRAM-ID>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token comment">// Generate the program client from IDL.</span>
|
|
<span class="token keyword">const</span> program <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">anchor<span class="token punctuation">.</span>Program</span><span class="token punctuation">(</span>idl<span class="token punctuation">,</span> programId<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
<span class="token comment">// Execute the RPC.</span>
|
|
<span class="token keyword">await</span> program<span class="token punctuation">.</span>rpc<span class="token punctuation">.</span><span class="token function">initialize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div><p>Notice how we dynamically created the <code>initialize</code> method under
|
|
the <code>rpc</code> namespace.</p> <p>Now, make sure to plugin your program's address into <code><YOUR-PROGRAM-ID></code> (a mild
|
|
annoyance that we'll address next). In order to run the client, you'll also need the path
|
|
to your wallet's keypair you generated when you ran <code>solana-keygen new</code>; you can find it
|
|
by running</p> <div class="language-bash extra-class"><pre class="language-bash"><code>solana config get keypair
|
|
</code></pre></div><p>Once you've got it, run the client with the environment variable <code>ANCHOR_WALLET</code> set to
|
|
that path, e.g.</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token assign-left variable">ANCHOR_WALLET</span><span class="token operator">=</span><span class="token operator"><</span>YOUR-KEYPAIR-<span class="token environment constant">PATH</span><span class="token operator">></span> node client.js
|
|
</code></pre></div><p>You just successfully created a client and executed a transaction on your localnet.</p> <h2 id="workspaces"><a href="#workspaces" class="header-anchor">#</a> Workspaces</h2> <p>So far we've seen the basics of how to create, deploy, and make RPCs to a program, but
|
|
deploying a program, copy and pasting the address, and explicitly reading
|
|
an IDL is all a bit tedious, and can easily get out of hand the more tests and the more
|
|
programs you have. For this reason, we introduce the concept of a workspace.</p> <p>Inspecting <a href="https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0/tests/basic-0.js" target="_blank" rel="noopener noreferrer">tests/basic-0.js<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, we see the above example can be reduced to</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Read the deployed program from the workspace.</span>
|
|
<span class="token keyword">const</span> program <span class="token operator">=</span> anchor<span class="token punctuation">.</span>workspace<span class="token punctuation">.</span>Basic0<span class="token punctuation">;</span>
|
|
<span class="token comment">// Execute the RPC.</span>
|
|
<span class="token keyword">await</span> program<span class="token punctuation">.</span>rpc<span class="token punctuation">.</span><span class="token function">initialize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div><p>The <code>workspace</code> namespace provides access to all programs in the local project and is
|
|
automatically updated to reflect the latest deployment, making it easy to change
|
|
your program, update your JavaScript, and run your tests in a fast feedback loop.</p> <div class="custom-block tip"><p class="custom-block-title">NOTE</p> <p>For now, the workspace feature is only available when running the <code>anchor test</code> command,
|
|
which will automatically <code>build</code>, <code>deploy</code>, and <code>test</code> all programs against a localnet
|
|
in one command.</p></div> <p>Finally, we can run the test. Don't forget to kill the local validator started earlier.
|
|
We won't need to start one manually for any future tutorials.</p> <div class="language-bash extra-class"><pre class="language-bash"><code>anchor <span class="token builtin class-name">test</span>
|
|
</code></pre></div><h2 id="next-steps"><a href="#next-steps" class="header-anchor">#</a> Next Steps</h2> <p>We've introduced the basic syntax of writing programs in Anchor along with a productive
|
|
workflow for building and testing. However, programs aren't all that interesting without
|
|
interacting with persistent state. We'll cover that next.</p></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
|
|
←
|
|
<a href="/anchor/getting-started/projects.html" class="prev">
|
|
Projects
|
|
</a></span> <span class="next"><a href="/anchor/tutorials/tutorial-1.html">
|
|
Arguments and Accounts
|
|
</a>
|
|
→
|
|
</span></p></div> </main></div><div class="global-ui"></div></div>
|
|
<script src="/anchor/assets/js/app.130b905b.js" defer></script><script src="/anchor/assets/js/2.90291299.js" defer></script><script src="/anchor/assets/js/17.29eac49f.js" defer></script>
|
|
</body>
|
|
</html>
|