I am writing tests for an app I built that uses NBitcoin to send bitcoin and make bitcoin transactions.
I have the following code to create fake bitcoins for an integration test:
private ICoin[] CreateFakeCoins(TxInList inputs, Script scriptPubKey)
{
var coins = inputs.Select(i => new Coin(i.PrevOut, inputs.Transaction.Outputs.CreateNewTxOut(Money.Coins(0.1m), scriptPubKey.WitHash.ScriptPubKey))).ToArray();
for (int i = 0; i < coins.Length; i++)
{
coins[i] = coins[i].ToScriptCoin(scriptPubKey);
}
return coins;
}
My integration test has this piece of code that's supposed to send the fake bitcoins to another wallet.
var k = new BitcoinSecret(new Key(), Network.TestNet);
var moneyInWallet1 = BitcoinHelper.GetBitcoinAddress(walletTestNet?.Address, Network.TestNet);
Transaction tx = Network.TestNet.CreateTransaction();
var privkey = new BitcoinSecret(walletTestNet?.Address, Network.TestNet);
var scriptPubKey = PayToWitScriptHashTemplate.Instance.GenerateScriptPubKey(k.PubKey.ScriptPubKey.WitHash);
var scriptPubKeyRec = PayToWitScriptHashTemplate.Instance.GenerateScriptPubKey(privkey.PubKey.ScriptPubKey.WitHash);
tx.Inputs.Add(new OutPoint(tx.GetHash(), 0), scriptPubKey.ToWitScript());
tx.Inputs.Add(new OutPoint(tx.GetHash(), 1), scriptPubKey.ToWitScript());
tx.Outputs.Add("21", k.PubKey.WitHash);
tx.Sign(new[] { k }, CreateFakeCoins(tx.Inputs, scriptPubKey));
Assert.Equal(k.GetAddress(ScriptPubKeyType.Segwit).ToString().Substring(0, 3), "tb1");
Assert.Equal(tx.Outputs[0].Value.Satoshi / 100000000, 21);
Assert.Equal(moneyInWallet1.Address.ToString().Substring(0, 3), "tb1");
var builder = Network.TestNet.CreateTransactionBuilder();
var (receiveAddress, receiveBtcSecret) = BitcoinHelper.GetBitcoinAddress(privKeyCurrent, Network.TestNet);
var (fromAddressProcessed, fromBtcSecret) = BitcoinHelper.GetBitcoinAddress(walletTestNet?.Address, Network.TestNet);
var amountSatoshiMult = Math.Ceiling(0.0006*100000000.00);
Money amountConvertedtoMoney = new Money((long)amountSatoshiMult);
var testibleOutputs = tx.Outputs.AsCoins().Cast<ICoin>().ToArray();
var txBuild = builder
.AddCoins(testibleOutputs)
.AddKeys(fromBtcSecret)
.Send(receiveAddress, amountConvertedtoMoney)
.SetChange(fromAddressProcessed, ChangeType.All)
.SendFees(Money.Coins(new decimal(0.0001)));
NBitcoin.Policy.TransactionPolicyError[] errors = null;
Transaction nextTx = txBuild.BuildTransaction(true);
var testerForBuilder = builder.Verify(nextTx, out errors);
Console.WriteLine(errors);
Console.WriteLine(testerForBuilder);
Assert.Equal(true, testerForBuilder);
In this code, the BitcoinHelper.GetBitcoinAddress
function simply receives an address string and returns a proper NBitcoin BitcoinAddress object.
This is a picture of the error I get:
Notice the WitnessProgramMissmatch
error.
What is the problem? Is CreateFakeCoins
not correctly creating fake coins for testing? How can I make this work?