Skip to content

Instantly share code, notes, and snippets.

@farukterzioglu
Last active December 10, 2019 08:19
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 farukterzioglu/5eb1bd42c1251145741836a29fecf9f2 to your computer and use it in GitHub Desktop.
Save farukterzioglu/5eb1bd42c1251145741836a29fecf9f2 to your computer and use it in GitHub Desktop.
multisig-test
ScriptError [ScriptError]:EvalFalse
ScriptVerify : [ScriptVerify]:StrictEnc | MinimalData | DiscourageUpgradableNops | CleanStack | Consensus | DiscourageUpgradableWitnessProgram | MinimalIf | NullFail
#region settings
//Rpc settings
var rpcClient = new RPCClient(
new RPCCredentialString { UserPassword = new NetworkCredential("myuser", "SomeDecentp4ssw0rd") },
"localhost:18993", Network.RegTest );
// NBX Settings
string cryptoCode = "DASH";
var networkProvider = new NBXplorerNetworkProvider(NetworkType.Regtest);
var network = networkProvider.GetFromCryptoCode(cryptoCode);
var client = new ExplorerClient(network, new Uri("http://localhost:24446"));
// Create a new strategy
var masterKeys = Enumerable.Range(0,2).Select( x => new ExtKey()).ToArray();
var publicKeys = masterKeys.Select( x => x.Neuter()).ToArray();
var strategy = new DerivationStrategyFactory(network.NBitcoinNetwork).CreateMultiSigDerivationStrategy(publicKeys, 2, new DerivationStrategyOptions(){
ScriptPubKeyType = ScriptPubKeyType.Legacy,
KeepOrder = true
});
// Track the strategy
await client.TrackAsync(strategy);
#endregion
// Send coin and generate
var newAddress = await client.GetUnusedAsync(strategy, DerivationFeature.Deposit);
var addressDetail = await rpcClient.SendCommandAsync(RPCOperations.validateaddress, newAddress.Address.ToString());
await rpcClient.SendToAddressAsync(newAddress.Address, Money.Coins(1M));
await rpcClient.EnsureGenerateAsync(1);
Coin[] unspentCoins;
do
{
await Task.Delay(10);
var utxos = await client.GetUTXOsAsync(strategy);
unspentCoins = utxos.GetUnspentCoins(true);
} while (!unspentCoins.Any());
Assert.AreEqual(1, unspentCoins.Count());
// Spend that utxo
var receiver = BitcoinAddress.Create("yM4RGsB4iE7QsQmqTxFoD9NufEkwWGDRRN", network.NBitcoinNetwork);
var changeAddress = await client.GetUnusedAsync(strategy, DerivationFeature.Change);
Assert.NotNull(changeAddress);
var multiSigPubKey = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, publicKeys.Select(k => k.PubKey).ToArray());
var scriptCoins = unspentCoins.Select( x => x.ToScriptCoin(multiSigPubKey));
var txBuilder = network.NBitcoinNetwork.CreateTransactionBuilder();
txBuilder.StandardTransactionPolicy = EasyPolicy;
var tx = txBuilder
.AddCoins(scriptCoins)
.AddKeys(masterKeys[0])
.Send(receiver, Money.Parse("0.05"))
.SendFees(Money.Parse("0.0001"))
.SetChange(changeAddress.Address)
.BuildTransaction(false);
var signed1 = txBuilder.SignTransaction(tx);
txBuilder = network.NBitcoinNetwork.CreateTransactionBuilder();
txBuilder.StandardTransactionPolicy = EasyPolicy;
var signed2 = txBuilder
.AddKeys(masterKeys[1])
.AddCoins(scriptCoins)
.SignTransaction(tx);
Assert.False(txBuilder.Verify(signed1));
Assert.False(txBuilder.Verify(signed2));
txBuilder = network.NBitcoinNetwork.CreateTransactionBuilder();
txBuilder.StandardTransactionPolicy = EasyPolicy;
tx = txBuilder
.AddCoins(scriptCoins)
.CombineSignatures(signed1, signed2);
txBuilder.Verify(tx, out var exc);
Assert.True(!exc.Any());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment