| 229 | } |
| 230 | |
| 231 | static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput) |
| 232 | { |
| 233 | std::vector<std::string> vStrInputParts; |
| 234 | boost::split(vStrInputParts, strInput, boost::is_any_of(":")); |
| 235 | |
| 236 | // separate TXID:VOUT in string |
| 237 | if (vStrInputParts.size()<2) |
| 238 | throw std::runtime_error("TX input missing separator"); |
| 239 | |
| 240 | // extract and validate TXID |
| 241 | std::string strTxid = vStrInputParts[0]; |
| 242 | if ((strTxid.size() != 64) || !IsHex(strTxid)) |
| 243 | throw std::runtime_error("invalid TX input txid"); |
| 244 | uint256 txid(uint256S(strTxid)); |
| 245 | |
| 246 | static const unsigned int minTxOutSz = 9; |
| 247 | static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz); |
| 248 | |
| 249 | // extract and validate vout |
| 250 | const std::string& strVout = vStrInputParts[1]; |
| 251 | int64_t vout; |
| 252 | if (!ParseInt64(strVout, &vout) || vout < 0 || vout > static_cast<int64_t>(maxVout)) |
| 253 | throw std::runtime_error("invalid TX input vout '" + strVout + "'"); |
| 254 | |
| 255 | // extract the optional sequence number |
| 256 | uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max(); |
| 257 | if (vStrInputParts.size() > 2) |
| 258 | nSequenceIn = std::stoul(vStrInputParts[2]); |
| 259 | |
| 260 | // append to transaction input list |
| 261 | CTxIn txin(txid, vout, CScript(), nSequenceIn); |
| 262 | tx.vin.push_back(txin); |
| 263 | } |
| 264 | |
| 265 | static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strInput) |
| 266 | { |