Created
February 22, 2014 00:43
-
-
Save dexX7/9146763 to your computer and use it in GitHub Desktop.
An inefficient way to collect dust from Mastercoin mutlisig transactions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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