Как синхронизироваться с блокчейном биткойна через bitcoinJ

Я пишу свое самое первое приложение, используя биткойн J API, и я немного застрял. Может быть, кто-нибудь может сказать мне, что мне не хватает.

Мое практическое приложение хочет написать образец контракта в блокчейне биткойнов, но, похоже, когда я пытаюсь это сделать. Я получаю сообщение от bitcoinJ, в котором говорится:

java.lang.IllegalStateException: невозможно вызвать до завершения запуска

Я думаю, мне нужно как-то дождаться синхронизации блокчейна, чтобы я мог отправлять туда что-то, верно?

Вот как выглядит мой java-код:

import org.bitcoinj.core.*;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.RegTestParams;
import org.bitcoinj.script.ScriptBuilder;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class SimpleExample {

    private WalletAppKit bitcoin;
    public  NetworkParameters params = RegTestParams.get();

    public SimpleExample() {
        bitcoin = new WalletAppKit(params, new File("."), "testfile" + "-" + params.getPaymentProtocolId()) {
            @Override
            protected void onSetupCompleted() {
                // Don't make the user wait for confirmations for now, as the intention is they're sending it
                // their own money!
                bitcoin.wallet().allowSpendingUnconfirmedTransactions();
            }

        };
    }

    public void timestamp(File doc) throws IOException, InsufficientMoneyException {
        // Hash it
        Sha256Hash hash = Sha256Hash.of(doc);

        // Create a tx with an OP_RETURN output
        Transaction tx = new Transaction(params);
        tx.addOutput(Coin.ZERO, ScriptBuilder.createOpReturnScript(hash.getBytes()));

        //Check if the Blockchain is synchronized before you do anything!!!!!!

        // Send it to the Bitcoin network
        bitcoin.wallet().sendCoins(Wallet.SendRequest.forTx(tx));

        // Transaction proof
        Proof proof = new Proof();
        proof.setTx(tx.bitcoinSerialize());
        proof.setFilename(doc.getName());

        // Grab the merkle branch when it appears in the block chain
        bitcoin.peerGroup().addEventListener(new AbstractPeerEventListener() {
            @Override
            public void onBlocksDownloaded(Peer peer, Block block, FilteredBlock filteredBlock, int blocksLeft) {
                List<Sha256Hash> hashes = new ArrayList<>();
                PartialMerkleTree tree = filteredBlock.getPartialMerkleTree();
                tree.getTxnHashAndMerkleRoot(hashes);
                if (hashes.contains(tx.getHash())) {
                    proof.setPartialMerkleTree(tree.bitcoinSerialize());
                    proof.setBlockHash(filteredBlock.getHash());
                }
            }
        });

        // Wait for confirmations (3)
        tx.getConfidence().addEventListener((confidence, reason) -> {
            if (confidence.getConfidenceType() != TransactionConfidence.ConfidenceType.BUILDING)
                return;
            proof.depth.set(confidence.getDepthInBlocks());
            if (proof.depth.get() == 3) {
                // Save the proof to disk
                String filename = doc.toString() + ".timestamp";
                try {
                    proof.saveTo(filename);
                    System.out.println("Proof complete - Saved to " + filename);
                } catch (IOException e) {
                    System.err.println(e);
                }
            }
        });
    }
}

Ответы (1)

Итак, я думаю, что нашел решение своего вопроса, немного осмотревшись.

Я изменил конструктор, чтобы явно установить адреса одноранговых узлов, например:

public SimpleExample() throws UnknownHostException {

        walletAppKit = new WalletAppKit(NETWORK_PARAMETERS,DIRECTORY, "test");
        walletAppKit
                .setAutoSave(true)
                .setBlockingStartup(false)
                .setPeerNodes(//Seed nodes for the test network
//                        new PeerAddress(InetAddress.getByName("seed.bitcoin.sipa.be"), 18333),
                        new PeerAddress(InetAddress.getByName("testnet-seed.bitcoin.petertodd.org"), 18333),
                        new PeerAddress(InetAddress.getByName("node3.mycelium.com"), 18333),
                        new PeerAddress(InetAddress.getLocalHost(), 18333));
    }

Еще одна вещь, которую я сделал, это вызвать 2 метода в WalletAppKit, чтобы начать синхронизацию:

walletAppKit.startAsync();
walletAppKit.awaitRunning();