mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-07-30 19:41:24 +00: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:
@@ -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.
Reference in New Issue
Block a user