So synchronisieren Sie mit der Bitcoin-Blockchain über bitcoinJ

Ich schreibe meine allererste Anwendung mit bitcoinJ api und bin etwas hängen geblieben. Vielleicht kann mir jemand sagen, was mir fehlt.

Meine Übungs-App will einen Mustervertrag in der Bitcoin-Blockchain schreiben, aber es kommt mir so vor, als versuche ich es. Ich bekomme eine Nachricht von bitcoinJ, die besagt:

java.lang.IllegalStateException: Kann nicht aufgerufen werden, bis der Start abgeschlossen ist

Ich denke, ich muss irgendwie warten, bis die Blockchain synchronisiert ist, damit ich Sachen an sie senden kann, richtig?

So sieht mein Java-Code aus:

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);
                }
            }
        });
    }
}

Antworten (1)

Ich glaube, ich habe die Lösung für meine eigene Frage gefunden, nachdem ich mich ein wenig umgesehen habe.

Ich habe den Konstruktor geändert, um die Peer-Adressen explizit festzulegen, wie folgt:

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));
    }

Eine andere Sache, die ich getan habe, war, 2 Methoden auf dem WalletAppKit aufzurufen, um die Synchronisierung zu starten:

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