public void CanSplitFees() { var satoshi = new Key(); var alice = new Key(); var bob = new Key(); var aliceCoins = new ICoin[] { RandomCoin("0.4", alice), RandomCoin("0.6", alice) }; var bobCoins = new ICoin[] { RandomCoin("0.2", bob), RandomCoin("0.3", bob) }; TransactionBuilder builder = new TransactionBuilder(); FeeRate rate = new FeeRate(Money.Coins(0.0004m)); var tx = builder .AddCoins(aliceCoins) .AddKeys(alice) .Send(satoshi, Money.Coins(0.1m)) .SetChange(alice) .Then() .AddCoins(bobCoins) .AddKeys(bob) .Send(satoshi, Money.Coins(0.01m)) .SetChange(bob) .SendEstimatedFeesSplit(rate) .BuildTransaction(true); var estimated = builder.EstimateFees(tx, rate); Assert.True(builder.Verify(tx, estimated)); // Alice should pay two times more fee than bob builder = new TransactionBuilder(); tx = builder .AddCoins(aliceCoins) .AddKeys(alice) .SetFeeWeight(2.0m) .Send(satoshi, Money.Coins(0.1m)) .SetChange(alice) .Then() .AddCoins(bobCoins) .AddKeys(bob) .Send(satoshi, Money.Coins(0.01m)) .SetChange(bob) .SendFeesSplit(Money.Coins(0.6m)) .BuildTransaction(true); var spentAlice = builder.FindSpentCoins(tx).Where(c => aliceCoins.Contains(c)).OfType<Coin>().Select(c => c.Amount).Sum(); var receivedAlice = tx.Outputs.AsCoins().Where(c => c.ScriptPubKey == alice.PubKey.Hash.ScriptPubKey).Select(c => c.Amount).Sum(); Assert.Equal(Money.Coins(0.1m + 0.4m), spentAlice - receivedAlice); var spentBob = builder.FindSpentCoins(tx).Where(c => bobCoins.Contains(c)).OfType<Coin>().Select(c => c.Amount).Sum(); var receivedBob = tx.Outputs.AsCoins().Where(c => c.ScriptPubKey == bob.PubKey.Hash.ScriptPubKey).Select(c => c.Amount).Sum(); Assert.Equal(Money.Coins(0.01m + 0.2m), spentBob - receivedBob); }