mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-18 13:17:55 +02:00
bitcoin-tx changes for blinded values
This commit is contained in:
parent
1950b69e6e
commit
8cbec40bec
1 changed files with 72 additions and 4 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#endif
|
||||
|
||||
#include "base58.h"
|
||||
#include "blind.h"
|
||||
#include "clientversion.h"
|
||||
#include "coins.h"
|
||||
#include "consensus/consensus.h"
|
||||
|
|
@ -74,7 +75,8 @@ static int AppInitRawTx(int argc, char* argv[])
|
|||
strUsage = HelpMessageGroup(_("Commands:"));
|
||||
strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
|
||||
strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
|
||||
strUsage += HelpMessageOpt("in=TXID:VOUT(:SEQUENCE_NUMBER)", _("Add input to TX"));
|
||||
strUsage += HelpMessageOpt("in=TXID:VOUT:VALUE(:SEQUENCE_NUMBER)", _("Add input to TX"));
|
||||
strUsage += HelpMessageOpt("blind=B1:B2:B3:...", _("Transaction input blinds"));
|
||||
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
|
||||
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
|
||||
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
|
||||
|
|
@ -208,7 +210,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
|
|||
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
|
||||
|
||||
// separate TXID:VOUT in string
|
||||
if (vStrInputParts.size()<2)
|
||||
if (vStrInputParts.size()<3)
|
||||
throw std::runtime_error("TX input missing separator");
|
||||
|
||||
// extract and validate TXID
|
||||
|
|
@ -226,14 +228,21 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
|
|||
if ((vout < 0) || (vout > (int)maxVout))
|
||||
throw std::runtime_error("invalid TX input vout");
|
||||
|
||||
// extract and validate VALUE
|
||||
std::string strValue = vStrInputParts[2];
|
||||
CAmount value;
|
||||
if (!ParseMoney(strValue, value))
|
||||
throw std::runtime_error("invalid TX output value");
|
||||
|
||||
// extract the optional sequence number
|
||||
uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max();
|
||||
if (vStrInputParts.size() > 2)
|
||||
nSequenceIn = std::stoul(vStrInputParts[2]);
|
||||
if (vStrInputParts.size() > 3)
|
||||
nSequenceIn = std::stoul(vStrInputParts[3]);
|
||||
|
||||
// append to transaction input list
|
||||
CTxIn txin(txid, vout, CScript(), nSequenceIn);
|
||||
tx.vin.push_back(txin);
|
||||
tx.nTxFee += value;
|
||||
}
|
||||
|
||||
static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strInput)
|
||||
|
|
@ -258,7 +267,12 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strIn
|
|||
|
||||
// construct TxOut, append to transaction output list
|
||||
CTxOut txout(value, scriptPubKey);
|
||||
if (addr.IsBlinded()) {
|
||||
CPubKey pubkey = addr.GetBlindingKey();
|
||||
txout.nValue.vchNonceCommitment = std::vector<unsigned char>(pubkey.begin(), pubkey.end());
|
||||
}
|
||||
tx.vout.push_back(txout);
|
||||
tx.nTxFee -= value;
|
||||
}
|
||||
|
||||
static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& strInput)
|
||||
|
|
@ -397,6 +411,52 @@ static void MutateTxAddOutData(CMutableTransaction& tx, const std::string& strIn
|
|||
|
||||
CTxOut txout(value, CScript() << OP_RETURN << data);
|
||||
tx.vout.push_back(txout);
|
||||
tx.nTxFee -= value;
|
||||
}
|
||||
|
||||
static void MutateTxBlind(CMutableTransaction& tx, const std::string& strInput)
|
||||
{
|
||||
std::vector<std::string> input_blinding_factors;
|
||||
boost::split(input_blinding_factors, strInput, boost::is_any_of(":"));
|
||||
|
||||
if (input_blinding_factors.size() != tx.vin.size())
|
||||
throw std::runtime_error("One input blinding factor required per transaction input");
|
||||
|
||||
bool fBlindedIns = false;
|
||||
bool fBlindedOuts = false;
|
||||
std::vector<uint256> input_blinds;
|
||||
std::vector<uint256> output_blinds;
|
||||
std::vector<CPubKey> output_pubkeys;
|
||||
for (size_t nIn = 0; nIn < tx.vin.size(); nIn++) {
|
||||
uint256 blind;
|
||||
blind.SetHex(input_blinding_factors[nIn]);
|
||||
if (blind.size() == 0) {
|
||||
input_blinds.push_back(blind);
|
||||
} else if (blind.size() == 32) {
|
||||
input_blinds.push_back(blind);
|
||||
fBlindedIns = true;
|
||||
}
|
||||
}
|
||||
for (size_t nOut = 0; nOut < tx.vout.size(); nOut++) {
|
||||
if (!tx.vout[nOut].nValue.IsAmount())
|
||||
throw std::runtime_error("Invalid parameter: transaction outputs must be unblinded");
|
||||
if (tx.vout[nOut].nValue.vchNonceCommitment.size() == 0) {
|
||||
output_pubkeys.push_back(CPubKey());
|
||||
} else {
|
||||
CPubKey pubkey(tx.vout[nOut].nValue.vchNonceCommitment);
|
||||
if (!pubkey.IsValid()) {
|
||||
throw std::runtime_error("Invalid parameter: invalid confidentiality public key given");
|
||||
}
|
||||
output_pubkeys.push_back(pubkey);
|
||||
fBlindedOuts = true;
|
||||
}
|
||||
output_blinds.push_back(uint256());
|
||||
}
|
||||
|
||||
if (fBlindedIns && !fBlindedOuts) {
|
||||
throw std::runtime_error("Confidential inputs without confidential outputs");
|
||||
}
|
||||
BlindOutputs(input_blinds, output_blinds, output_pubkeys, tx);
|
||||
}
|
||||
|
||||
static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& strInput)
|
||||
|
|
@ -434,10 +494,13 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& str
|
|||
// construct TxOut, append to transaction output list
|
||||
CTxOut txout(value, scriptPubKey);
|
||||
tx.vout.push_back(txout);
|
||||
tx.nTxFee -= value;
|
||||
}
|
||||
|
||||
static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInIdx)
|
||||
{
|
||||
// TODO: reduce nTxFee
|
||||
|
||||
// parse requested deletion index
|
||||
int inIdx = atoi(strInIdx);
|
||||
if (inIdx < 0 || inIdx >= (int)tx.vin.size()) {
|
||||
|
|
@ -451,6 +514,8 @@ static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInId
|
|||
|
||||
static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOutIdx)
|
||||
{
|
||||
// TODO: increase nTxFee
|
||||
|
||||
// parse requested deletion index
|
||||
int outIdx = atoi(strOutIdx);
|
||||
if (outIdx < 0 || outIdx >= (int)tx.vout.size()) {
|
||||
|
|
@ -685,6 +750,9 @@ static void MutateTx(CMutableTransaction& tx, const std::string& command,
|
|||
else if (command == "sign") {
|
||||
if (!ecc) { ecc.reset(new Secp256k1Init()); }
|
||||
MutateTxSign(tx, commandVal);
|
||||
} else if (command == "blind") {
|
||||
if (!ecc) { ecc.reset(new Secp256k1Init()); }
|
||||
MutateTxBlind(tx, commandVal);
|
||||
}
|
||||
|
||||
else if (command == "load")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue