Skip to content

Instantly share code, notes, and snippets.

@dexX7
Created February 22, 2014 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dexX7/9146763 to your computer and use it in GitHub Desktop.
Save dexX7/9146763 to your computer and use it in GitHub Desktop.
An inefficient way to collect dust from Mastercoin mutlisig transactions.
// Uses BitcoinRpcSharp
// https://github.com/BitKoot/BitcoinRpcSharp
public struct TxOutput
{
public string Address;
public string TxId;
public string Type;
public int N;
public double Value;
}
...
public string CreateDustTxHex(string account, int offset, int start)
{
// Create connection
var rpcUrl = "http://[IP]:[PORT]";
var rpcUser = "[USERNAME]";
var rpcPassword = "[PASSWORD]";
var wallet = new BitcoinWallet(rpcUrl, rpcUser, rpcPassword, false);
// Get address for account
var address = wallet.GetAddressesByAccount(account).First();
// Get transactions
var txs = wallet.ListTransactions(account, offset, start)
// Get transaction details
var rawTxs = new List<DecodedRawTransaction>();
foreach (var tx in txs)
{
rawTxs.Add(wallet.GetRawTransaction(tx.TxId, 1));
}
// Get potential outputs
var outputs = new List<TxOutput>();
foreach (var tx in rawTxs)
{
foreach (var vout in tx.VOut)
{
if (vout.ScriptPubKey.Type == "multisig")
{
if (vout.ScriptPubKey.Addresses.Contains(address) && vout.ScriptPubKey.ReqSigs < 2)
{
var txOutput = new TxOutput();
txOutput.Address = address;
txOutput.TxId = tx.TxId;
txOutput.Type = vout.ScriptPubKey.Type;
txOutput.N = vout.N;
txOutput.Value = vout.Value;
outputs.Add(txOutput);
}
}
}
}
// Kick duplicates
outputs = outputs.Distinct().ToList();
// Get spendable outputs
var spendable = new List<TxOutput>();
foreach (var o in outputs)
{
var rawTransaction = new CreateRawTransaction();
rawTransaction.AddInput(o.TxId, o.N);
rawTransaction.AddOutput(address, (decimal)0.00001);
var rawTxHex = wallet.CreateRawTransaction(rawTransaction);
var unsignedRawTransaction = new SignRawTransaction(rawTxHex);
var signedRawTransaction = wallet.SignRawTransaction(unsignedRawTransaction);
if (signedRawTransaction.Complete)
{
spendable.Add(o);
}
}
// Get other spendable outputs
var minConf = 0;
var maxConf = 999999;
var unspent = wallet.ListUnspent(minConf, maxConf);
foreach (var tx in unspent)
{
if (tx.Address == address)
{
var txOutput = new TxOutput();
txOutput.Address = tx.Address;
txOutput.TxId = tx.TxId;
txOutput.Type = "pubhashkey";
txOutput.N = tx.VOut;
txOutput.Value = tx.Amount;
spendable.Add(txOutput);
}
}
// Create raw temp transaction
var rawDustTx = new CreateRawTransaction();
var spendableSum = 0m;
var netValue = 0m;
foreach (var o in spendable)
{
spendableSum += (decimal)o.Value;
rawDustTx.AddInput(o.TxId, o.N);
}
// Temp output to calculate correct fee
rawDustTx.AddOutput(address, 0.0001m);
// Sign transaction
var rawDustTmpTxHex = wallet.CreateRawTransaction(rawDustTx);
var unsignedDustTmpTx = new SignRawTransaction(rawDustTmpTxHex);
var signedDustTmpTx = wallet.SignRawTransaction(unsignedDustTmpTx);
// Calculate fee
var size = signedDustTmpTx.Hex.Length / 2m;
var kb = size / 1000m;
var fee = Math.Ceiling(kb) / 10000m;
// Create final transaction with correct fee
netValue = spendableSum - fee;
rawDustTx.Outputs[address] = netValue;
return wallet.CreateRawTransaction(rawDustTx);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment