public MyBlock(NetworkParameters params, String data) throws ProtocolException {
super(params, swapBytes(Hex.decode(data), 80));
this.dataString = data;
}
public static byte[] swapBytes(byte[] bytes, int trimLength) {
byte[] rev = new byte[trimLength != -1 && bytes.length > trimLength ? trimLength : bytes.length];
for (int i = 0; i < rev.length; i += 4) {
byte[] chunk = Arrays.copyOfRange(bytes, i , i + 4);
chunk = Utils.reverseBytes(chunk);
System.arraycopy(chunk, 0, rev, i , 4);
}
return rev;
}
public byte[] getBytes() {
if (originalBytes == null) {
originalBytes = new byte[80];
Utils.uint32ToByteArrayLE(getVersion(), originalBytes, 0);
System.arraycopy(Utils.reverseBytes(getPrevBlockHash()), 0, originalBytes, 4, 32);
System.arraycopy(Utils.reverseBytes(getMerkleRoot()), 0, originalBytes, 36, 32);
Utils.uint32ToByteArrayLE(getTime(), originalBytes, 68);
Utils.uint32ToByteArrayLE(getDifficultyTarget(), originalBytes, 72);
Utils.uint32ToByteArrayLE(getNonce(), originalBytes, 76);
}
return originalBytes;
}
byte[] bytes = block.getBytes();
bytes = swapBytes(bytes, 80);
byte[] padded = block.padForSHA256(bytes);
L.println(Utils.bytesToHexString(padded));
public byte[] getMidstate1() {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
digest.getProvider();
digest.update(getBytes(), 0, 64);
byte[] midstate = digest.digest();
return midstate;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
public byte[] getMidstate() {
SHA256Digest sha = new SHA256Digest();
sha.update(getBytes(), 0, 64);
sha.update(getBytes(), 64, 16);
byte[] midstate = new byte[32];
int finalResult = sha.doFinal(midstate, 0);
return midstate;
}
It's way too early to be trying to implement getwork serving. BitCoinJ is a long way from being able to replace the C++ server I'm afraid. It's months of work, at minimum.
If you have any non-trivial amount of mining taking place against a BitCoinJ based node you open up the network to attack and could cause large splits in the chain.
Since bitcoinj only stores the small subset of transactions that apply
to the user you have no way of knowing whether the transactions you
construct a block from are double spends or otherwise invalid.
If you include invalid spends full nodes will reject your block but
other simple mode nodes might not. These nodes in turn will reject
mainline blocks and be on a forked chain.
In the long run it would be nice if the developer had the option of
using bitcoinj in full or spv mode. A generalized API that could be
used either way would be a boon to the community.
Storing the full block chain would be a good start. Its also going to
be tough since it also deals with how transactions are stored.
Right now the transactions are kind of locked to being represented in
serialized objects and quite a bit of plumbing needs to be swapped to
change that.
I would think as long as making the API fuller featured doesn't hurt
mobile capabilities it could only be a good thing.
This week I have hooked up the bitcoinj block downloading and will start
on the wallet display/ send/ receive soon so it is quite near to being a
minimal viable product. You might want to have a look at that.
--
multibit.org : coming soon : bitcoin desktop client : powered by bitcoinj
Now you see why I say it's a lot of work :-)
Top of the list seems like a good place to start. I'll try to have a look into that this evening then.
- Transaction fees: We need a getFee() method on Transaction, a way to set fees when creating spends (these are easy), and less easy, the Wallet needs to know how to create spends with automatically selected fees such that the network will always relay them and it should be able to minimize the fees paid through smart coin selection. Along with unit tests for all of that of course. Once that's done the Block checking code can implement the inflation formula and then verify the value on the coinbase tx. [...]
- Value capping: there has been a long-standing TODO to introduce a value abstraction (currently we use BigIntegers). As part of doing that, we'd implement the MAX_MONEY checks to ensure we never end up with negative value or more than 21 million coins. Currently if we get a transaction with an invalid value field we wouldn't notice. Checking this doesn't hurt mobile users and is required for a full implementation.
>> * *Transaction fees:* We need a getFee() method on Transaction, a
>> way to set fees when creating spends (these are easy), and less
>> easy, the Wallet needs to know how to create spends with
>> automatically selected fees such that the network will always...
>>
> Top of the list seems like a good place to start. I'll try to have a
> look into that this evening then.
FYI: The "setting fees" part is implemented in my branch. Have a look at:
http://code.google.com/p/bitcoinj/issues/detail?id=45#c5
>> * *Value capping:* there has been a long-standing TODO to
>> introduce a value abstraction (currently we use BigIntegers). As
>> part of doing that, we'd implement the MAX_MONEY checks to
>> ensure we never end up with negative value or more than 21
>> million coins. Currently if we get a transaction with an invalid
>> value field we wouldn't notice. Checking this doesn't hurt
>> mobile users and is required for a full implementation.
>>
> Looks like work has been started on this here:
> https://github.com/hegjon/bitcoinj/commit/61a2c0a7c2715f772a481da58a1c575c67bebbc0
> Is there a reason this has been neglected for a couple of months?
> Although the sanity checks you mention don't seem to have been done yet,
> this should be a decent foundation to build on.
About the BigInteger replacement: will this actually replace BigInteger
or will it encapsulate BigInteger? I am a bit ancious that instantiating
another couple of thousand objects will hit mobile devices too bad.
There are already memory problems, although I currently can't tell if
they are the result of a bug.
So if it is possible at all, I'd vote for not encapsulating any objects
into the future "Bitcoin" object.
I guess if performance is really a problem then most, if not all, of
these convenience methods could be made static and the class would
simply operate on existing BigIntegers.
Thanks, looks like a good start. Is there a public repo I can use? I only need read-only at this point.
Once I have the Swing rendition done and reasonably stable I plan to add
another set of views rendering to vanilla HTML (Tomcat + Struts + JSPs
probably) so that there is a JEE web application for people to use too.
My understanding is that a Bitcoin class would wrap BigInteger
make sure it was constrained to acceptable values, and provide convenience methods for creating, printing, etc bitcoin values.
Looks like work has been started on this here: https://github.com/hegjon/bitcoinj/commit/61a2c0a7c2715f772a481da58a1c575c67bebbc0
Is there a reason this has been neglected for a couple of months?
About the BigInteger replacement: will this actually replace BigInteger
or will it encapsulate BigInteger? I am a bit ancious that instantiating
another couple of thousand objects will hit mobile devices too bad.
There are already memory problems, although I currently can't tell if
they are the result of a bug.
So if it is possible at all, I'd vote for not encapsulating any objects
into the future "Bitcoin" object.
Yes, you are right. And since Mike asserted that we can use long instead
of BigInteger, my objections are off the table.
Should we start collecting what operations we'd need on a "CoinsAmount"
object?
Should we start collecting what operations we'd need on a "CoinsAmount"
object?