Skip to content

Conversation

@jnewbery
Copy link
Contributor

@jnewbery jnewbery commented Oct 4, 2016

bitcoin-tx can currently create transactions with the following TXO types:

  • Pay to Pub Key Hash
  • null data (OP_RETURN)
  • Pay to Script Hash

This PR enhances bitcoin-tx so all remaining standard TXO types can be created:

  • Pay to Pub Key
  • Multi-sig
    • bare multi-sig
    • multi-sig in Pay To Script Hash
    • multi-sig in Pay to Witness Script Hash
    • multi-sig in Pay to Witness Script Hash, wrapped in P2SH
  • Pay to Witness Pub Key Hash
    • Pay to Witness Pub Key Hash, wrapped in P2SH
  • Pay to Witness Script Hash
    • Pay to Witness Script Hash, wrapped in P2SH

The PR also includes new test cases for all tx types.

@fanquake
Copy link
Member

fanquake commented Oct 5, 2016

Windows builds are failing:

make[2]: Entering directory `/home/travis/build/bitcoin/bitcoin/build/src'
  CXX      bitcoin_tx-bitcoin-tx.o
../../src/bitcoin-tx.cpp: In function ‘void MutateTxAddOutMultiSig(CMutableTransaction&, const string&)’:
../../src/bitcoin-tx.cpp:309:5: error: ‘uint’ was not declared in this scope
     uint required = std::stoul(vStrInputParts[1]);
     ^
../../src/bitcoin-tx.cpp:309:10: error: expected ‘;’ before ‘required’
     uint required = std::stoul(vStrInputParts[1]);
          ^
../../src/bitcoin-tx.cpp:312:10: error: expected ‘;’ before ‘numkeys’
     uint numkeys = std::stoul(vStrInputParts[2]);
          ^
../../src/bitcoin-tx.cpp:315:33: error: ‘numkeys’ was not declared in this scope
     if (vStrInputParts.size() < numkeys + 3)
                                 ^
../../src/bitcoin-tx.cpp:318:9: error: ‘required’ was not declared in this scope
     if (required < 1 || required > 20 || numkeys < 1 || numkeys > 20 || numkeys < required)
         ^
../../src/bitcoin-tx.cpp:318:42: error: ‘numkeys’ was not declared in this scope
     if (required < 1 || required > 20 || numkeys < 1 || numkeys > 20 || numkeys < required)
                                          ^
../../src/bitcoin-tx.cpp:324:14: error: expected ‘;’ before ‘pos’
     for(uint pos = 1; pos <= numkeys; pos++) {
              ^
../../src/bitcoin-tx.cpp:324:23: error: ‘pos’ was not declared in this scope
     for(uint pos = 1; pos <= numkeys; pos++) {
                       ^
../../src/bitcoin-tx.cpp:324:30: error: ‘numkeys’ was not declared in this scope
     for(uint pos = 1; pos <= numkeys; pos++) {
                              ^
../../src/bitcoin-tx.cpp:334:34: error: ‘numkeys’ was not declared in this scope
     if (vStrInputParts.size() == numkeys + 4) {
                                  ^
../../src/bitcoin-tx.cpp:344:49: error: ‘required’ was not declared in this scope
     CScript scriptPubKey = GetScriptForMultisig(required, pubkeys);
                                                 ^
make[2]: *** [bitcoin_tx-bitcoin-tx.o] Error 1
make[2]: Leaving directory `/home/travis/build/bitcoin/bitcoin/build/src'
make[1]: *** [check-recursive] Error 1
make[1]: Leaving directory `/home/travis/build/bitcoin/bitcoin/build/src'
make: *** [check-recursive] Error 1

@jnewbery jnewbery force-pushed the add-p2sh-segwit-options-to-bitcoin-tx branch from c23fa1d to ca0f851 Compare October 5, 2016 13:48
@paveljanik
Copy link
Contributor

Concept ACK

New warning:

bitcoin-tx.cpp:283:25: warning: declaration shadows a local variable [-Wshadow]
        CBitcoinAddress addr(scriptPubKey);
                        ^
bitcoin-tx.cpp:265:21: note: previous declaration is here
    CBitcoinAddress addr(scriptPubKey);
                    ^
1 warning generated.

@jnewbery jnewbery force-pushed the add-p2sh-segwit-options-to-bitcoin-tx branch from ca0f851 to f6bbe64 Compare October 5, 2016 19:03
@jnewbery
Copy link
Contributor Author

jnewbery commented Oct 5, 2016

Thanks @paveljanik . Fixed in squashed commit.

@paveljanik
Copy link
Contributor

-Wshadow clean now, thanks!

I'll read the changes later tonight.

_("Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output") + ". " +
_("Optionally add the \"S\" flag to wrap the output in a pay-to-script-hash."));
strUsage += HelpMessageOpt("outmultisig=VALUE:REQUIRED:PUBKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]", _("Add Pay To n-of-m Multi-sig output to TX. n = REQUIRED, m = PUBKEYS") + ". " +
_("Optionally add the \"W\" flag to produce a pay-to-witness-script-hash output") + ". " +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you sometimes translate dot at the end of sentence and sometimes not?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for some reason I get a compile error when I put the dot in the sentence:

bitcoin-tx.cpp:79:13: error: expected ')'
            _("Optionally add the \"W\" flag to produce a pay-to-witness-pubkey-hash output") + ". " +
            ^
bitcoin-tx.cpp:78:35: note: to match this '('
        strUsage += HelpMessageOpt("outpubkey=VALUE:PUBKEY[:FLAGS]", _("Add pay-to-pubkey output to TX. ")
                                  ^
1 error generated.

(pos == 0) ||
(pos == (strInput.size() - 1)))
throw runtime_error("TX output missing separator");
// Seperate into VALUE:ADDRESS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate (e -> a)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

throw runtime_error("TX output missing separator");
// Seperate into VALUE:ADDRESS
vector<string> vStrInputParts;
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
Copy link
Contributor

@paveljanik paveljanik Oct 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds another dependency on boost. But as we already use it in this file, it is OK. And definitely looks better ;-)

vector<string> vStrInputParts;
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));

// Extract and validate VALUE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ grep "Extract and validate VALUE" bitcoin-tx.cpp 
    // Extract and validate VALUE
    // Extract and validate VALUE
    // Extract and validate VALUE
$ 

What about adding some function for this and share the code in all instances?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 79cd927

@jonasschnelli
Copy link
Contributor

Concept ACK.

bScriptHash = (flags.find("S") != string::npos);
}

if (bSegWit) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for bSegWit and not directly use (flags.find("W") != string::pos)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below. The flags are not exclusive. I need to put the flags.find() test inside the (vStrInputParts.size() == 3) so I may as well parse for both flags at the same point and store the result in variables.

// Call GetScriptForWitness() to build a P2WSH scriptPubKey
scriptPubKey = GetScriptForWitness(scriptPubKey);
}
if (bScriptHash) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a else if?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're not exclusive. If both flags are used, we output a P2WPKH wrapped in P2SH.

CPubKey pubkey(ParseHex(vStrInputParts[1]));
if (!pubkey.IsFullyValid())
throw runtime_error("invalid TX output pubkey");
CScript scriptPubKey = GetScriptForRawPubKey(pubkey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this result in supporting pure P2PK (not P2PKH)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - without either flag, the TXO will be a P2PK.

  • With just the H flag, the TXO is a P2SH
  • With just the W flag, the TXO is a P2WPK
  • With both the H and W flags, the TXO is a P2WPK wrapped in a P2SH

@laanwj
Copy link
Member

laanwj commented Oct 18, 2016

Needs rebase.

@jnewbery jnewbery force-pushed the add-p2sh-segwit-options-to-bitcoin-tx branch from 79cd927 to 1733547 Compare October 18, 2016 20:32
@jnewbery
Copy link
Contributor Author

Rebased. @jonasschnelli - are you happy with my responses above?

@jonasschnelli
Copy link
Contributor

@jnewbery: Yes.
utACK, will test now...

@jonasschnelli
Copy link
Contributor

Travis is failing on the new tests:

Running test/bitcoin-util-test.py...
make[4]: Entering directory `/home/travis/build/bitcoin/bitcoin/build/src'
Output data mismatch for txcreatescript1.json
make[3]: *** [check-local] Error 1
make[3]: *** Waiting for unfinished jobs....

