Author

Topic: Some more work on using bitcoinj from C++ (Read 2615 times)

legendary
Activity: 1526
Merit: 1134
July 22, 2013, 09:52:47 AM
#1
I sent this to the Hive guys, so in the interest of keeping a level playing field here's a brief note about it:

  https://code.google.com/p/bitcoinj/wiki/UsingFromOtherLanguages

I did some experiments with using a JNI wrapper generator to export the bitcoinj API into C++. This still requires you to ship a JVM with your app - cutting it down to size is a topic for another day. However once you bundle the JVM you can then proceed to use the API in a somewhat natural c++ish way. Example code:

https://github.com/mikehearn/cppjvm/blob/master/mytest/bcj-hello-world.cpp

Code:
using namespace com::google::bitcoin::core;
using namespace com::google;
using namespace jvm;

class ExampleBalanceListener : public native::WalletEventListener {
public:
virtual void onCoinsReceived(Wallet &wallet, Transaction &tx, long prevBalance, long newBalance) {
// Callbacks run on the user thread (see bitcoinj documentation)
std::cout << "We got some moneyzzz!! Received " << (newBalance - prevBalance) << " satoshis" << std::endl;
}

virtual void onKeysAdded(Wallet &wallet, java::util::List &keys) {
// Callbacks run on the user thread (see bitcoinj documentation)
std::cout << "Someone added " << keys.size() << " keys" << std::endl;
}
};

int main(int argc, char *argv[])
{
try
{
create_global_vm("bitcoinj-tools-0.10-SNAPSHOT.jar");
}
catch (const std::exception &e)
{
std::cout << "Initialising JVM: " << e.what() << std::endl;
}

// Any variables declared that aren't jvm::global<> whilst this is in scope will become
// eligible for garbage collection after it goes out of scope. Here we just cover the
// whole main function.
local_frame lf;

// Register native callback methods (see native-listeners.cpp)
register_natives();

// Simple example of making a Java static method call.
std::string vm_name = java::lang::System::getProperty("java.vm.name");
std::cout << vm_name << std::endl;

// Make the bitcoinj logging more concise.
bitcoin::utils::BriefLogFormatter::init();

// Create a basic wallet app.
NetworkParameters params = NetworkParameters::testNet();

java::io::File directory(".");
bitcoin::kits::WalletAppKit kit(params, directory, "hello-world");
// Wait for the network to come up and the block chain to synchronize.
kit.startAndWait();
// Register a listener to find out when we received coins.
ExampleBalanceListener *listener = new ExampleBalanceListener();
kit.wallet().addEventListener(listener->peer);
// Create a new key.
bitcoin::core::ECKey key = jnew();
kit.wallet().addKey(key);

std::string address = key.toAddress(params).toString();
std::cout << "Plz send some moneyz to " << address << std::endl;
}

The work is incomplete. It requires some more documentation and fleshing out of the native callback thunks (it's brainless, copy/paste style work). Then, integration with the core bitcoinj codebase.

However if you have a project that requires access to an SPV implementation from (Objective) C++ I hope this work shows the path.
Jump to: