-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #60 from twostack/expose-pre-image
V2 Refactor
- Loading branch information
Showing
43 changed files
with
3,206 additions
and
2,778 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import 'dart:typed_data'; | ||
|
||
import 'package:dartsv/dartsv.dart'; | ||
import 'package:hex/hex.dart'; | ||
|
||
/// Utility class to represent a parsed 'token' in the encoded script. | ||
class ScriptChunk { | ||
|
||
List<int> _buf; | ||
int _len; | ||
int _opcodenum; | ||
|
||
///Construct a ScriptChunk | ||
/// | ||
/// [_buf] - Buffer containing data in case of OP_PUSHDATA | ||
/// | ||
/// [_len] - length of _buf | ||
/// | ||
/// [_opcodenum] - Bitcoin script OpCode. See [OpCodes]. | ||
/// | ||
ScriptChunk(this._buf, this._len, this._opcodenum); | ||
|
||
/// Returns this script chunk's numeric opcode | ||
/// | ||
int get opcodenum => _opcodenum; | ||
|
||
/// Sets this script chunk's numeric opcode | ||
/// | ||
set opcodenum(int value) { | ||
_opcodenum = value; | ||
} | ||
|
||
/// Returns the length of the buffer in case of PUSHDATAx instruction. Zero otherwise. | ||
/// | ||
int get len => _len; | ||
|
||
/// Sets the length of data contained in PUSHDATAx instruction. Zero otherwise. | ||
/// | ||
set len(int value) { | ||
_len = value; | ||
} | ||
|
||
/// Returns the byte array containing the data from a PUSHDATAx instruction. | ||
/// | ||
List<int> get buf => _buf; | ||
|
||
/// Sets the byte array of representing PUSHDATAx instruction. | ||
/// | ||
set buf(List<int> value) { | ||
_buf = value; | ||
} | ||
|
||
bool equalsOpCode(int opcode) { | ||
return opcode == _opcodenum; | ||
} | ||
|
||
/** | ||
* If this chunk is a single byte of non-pushdata content (could be OP_RESERVED or some invalid Opcode) | ||
*/ | ||
bool isOpCode() { | ||
return _opcodenum > OpCodes.OP_PUSHDATA4; | ||
} | ||
|
||
/** | ||
* Returns true if this chunk is pushdata content, including the single-byte pushdatas. | ||
*/ | ||
bool isPushData() { | ||
return _opcodenum <= OpCodes.OP_16; | ||
} | ||
|
||
/** If this chunk is an OP_N opcode returns the equivalent integer value. */ | ||
int decodeOpN() { | ||
return SVScript.decodeFromOpN(_opcodenum); | ||
} | ||
|
||
int size() { | ||
final int opcodeLength = 1; | ||
|
||
int pushDataSizeLength = 0; | ||
if (_opcodenum == OpCodes.OP_PUSHDATA1) pushDataSizeLength = 1; | ||
else if (_opcodenum == OpCodes.OP_PUSHDATA2) pushDataSizeLength = 2; | ||
else if (_opcodenum == OpCodes.OP_PUSHDATA4) pushDataSizeLength = 4; | ||
|
||
final int dataLength = _buf == null ? 0 : _buf.length; | ||
|
||
return opcodeLength + pushDataSizeLength + dataLength; | ||
} | ||
|
||
|
||
/// Checks to see if the PUSHDATA instruction is using the *smallest* pushdata opcode it can. | ||
/// | ||
/// [i] - Index of ScriptChunk. This should be a pushdata instruction. | ||
/// | ||
/// Returns true if the *smallest* pushdata opcode was used. | ||
bool checkMinimalPush(int i) { | ||
|
||
if (_buf.isEmpty) { | ||
// Could have used OP_0. | ||
return (_opcodenum == OpCodes.OP_0); | ||
} else if (_buf.length == 1 && buf[0] >= 1 && buf[0] <= 16) { | ||
// Could have used OP_1 .. OP_16. | ||
return _opcodenum == OpCodes.OP_1 + (buf[0] - 1); | ||
} else if (_buf.length == 1 && buf[0] == 0x81) { | ||
// Could have used OP_1NEGATE | ||
return _opcodenum == OpCodes.OP_1NEGATE; | ||
} else if (_buf.length <= 75) { | ||
// Could have used a direct push (opcode indicating number of bytes pushed + those bytes). | ||
return _opcodenum == buf.length; | ||
} else if (_buf.length <= 255) { | ||
// Could have used OP_PUSHDATA. | ||
return _opcodenum == OpCodes.OP_PUSHDATA1; | ||
} else if (_buf.length <= 65535) { | ||
// Could have used OP_PUSHDATA2. | ||
return _opcodenum == OpCodes.OP_PUSHDATA2; | ||
} | ||
return true; | ||
} | ||
|
||
String toEncodedString(bool asm){ | ||
StringBuffer str = new StringBuffer(); | ||
if (_buf == null || _buf.length <= 0) { | ||
|
||
// no data chunk | ||
if (!OpCodes.getOpCodeName(opcodenum).startsWith("NON_OP")) { | ||
if (asm) { | ||
// A few cases where the opcode name differs from reverseMap | ||
// aside from 1 to 16 data pushes. | ||
if (opcodenum == 0) { | ||
// OP_0 -> 0 | ||
str.write("0"); | ||
} else if (opcodenum == 79) { | ||
// OP_1NEGATE -> 1 | ||
str.write("-1"); | ||
} else { | ||
str.write( OpCodes.getOpCodeName(opcodenum)); | ||
} | ||
} else { | ||
str.write( OpCodes.getOpCodeName(opcodenum)); | ||
} | ||
} else { | ||
String numstr = HEX.encode([opcodenum]); | ||
|
||
//uneven numbers get padded with a leading zero | ||
if (numstr.length % 2 != 0) { | ||
numstr = "0" + numstr; | ||
} | ||
if (asm) { | ||
str.write( numstr); | ||
} else { | ||
str.write("0x" + numstr); | ||
} | ||
} | ||
} else { | ||
// data chunk | ||
if (!asm && (opcodenum == OpCodes.OP_PUSHDATA1 || | ||
opcodenum == OpCodes.OP_PUSHDATA2 || | ||
opcodenum == OpCodes.OP_PUSHDATA4)) { | ||
str.write( OpCodes.getOpCodeName(opcodenum) + " "); | ||
} | ||
if (_buf.length > 0) { | ||
if (asm) { | ||
str.write(HEX.encode(_buf)); | ||
} else { | ||
str.write("${_buf.length} 0x${HEX.encode(_buf)}"); | ||
} | ||
} | ||
} | ||
return str.toString(); | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
|
||
|
||
import 'dart:core'; | ||
import 'dart:core'; | ||
|
||
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_SPLIT_RANGE("SPLIT_RANGE"), | ||
SCRIPT_ERR_INVALID_NUMBER_RANGE("INVALID_NUMBER_RANGE"), | ||
SCRIPT_ERR_NUMBER_OVERFLOW("SCRIPTNUM_OVERFLOW"), | ||
SCRIPT_ERR_NUMBER_MINENCODE("SCRIPTNUM_MINENCODE"), | ||
SCRIPT_ERR_DIV_BY_ZERO("DIV_BY_ZERO"), | ||
SCRIPT_ERR_MOD_BY_ZERO("MOD_BY_ZERO"), | ||
SCRIPT_ERR_NONCOMPRESSED_PUBKEY("NONCOMPRESSED_PUBKEY"), | ||
SCRIPT_ERR_ILLEGAL_FORKID("ILLEGAL_FORKID"), | ||
SCRIPT_ERR_SIGHASH_FORKID("SIGHASH_FORKID"), | ||
SCRIPT_ERR_MUST_USE_FORKID("MUST_USE_FORKID"), | ||
|
||
/* 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_ERR_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"), | ||
|
||
/* segregated witness */ | ||
SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH("WITNESS_PROGRAM_WRONG_LENGTH"), | ||
SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY("WITNESS_PROGRAM_WITNESS_EMPTY"), | ||
SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH("WITNESS_PROGRAM_MISMATCH"), | ||
SCRIPT_ERR_WITNESS_MALLEATED("WITNESS_MALLEATED"), | ||
SCRIPT_ERR_WITNESS_MALLEATED_P2SH("WITNESS_MALLEATED_P2SH"), | ||
SCRIPT_ERR_WITNESS_UNEXPECTED("WITNESS_UNEXPECTED"), | ||
SCRIPT_ERR_WITNESS_PUBKEYTYPE("WITNESS_PUBKEYTYPE"), | ||
|
||
SCRIPT_ERR_ERROR_COUNT("ERROR_COUNT"); | ||
|
||
final String _mnemonic; | ||
|
||
const ScriptError(this._mnemonic); | ||
|
||
String get mnemonic => _mnemonic; | ||
|
||
} |
Oops, something went wrong.