uint32_t ScoreSelectCoinsOutput(vector
The input to this function is a coin-selection, a target output value and a fee. By writing a method that assigns a score to a selection, you you can then randomly sort your input list 100 times, pick the top X inputs that satisfy your target+fee, and then keep the one with the best score. In my code, I am slowly adding smarter solutions and phasing out the randomly selected ones, but if you pick a high enough sample size, you're bound to get at least one good solution in pot even with nothing but random selections in the search:
uint32_t bestScore = UINT32_MAX;
for(int i=0; i<100; i++)
{
random_shuffle(unspentTxOutList.begin(), unspentTxOutList.end())
uint64_t sum = 0;
uint32_t index=0
vector
while(sum < target+fee)
{
selection.push_back(selection[index]);
sum += selection[index].getValue();
index++
}
uint32_t score = ScoreSelectCoinsOutput(selection, target, fee);
if( score < bestScore)
{
finalSelection = selection;
bestScore = score;
}
}
// Now you have a pretty good selection!
Then, the entire SelectCoins algorithm is based on how you "score" a selectCoins solution. In my code, I evaluate a bunch of different "selection factors", such as how many input addresses it combines, if it includes zero-confirm txs, how many bytes, how obvious it is which output is change/recipient, etc. I make sure that each of these factors spits out a number between 0 and 1 (with 1 being favorable), and then multiply each score by a weight:
WEIGHT_ALLOWFREE = 100
WEIGHT_NUMADDR = 100
WEIGHT_TXSIZE = 50
WEIGHT_PRIORITY = 60
WEIGHT_OUTANONYM = 30
The weights are configurable (and completely arbitrary--only significant relative to each other), and gives you the option to modify them for your use-case: you can make "WEIGHT_NUMADDR=10000" and "WEIGHT_OUTANONYM=10000" to try to max-out anonymity at any expense.