@jnewbery jnewbery force-pushed the add-p2sh-segwit-options-to-bitcoin-tx branch 2 times, most recently from f5b706d to e5fecbf Compare October 24, 2016 14:20
@jnewbery
Copy link
Contributor Author

I've fixed the failing testcases and squashed the commits. @jonasschnelli - please let me know if you have any further feedback for this PR.

@jonasschnelli
Copy link
Contributor

slightly tested ACK e5fecbf64d1dad360490294d1aad79497dcb1de7.
Someone should verify the unit tests fixtures.

@laanwj
Copy link
Member

laanwj commented Dec 14, 2016

utACK.
Needs rebase though.

@laanwj laanwj modified the milestones: 0.15.0, 0.14.0 Dec 14, 2016
@jnewbery jnewbery force-pushed the add-p2sh-segwit-options-to-bitcoin-tx branch from e5fecbf to e0d9e1f Compare December 23, 2016 13:43
@jnewbery
Copy link
Contributor Author

rebased

@maflcko
Copy link
Member

maflcko commented Dec 27, 2016

Travis fails with

2016-12-27 19:30:20,251 - ERROR - Output data mismatch for txcreatescript1.hex (format hex)

Edit: Also make sure to include all new files: #9436

czzarr and others added 3 commits December 29, 2016 15:40
This commit enhances bitcoin-tx so all remaining standard TXO types can be created:

