mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-02-24 22:58:32 +01:00
ScriptPattern: Add pattern matcher for segwit commitment (in an output of the coinbase transaction).
Adds a test for parsing block 481815, which contains a segwit commitment in its coinbase.
This commit is contained in:
parent
d30d83c616
commit
b976205716
3 changed files with 45 additions and 0 deletions
|
@ -19,8 +19,11 @@ package org.bitcoinj.script;
|
|||
|
||||
import org.bitcoinj.core.LegacyAddress;
|
||||
import org.bitcoinj.core.SegwitAddress;
|
||||
import org.bitcoinj.core.Sha256Hash;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.bitcoinj.script.Script.decodeFromOpN;
|
||||
|
@ -274,4 +277,31 @@ public class ScriptPattern {
|
|||
List<ScriptChunk> chunks = script.chunks;
|
||||
return chunks.size() > 0 && chunks.get(0).equalsOpCode(ScriptOpCodes.OP_RETURN);
|
||||
}
|
||||
|
||||
private static final byte[] SEGWIT_COMMITMENT_HEADER = Hex.decode("aa21a9ed");
|
||||
|
||||
/**
|
||||
* Returns whether this script matches the pattern for a segwit commitment (in an output of the coinbase
|
||||
* transaction).
|
||||
*/
|
||||
public static boolean isSegwitCommitment(Script script) {
|
||||
List<ScriptChunk> chunks = script.chunks;
|
||||
if (chunks.size() < 2)
|
||||
return false;
|
||||
if (!chunks.get(0).equalsOpCode(ScriptOpCodes.OP_RETURN))
|
||||
return false;
|
||||
byte[] chunkData = chunks.get(1).data;
|
||||
if (chunkData == null || chunkData.length != 36)
|
||||
return false;
|
||||
if (!Arrays.equals(Arrays.copyOfRange(chunkData, 0, 4), SEGWIT_COMMITMENT_HEADER))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the hash from a segwit commitment (in an output of the coinbase transaction).
|
||||
*/
|
||||
public static Sha256Hash extractSegwitCommitmentHash(Script script) {
|
||||
return Sha256Hash.wrap(Arrays.copyOfRange(script.chunks.get(1).data, 4, 36));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,15 @@ import org.bitcoinj.params.MainNetParams;
|
|||
import org.bitcoinj.params.TestNet2Params;
|
||||
import org.bitcoinj.params.TestNet3Params;
|
||||
import org.bitcoinj.params.UnitTestParams;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.script.ScriptOpCodes;
|
||||
import org.bitcoinj.script.ScriptPattern;
|
||||
import org.bitcoinj.wallet.Wallet;
|
||||
import org.bitcoinj.wallet.Wallet.BalanceType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
|
@ -242,6 +245,18 @@ public class BlockTest {
|
|||
assertEquals(Coin.ZERO, wallet.getBalance(BalanceType.AVAILABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlock481815_segwitCommitmentInCoinbase() throws Exception {
|
||||
Block block481815 = MAINNET.getDefaultSerializer().makeBlock(ByteStreams.toByteArray(
|
||||
getClass().getResourceAsStream("block481815.dat")));
|
||||
assertEquals(2097, block481815.getTransactions().size());
|
||||
Transaction coinbase = block481815.getTransactions().get(0);
|
||||
final Script segwitCommitment = coinbase.getOutput(1).getScriptPubKey();
|
||||
assertTrue(ScriptPattern.isSegwitCommitment(segwitCommitment));
|
||||
assertEquals("3d03076733467c45b08ec503a0c5d406647b073e1914d35b5111960ed625f3b7",
|
||||
ScriptPattern.extractSegwitCommitmentHash(segwitCommitment).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isBIPs() throws Exception {
|
||||
final Block genesis = MAINNET.getGenesisBlock();
|
||||
|
|
BIN
core/src/test/resources/org/bitcoinj/core/block481815.dat
Normal file
BIN
core/src/test/resources/org/bitcoinj/core/block481815.dat
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue