> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Solana 프로그램 처음 배포하기

> Solana 프로그램을 소스에서 라이브 devnet 거래로 가져오고, 모든 자금 조달, 배포, 호출을 Helius RPC를 통해 경로 설정합니다.

export const DevnetFaucet = () => {
  const [apiKey, setApiKey] = useState('');
  const [address, setAddress] = useState('');
  const [loading, setLoading] = useState(false);
  const [result, setResult] = useState(null);
  const [error, setError] = useState(null);
  const handleAirdrop = async e => {
    e.preventDefault();
    setLoading(true);
    setError(null);
    setResult(null);
    try {
      const res = await fetch(`https://devnet.helius-rpc.com/?api-key=${apiKey}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          jsonrpc: '2.0',
          id: 'faucet',
          method: 'requestAirdrop',
          params: [address, 1000000000]
        })
      });
      const json = await res.json();
      if (json.error) throw new Error(json.error.message || 'Airdrop failed');
      setResult(json.result);
    } catch (err) {
      setError(err.message || 'Airdrop failed. The devnet faucet is rate-limited, try again shortly.');
    } finally {
      setLoading(false);
    }
  };
  const btnClass = loading ? 'px-4 py-2 font-medium rounded-full bg-gray-300 dark:bg-gray-700 cursor-not-allowed' : 'px-4 py-2 font-medium rounded-full bg-primary hover:bg-primary/80 text-white';
  return <div className="p-4 border dark:border-zinc-950/80 rounded-xl bg-white dark:bg-zinc-950/80 shadow-sm">
      <form onSubmit={handleAirdrop} className="space-y-4">
        <div>
          <label className="block text-sm text-zinc-950/70 dark:text-white/70 mb-1">Your API Key</label>
          <input type="text" value={apiKey} onChange={e => setApiKey(e.target.value)} placeholder="Enter your API key" className="w-full p-2 border rounded dark:bg-zinc-900 dark:border-zinc-700" required />
        </div>
        <div>
          <label className="block text-sm text-zinc-950/70 dark:text-white/70 mb-1">Devnet Wallet Address</label>
          <input type="text" value={address} onChange={e => setAddress(e.target.value)} placeholder="Your devnet address" className="w-full p-2 border rounded dark:bg-zinc-900 dark:border-zinc-700" required />
        </div>
        <button type="submit" disabled={loading} className={btnClass}>
          {loading ? 'Requesting...' : 'Request 1 Devnet SOL'}
        </button>
      </form>
      <p className="mt-3 text-xs text-zinc-500 dark:text-zinc-400">
        Your API key is used only in your browser to call Helius directly. It is never sent anywhere else.
      </p>
      {error ? <div className="mt-4 p-3 bg-red-100 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded text-red-700 dark:text-red-300">
          <strong>Error:</strong> {error}
        </div> : null}
      {result ? <div className="mt-4 p-3 bg-green-100 dark:bg-green-900/30 border border-green-200 dark:border-green-800 rounded text-green-700 dark:text-green-300 text-sm break-all">
          <strong>Airdrop sent!</strong> Signature: {result}
        </div> : null}
    </div>;
};

이 가이드에서는 실제 프로그램을 개발 네트워크에 배포하고 호출하는 방법을 설명합니다. 전체 흐름은 Helius 인프라에서 실행됩니다. 지갑에 [`requestAirdrop`](/docs/ko/api-reference/rpc/http/requestairdrop)로 자금을 조달하고, 미리 작성된 샘플 프로그램을 배포한 다음 [`sendTransaction`](/docs/ko/api-reference/rpc/http/sendtransaction)로 호출하여 [`getSignatureStatuses`](/docs/ko/api-reference/rpc/http/getsignaturestatuses)로 결과를 확인합니다. 준비된 프로그램을 사용하면 Rust 코딩 대신 배포 및 호출 루프에 집중할 수 있습니다.

<Info>
  **필수 조건:** [Solana CLI](https://solana.com/docs/intro/installation) 및 [Rust](https://www.rust-lang.org/tools/install) (프로그램 빌드용), Node.js 18+ (호출용), [Helius API 키](https://dashboard.helius.dev/api-keys)가 필요합니다. Devnet은 모든 Helius 플랜에서 작동합니다.
</Info>

***

<Steps>
  <Step title="Helius devnet RPC로 Solana CLI 지점 설정">
    모든 CLI 명령에 Helius 엔드포인트를 사용하고 아직 지갑이 없다면 지갑을 생성하세요:

    ```bash theme={"system"}
    solana config set --url https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY
    solana-keygen new --no-bip39-passphrase   # skip if you already have a keypair
    solana address
    ```

    `solana address`는 지갑의 공개 키를 출력하며, 다음에 자금을 조달할 것입니다.
  </Step>

  <Step title="Devnet SOL 받기">
    배포에는 약간의 SOL이 필요합니다. Devnet SOL은 무료이며 테스트에만 유효하므로 아래의 수도꼭지나 CLI로 주소에 자금을 추가하세요:

    ```bash theme={"system"}
    solana airdrop 1
    solana balance
    ```

    <DevnetFaucet />

    <Note>
      Devnet 수도꼭지는 속도 제한이 있습니다. 에어드롭이 실패할 경우 잠시 기다렸다가 다시 시도하거나 Solana의 공식 [devnet 웹 수도꼭지](https://faucet.solana.com/)를 대체 방법으로 사용할 수 있습니다. 샘플 프로그램 배포에는 약 1 SOL만 필요합니다.
    </Note>
  </Step>

  <Step title="샘플 프로그램 클론 및 빌드">
    Solana의 공식 [program-examples](https://github.com/solana-developers/program-examples) 저장소에서 "Hello, Solana!" 프로그램을 가져옵니다. 호출하면 인사를 기록하며, 이는 전체 루프가 작동한다는 것을 입증하는 최소한의 프로그램입니다.

    ```bash theme={"system"}
    git clone https://github.com/solana-developers/program-examples.git
    cd program-examples
    cargo build-sbf --manifest-path basics/hello-solana/native/program/Cargo.toml
    ```

    `program-examples`는 Cargo 워크스페이스이므로 `cargo build-sbf`는 프로그램을 저장소 루트(프로그램 폴더 내가 아님)에서 `target/deploy/hello_solana_program.so`로 컴파일합니다. 다음 단계를 위해 `program-examples` 디렉토리에 머무르십시오.
  </Step>

  <Step title="Helius를 통해 개발 네트워크에 배포하기">
    ```bash theme={"system"}
    solana program deploy target/deploy/hello_solana_program.so
    ```

    CLI는 배포 트랜잭션을 Helius RPC를 통해 제출하고 **프로그램 ID**를 출력합니다. 다음에 이 프로그램을 호출할 것이므로 복사해 둡니다.

    ```
    Program Id: 4Nd1mYQ...your program id...
    ```
  </Step>

  <Step title="sendTransaction으로 프로그램 호출">
    새 폴더에서 트랜잭션을 빌드하고 전송하고 확인하는 작은 TypeScript 클라이언트를 설정합니다.

    ```bash theme={"system"}
    mkdir invoke-client && cd invoke-client
    npm init -y
    npm install @solana/web3.js
    ```

    ```typescript invoke.ts [expandable] theme={"system"}
    import {
      Connection,
      Keypair,
      PublicKey,
      Transaction,
      TransactionInstruction,
    } from "@solana/web3.js";
    import { readFileSync } from "fs";
    import { homedir } from "os";

    const RPC = "https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY";
    const PROGRAM_ID = new PublicKey("YOUR_PROGRAM_ID"); // from the deploy step

    async function main() {
      const connection = new Connection(RPC, "confirmed");

      // Load the same keypair the CLI created and funded.
      const secret = JSON.parse(
        readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")
      );
      const payer = Keypair.fromSecretKey(Uint8Array.from(secret));

      // The hello-solana program takes no accounts and no data. It just logs.
      const instruction = new TransactionInstruction({
        keys: [],
        programId: PROGRAM_ID,
        data: Buffer.alloc(0),
      });

      const tx = new Transaction().add(instruction);
      const { blockhash } = await connection.getLatestBlockhash();
      tx.recentBlockhash = blockhash;
      tx.feePayer = payer.publicKey;
      tx.sign(payer);

      // sendTransaction submits the signed transaction to the cluster via Helius.
      const signature = await connection.sendRawTransaction(tx.serialize());
      console.log("Sent:", signature);

      // Poll getSignatureStatuses until the transaction is confirmed.
      for (let i = 0; i < 30; i++) {
        const { value } = await connection.getSignatureStatuses([signature]);
        const status = value[0];
        if (status?.confirmationStatus === "confirmed" || status?.confirmationStatus === "finalized") {
          if (status.err) throw new Error(`Failed: ${JSON.stringify(status.err)}`);
          console.log("Confirmed! View it on Solana Explorer:");
          console.log(`https://explorer.solana.com/tx/${signature}?cluster=devnet`);
          return;
        }
        await new Promise((r) => setTimeout(r, 1000));
      }
      throw new Error("Timed out waiting for confirmation");
    }

    main().catch(console.error);
    ```

    `YOUR_API_KEY` 및 `YOUR_PROGRAM_ID`를 대체한 후 실행하십시오:

    ```bash theme={"system"}
    npx tsx invoke.ts
    ```

    서명이 나오고 탐색기 링크가 제공됩니다. 링크를 열고 **프로그램 명령 로그**를 확장하여 프로그램의 `Hello, Solana!` 인사를 확인하세요.
  </Step>
</Steps>

## 무슨 일이 일어나고 있는가

### 모든 것이 Helius RPC를 통해 라우팅됩니다

`solana config set --url`는 모든 CLI 명령(에어드롭, 배포, 잔액 검사)을 Helius devnet 엔드포인트로 지시합니다. TypeScript 클라이언트도 동일한 엔드포인트를 사용하므로 전체 흐름이 Helius 인프라에서 실행됩니다.

### 호출 루프: 보내고 확인하기

`sendRawTransaction`는 내부적으로 [`sendTransaction`](/docs/ko/api-reference/rpc/http/sendtransaction) RPC 메서드를 호출하고 트랜잭션이 네트워크에서 처리되기 전에 즉시 서명을 반환합니다. 그래서 [`getSignatureStatuses`](/docs/ko/api-reference/rpc/http/getsignaturestatuses)를 반복 폴링하여 `confirmationStatus`가 `confirmed`에 도달할 때까지 확인하고, 실패를 잡기 위하여 `err`를 확인합니다. 이 전송 후 확인 패턴은 모든 Solana 트랜잭션을 제출하는 기초입니다.

## 다음 단계

<CardGroup cols={2}>
  <Card title="Devnet SOL 얻는 방법" icon="faucet-drip" href="/docs/ko/rpc/devnet-sol">
    Devnet 지갑에 자금을 조달하는 모든 방법과 속도 제한 팁.
  </Card>

  <Card title="sendTransaction" icon="paper-plane" href="/docs/ko/api-reference/rpc/http/sendtransaction">
    skipPreflight, preflightCommitment 및 재시도와 같은 모든 매개변수.
  </Card>

  <Card title="거래를 신뢰성 있게 배치" icon="rocket" href="/docs/ko/api-reference/sender/sendtransaction">
    메인넷으로 전환할 때 초저지연 랜딩을 위하여 Sender를 사용하십시오.
  </Card>

  <Card title="포트폴리오 추적기 빌드" icon="wallet" href="/docs/ko/quickstart/portfolio-tracker">
    다른 트랙: 실시간 활동 피드와 함께 지갑의 토큰, NFT 및 SOL을 가져옵니다.
  </Card>
</CardGroup>
