Skip to content

Commit

Permalink
More serializers & deserializers
Browse files Browse the repository at this point in the history
* Serializers
   + Address
   + Sha256Hash
  + Transaction

* Deserializers
   + Sha256Hash
  • Loading branch information
msgilligan committed Sep 21, 2015
1 parent c15b456 commit 79d27ea
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.msgilligan.bitcoinj.rpc.conversion.AddressSerializer;
import com.msgilligan.bitcoinj.rpc.conversion.BitcoinMath;
import com.msgilligan.bitcoinj.rpc.conversion.CoinDeserializer;
import com.msgilligan.bitcoinj.rpc.conversion.CoinSerializer;
import com.msgilligan.bitcoinj.rpc.conversion.Sha256HashDeserializer;
import com.msgilligan.bitcoinj.rpc.conversion.Sha256HashSerializer;
import com.msgilligan.bitcoinj.rpc.conversion.TransactionSerializer;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.AddressFormatException;
import org.bitcoinj.core.Coin;
Expand All @@ -24,7 +28,6 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -73,7 +76,11 @@ static protected ObjectMapper createMapper() {
ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("BitcoinJMappingClient", new Version(1, 0, 0, null, null, null))
.addDeserializer(Coin.class, new CoinDeserializer())
.addSerializer(Coin.class, new CoinSerializer());
.addDeserializer(Sha256Hash.class, new Sha256HashDeserializer())
.addSerializer(Address.class, new AddressSerializer())
.addSerializer(Coin.class, new CoinSerializer())
.addSerializer(Sha256Hash.class, new Sha256HashSerializer())
.addSerializer(Transaction.class, new TransactionSerializer());
mapper.registerModule(testModule);
return mapper;
}
Expand Down Expand Up @@ -209,8 +216,7 @@ public Integer getBlockCount() throws JsonRPCException, IOException {
*/
public Sha256Hash getBlockHash(Integer index) throws JsonRPCException, IOException {
List<Object> params = createParamList(index);
String hashStr = send("getblockhash", params);
Sha256Hash hash = Sha256Hash.wrap(hashStr);
Sha256Hash hash = send("getblockhash", params, Sha256Hash.class);
return hash;
}

Expand All @@ -222,7 +228,7 @@ public Sha256Hash getBlockHash(Integer index) throws JsonRPCException, IOExcepti
*/
public Map<String, Object> getBlock(Sha256Hash hash) throws JsonRPCException, IOException {
// Use "verbose = true"
List<Object> params = createParamList(hash.toString(), true);
List<Object> params = createParamList(hash, true);
Map<String, Object> json = send("getblock", params);
return json;
}
Expand Down Expand Up @@ -328,7 +334,7 @@ public Address getAccountAddress(String account) throws JsonRPCException, IOExce
* @return The private key
*/
public ECKey dumpPrivKey(Address address) throws IOException, JsonRPCStatusException {
List<Object> params = createParamList(address.toString());
List<Object> params = createParamList(address);
String base58Key = send("dumpprivkey", params);
ECKey key;
try {
Expand Down Expand Up @@ -374,7 +380,7 @@ public String createRawTransaction(List<Outpoint> inputs, Map<Address, Coin> out
List<Map<String, Object>> inputsJson = new ArrayList<Map<String, Object>>();
for (Outpoint outpoint : inputs) {
Map<String, Object> outMap = new HashMap<String, Object>();
outMap.put("txid", outpoint.getTxid().toString());
outMap.put("txid", outpoint.getTxid());
outMap.put("vout", outpoint.getVout());
inputsJson.add(outMap);
}
Expand Down Expand Up @@ -415,15 +421,15 @@ public Transaction getRawTransaction(Sha256Hash txid) throws JsonRPCException, I
}

public byte[] getRawTransactionBytes(Sha256Hash txid) throws JsonRPCException, IOException {
List<Object> params = createParamList(txid.toString());
List<Object> params = createParamList(txid);
String hexEncoded = send("getrawtransaction", params);
byte[] raw = BitcoinClient.hexStringToByteArray(hexEncoded);
return raw;
}

/* TODO: Return a stronger type than an a Map? */
public Map<String, Object> getRawTransactionMap(Sha256Hash txid) throws JsonRPCException, IOException {
List<Object> params = createParamList(txid.toString(), 1);
List<Object> params = createParamList(txid, 1);
Map<String, Object> json = send("getrawtransaction", params);
return json;
}
Expand All @@ -437,14 +443,14 @@ public Sha256Hash sendRawTransaction(String hexTx) throws JsonRPCException, IOEx
}

public Sha256Hash sendRawTransaction(Transaction tx, Boolean allowHighFees) throws JsonRPCException, IOException {
String hexTx = transactionToHex(tx);
return sendRawTransaction(hexTx, allowHighFees);
List<Object> params = createParamList(tx, allowHighFees);
Sha256Hash hash = send("sendrawtransaction", params, Sha256Hash.class);
return hash;
}

public Sha256Hash sendRawTransaction(String hexTx, Boolean allowHighFees) throws JsonRPCException, IOException {
List<Object> params = createParamList(hexTx, allowHighFees);
String txid = send("sendrawtransaction", params);
Sha256Hash hash = Sha256Hash.wrap(txid);
Sha256Hash hash = send("sendrawtransaction", params, Sha256Hash.class);
return hash;
}

Expand All @@ -462,7 +468,7 @@ public Coin getReceivedByAddress(Address address) throws JsonRPCException, IOExc
* @throws IOException
*/
public Coin getReceivedByAddress(Address address, Integer minConf) throws JsonRPCException, IOException {
List<Object> params = createParamList(address.toString(), minConf);
List<Object> params = createParamList(address, minConf);
Coin balance = send("getreceivedbyaddress", params, Coin.class);
return balance;
}
Expand Down Expand Up @@ -507,12 +513,7 @@ public List<UnspentOutput> listUnspent(Integer minConf, Integer maxConf)
*/
public List<UnspentOutput> listUnspent(Integer minConf, Integer maxConf, Iterable<Address> filter)
throws JsonRPCException, IOException {
List<String> addressFilter = null;
if (filter != null) {
addressFilter = applyToString(filter);
}

List<Object> params = createParamList(minConf, maxConf, addressFilter);
List<Object> params = createParamList(minConf, maxConf, filter);
List<Map<String, Object>> unspentMaps = send("listunspent", params);
List<UnspentOutput> unspent = new ArrayList<UnspentOutput>();
for (Map<String, Object> uoMap : unspentMaps) {
Expand Down Expand Up @@ -558,7 +559,7 @@ public Map<String, Object> getTxOut(Sha256Hash txid, Integer vout) throws JsonRP
*/
public Map<String, Object> getTxOut(Sha256Hash txid, Integer vout, Boolean includeMemoryPool)
throws JsonRPCException, IOException {
List<Object> params = createParamList(txid.toString(), vout, includeMemoryPool);
List<Object> params = createParamList(txid, vout, includeMemoryPool);
Map<String, Object> json = send("gettxout", params);
return json;
}
Expand Down Expand Up @@ -601,24 +602,21 @@ public Sha256Hash sendToAddress(Address address, Coin amount) throws JsonRPCExce

public Sha256Hash sendToAddress(Address address, Coin amount, String comment, String commentTo)
throws JsonRPCException, IOException {
List<Object> params = createParamList(address.toString(), amount, comment, commentTo);
String txid = send("sendtoaddress", params);
Sha256Hash hash = Sha256Hash.wrap(txid);
List<Object> params = createParamList(address, amount, comment, commentTo);
Sha256Hash hash = send("sendtoaddress", params, Sha256Hash.class);
return hash;
}

public Sha256Hash sendFrom(String account, Address address, Coin amount)
throws JsonRPCException, IOException {
List<Object> params = createParamList(account, address.toString(), amount);
String txid = send("sendfrom", params);
Sha256Hash hash = Sha256Hash.wrap(txid);
List<Object> params = createParamList(account, address, amount);
Sha256Hash hash = send("sendfrom", params, Sha256Hash.class);
return hash;
}

public Sha256Hash sendMany(String account, Map<Address, Coin> amounts) throws JsonRPCException, IOException {
List<Object> params = Arrays.asList(account, amounts);
String txid = send("sendmany", params);
Sha256Hash hash = Sha256Hash.wrap(txid);
Sha256Hash hash = send("sendmany", params, Sha256Hash.class);
return hash;
}

Expand All @@ -635,7 +633,7 @@ public Boolean setTxFee(Coin amount) throws JsonRPCException, IOException {
}

public Map<String, Object> getTransaction(Sha256Hash txid) throws JsonRPCException, IOException {
List<Object> params = createParamList(txid.toString());
List<Object> params = createParamList(txid);
Map<String, Object> transaction = send("gettransaction", params);
return transaction;
}
Expand Down Expand Up @@ -708,7 +706,7 @@ public Boolean commandExists(String command) throws JsonRPCException, IOExceptio
* @since Bitcoin Core 0.10
*/
public void invalidateBlock(Sha256Hash hash) throws JsonRPCException, IOException {
List<Object> params = createParamList(hash.toString());
List<Object> params = createParamList(hash);
send("invalidateblock", params);
}

Expand All @@ -721,7 +719,7 @@ public void invalidateBlock(Sha256Hash hash) throws JsonRPCException, IOExceptio
* @since Bitcoin Core 0.10
*/
public void reconsiderBlock(Sha256Hash hash) throws JsonRPCException, IOException {
List<Object> params = createParamList(hash.toString());
List<Object> params = createParamList(hash);
send("reconsiderblock", params);
}

Expand Down Expand Up @@ -769,38 +767,4 @@ public static byte[] hexStringToByteArray(String s) {
}
return data;
}

/**
* Converts a transaction into a hex-encoded string.
*
* @param tx A transaction object
* @return The hex-encoded string
*/
private String transactionToHex(Transaction tx) {
// From: http://bitcoin.stackexchange.com/questions/8475/how-to-get-hex-string-from-transaction-in-bitcoinj
final StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
byte[] bytes = tx.bitcoinSerialize();
for (byte b : bytes) {
formatter.format("%02x", b);
}
formatter.close();
return sb.toString();
}

/**
* Applies toString() to every element of {@code elements} and returns a list of the results.
*
* @param elements The elements
* @return The list of strings
*/
private <T> List<String> applyToString(Iterable<T> elements) {
List<String> stringList = new ArrayList<String>();
for (T element : elements) {
String elementAsString = element.toString();
stringList.add(elementAsString);
}
return stringList;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.msgilligan.bitcoinj.rpc.conversion;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.bitcoinj.core.Address;

import java.io.IOException;

/**
*
*/
public class AddressSerializer extends JsonSerializer<Address> {
@Override
public void serialize(Address value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeString(value.toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.msgilligan.bitcoinj.rpc.conversion;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Sha256Hash;

import java.io.IOException;
import java.math.BigDecimal;

/**
*
*/
public class Sha256HashDeserializer extends JsonDeserializer<Sha256Hash> {
@Override
public Sha256Hash deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonToken token = p.getCurrentToken();
switch (token) {
case VALUE_STRING:
return Sha256Hash.wrap(p.getValueAsString());
default:
throw ctxt.mappingException(Object.class, token);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.msgilligan.bitcoinj.rpc.conversion;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.bitcoinj.core.Sha256Hash;

import java.io.IOException;

/**
*
*/
public class Sha256HashSerializer extends JsonSerializer<Sha256Hash> {
@Override
public void serialize(Sha256Hash value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeString(value.toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.msgilligan.bitcoinj.rpc.conversion;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.bitcoinj.core.Transaction;

import java.io.IOException;
import java.util.Formatter;

/**
*
*/
public class TransactionSerializer extends JsonSerializer<Transaction> {
@Override
public void serialize(Transaction value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
// From: http://bitcoin.stackexchange.com/questions/8475/how-to-get-hex-string-from-transaction-in-bitcoinj
final StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
byte[] bytes = value.bitcoinSerialize();
for (byte b : bytes) {
formatter.format("%02x", b);
}
formatter.close();
gen.writeString(sb.toString());
}
}

0 comments on commit 79d27ea

Please sign in to comment.