- Pay to Pub Key
- Multi-sig
  - bare multi-sig
  - multi-sig in Pay To Script Hash
  - multi-sig in Pay to Witness Script Hash
  - multi-sig in Pay to Witness Script Hash, wrapped in P2SH
- Pay to Witness Pub Key Hash
  - Pay to Witness Pub Key Hash, wrapped in P2SH
- Pay to Witness Script Hash
  - Pay to Witness Script Hash, wrapped in P2SH
This commit add testcases to test the following functions in bitcoin-tx:

- add a pay to non-standard script output
- add a P2SH output
- add a P2WSH output
- add a P2WSH wrapped in a P2SH output
- add a pay to pub key output
- add a P2WPKH output
- add a P2WPKH wrapped in a P2SH output
- add a bare multisig output
- add a multisig in P2SH output
- add a multisig in a P2WSH output
- add a multisig in a P2WSH wrapped in as P2SH output
@jnewbery jnewbery force-pushed the add-p2sh-segwit-options-to-bitcoin-tx branch from e0d9e1f to b7e144b Compare December 29, 2016 15:41
@jnewbery
Copy link
Contributor Author

jnewbery commented Jan 9, 2017

Rebased. I had to do a couple of large merges (removing std namespace and updating default tx version). @laanwj - let me know if there's anything I can do to help get this merged into master.

@laanwj laanwj merged commit 0c50909 into bitcoin:master Jan 12, 2017
laanwj added a commit that referenced this pull request Jan 12, 2017
0c50909 testcases: explicitly specify transaction version 1 (John Newbery)
b7e144b Add test cases to test new bitcoin-tx functionality (jnewbery)
61a1534 Add all transaction output types to bitcoin-tx. (jnewbery)
1814b08 add p2sh and segwit options to bitcoin-tx outscript command (Stanislas Marion)
@jnewbery jnewbery deleted the add-p2sh-segwit-options-to-bitcoin-tx branch January 12, 2017 13:47
codablock pushed a commit to codablock/dash that referenced this pull request Jan 21, 2018
0c50909 testcases: explicitly specify transaction version 1 (John Newbery)
b7e144b Add test cases to test new bitcoin-tx functionality (jnewbery)
61a1534 Add all transaction output types to bitcoin-tx. (jnewbery)
1814b08 add p2sh and segwit options to bitcoin-tx outscript command (Stanislas Marion)
andvgal pushed a commit to energicryptocurrency/gen2-energi that referenced this pull request Jan 6, 2019
0c50909 testcases: explicitly specify transaction version 1 (John Newbery)
b7e144b Add test cases to test new bitcoin-tx functionality (jnewbery)
61a1534 Add all transaction output types to bitcoin-tx. (jnewbery)
1814b08 add p2sh and segwit options to bitcoin-tx outscript command (Stanislas Marion)
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Feb 27, 2019
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Feb 27, 2019
…dablock committed on Jan 20, 2018 Use version 2 blocks for miner_tests … @codablock codablock committed on Jan 20, 2018   Merge bitcoin#7871: Manual block file pruning.  …  @laanwj @codablock laanwj authored and codablock committed on Jan 11, 2017   Merge bitcoin#9507: Fix use-after-free in CTxMemPool::removeConflicts()  …  @sipa @codablock sipa authored and codablock committed on Jan 11, 2017   Merge bitcoin#9297: Various RPC help outputs updated  …  @MarcoFalke @codablock MarcoFalke authored and codablock committed on Jan 12, 2017   Merge bitcoin#9416: travis: make distdir before make  …  @MarcoFalke @codablock MarcoFalke authored and codablock committed on Jan 12, 2017   Merge bitcoin#9520: Deprecate non-txindex getrawtransaction and bette…  …  @MarcoFalke @codablock MarcoFalke authored and codablock committed on Jan 12, 2017   Merge bitcoin#9518: Return height of last block pruned by pruneblockc…  …  @MarcoFalke @codablock MarcoFalke authored and codablock committed on Jan 12, 2017   Merge bitcoin#9472: Disentangle progress estimation from checkpoints …  …  @laanwj @codablock laanwj authored and codablock committed on Jan 12, 2017   Merge bitcoin#8883: Add all standard TXO types to bitcoin-tx  …  @laanwj @codablock laanwj authored and codablock committed on Jan 12, 2017   Merge bitcoin#9261: Add unstored orphans with rejected parents to rec…  …  @laanwj @codablock laanwj authored and codablock committed on Jan 12, 2017   Merge bitcoin#9468: [Depends] Dependency updates for 0.14.0  …  @laanwj @codablock laanwj authored and codablock committed on Jan 12, 2017   Merge bitcoin#9222: Add 'subtractFeeFromAmount' option to 'fundrawtra…  …  @laanwj @codablock laanwj authored and codablock committed on Jan 12, 2017   Merge bitcoin#9490: Replace FindLatestBefore used by importmuti with …  …  @sipa @codablock sipa authored and codablock committed on Jan 13, 2017   Merge bitcoin#9469: [depends] Qt 5.7.1  …  @laanwj @codablock laanwj authored and codablock committed on Jan 15, 2017   Merge bitcoin#9380: Separate different uses of minimum fees  …  @laanwj @codablock laanwj authored and codablock committed on Jan 16, 2017   Remove SegWit related code in dash-tx  @codablock codablock committed on Sep 21, 2017   Merge bitcoin#9561: Wake message handling thread when we receive a ne…  …  @sipa @codablock sipa authored and codablock committed on Jan 17, 2017   Merge bitcoin#9508: Remove unused Python imports  …  @MarcoFalke @codablock MarcoFalke authored and codablock committed on Jan 18, 2017   Merge bitcoin#9512: Fix various things -fsanitize complains about
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants