neow3j - Java SDK Quickstart

네오 블록체인·2025년 10월 10일

Neo N3

목록 보기
5/8

1. 소개

Neow3j는 Java 플랫폼(Java, Kotlin, Android)을 사용하여 Neo dApp과 스마트 컨트랙트를 구축하기 위한 쉽고 신뢰할 수 있는 도구를 제공하는 개발 툴킷입니다. neow3j와 기술 문서에 대한 더 자세한 정보는 neow3j.io를 확인해주세요.

2. 설정

요구사항

Java

Java에서 DApp 개발을 위해서는 최소 버전 8 이상의 Java SDK가 필요합니다. Java OpenJDK 다운로드는 Adoptium에서 확인하세요.

Neo-Express

Neo-Express는 개발 목적으로 로컬 프라이빗 블록체인을 설정하기 위한 도구입니다. neow3j SDK를 사용하여 Neo 블록체인과 상호작용하는 방법을 배우는 데 사용할 것입니다. 이 도구는 시스템에 .NET Core가 설치되어 있어야 합니다. 설정을 위해 여기의 Neo-Express 설치 섹션을 따라해주세요.

개발 환경

neow3j로 dApp을 개발할 때는 어떤 에디터를 사용해도 되지만, IntelliJ IDEAVisual Studio Code 사용을 권장합니다. IntelliJ는 최고의 Java/Kotlin 개발자 경험을 제공하고, VS Code는 Neo 개발을 위한 강력한 확장 기능을 제공합니다.

VS Code를 사용한다면 Neo Blockchain Toolkit 확장을 설치해야 합니다. 이 확장은 프라이빗 블록체인의 쉬운 설정, 주소에 빠르게 자금을 조달하는 기능, 에디터 내 블록 탐색기 등을 지원합니다. VS Code에서 최적의 Java 지원을 위해서는 Java Extension Pack 사용을 권장합니다.

코드

dApp 프로젝트를 빠르게 설정하려면 SDK 보일러플레이트 템플릿 저장소를 사용할 수 있습니다. 이 프로젝트는 두 가지 간단한 예제를 포함하고 있습니다. 먼저 트랜잭션을 구축, 서명 및 전송하는 방법을 배우고, 그 다음 Neo N3 블록체인에서 새로운 블록을 구독하는 방법을 보여드리겠습니다.

GitHub에서 Use this template을 클릭하여 자신만의 저장소를 만들거나, 다음 명령어로 클론할 수 있습니다:

git clone https://github.com/neow3j/neow3j-boilerplate-sdk.git
cd neow3j-boilerplate-sdk && git checkout -b devportal-quickstart-tutorial

NOTE
이 튜토리얼은 devportal-quickstart-tutorial 브랜치를 기반으로 하며, main 브랜치와 같은 커밋이 아닐 수 있습니다.

3. 트랜잭션 구축, 서명 및 전송

다음 예제 코드에서는 10 NEO를 전송하는 트랜잭션이 구축, 서명 및 전송됩니다. 그런 다음 트랜잭션이 성공적으로 실행되고 블록체인에 저장될 때 그 상태가 출력됩니다.

package com.axlabs.boilerplate;

import io.neow3j.contract.GasToken;
import io.neow3j.crypto.WIF;
import io.neow3j.protocol.Neow3j;
import io.neow3j.protocol.core.response.NeoApplicationLog;
import io.neow3j.protocol.core.response.NeoSendRawTransaction;
import io.neow3j.protocol.http.HttpService;
import io.neow3j.transaction.AccountSigner;
import io.neow3j.transaction.Transaction;
import io.neow3j.transaction.TransactionBuilder;
import io.neow3j.types.Hash160;
import io.neow3j.types.Hash256;
import io.neow3j.utils.Await;
import io.neow3j.utils.Numeric;
import io.neow3j.wallet.Account;

import java.math.BigDecimal;
import java.math.BigInteger;

public class BuildAndSendTransaction {

    public static void main(String[] args) throws Throwable {

        // Initialize Neow3j to connect to a testnet Neo node.
        Neow3j neow3j = Neow3j.build(new HttpService("http://seed2t5.neo.org:20332"));

        // Initialize GasToken.
        GasToken gasToken = new GasToken(neow3j);

        // Define sender and recipient of transfer.
        Hash160 recipient = new Hash160("b897160506030c5d06dc087a21544b4853768012");
        String aliceWif = WIF.getWIFFromPrivateKey(
                Numeric.hexStringToByteArray("6c54536dbd876b92bfc96dd7b9fd6a4286d9a51ac5e26b5cf9becfa27e330918"));
        Account alice = Account.fromWIF(aliceWif);

        // Start building a transfer transaction of GAS. Note that the GasToken has 8 decimals and you need to provide
        // the transfer amount in fractions. The following 1 GAS equals 1_00000000 GAS fractions.
        BigInteger amount = gasToken.toFractions(new BigDecimal("1"));
        TransactionBuilder b = gasToken.transfer(alice, recipient, amount);

        // Set the signers, sign the transaction and get the signed transaction ready to be sent.
        Transaction tx = b.signers(AccountSigner.calledByEntry(alice))
                .sign();

        // Send the transaction.
        NeoSendRawTransaction response = tx.send();

        // Make sure the node returns no error and then get the transaction hash and wait for execution.
        if (response.hasError()) {
            System.out.printf("Transaction was not successful. Error message from Neo node was: '%s'\n",
                    response.getError().getMessage());
        } else {
            // Get the transaction hash and wait for the transaction to be persisted.
            Hash256 txHash = response.getSendRawTransaction().getHash();
            Await.waitUntilTransactionIsExecuted(txHash, neow3j);

            // Get the transaction's application log and print it.
            NeoApplicationLog applicationLog = neow3j.getApplicationLog(txHash).send().getApplicationLog();
            System.out.println(applicationLog);
        }
    }

}

임포트

임포트는 예제 컨트랙트에서 사용되는 neow3j SDK 클래스들을 보여줍니다. 지원되는 클래스와 메서드의 전체 개요는 neow3j의 javadoc 여기여기에서 확인할 수 있습니다.

package com.axlabs.boilerplate;

import io.neow3j.contract.GasToken;
import io.neow3j.crypto.WIF;
import io.neow3j.protocol.Neow3j;
import io.neow3j.protocol.core.response.NeoApplicationLog;
import io.neow3j.protocol.core.response.NeoSendRawTransaction;
import io.neow3j.protocol.http.HttpService;
import io.neow3j.transaction.AccountSigner;
import io.neow3j.transaction.Transaction;
import io.neow3j.transaction.TransactionBuilder;
import io.neow3j.types.Hash160;
import io.neow3j.types.Hash256;
import io.neow3j.utils.Await;
import io.neow3j.utils.Numeric;
import io.neow3j.wallet.Account;

import java.math.BigDecimal;
import java.math.BigInteger;

Neo N3 네트워크에 연결

Neow3j 클래스는 Neo N3 블록체인에 대한 연결을 설정합니다. 예제 코드의 엔드포인트는 테스트넷 노드를 가리킵니다. 로컬 Neo N3 네트워크를 실행하고 neow3j를 통해 상호작용하려면 이 엔드포인트를 그에 맞게 변경해야 합니다.

Neow3j neow3j = Neow3j.build(new HttpService("http://seed2t5.neo.org:20332"));

GasToken 초기화

예제 코드에서는 1 GAS가 전송됩니다. GAS 토큰은 네이티브 스마트 컨트랙트 GasToken에서 관리됩니다. Neow3j의 GasToken 클래스는 GasToken 스마트 컨트랙트에서 호출할 수 있는 모든 필요한 메서드를 제공합니다. 이를 통해 블록체인으로 전송할 수 있는 전송 트랜잭션을 구축할 수 있습니다.

GasToken gasToken = new GasToken(neow3j);

이제 alice로부터 스크립트 해시 b897160506030c5d06dc087a21544b4853768012로 1 GAS를 전송하는 트랜잭션을 구축하는 데 필요한 모든 매개변수를 준비합니다.

Hash160 recipient = new Hash160("b897160506030c5d06dc087a21544b4853768012");

// Alice's address = NNSyinBZAr8HMhjj95MfkKD1PY7YWoDweR
String aliceWif = WIF.getWIFFromPrivateKey(
        Numeric.hexStringToByteArray("6c54536dbd876b92bfc96dd7b9fd6a4286d9a51ac5e26b5cf9becfa27e330918"));
Account alice = Account.fromWIF(aliceWif);

전송 스크립트 생성

전송 스크립트를 구축하기 전에 GasToken의 소수점을 고려해야 합니다. GasToken은 8개의 소수점을 가지며, 스크립트에서 전송 금액을 분수로 전달해야 합니다. 즉, 1 GAS를 전송하려면 전송 금액으로 1_00000000을 전달해야 합니다. 이를 더 간단하게 하기 위해 분수를 계산하는 toFractions(BigDecimal) 메서드를 사용할 수 있습니다.

BigInteger amount = gasToken.toFractions(new BigDecimal("1"));

다음 매개변수를 가진 GasTokentransfer() 메서드는 전송 스크립트를 구축하고 TransactionBuilder를 초기화합니다. 트랜잭션을 구축하기 전에 이 TransactionBuilder에서 추가 네트워크 수수료, 서명자 등과 같은 추가 변수를 설정할 수 있습니다.

TransactionBuilder b = gasToken.transfer(alice, recipient, amount);

트랜잭션 구축 및 서명

alice로부터 GAS를 전송하려면 alice가 이 트랜잭션의 증인이 되어야 합니다. alice 계정은 증인 범위 calledByEntry를 가진 서명자로 TransactionBuilder에 설정할 수 있습니다. 그런 다음 TransactionBuilder는 서명할 준비가 됩니다. sign() 메서드가 호출되면 트랜잭션이 구축되고, TransactionBuilder의 서명자에게 전달된 제공된 계정으로 증인이 추가됩니다.

Transaction tx = b.signers(AccountSigner.calledByEntry(alice))
        .sign();

트랜잭션 전송

트랜잭션이 이제 전송할 준비가 되었으며 send() 메서드로 전송할 수 있습니다.

NeoSendRawTransaction response = tx.send();

응답 대기

트랜잭션이 전송되었으므로 이제 노드의 응답에서 오류를 확인할 수 있습니다. 오류가 없다면 트랜잭션 해시를 검색하고 Await.waitUntilTransactionIsExecuted() 메서드가 트랜잭션이 블록체인에 저장될 때까지 기다립니다. 그런 다음 트랜잭션의 애플리케이션 로그를 가져옵니다. 이 로그에는 트랜잭션에 대한 모든 관련 정보(알림, 호출 결과, 상태 등)가 포함되어 있습니다.

if (response.hasError()) {
    System.out.printf("Transaction was not successful. Error message from Neo node was: '%s'\n",
            response.getError().getMessage());
} else {
    Hash256 txHash = response.getSendRawTransaction().getHash();
    Await.waitUntilTransactionIsExecuted(txHash, neow3j);

    NeoApplicationLog applicationLog = neow3j.getApplicationLog(txHash).send().getApplicationLog();
    System.out.println(applicationLog);
}

4. 새로운 블록 추적

다음 예제에서는 Neo N3 네트워크를 구독하여 새로 생성된 블록을 추적합니다.

package com.axlabs.boilerplate;

import io.neow3j.protocol.Neow3j;
import io.neow3j.protocol.http.HttpService;

import java.io.IOException;

public class SubscribeToBlocks {

    public static void main(String[] args) throws IOException {

        // Initialize Neow3j to connect to a testnet Neo node.
        Neow3j neow3j = Neow3j.build(new HttpService("http://seed2t5.neo.org:20332"));

        // Subscribe to new blocks on the testnet.
        neow3j.subscribeToNewBlocksObservable(true)
                .subscribe((blockReqResult) -> {
                    System.out.println("#######################################");
                    System.out.println("Block Index:     " + blockReqResult.getBlock().getIndex());
                    System.out.println("Block Hash:      " + blockReqResult.getBlock().getHash());
                    System.out.println("Prev Block Hash: " + blockReqResult.getBlock().getPrevBlockHash());
                    System.out.println("Next Consensus:  " + blockReqResult.getBlock().getNextConsensus());
                    System.out.println("Transactions:    " + blockReqResult.getBlock().getTransactions());
                });
    }

}

새로운 블록 구독

이전 예제와 마찬가지로 먼저 Neow3j 객체를 초기화하여 블록체인에 대한 연결을 설정해야 합니다.

Neow3j neow3j = Neow3j.build(new HttpService("http://seed2t5.neo.org:20332"));

subscribeToNewBlocksObservable() 메서드는 모든 새로운 블록을 방출하는 관찰 가능한 객체를 생성하고 subscribe() 메서드는 콜백 함수를 제공합니다.

이 예제에서는 새로운 블록이 존재하자마자 새로운 블록의 정보, 즉 인덱스, 해시, 이전 블록 해시, 다음 합의 노드 및 해당 블록에 포함된 모든 트랜잭션 목록을 출력합니다.

neow3j.subscribeToNewBlocksObservable(true)
        .subscribe((blockReqResult) -> {
            System.out.println("#######################################");
            System.out.println("Block Index:     " + blockReqResult.getBlock().getIndex());
            System.out.println("Block Hash:      " + blockReqResult.getBlock().getHash());
            System.out.println("Prev Block Hash: " + blockReqResult.getBlock().getPrevBlockHash());
            System.out.println("Next Consensus:  " + blockReqResult.getBlock().getNextConsensus());
            System.out.println("Transactions:    " + blockReqResult.getBlock().getTransactions());
        });

정보

발생할 수 있는 문제를 자유롭게 보고해주세요. 백로그에 직접 포함하여 도움을 주시려면 여기에서 이슈를 열어주세요.

profile
스마트 이코노미를 위한 퍼블릭 블록체인, 네오에 대한 모든것

0개의 댓글