Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix signing of createrawtransaction name_update's #80

Merged
merged 7 commits into from
May 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
v0.3.74
======
* allow for atomic name transactions via rpc commands (Domob)
* new rpc commands: name_pending, getchains (Domob)
* Simplified blkindex.dat for smaller file size and faster startup - not backward compatible ("remove auxpow", Domob) - IT WILL TAKE A WHILE FOR THE REWRITE ON THE FIRST START
* Implement name_update in createrawtransaction (Domob)
Expand Down
44 changes: 6 additions & 38 deletions src/namecoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,32 +230,6 @@ CScript RemoveNameScriptPrefix(const CScript& scriptIn)
return CScript(pc, scriptIn.end());
}

bool SignNameSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript())
{
assert(nIn < txTo.vin.size());
CTxIn& txin = txTo.vin[nIn];
assert(txin.prevout.n < txFrom.vout.size());
const CTxOut& txout = txFrom.vout[txin.prevout.n];

// Leave out the signature from the hash, since a signature can't sign itself.
// The checksig op will also drop the signatures from its hash.

const CScript& scriptPubKey = RemoveNameScriptPrefix(txout.scriptPubKey);
uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);

if (!Solver(*pwalletMain, scriptPubKey, hash, nHashType, txin.scriptSig))
return false;

txin.scriptSig = scriptPrereq + txin.scriptSig;

// Test solution
if (scriptPrereq.empty())
if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))
return false;

return true;
}

bool IsMyName(const CTransaction& tx, const CTxOut& txout)
{
const CScript& scriptPubKey = RemoveNameScriptPrefix(txout.scriptPubKey);
Expand All @@ -265,7 +239,7 @@ bool IsMyName(const CTransaction& tx, const CTxOut& txout)
return true;
}

bool CreateTransactionWithInputTx(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxIn, int nTxOut, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
bool CreateTransactionWithInputTx(const vector<pair<CScript, int64> >& vecSend, const CWalletTx& wtxIn, int nTxOut, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
{
int64 nValue = 0;
BOOST_FOREACH(const PAIRTYPE(CScript, int64)& s, vecSend)
Expand Down Expand Up @@ -366,16 +340,8 @@ bool CreateTransactionWithInputTx(const vector<pair<CScript, int64> >& vecSend,
int nIn = 0;
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int)& coin, vecCoins)
{
if (coin.first == &wtxIn && coin.second == nTxOut)
{
if (!SignNameSignature(*coin.first, wtxNew, nIn++))
throw runtime_error("could not sign name coin output");
}
else
{
if (!SignSignature(*pwalletMain, *coin.first, wtxNew, nIn++))
return false;
}
if (!SignSignature(*pwalletMain, *coin.first, wtxNew, nIn++))
return false;
}

// Limit size
Expand Down Expand Up @@ -409,7 +375,7 @@ bool CreateTransactionWithInputTx(const vector<pair<CScript, int64> >& vecSend,

// nTxOut is the output from wtxIn that we should grab
// requires cs_main lock
string SendMoneyWithInputTx(CScript scriptPubKey, int64 nValue, int64 nNetFee, CWalletTx& wtxIn, CWalletTx& wtxNew, bool fAskFee)
string SendMoneyWithInputTx(const CScript& scriptPubKey, int64 nValue, int64 nNetFee, const CWalletTx& wtxIn, CWalletTx& wtxNew, bool fAskFee)
{
int nTxOut = IndexOfNameOutput(wtxIn);
CReserveKey reservekey(pwalletMain);
Expand Down Expand Up @@ -1385,6 +1351,8 @@ AddRawTxNameOperation (CTransaction& tx, const Object& obj)
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, msg.str ());
}

tx.nVersion = NAMECOIN_TX_VERSION;

/* Find the transaction input to add. */

CRITICAL_BLOCK(cs_main)
Expand Down
4 changes: 2 additions & 2 deletions src/namecoin.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ bool DecodeNameTx(const CTransaction& tx, int& op, int& nOut, std::vector<std::v
bool DecodeNameScript(const CScript& script, int& op, std::vector<std::vector<unsigned char> > &vvch, CScript::const_iterator& pc);
bool DecodeNameScript(const CScript& script, int& op, std::vector<std::vector<unsigned char> > &vvch);
bool GetNameAddress(const CTransaction& tx, std::string& strAddress);
std::string SendMoneyWithInputTx(CScript scriptPubKey, int64 nValue, int64 nNetFee, CWalletTx& wtxIn, CWalletTx& wtxNew, bool fAskFee);
bool CreateTransactionWithInputTx(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxIn, int nTxOut, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
std::string SendMoneyWithInputTx(const CScript& scriptPubKey, int64 nValue, int64 nNetFee, const CWalletTx& wtxIn, CWalletTx& wtxNew, bool fAskFee);
bool CreateTransactionWithInputTx(const std::vector<std::pair<CScript, int64> >& vecSend, const CWalletTx& wtxIn, int nTxOut, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
int64 GetNetworkFee(int nHeight);

/* Handle the name operation part of the RPC call createrawtransaction. */
Expand Down
54 changes: 16 additions & 38 deletions src/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
#include "namecoin.h"

using namespace std;
using namespace boost;
Expand Down Expand Up @@ -1248,58 +1249,35 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransa
assert(nIn < txTo.vin.size());
CTxIn& txin = txTo.vin[nIn];

/* Try to decode a name script and strip it if it is there. */
int op;
std::vector<vchType> vvch;
CScript::const_iterator pc = fromPubKey.begin ();
CScript rawScript;
if (DecodeNameScript (fromPubKey, op, vvch, pc))
rawScript = CScript(pc, fromPubKey.end ());
else
rawScript = fromPubKey;

// Leave out the signature from the hash, since a signature can't sign itself.
// The checksig op will also drop the signatures from its hash.
uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType);
const uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType);

//txnouttype whichType;
if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig /* , whichType */ ))
if (!Solver(keystore, rawScript, hash, nHashType, txin.scriptSig))
return false;

/*if (whichType == TX_SCRIPTHASH)
{
// Solver returns the subscript that need to be evaluated;
// the final scriptSig is the signatures from that
// and then the serialized subscript:
CScript subscript = txin.scriptSig;

// Recompute txn hash using subscript in place of scriptPubKey:
uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType);

txnouttype subType;
bool fSolved =
Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH;
// Append serialized subscript whether or not it is completely signed:
txin.scriptSig << static_cast<valtype>(subscript);
if (!fSolved) return false;
}*/

// Test solution
return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn /* , true, true */ , 0);
return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, 0);
}

bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType)
{
assert(nIn < txTo.vin.size());
CTxIn& txin = txTo.vin[nIn];
assert(txin.prevout.n < txFrom.vout.size());
const CTxOut& txout = txFrom.vout[txin.prevout.n];

// Leave out the signature from the hash, since a signature can't sign itself.
// The checksig op will also drop the signatures from its hash.
uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);

if (!Solver(keystore, txout.scriptPubKey, hash, nHashType, txin.scriptSig))
return false;

txin.scriptSig = scriptPrereq + txin.scriptSig;

// Test solution
if (scriptPrereq.empty())
if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))
return false;

return true;
return SignSignature (keystore, txout.scriptPubKey, txTo, nIn, nHashType);
}


Expand Down
2 changes: 1 addition & 1 deletion src/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* pkeystore, std:
bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType);
bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript());
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0);
bool ExtractDestination(const CScript& scriptPubKey, std::string& addressRet);

Expand Down