Skip to content

Commit

Permalink
create a shared library to make creating wallets easier. (dashpay#1130)
Browse files Browse the repository at this point in the history
* create a shared library whose API presents the complicated or time consuming functions needed for creating and sending transactions
  • Loading branch information
gandrewstone authored and wagerr-builder committed Oct 21, 2022
1 parent c0ca89b commit e4d10ee
Show file tree
Hide file tree
Showing 4 changed files with 393 additions and 157 deletions.
45 changes: 44 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ LIBBITCOIN_ZMQ=libdash_zmq.a
endif
if BUILD_BITCOIN_LIBS
LIBBITCOINCONSENSUS=libdashconsensus.la
LIBBITCOINCORE=libdashcore.la
endif
if ENABLE_WALLET
LIBBITCOIN_WALLET=libdash_wallet.a
Expand Down Expand Up @@ -97,7 +98,7 @@ EXTRA_LIBRARIES += \
$(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_ZMQ)

lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
lib_LTLIBRARIES = $(LIBBITCOINCORE) $(LIBBITCOINCONSENSUS)

bin_PROGRAMS =
noinst_PROGRAMS =
Expand Down Expand Up @@ -439,6 +440,31 @@ libdash_wallet_a_SOURCES = \
wallet/coinselection.cpp \
$(BITCOIN_CORE_H)

libdashcore_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
libdashcore_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)

libdashcore_a_SOURCES = \
wagerrlib/wagerrlib.cpp \
script/sigcommon.cpp \
hash.cpp \
hash.h \
key.cpp \
key.h \
primitives/transaction.cpp \
primitives/transaction.h \
pubkey.cpp \
pubkey.h \
random.cpp \
random.h \
support/cleanse.cpp \
support/cleanse.h \
uint256.cpp \
uint256.h \
utilstrencodings.cpp \
utilstrencodings.h \
utiltime.cpp \
utiltime.h

# crypto primitives library
crypto_libdash_crypto_base_a_CPPFLAGS = $(AM_CPPFLAGS) $(PIC_FLAGS)
crypto_libdash_crypto_base_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) $(PIC_FLAGS)
Expand Down Expand Up @@ -573,6 +599,7 @@ libdash_consensus_a_SOURCES = \
script/script.h \
script/script_error.cpp \
script/script_error.h \
script/sigcommon.cpp \
serialize.h \
span.h \
streams.h \
Expand Down Expand Up @@ -726,6 +753,22 @@ dash_tx_LDADD = \
dash_tx_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(CRYPTO_LIBS) $(BLS_LIBS)
#

# dashcore library #
if BUILD_BITCOIN_LIBS
libdashcore_la_SOURCES = $(libdashcore_a_SOURCES) $(crypto_libdash_crypto_a_SOURCES)

if GLIBC_BACK_COMPAT
libdashcore_la_SOURCES += compat/glibc_compat.cpp
endif

libdashcore_la_LDFLAGS = $(AM_LDFLAGS) $(SSL_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS) -no-undefined $(RELDFLAGS)
libdashcore_la_LIBADD = $(LIBSECP256K1)
libdashcore_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(BOOST_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL
libdashcore_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)

endif
#

# dashconsensus library #
if BUILD_BITCOIN_LIBS
include_HEADERS = script/dashconsensus.h
Expand Down
156 changes: 0 additions & 156 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1279,162 +1279,6 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
return set_success(serror);
}

namespace {

/**
* Wrapper that serializes like CTransaction, but with the modifications
* required for the signature hash done in-place
*/
class CTransactionSignatureSerializer {
private:
const CTransaction& txTo; //!< reference to the spending transaction (the one being serialized)
const CScript& scriptCode; //!< output script being consumed
const unsigned int nIn; //!< input index of txTo being signed
const bool fAnyoneCanPay; //!< whether the hashtype has the SIGHASH_ANYONECANPAY flag set
const bool fHashSingle; //!< whether the hashtype is SIGHASH_SINGLE
const bool fHashNone; //!< whether the hashtype is SIGHASH_NONE

public:
CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) :
txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE),
fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {}

/** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */
template<typename S>
void SerializeScriptCode(S &s) const {
CScript::const_iterator it = scriptCode.begin();
CScript::const_iterator itBegin = it;
opcodetype opcode;
unsigned int nCodeSeparators = 0;
while (scriptCode.GetOp(it, opcode)) {
if (opcode == OP_CODESEPARATOR)
nCodeSeparators++;
}
::WriteCompactSize(s, scriptCode.size() - nCodeSeparators);
it = itBegin;
while (scriptCode.GetOp(it, opcode)) {
if (opcode == OP_CODESEPARATOR) {
s.write((char*)&itBegin[0], it-itBegin-1);
itBegin = it;
}
}
if (itBegin != scriptCode.end())
s.write((char*)&itBegin[0], it-itBegin);
}

/** Serialize an input of txTo */
template<typename S>
void SerializeInput(S &s, unsigned int nInput) const {
// In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized
if (fAnyoneCanPay)
nInput = nIn;
// Serialize the prevout
::Serialize(s, txTo.vin[nInput].prevout);
// Serialize the script
if (nInput != nIn)
// Blank out other inputs' signatures
::Serialize(s, CScript());
else
SerializeScriptCode(s);
// Serialize the nSequence
if (nInput != nIn && (fHashSingle || fHashNone))
// let the others update at will
::Serialize(s, (int)0);
else
::Serialize(s, txTo.vin[nInput].nSequence);
}

/** Serialize an output of txTo */
template<typename S>
void SerializeOutput(S &s, unsigned int nOutput) const {
if (fHashSingle && nOutput != nIn)
// Do not lock-in the txout payee at other indices as txin
::Serialize(s, CTxOut());
else
::Serialize(s, txTo.vout[nOutput]);
}

/** Serialize txTo */
template<typename S>
void Serialize(S &s) const {
// Serialize nVersion
int32_t n32bitVersion = txTo.nVersion | (txTo.nType << 16);
::Serialize(s, n32bitVersion);
// Serialize vin
unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size();
::WriteCompactSize(s, nInputs);
for (unsigned int nInput = 0; nInput < nInputs; nInput++)
SerializeInput(s, nInput);
// Serialize vout
unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size());
::WriteCompactSize(s, nOutputs);
for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++)
SerializeOutput(s, nOutput);
// Serialize nLockTime
::Serialize(s, txTo.nLockTime);
if (txTo.nVersion == 3 && txTo.nType != TRANSACTION_NORMAL)
::Serialize(s, txTo.vExtraPayload);
}
};

uint256 GetPrevoutHash(const CTransaction& txTo) {
CHashWriter ss(SER_GETHASH, 0);
for (const auto& txin : txTo.vin) {
ss << txin.prevout;
}
return ss.GetHash();
}

uint256 GetSequenceHash(const CTransaction& txTo) {
CHashWriter ss(SER_GETHASH, 0);
for (const auto& txin : txTo.vin) {
ss << txin.nSequence;
}
return ss.GetHash();
}

uint256 GetOutputsHash(const CTransaction& txTo) {
CHashWriter ss(SER_GETHASH, 0);
for (const auto& txout : txTo.vout) {
ss << txout;
}
return ss.GetHash();
}

} // namespace

PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo)
{
hashPrevouts = GetPrevoutHash(txTo);
hashSequence = GetSequenceHash(txTo);
hashOutputs = GetOutputsHash(txTo);
}

uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache)
{
assert(nIn < txTo.vin.size());

static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));

// Check for invalid use of SIGHASH_SINGLE
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
if (nIn >= txTo.vout.size()) {
// nOut out of range
return one;
}
}

// Wrapper to serialize only the necessary parts of the transaction being signed
CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType);

// Serialize and hash
CHashWriter ss(SER_GETHASH, 0);
ss << txTmp << nHashType;
return ss.GetHash();
}

bool BaseSignatureChecker::VerifySignature(const std::vector<uint8_t>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
return pubkey.Verify(sighash, vchSig);
Expand Down
Loading

0 comments on commit e4d10ee

Please sign in to comment.