ConsensusJ / consensusj

Bitcoin components for JVM & Android (JSON client & server support, services, DSL, CLI)
Apache License 2.0
83 stars 35 forks source link

examples required #21

Open magg opened 7 years ago

magg commented 7 years ago

Hello

It would be great if you provided examples on how to use the Bitconj json rpc client

thanks!

msgilligan commented 7 years ago

Good point - some examples would be helpful.

In the meantime, Here's a very simple example as a Groovy script:

#!/usr/bin/env groovy
@GrabResolver(name='bitcoinjaddons', root='https://dl.bintray.com/msgilligan/maven')
@Grab('com.msgilligan:bitcoinj-rpcclient:0.2.1')
import com.msgilligan.bitcoinj.rpc.BitcoinClient
import org.bitcoinj.params.MainNetParams

URI server = new URI("http://localhost:8332")
BitcoinClient client = new BitcoinClient(MainNetParams.get(), server, "rpcusername", "rpcpassword")
println client.getBlockCount()

If you have the groovy command installed this script will run as-is (if you edit the URI, RPC username and password)

magg commented 7 years ago

thanks for the script

msgilligan commented 7 years ago

You're welcome. If you modify it and use it for anything interesting that you can share -- let us know!

milansismanovic commented 6 years ago

I have written a little test for BitcoinExtendedClient. I could clean it up. It has some problems: calling client.getBlock fails depending on which block number is retrieved. The error message is: [main] ERROR org.consensusj.jsonrpc.RPCClient - JsonProcessingException: {} com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NegativeArraySizeException) (through reference chain: org.consensusj.jsonrpc.JsonRpcResponse["result"]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:388) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:348) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1592) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:278)

Here is the content of the file BitcoinExtendedClientTest.java: package com.msgilligan.bitcoinj.rpc;

import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.net.URI; import java.util.LinkedList; import java.util.List; import java.util.logging.Logger;

import org.bitcoinj.core.Address; import org.bitcoinj.core.Block; import org.bitcoinj.core.Coin; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionInput; import org.bitcoinj.core.TransactionOutPoint; import org.bitcoinj.core.TransactionOutput; import org.bitcoinj.params.TestNet3Params; import org.consensusj.jsonrpc.JsonRPCStatusException; import org.junit.BeforeClass; import org.junit.Test;

public class BitcoinExtendedClientTest { private static final Logger log = Logger.getLogger(BitcoinExtendedClientTest.class.getName());

static BitcoinExtendedClient client;

final static String host = "localhost";
static String rpcuser = "test";
static String rpcpassword = "test";
String faucetAddress = "mofhdVSgsUsVacWsf8QMNhDQqYnVXPtnZH";

@BeforeClass
public static void setUpBeforeClass() throws Exception {
    if (client == null) {
        NetworkParameters netParams = TestNet3Params.get();

        URI server = RPCURI.getDefaultTestNetURI();

        client = new BitcoinExtendedClient(netParams, server, rpcuser, rpcpassword);

        NetworkParameters params = client.getNetParams();
        log.info(params.toString());

        // NetworkParameters netIdString= TestNet3Params.get();;
        RPCConfig config = new RPCConfig(TestNet3Params.get(), server, rpcuser, rpcpassword);
        client = new BitcoinExtendedClient(config);

        log.info(client.getCommands().toString());
        log.info(client.getBlockChainInfo().toString());
    }
}

@Test
public void testGetBitcoinBalanceAddress() throws Exception {
    if (client == null) {
        setUpBeforeClass();
    }
    Address address = Address.fromBase58(TestNet3Params.get(), faucetAddress);
    Coin coin = client.getBitcoinBalance(address);

    log.info("***********coin: " + coin.toFriendlyString());
}

@Test
public void testGetBlockCount() throws Exception {
    if (client == null) {
        setUpBeforeClass();
    }
    log.info("getBlockCount(): " + client.getBlockCount());
    int blockCount = client.getBlockCount();
    log.info("block count: " + blockCount);
    log.info(client.getBlockChainInfo().toString());
    log.info(client.listUnspent().toString());

    Block block = client.getBlock(657810);
    log.info(block.toString());
}

@Test
public void testGetBlockInteger() throws Exception {
    if (client == null) {
        setUpBeforeClass();
    }
    int N = 1000;
    List<Transaction> txs = new LinkedList<Transaction>();
    for (int i = 1; i <= N; i++) {
        Block block = client.getBlock(i);
        txs.addAll(block.getTransactions());
    }
    String title = ">>>>>>>>>>>>>>>>>all transactions " + txs.size() + " from the first " + N + " blocks";
    log.info(title);
    log.info("current dir: " + System.getProperty("user.dir"));
    FileOutputStream outf = new FileOutputStream("testnet-txs.txt");
    PrintStream out = new PrintStream(outf);
    // out = System.out;
    out.println(title);
    int i = 0;
    for (Transaction t : txs) {
        log.info("" + i++);
        writeTransaction(t, out);
        // out.println(">>in >>" + t.getInputs().toString());
        // out.println(">>out>>" + t.getOutputs().toString());
    }
    out.close();
    outf.close();
}

void writeBlock(int blockNumber) throws JsonRPCStatusException, IOException {
    log.info("block " + blockNumber + ":" + client.getBlock(blockNumber).toString());
}

@Test
public void testTransactions() throws JsonRPCStatusException, IOException {
    // iterate backwards
    int blocks = client.getBlockChainInfo().getBlocks();
    writeBlock(1);
    writeBlock(blocks / 8);
    writeBlock(blocks / 4);
    writeBlock(blocks / 2);
    writeBlock(blocks * 6 / 10);
    writeBlock(blocks * 7 / 10);
    writeBlock(blocks * 76 / 100);
    writeBlock(blocks * 79 / 100);
    writeBlock(blocks * 81 / 100);
    writeBlock(blocks * 9 / 10);
    writeBlock(blocks * 901 / 1000);
    writeBlock(blocks * 969 / 1000);
    writeBlock(blocks * 992 / 1000);
    writeBlock(blocks * 993 / 1000);
    writeBlock(blocks);

    int i = 10;
    while (i-- > 0) {
        Block block = client.getBlock(blocks - 1);
        List<Transaction> txs = block.getTransactions();
        for (Transaction t : txs) {
            log.info(t.toString());
        }
    }
}

@Test
public void testGetTransaction() throws Exception {
    if (client == null) {
        setUpBeforeClass();
    }
    Sha256Hash txid = Sha256Hash.wrap("f1114ac0d88a47daa8f28573cf539496c69720e4bf4ff42b60b8d8f6902b30ce");
    // TxOutInfo txo0 = client.getTxOut(txid, 0);
    // TxOutInfo txo1 = client.getTxOut(txid, 1);
    Transaction t = client.getRawTransaction(txid);
    System.out.println(t);
    // TransactionConfidence confidence = t.getConfidence();
    // WalletTransactionInfo wti = client.getTransaction(txid);
    // Block block = client.getBlock(wti.getBlockhash());
}

private void writeTransaction(Transaction t, PrintStream out) throws JsonRPCStatusException, IOException {
    for (TransactionInput ti : t.getInputs()) {
        TransactionOutPoint outpoint = ti.getOutpoint();
        log.info(outpoint.toString());
        Sha256Hash hash = outpoint.getHash();
        Transaction tiFrom = client.getRawTransaction(hash);
        TransactionOutput tiFromTo = tiFrom.getOutput(0);
        String fromAddress = ti.isCoinBase() ? "COINBASE" : ti.getFromAddress().toString();
        String value = ti.getValue() == null ? "" : ti.getValue().toPlainString();
        out.println(t.getHashAsString() + ";" + fromAddress + ";" + value);
    }
    for (TransactionOutput to : t.getOutputs()) {
        out.println(t.getHashAsString() + ";;" + to.getSpentBy() + ";" + to.getValue());
    }
}

}

milansismanovic commented 6 years ago

I have created a simpler test for BitcoinExtendedClient (that fails for a good reason - will create an issue for this). It connects to a server and iterates through the last 100 blocks and writes them to the log: package com.msgilligan.bitcoinj.rpc;

import java.net.URI; import java.util.List;

import org.bitcoinj.core.Block; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.Transaction; import org.bitcoinj.params.MainNetParams; import org.bitcoinj.params.TestNet3Params; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory;

public class BitcoinExtendedClientTest2 { private static final Logger log = LoggerFactory.getLogger(BitcoinExtendedClientTest2.class);

static BitcoinExtendedClient client;

final static String host = "trebledev.treblewallet.io";
// final static String host = "localhost";
static String rpcuser = "test";
static String rpcpassword = "test";

@BeforeClass
public static void setUpBeforeClass() throws Exception {
    if (client == null) {
        NetworkParameters netParams = TestNet3Params.get();
        // NetworkParameters netParams = MainNetParams.get();
        URI server = RPCURI.getDefaultTestNetURI();
        client = new BitcoinExtendedClient(netParams, server, rpcuser, rpcpassword);
        RPCConfig config = new RPCConfig(TestNet3Params.get(), server, rpcuser, rpcpassword);
        client = new BitcoinExtendedClient(config);
        log.info(client.getBlockChainInfo().toString());
    }
}

@Test
public void testGetBlockInteger() throws Exception {
    // get last N blocks
    // log the block and their transactions
    int currentBlockDepth = client.getBlockCount();
    int N = 100;
    int successfulBlockRetrieves = 0;
    for (int i = currentBlockDepth; i > currentBlockDepth - N; i--) {
        Block block;
        try {
            block = client.getBlock(i);
            successfulBlockRetrieves++;
        } catch (Exception e) {
            Sha256Hash hash = client.getBlockHash(i);
            log.error("error getting block: " + i + " with hash: " + hash.toString());
            continue;
        }
        log.info("block: " + i + ": " + block.toString());
        List<Transaction> txs = block.getTransactions();
        for (Transaction t : txs) {
            log.info("transaction: " + t.toString());
        }
    }
    log.info("successfulBlockRetrieve: " + successfulBlockRetrieves + " of " + N);
}

}

fresh-fx59 commented 8 months ago

Just want to refresh this thread a bit to help someone working with bitcoinj 0.17-alpha3 and consensusj 0.7.0-alpha3. I've spent sometime on starting this up. Don't forget to tick Enable RPC Server checkbox if you are using bitcoin core or make appropriate setting in bitcoind.

Config class

import lombok.extern.slf4j.Slf4j;
import org.bitcoinj.params.TestNet3Params;
import org.consensusj.bitcoin.jsonrpc.BitcoinClient;
import org.consensusj.bitcoin.jsonrpc.RpcConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

@Slf4j
@Configuration
public class BitcoinConfig {

    @Bean
    public BitcoinClient getClient() throws URISyntaxException, IOException {
        URI uri = new URI("http://localhost:18332/");
        RpcConfig config = new RpcConfig(TestNet3Params.get().network(), uri, "user", "password");
        BitcoinClient client = new BitcoinClient(config);
        log.info("Blocks count " + client.getBlockChainInfo().getBlocks());
        return client;
    }
}

Part of pom.xml related to consensusj and bitcoinj

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <repositories>
        <repository>
            <id>gitlab-maven</id>
            <url>https://gitlab.com/api/v4/projects/8482916/packages/maven</url>
        </repository>
    </repositories>

    <distributionManagement>
        <repository>
            <id>gitlab-maven</id>
            <url>https://gitlab.com/api/v4/projects/8482916/packages/maven</url>
        </repository>

        <snapshotRepository>
            <id>gitlab-maven</id>
            <url>https://gitlab.com/api/v4/projects/8482916/packages/maven</url>
        </snapshotRepository>
    </distributionManagement>

    <properties>
        <java.version>21</java.version>
        <bitcoinj-core.version>0.17-alpha3</bitcoinj-core.version>
        <consensusj.version>0.7.0-alpha3</consensusj.version>
    </properties>

    <dependencies>
        <!--https://gitlab.com/ConsensusJ/consensusj/-/packages/19200815-->
        <dependency>
            <groupId>com.msgilligan</groupId>
            <artifactId>cj-btc-jsonrpc</artifactId>
            <version>${consensusj.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.bitcoinj/bitcoinj-core -->
        <dependency>
            <groupId>org.bitcoinj</groupId>
            <artifactId>bitcoinj-core</artifactId>
            <version>${bitcoinj-core.version}</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>

And this is bitcoind.conf

# Generated by https://jlopp.github.io/bitcoin-core-config-generator/

# This config should be placed in following path:
# $HOME/Library/Application Support/Bitcoin/bitcoin.conf

# [chain]
# Test Network.
chain=test

# [debug]
# Enable debug logging for all categories.
debug=1
# Log IP Addresses in debug output.
logips=1

rpcuser=user
rpcpassword=password

# [Sections]
# Most options automatically apply to mainnet, testnet, and regtest networks.
# If you want to confine an option to just one network, you should add it in the relevant section.
# EXCEPTIONS: The options addnode, connect, port, bind, rpcport, rpcbind and wallet
# only apply to mainnet unless they appear in the appropriate section below.

# Options only for mainnet
[main]

# Options only for testnet
[test]

# Options only for regtest
[regtest]