Commit c3362447 authored by Daniel Connolly's avatar Daniel Connolly

Merge ilozanof updates

parents 211c5fa7 d4f474db
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Copyright 2011 Google Inc. * Copyright 2011 Google Inc.
* Copyright 2014 Andreas Schildbach * Copyright 2014 Andreas Schildbach
* Copyright 2014-2016 the libsecp256k1 contributors * Copyright 2014-2016 the libsecp256k1 contributors
* Copyright 2018 the bitcoinj-cash developers
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -14,10 +15,14 @@ ...@@ -14,10 +15,14 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
* This file has been modified by the bitcoinj-cash developers for the bitcoinj-cash project.
* The original file was from the bitcoinj project (https://github.com/bitcoinj/bitcoinj).
*/ */
package org.bitcoinj.core; package org.bitcoinj.core;
import org.bitcoinj.core.VerificationException.*;
import org.bitcoinj.crypto.*; import org.bitcoinj.crypto.*;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
...@@ -580,19 +585,15 @@ public class ECKey implements EncryptableItem { ...@@ -580,19 +585,15 @@ public class ECKey implements EncryptableItem {
decoder = new ASN1InputStream(bytes); decoder = new ASN1InputStream(bytes);
DLSequence seq = (DLSequence) decoder.readObject(); DLSequence seq = (DLSequence) decoder.readObject();
if (seq == null) if (seq == null)
throw new RuntimeException("Reached past end of ASN.1 stream."); throw new SignatureFormatError("Reached past end of ASN.1 stream.");
ASN1Integer r, s; ASN1Integer r, s;
try { r = (ASN1Integer) seq.getObjectAt(0);
r = (ASN1Integer) seq.getObjectAt(0); s = (ASN1Integer) seq.getObjectAt(1);
s = (ASN1Integer) seq.getObjectAt(1);
} catch (ClassCastException e) {
throw new IllegalArgumentException(e);
}
// OpenSSL deviates from the DER spec by interpreting these values as unsigned, though they should not be // OpenSSL deviates from the DER spec by interpreting these values as unsigned, though they should not be
// Thus, we always use the positive versions. See: http://r6.ca/blog/20111119T211504Z.html // Thus, we always use the positive versions. See: http://r6.ca/blog/20111119T211504Z.html
return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue()); return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue());
} catch (IOException e) { } catch (Exception e) {
throw new RuntimeException(e); throw new SignatureFormatError(e);
} finally { } finally {
if (decoder != null) if (decoder != null)
try { decoder.close(); } catch (IOException x) {} try { decoder.close(); } catch (IOException x) {}
...@@ -713,15 +714,19 @@ public class ECKey implements EncryptableItem { ...@@ -713,15 +714,19 @@ public class ECKey implements EncryptableItem {
} }
ECDSASigner signer = new ECDSASigner(); ECDSASigner signer = new ECDSASigner();
ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE.getCurve().decodePoint(pub), CURVE);
signer.init(false, params);
try { try {
ECPublicKeyParameters params = new ECPublicKeyParameters(CURVE.getCurve().decodePoint(pub), CURVE);
signer.init(false, params);
return signer.verifySignature(data, signature.r, signature.s); return signer.verifySignature(data, signature.r, signature.s);
} catch (NullPointerException e) { } catch (NullPointerException e) {
// Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures. Those signatures // Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures. Those signatures
// are inherently invalid/attack sigs so we just fail them here rather than crash the thread. // are inherently invalid/attack sigs so we just fail them here rather than crash the thread.
log.error("Caught NPE inside bouncy castle", e); log.error("Caught NPE inside bouncy castle", e);
return false; return false;
} catch (IllegalArgumentException e) {
throw new SignatureFormatError(e);
} catch (ArrayIndexOutOfBoundsException e) {
throw new SignatureFormatError(e);
} }
} }
......
/* /*
* Copyright 2011 Google Inc. * Copyright 2011 Google Inc.
* Copyright 2018 the bitcoinj-cash developers
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -12,18 +13,36 @@ ...@@ -12,18 +13,36 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
* This file has been modified by the bitcoinj-cash developers for the bitcoinj-cash project.
* The original file was from the bitcoinj project (https://github.com/bitcoinj/bitcoinj).
*/ */
package org.bitcoinj.core; package org.bitcoinj.core;
@SuppressWarnings("serial")
import org.bitcoinj.script.ScriptError;
public class ScriptException extends VerificationException { public class ScriptException extends VerificationException {
public ScriptException(String msg) { private ScriptError err = null;
public ScriptException(ScriptError err, String msg) {
super(msg); super(msg);
this.err = err;
} }
public ScriptException(String msg, Exception e) { public ScriptException(ScriptError err, String msg, Exception e) {
super(msg, e); super(msg, e);
this.err = err;
}
public ScriptException(String msg) {
super(msg);
} }
public ScriptError getError() {
return err;
}
} }
...@@ -160,6 +160,24 @@ public class Transaction extends ChildMessage { ...@@ -160,6 +160,24 @@ public class Transaction extends ChildMessage {
// can properly keep track of optimal encoded size // can properly keep track of optimal encoded size
private int optimalEncodingMessageSize; private int optimalEncodingMessageSize;
public boolean isOpReturn() {
if (getOpReturnData() != null) {
return true;
}
return false;
}
public byte[] getOpReturnData() {
// Only one OP_RETURN output per transaction is allowed as "standard" transaction
// So just return the first OP_RETURN data found
for (TransactionOutput output : outputs) {
if (output.isOpReturn()) {
return output.getOpReturnData();
}
}
return null;
}
/** /**
* This enum describes the underlying reason the transaction was created. It's useful for rendering wallet GUIs * This enum describes the underlying reason the transaction was created. It's useful for rendering wallet GUIs
* more appropriately. * more appropriately.
...@@ -953,6 +971,12 @@ public class Transaction extends ChildMessage { ...@@ -953,6 +971,12 @@ public class Transaction extends ChildMessage {
return addOutput(new TransactionOutput(params, this, value, address)); return addOutput(new TransactionOutput(params, this, value, address));
} }
public TransactionOutput addData(byte[] data) {
Script script = ScriptBuilder.createOpReturnScript(data);
return addOutput(new TransactionOutput(params, this, Coin.ZERO, script.getProgram()));
}
/** /**
* Creates an output that pays to the given pubkey directly (no address) with the given value, adds it to this * Creates an output that pays to the given pubkey directly (no address) with the given value, adds it to this
* transaction, and returns the new output. * transaction, and returns the new output.
...@@ -1063,9 +1087,10 @@ public class Transaction extends ChildMessage { ...@@ -1063,9 +1087,10 @@ public class Transaction extends ChildMessage {
byte[] redeemScript, byte[] redeemScript,
Coin value, Coin value,
SigHash hashType, SigHash hashType,
boolean anyoneCanPay) boolean anyoneCanPay,
Set<Script.VerifyFlag> verifyFlags)
{ {
Sha256Hash hash = hashForSignatureWitness(inputIndex, redeemScript, value, hashType, anyoneCanPay); Sha256Hash hash = hashForSignatureWitness(inputIndex, redeemScript, value, hashType, anyoneCanPay, verifyFlags);
return new TransactionSignature(key.sign(hash, aesKey), hashType, anyoneCanPay, true); return new TransactionSignature(key.sign(hash, aesKey), hashType, anyoneCanPay, true);
} }
...@@ -1101,9 +1126,10 @@ public class Transaction extends ChildMessage { ...@@ -1101,9 +1126,10 @@ public class Transaction extends ChildMessage {
Script redeemScript, Script redeemScript,
Coin value, Coin value,
SigHash hashType, SigHash hashType,
boolean anyoneCanPay) boolean anyoneCanPay,
Set<Script.VerifyFlag> verifyFlags)
{ {
Sha256Hash hash = hashForSignatureWitness(inputIndex, redeemScript.getProgram(), value, hashType, anyoneCanPay); Sha256Hash hash = hashForSignatureWitness(inputIndex, redeemScript.getProgram(), value, hashType, anyoneCanPay, verifyFlags);
return new TransactionSignature(key.sign(hash, aesKey), hashType, anyoneCanPay, true); return new TransactionSignature(key.sign(hash, aesKey), hashType, anyoneCanPay, true);
} }
/** /**
...@@ -1251,6 +1277,18 @@ public class Transaction extends ChildMessage { ...@@ -1251,6 +1277,18 @@ public class Transaction extends ChildMessage {
* @param type Should be SigHash.ALL * @param type Should be SigHash.ALL
* @param anyoneCanPay should be false. * @param anyoneCanPay should be false.
*/ */
public synchronized Sha256Hash hashForSignatureWitness(
int inputIndex,
Script scriptCode,
Coin prevValue,
SigHash type,
boolean anyoneCanPay,
Set<Script.VerifyFlag> verifyFlags)
{
byte[] connectedScript = scriptCode.getProgram();
return hashForSignatureWitness(inputIndex, connectedScript, prevValue, type, anyoneCanPay, verifyFlags);
}
public synchronized Sha256Hash hashForSignatureWitness( public synchronized Sha256Hash hashForSignatureWitness(
int inputIndex, int inputIndex,
Script scriptCode, Script scriptCode,
...@@ -1259,7 +1297,7 @@ public class Transaction extends ChildMessage { ...@@ -1259,7 +1297,7 @@ public class Transaction extends ChildMessage {
boolean anyoneCanPay) boolean anyoneCanPay)
{ {
byte[] connectedScript = scriptCode.getProgram(); byte[] connectedScript = scriptCode.getProgram();
return hashForSignatureWitness(inputIndex, connectedScript, prevValue, type, anyoneCanPay); return hashForSignatureWitness(inputIndex, connectedScript, prevValue, type, anyoneCanPay, null);
} }
public synchronized Sha256Hash hashForSignatureWitness( public synchronized Sha256Hash hashForSignatureWitness(
...@@ -1267,11 +1305,38 @@ public class Transaction extends ChildMessage { ...@@ -1267,11 +1305,38 @@ public class Transaction extends ChildMessage {
byte[] connectedScript, byte[] connectedScript,
Coin prevValue, Coin prevValue,
SigHash type, SigHash type,
boolean anyoneCanPay) boolean anyoneCanPay) {
return hashForSignatureWitness(inputIndex, connectedScript, prevValue, type, anyoneCanPay, null);
}
public synchronized Sha256Hash hashForSignatureWitness(
int inputIndex,
byte[] connectedScript,
Coin prevValue,
SigHash type,
boolean anyoneCanPay,
Set<Script.VerifyFlag> verifyFlags)
{ {
byte sigHashType = (byte) TransactionSignature.calcSigHashValue(type, anyoneCanPay, true); byte sigHashType = (byte) TransactionSignature.calcSigHashValue(type, anyoneCanPay, true);
ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(length == UNKNOWN_LENGTH ? 256 : length + 4); ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(length == UNKNOWN_LENGTH ? 256 : length + 4);
try { try {
// Replay Protection Implementation:
// If the "REPLAY PRIOTECTION" Flag is activated, we implement the Replay Protection Algorithm, which
// allows us the use different Fork IDS in the future. The Fork ID will be stored in the 24 more significant
// bits of nSigHashType (which is not a single byte now, but a 32 one).
// The following implementation is based on the one from bitcoin-abc:
int nSigHashType = sigHashType;
if ((verifyFlags!= null) && verifyFlags.contains(Script.VerifyFlag.REPLAY_PROTECTION)) {
// Legacy chain's value for fork id must be of the form 0xffxxxx.
// By xoring with 0xdead, we ensure that the value will be different
// from the original one, even if it already starts with 0xff.
int forkId = 0; // for now, the forkID is ZERO.
int newForkValue = forkId ^ 0xdead;
nSigHashType = sigHashType | ((0xff0000 | newForkValue) << 8);
}
byte[] hashPrevouts = new byte[32]; byte[] hashPrevouts = new byte[32];
byte[] hashSequence = new byte[32]; byte[] hashSequence = new byte[32];
byte[] hashOutputs = new byte[32]; byte[] hashOutputs = new byte[32];
...@@ -1326,7 +1391,8 @@ public class Transaction extends ChildMessage { ...@@ -1326,7 +1391,8 @@ public class Transaction extends ChildMessage {
uint32ToByteStreamLE(inputs.get(inputIndex).getSequenceNumber(), bos); uint32ToByteStreamLE(inputs.get(inputIndex).getSequenceNumber(), bos);
bos.write(hashOutputs); bos.write(hashOutputs);
uint32ToByteStreamLE(this.lockTime, bos); uint32ToByteStreamLE(this.lockTime, bos);
uint32ToByteStreamLE(0x000000ff & sigHashType, bos); // uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
uint32ToByteStreamLE(nSigHashType, bos);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); // Cannot happen. throw new RuntimeException(e); // Cannot happen.
} }
......
...@@ -50,6 +50,23 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -50,6 +50,23 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class TransactionInput extends ChildMessage { public class TransactionInput extends ChildMessage {
/** Magic sequence number that indicates there is no sequence number. */ /** Magic sequence number that indicates there is no sequence number. */
public static final long NO_SEQUENCE = 0xFFFFFFFFL; public static final long NO_SEQUENCE = 0xFFFFFFFFL;
/**
* BIP68: If this flag set, sequence is NOT interpreted as a relative lock-time.
*/
public static final long SEQUENCE_LOCKTIME_DISABLE_FLAG = 1L << 31;
/**
* BIP68: If sequence encodes a relative lock-time and this flag is set, the relative lock-time has units of 512
* seconds, otherwise it specifies blocks with a granularity of 1.
*/
public static final long SEQUENCE_LOCKTIME_TYPE_FLAG = 1L << 22;
/**
* BIP68: If sequence encodes a relative lock-time, this mask is applied to extract that lock-time from the sequence
* field.
*/
public static final long SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
private static final byte[] EMPTY_ARRAY = new byte[0]; private static final byte[] EMPTY_ARRAY = new byte[0];
// Magic outpoint index that indicates the input is in fact unconnected. // Magic outpoint index that indicates the input is in fact unconnected.
private static final long UNCONNECTED = 0xFFFFFFFFL; private static final long UNCONNECTED = 0xFFFFFFFFL;
......
...@@ -427,4 +427,16 @@ public class TransactionOutput extends ChildMessage { ...@@ -427,4 +427,16 @@ public class TransactionOutput extends ChildMessage {
public int hashCode() { public int hashCode() {
return Objects.hashCode(value, parent, Arrays.hashCode(scriptBytes)); return Objects.hashCode(value, parent, Arrays.hashCode(scriptBytes));
} }
public boolean isOpReturn() {
return getScriptPubKey() != null && getScriptPubKey().isOpReturn();
}
public byte[] getOpReturnData() {
if (isOpReturn()) {
return getScriptPubKey().getChunks().get(1).data;
}
return null;
}
} }
/* /*
* Copyright 2011 Google Inc. * Copyright 2011 Google Inc.
* Copyright 2018 the bitcoinj-cash developers
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -12,6 +13,9 @@ ...@@ -12,6 +13,9 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
* This file has been modified by the bitcoinj-cash developers for the bitcoinj-cash project.
* The original file was from the bitcoinj project (https://github.com/bitcoinj/bitcoinj).
*/ */
package org.bitcoinj.core; package org.bitcoinj.core;
...@@ -30,15 +34,22 @@ public class VerificationException extends RuntimeException { ...@@ -30,15 +34,22 @@ public class VerificationException extends RuntimeException {
super(msg, t); super(msg, t);
} }
public static class EmptyInputsOrOutputs extends VerificationException { public static class BlockVersionOutOfDate extends VerificationException {
public EmptyInputsOrOutputs() { public BlockVersionOutOfDate(final long version) {
super("Transaction had no inputs or no outputs."); super("Block version #"
+ version + " is outdated.");
} }
} }
public static class LargerThanMaxBlockSize extends VerificationException { public static class CoinbaseHeightMismatch extends VerificationException {
public LargerThanMaxBlockSize() { public CoinbaseHeightMismatch(final String message) {
super("Transaction larger than MAX_BLOCK_SIZE"); super(message);
}
}
public static class CoinbaseScriptSizeOutOfRange extends VerificationException {
public CoinbaseScriptSizeOutOfRange() {
super("Coinbase script size out of range");
} }
} }
...@@ -48,9 +59,9 @@ public class VerificationException extends RuntimeException { ...@@ -48,9 +59,9 @@ public class VerificationException extends RuntimeException {
} }
} }
public static class NegativeValueOutput extends VerificationException { public static class EmptyInputsOrOutputs extends VerificationException {
public NegativeValueOutput() { public EmptyInputsOrOutputs() {
super("Transaction output negative"); super("Transaction had no inputs or no outputs.");
} }
} }
...@@ -60,30 +71,32 @@ public class VerificationException extends RuntimeException { ...@@ -60,30 +71,32 @@ public class VerificationException extends RuntimeException {
} }
} }
public static class LargerThanMaxBlockSize extends VerificationException {
public LargerThanMaxBlockSize() {
super("Transaction larger than MAX_BLOCK_SIZE");
}
}
public static class CoinbaseScriptSizeOutOfRange extends VerificationException { public static class NegativeValueOutput extends VerificationException {
public CoinbaseScriptSizeOutOfRange() { public NegativeValueOutput() {
super("Coinbase script size out of range"); super("Transaction output negative");
} }
} }
public static class SignatureFormatError extends VerificationException {
public SignatureFormatError(String msg) {
super(msg);
}
public static class BlockVersionOutOfDate extends VerificationException { public SignatureFormatError(Exception e) {
public BlockVersionOutOfDate(final long version) { super(e);
super("Block version #"
+ version + " is outdated.");
} }
} }
public static class UnexpectedCoinbaseInput extends VerificationException { public static class UnexpectedCoinbaseInput extends VerificationException {
public UnexpectedCoinbaseInput() { public UnexpectedCoinbaseInput() {
super("Coinbase input as input in non-coinbase transaction"); super("Coinbase input as input in non-coinbase transaction");
} }
} }
public static class CoinbaseHeightMismatch extends VerificationException {
public CoinbaseHeightMismatch(final String message) {
super(message);
}
}
} }
...@@ -89,6 +89,20 @@ public class TransactionSignature extends ECKey.ECDSASignature { ...@@ -89,6 +89,20 @@ public class TransactionSignature extends ECKey.ECDSASignature {
return sighashFlags; return sighashFlags;
} }
/**
* Checkes if the Hashtype is properly set in the signature.
* (from bicopinj-cash)
*
* @param signature Signature
* @return True (correct Hashtype)/ False
*/
public static boolean isValidHashType(byte[] signature) {
boolean result = true;
int hashType = (signature[signature.length-1] & 0xff) & ~(Transaction.SigHash.ANYONECANPAY.value| SigHash.FORKID.value); // mask the byte to prevent sign-extension hurting us
if (hashType < Transaction.SigHash.ALL.value || hashType > Transaction.SigHash.SINGLE.value)
result = false;
return result;
}
/** /**
* Returns true if the given signature is has canonical encoding, and will thus be accepted as standard by * Returns true if the given signature is has canonical encoding, and will thus be accepted as standard by
* Bitcoin Core. DER and the SIGHASH encoding allow for quite some flexibility in how the same structures * Bitcoin Core. DER and the SIGHASH encoding allow for quite some flexibility in how the same structures
...@@ -103,11 +117,9 @@ public class TransactionSignature extends ECKey.ECDSASignature { ...@@ -103,11 +117,9 @@ public class TransactionSignature extends ECKey.ECDSASignature {
// Where R and S are not negative (their first byte has its highest bit not set), and not // Where R and S are not negative (their first byte has its highest bit not set), and not
// excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
// in which case a single 0 byte is necessary and even required). // in which case a single 0 byte is necessary and even required).
if (signature.length < 9 || signature.length > 73)
return false;
int hashType = (signature[signature.length-1] & 0xff) & ~(Transaction.SigHash.ANYONECANPAY.value| SigHash.FORKID.value); // mask the byte to prevent sign-extension hurting us
if (hashType < Transaction.SigHash.ALL.value || hashType > Transaction.SigHash.SINGLE.value) if (signature.length < 9 || signature.length > 73)
return false; return false;
// "wrong type" "wrong length marker" // "wrong type" "wrong length marker"
......
/*
* Copyright 2017 Nicola Atzei
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bitcoinj.script;
import java.util.HashMap;
import java.util.Map;
public enum ScriptError {
SCRIPT_ERR_OK("OK"),
SCRIPT_ERR_UNKNOWN_ERROR("UNKNOWN_ERROR"),
SCRIPT_ERR_EVAL_FALSE("EVAL_FALSE"),
SCRIPT_ERR_OP_RETURN("OP_RETURN"),
SCRIPT_ERR_STANDARD("STANDARD_SCRIPT"),
/* Max sizes */
SCRIPT_ERR_SCRIPT_SIZE("SCRIPT_SIZE"),
SCRIPT_ERR_PUSH_SIZE("PUSH_SIZE"),
SCRIPT_ERR_OP_COUNT("OP_COUNT"),
SCRIPT_ERR_STACK_SIZE("STACK_SIZE"),
SCRIPT_ERR_SIG_COUNT("SIG_COUNT"),
SCRIPT_ERR_PUBKEY_COUNT("PUBKEY_COUNT"),
SCRIPT_ER_OPERAND_SIZE("OPERAND_SIZE"),
/* Failed verify operations */
SCRIPT_ERR_VERIFY("VERIFY"),
SCRIPT_ERR_EQUALVERIFY("EQUALVERIFY"),
SCRIPT_ERR_CHECKMULTISIGVERIFY("CHECKMULTISIGVERIFY"),
SCRIPT_ERR_CHECKSIGVERIFY("CHECKSIGVERIFY"),
SCRIPT_ERR_NUMEQUALVERIFY("NUMEQUALVERIFY"),
/* Logical/Format/Canonical errors */
SCRIPT_ERR_BAD_OPCODE("BAD_OPCODE"),
SCRIPT_ERR_DISABLED_OPCODE("DISABLED_OPCODE"),
SCRIPT_ERR_INVALID_STACK_OPERATION("INVALID_STACK_OPERATION"),
SCRIPT_ERR_INVALID_ALTSTACK_OPERATION("INVALID_ALTSTACK_OPERATION"),
SCRIPT_ERR_UNBALANCED_CONDITIONAL("UNBALANCED_CONDITIONAL"),
/* CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY */
SCRIPT_ERR_NEGATIVE_LOCKTIME("NEGATIVE_LOCKTIME"),
SCRIPT_ERR_UNSATISFIED_LOCKTIME("UNSATISFIED_LOCKTIME"),
/* Malleability */
SCRIPT_ERR_SIG_HASHTYPE("SIG_HASHTYPE"),
SCRIPT_ERR_SIG_DER("SIG_DER"),
SCRIPT_ERR_MINIMALDATA("MINIMALDATA"),
SCRIPT_ERR_SIG_PUSHONLY("SIG_PUSHONLY"),
SCRIPT_ERR_SIG_HIGH_S("SIG_HIGH_S"),
SCRIPT_ERR_SIG_NULLDUMMY("SIG_NULLDUMMY"),
SCRIPT_ERR_PUBKEYTYPE("PUBKEYTYPE"),
SCRIPT_ERR_CLEANSTACK("CLEANSTACK"),
SCRIPT_ERR_MINIMALIF("MINIMALIF"),
SCRIPT_ERR_SIG_NULLFAIL("NULLFAIL"),
/* softfork safeness */
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS("DISCOURAGE_UPGRADABLE_NOPS"),
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"),
/* Other Errors */
SCRIPT_ERR_DIV_BY_ZERO("DIV_BY_ZERO"),
SCRIPT_ERR_MOD_BY_ZERO("MOD_BY_ZERO"),
SCRIPT_ERR_SPLIT_RANGE("SPLIT_RANGE"),
SCRIPT_ERR_IMPOSSIBLE_ENCODING("IMPOSSIBLE_ENCODING"),
SCRIPT_ERR_INVALID_NUMBER_RANGE("INVALID_NUMBER_RANGE"),
SCRIPT_ERR_FORKID("ILLEGAL_FORKID");
private final String mnemonic;
private static final Map<String, ScriptError> mnemonicToScriptErrorMap;
private ScriptError(String name) {
this.mnemonic = name;
}
static {
mnemonicToScriptErrorMap = new HashMap<>();
for (ScriptError err : ScriptError.values()) {
mnemonicToScriptErrorMap.put(err.getMnemonic(), err);
}
}
public String getMnemonic() {
return mnemonic;
}
public static ScriptError fromMnemonic(String name) {
ScriptError err = mnemonicToScriptErrorMap.get(name);
if (err == null)
throw new IllegalArgumentException(name + " is not a valid name");
return err;
}
}
\ No newline at end of file
/* /*
* Copyright 2013 Google Inc. * Copyright 2013 Google Inc.
* Copyright 2018 the bitcoinj-cash developers
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -12,6 +13,9 @@ ...@@ -12,6 +13,9 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*