public void CanCompressScript() { var key = new Key(true); //Pay to pubkey hash (encoded as 21 bytes) var script = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(key.PubKey.Hash); AssertCompressed(script, 21); script = PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(key.PubKey.Decompress().Hash); AssertCompressed(script, 21); //Pay to script hash (encoded as 21 bytes) script = PayToScriptHashTemplate.Instance.GenerateScriptPubKey(script); AssertCompressed(script, 21); //Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes) script = PayToPubkeyTemplate.Instance.GenerateScriptPubKey(key.PubKey); script = AssertCompressed(script, 33); var readenKey = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(script); AssertEx.CollectionEquals(readenKey.ToBytes(), key.PubKey.ToBytes()); script = PayToPubkeyTemplate.Instance.GenerateScriptPubKey(key.PubKey.Decompress()); script = AssertCompressed(script, 33); readenKey = PayToPubkeyTemplate.Instance.ExtractScriptPubKeyParameters(script); AssertEx.CollectionEquals(readenKey.ToBytes(), key.PubKey.Decompress().ToBytes()); //Other scripts up to 121 bytes require 1 byte + script length. script = new Script(Enumerable.Range(0, 60).Select(_ => (Op)OpcodeType.OP_RETURN).ToArray()); AssertCompressed(script, 61); script = new Script(Enumerable.Range(0, 120).Select(_ => (Op)OpcodeType.OP_RETURN).ToArray()); AssertCompressed(script, 121); //Above that, scripts up to 16505 bytes require 2 bytes + script length. script = new Script(Enumerable.Range(0, 122).Select(_ => (Op)OpcodeType.OP_RETURN).ToArray()); AssertCompressed(script, 124); }
public void CanCacheNoSqlRepository() { var cached = new CachedNoSqlRepository(new InMemoryNoSqlRepository()); byte[] data1 = new byte[] { 1, 2, 3, 4, 5, 6 }; byte[] data2 = new byte[] { 11, 22, 33, 4, 5, 66 }; cached.InnerRepository.Put("data1", new RawData(data1)); Assert.NotNull(cached.Get <RawData>("data1")); cached.InnerRepository.Put("data1", new RawData(data2)); cached.Flush(); var data1Actual = cached.InnerRepository.Get <RawData>("data1"); AssertEx.CollectionEquals(data1Actual.Data, data2); cached.Put("data1", new RawData(data1)); data1Actual = cached.InnerRepository.Get <RawData>("data1"); AssertEx.CollectionEquals(data1Actual.Data, data2); cached.Flush(); data1Actual = cached.InnerRepository.Get <RawData>("data1"); AssertEx.CollectionEquals(data1Actual.Data, data1); cached.Put("data1", null); cached.Flush(); Assert.Null(cached.InnerRepository.Get <RawData>("data1")); cached.Put("data1", new RawData(data1)); cached.Put("data1", null); cached.Flush(); Assert.Null(cached.InnerRepository.Get <RawData>("data1")); cached.Put("data1", null); cached.Put("data1", new RawData(data1)); cached.Flush(); Assert.NotNull(cached.InnerRepository.Get <RawData>("data1")); }
public void EncryptedSecretECmultiplyNoLotSimple() { var compressedValues = new[] { false, true }; foreach (bool compressed in compressedValues) { var code = new BitcoinPassphraseCode("test", Network.Main, null); Assert.Null(code.LotSequence); EncryptedKeyResult result = code.GenerateEncryptedSecret(compressed); Assert.True(result.ConfirmationCode.Check("test", result.GeneratedAddress)); Assert.False(result.ConfirmationCode.Check("toto", result.GeneratedAddress)); Assert.False(result.ConfirmationCode.Check("test", new Key().PubKey.GetAddress(Network.Main))); Key decryptedKey = result.EncryptedKey.GetKey("test"); Assert.Equal(result.GeneratedAddress.ToString(), decryptedKey.PubKey.GetAddress(Network.Main).ToString()); Assert.Throws <SecurityException>(() => result.EncryptedKey.GetKey("wrong")); //Can regenerate same result with same seed EncryptedKeyResult result2 = code.GenerateEncryptedSecret(compressed, seedb: result.Seed); Key decryptedKey2 = result.EncryptedKey.GetKey("test"); AssertEx.CollectionEquals(decryptedKey2.ToBytes(), decryptedKey.ToBytes()); } }
public void bloom_create_insert_serialize() { BloomFilter filter = new BloomFilter(3, 0.01, 0, BloomFlags.UPDATE_ALL); filter.Insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")); Assert.True(filter.Contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter doesn't contain just-inserted object!"); // One bit different in first byte Assert.True(!filter.Contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")), "BloomFilter contains something it shouldn't!"); filter.Insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")); Assert.True(filter.Contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")), "BloomFilter doesn't contain just-inserted object (2)!"); filter.Insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")); Assert.True(filter.Contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "BloomFilter doesn't contain just-inserted object (3)!"); var ms = new MemoryStream(); BitcoinStream bitcoinStream = new BitcoinStream(ms, true); bitcoinStream.ReadWrite(filter); var expected = ParseHex("03614e9b050000000000000001"); AssertEx.CollectionEquals(expected, ms.ToArray()); }
public void methods() { Assert.True(R1L.GetHex() == R1L.ToString()); Assert.True(R2L.GetHex() == R2L.ToString()); Assert.True(OneL.GetHex() == OneL.ToString()); Assert.True(MaxL.GetHex() == MaxL.ToString()); uint256 TmpL = new uint256(R1L); Assert.True(TmpL == R1L); TmpL.SetHex(R2L.ToString()); Assert.True(TmpL == R2L); TmpL.SetHex(ZeroL.ToString()); Assert.True(TmpL == 0); TmpL.SetHex(HalfL.ToString()); Assert.True(TmpL == HalfL); TmpL.SetHex(R1L.ToString()); AssertEx.CollectionEquals(R1L.ToBytes(), R1Array); AssertEx.CollectionEquals(TmpL.ToBytes(), R1Array); AssertEx.CollectionEquals(R2L.ToBytes(), R2Array); AssertEx.CollectionEquals(ZeroL.ToBytes(), ZeroArray); AssertEx.CollectionEquals(OneL.ToBytes(), OneArray); Assert.True(R1L.Size == 32); Assert.True(R2L.Size == 32); Assert.True(ZeroL.Size == 32); Assert.True(MaxL.Size == 32); //No sense in .NET //Assert.True(R1L.begin() + 32 == R1L.end()); //Assert.True(R2L.begin() + 32 == R2L.end()); //Assert.True(OneL.begin() + 32 == OneL.end()); //Assert.True(MaxL.begin() + 32 == MaxL.end()); //Assert.True(TmpL.begin() + 32 == TmpL.end()); Assert.True(R1L.GetLow64() == R1LLow64); Assert.True(HalfL.GetLow64() == 0x0000000000000000UL); Assert.True(OneL.GetLow64() == 0x0000000000000001UL); Assert.True(R1L.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 32); Assert.True(ZeroL.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 32); MemoryStream ss = new MemoryStream(); R1L.Serialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(R1Array)); TmpL.Unserialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(R1L == TmpL); ss = new MemoryStream(); ZeroL.Serialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(ZeroArray)); ss.Position = 0; TmpL.Unserialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ZeroL == TmpL); ss = new MemoryStream(); MaxL.Serialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(MaxArray)); ss.Position = 0; TmpL.Unserialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(MaxL == TmpL); ss = new MemoryStream(); Assert.True(R1S.GetHex() == R1S.ToString()); Assert.True(R2S.GetHex() == R2S.ToString()); Assert.True(OneS.GetHex() == OneS.ToString()); Assert.True(MaxS.GetHex() == MaxS.ToString()); uint160 TmpS = new uint160(R1S); Assert.True(TmpS == R1S); TmpS.SetHex(R2S.ToString()); Assert.True(TmpS == R2S); TmpS.SetHex(ZeroS.ToString()); Assert.True(TmpS == 0); TmpS.SetHex(HalfS.ToString()); Assert.True(TmpS == HalfS); TmpS.SetHex(R1S.ToString()); Assert.True(ArrayToString(R1S.ToBytes()) == ArrayToString(R1Array.Take(20).ToArray())); Assert.True(ArrayToString(TmpS.ToBytes()) == ArrayToString(R1Array.Take(20).ToArray())); Assert.True(ArrayToString(R2S.ToBytes()) == ArrayToString(R2Array.Take(20).ToArray())); Assert.True(ArrayToString(ZeroS.ToBytes()) == ArrayToString(ZeroArray.Take(20).ToArray())); Assert.True(ArrayToString(OneS.ToBytes()) == ArrayToString(OneArray.Take(20).ToArray())); Assert.True(R1S.Size == 20); Assert.True(R2S.Size == 20); Assert.True(ZeroS.Size == 20); Assert.True(MaxS.Size == 20); //No sense in .NET //Assert.True(R1S.begin() + 20 == R1S.end()); //Assert.True(R2S.begin() + 20 == R2S.end()); //Assert.True(OneS.begin() + 20 == OneS.end()); //Assert.True(MaxS.begin() + 20 == MaxS.end()); //Assert.True(TmpS.begin() + 20 == TmpS.end()); Assert.True(R1S.GetLow64() == R1LLow64); Assert.True(HalfS.GetLow64() == 0x0000000000000000UL); Assert.True(OneS.GetLow64() == 0x0000000000000001UL); Assert.True(R1S.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 20); Assert.True(ZeroS.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 20); R1S.Serialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(R1Array.Take(20).ToArray())); ss.Position = 0; TmpS.Unserialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(R1S == TmpS); ss = new MemoryStream(); ZeroS.Serialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(ZeroArray.Take(20).ToArray())); ss.Position = 0; TmpS.Unserialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ZeroS == TmpS); ss = new MemoryStream(); MaxS.Serialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(MaxArray.Take(20).ToArray())); ss.Position = 0; TmpS.Unserialize(ss, 0, ProtocolVersion.PROTOCOL_VERSION); Assert.True(MaxS == TmpS); ss = new MemoryStream(); //for(int i = 0 ; i < 255 ; ++i) //{ // Assert.True((OneL << i).GetDouble() == Math.Pow(1.0, i)); // if(i < 160) // Assert.True((OneS << i).GetDouble() == Math.Pow(1.0, i)); //} //Assert.True(ZeroL.GetDouble() == 0.0); //Assert.True(ZeroS.GetDouble() == 0.0); //for(int i = 256 ; i > 53 ; --i) // Assert.True(almostEqual((R1L >> (256 - i)).GetDouble(), Math.Pow(R1Ldouble, i))); //for(int i = 160 ; i > 53 ; --i) // Assert.True(almostEqual((R1S >> (160 - i)).GetDouble(), Math.Pow(R1Sdouble, i))); //ulong R1L64part = (R1L >> 192).GetLow64(); //ulong R1S64part = (R1S >> 96).GetLow64(); //for(int i = 53 ; i > 0 ; --i) // doubles can store all integers in {0,...,2^54-1} exactly //{ // Assert.True((R1L >> (256 - i)).GetDouble() == (double)(R1L64part >> (64 - i))); // Assert.True((R1S >> (160 - i)).GetDouble() == (double)(R1S64part >> (64 - i))); //} }
public void CanCreatePayment() { var tests = new[] { new CanCreatePaymentData { //sx stealth-newkey StealthAddress = "vJmtjxSDxNPXL4RNapp9ARdqKz3uJyf1EDGjr1Fgqs9c8mYsVH82h8wvnA4i5rtJ57mr3kor1EVJrd4e5upACJd588xe52yXtzumxj", ScanSecret = "3e49e7257cb31db997edb1cf8299af0f37e2663e2260e4b8033e49d39a6d02f2", ScanPubKey = "025e58a31122b38c86abc119b9379fe247410aee87a533f9c07b189aef6c3c1f52", SpendSecret = "aa3db0cfb3edc94de4d10f873f8190843f2a17484f6021a95a7742302c744748", SpendPubKey = "03616562c98e7d7b74be409a787cec3a912122f3fb331a9bee9b0b73ce7b9f50af", //sx newkey | sx wif-to-secret EphemSecret = "9e63abaf8dcd5ea3919e6de0b6c544e00bf51bf92496113a01d6e369944dc091", EphemPubKey = "03403d306ec35238384c7e340393335f9bc9bb4a2e574eb4e419452c4ea19f14b0", //sx steatlh-uncover-secret [EphemPubKey] [ScanSecret] [SpendSecret] StealthSecret = "4e422fb1e5e1db6c1f6ab32a7706d368ceb385e7fab098e633c5c5949c3b97cd", //sx stealth-initiate [EphemSecret] [ScanPubKey] [SpendPubKey] (for sender) //or //sx stealth-uncover [EphemPubKey] [ScanSecret] [SpendPubKey] (for receiver) StealthPubKey = "02726112ad39cb6bf848b1b1ef30b88e35286bf99f746c2be575f96c0e02a9357c", }, //Need padding for to find the stealth secret new CanCreatePaymentData { StealthAddress = "vJmyTEybwCKz7W8y6vP62jo7RoyfLneiANcPLBBNYwn98EXzQRStMKqKGRiZhqscuQ6WKy2J3U3zfx72V3b2J6YvxxBcxUj4XMDsw7", ScanSecret = "2f517d81cf30e47dbf4809321275bbfd92192af81a6141a17aa53e40bd28fe36", ScanPubKey = "039d91ae0eebea6dc500fb57b704abce3d3fa700cc762a52bc5dcaee27770a8402", SpendSecret = "71e33219884fc27011f8da9adcc730f0c2e940759bdb1b615764492bce04fcea", SpendPubKey = "021a3d5b40ec83fc58b5a23207eb9c99b741d8f0e9f8b80f04f49cec915b540c40", EphemSecret = "578ffe42c0fbfb324a31f41dbbcd8b1f910ce2f4d803444a83b18ae9f8ccd97e", EphemPubKey = "03c190be0a1c6e50577b3dd637b1fff9344de31c2544ff3d815535c0515711150f", StealthSecret = "006d138b4bcef0f09c8784c0cc68f2be4497a1a822d8d7b0519c5c0378b5cb45", StealthPubKey = "0223a99278a5279ea93718503a42377067e72960eb808d8bff6defdd95d4feff76" } }; foreach (var test in tests) { var scan = AssertKeys(test.ScanSecret, test.ScanPubKey); var spend = AssertKeys(test.SpendSecret, test.SpendPubKey); var ephem = AssertKeys(test.EphemSecret, test.EphemPubKey); var stealth = AssertKeys(test.StealthSecret, test.StealthPubKey); var address = spend.PubKey.CreateStealthAddress(scan.PubKey, Network.Main); Assert.Equal(test.StealthAddress, address.ToString()); //Try roundtrip address = new BitcoinStealthAddress(address.ToBytes(), Network.Main); Assert.Equal(test.StealthAddress, address.ToString()); var payment = address.CreatePayment(ephem); var generatedKey = spend.Uncover(scan, payment.Metadata.EphemKey); if (stealth != null) { Assert.Equal(stealth.PubKey.Hash, payment.StealthKeys[0].ID); Assert.Equal(stealth.ToBytes(), generatedKey.ToBytes()); } var uncoveredSender = spend.PubKey.UncoverSender(ephem, scan.PubKey); var uncovertedReceiver = spend.PubKey.UncoverReceiver(scan, ephem.PubKey); AssertEx.CollectionEquals(uncoveredSender.ToBytes(), uncovertedReceiver.ToBytes()); AssertEx.CollectionEquals(generatedKey.PubKey.ToBytes(), uncovertedReceiver.ToBytes()); var transaction = new Transaction(); payment.AddToTransaction(transaction, 100); } }
public void CanConvertText() { string testPhrase = "é ^ç hello \"12345\" wooorld"; var tests = new[] { new { Encoder = Encoders.Hex, Input = testPhrase, Expected = "c3a9205ec3a72068656c6c6f20223132333435222020776f6f6f726c64", }, new { Encoder = Encoders.Base58, Input = testPhrase, Expected = "9tBRc991GhmZNsV5qSyynUsnRCNvxdvvWDmj3nAP" }, new { Encoder = Encoders.Base58Check, Input = testPhrase, //Different from brainwallet, because brainwallet code convert the data to bitcoin address instead of directely formating in base58check (ie : the data followed be the 4 hash bytes) Expected = "2189xoVGsHC6VbVPUrKeH3fhT429VDruzdgUJFk37PNskG" }, new { Encoder = Encoders.Base64, Input = testPhrase, Expected = "w6kgXsOnIGhlbGxvICIxMjM0NSIgIHdvb29ybGQ=" }, //Not yet implemented //new //{ // Encoder = Encoders.Bin, // Input = testPhrase, // Expected = "11000011 10101001 00100000 01011110 11000011 10100111 00100000 01101000 01100101 01101100 01101100 01101111 00100000 00100010 00110001 00110010 00110011 00110100 00110101 00100010 00100000 00100000 01110111 01101111 01101111 01101111 01110010 01101100 01100100" //}, //Not yet implemented //new //{ // Encoder = Encoders.Dec, // Input = testPhrase, // Expected = "5275000693703128425041367611933003709099386868005962673424426230508644" //}, //Useless for bitcoin //new //{ // Encoder = Encoders.RFC1751, // Input = testPhrase, // Expected = "A A OWE BANG BAN BUST KITE ARK HAT SEEN OBOE GRIM KIN GASH GLOB COAT BANE DUN JO MILL SIGH SLID MAD PAR" //}, //Useless for bitcoin //new //{ // Encoder = Encoders.Poetry, // Input = testPhrase, // Expected = "perfect perfect perfect soul stone royal fault companion sharp cross build leap possess possibly yet bone magic beam illuminate moonlight foul juice darkness universe" //}, //Useless for bitcoin //new //{ // Encoder = Encoders.Rot13, // Input = testPhrase, // Expected = "é ^ç uryyb \"12345\" jbbbeyq" //}, //Useless for bitcoin //new //{ // Encoder = Encoders.Easy16, // Input = testPhrase, // Expected = "aaaa aauf reda houf rkda jwjh juju jnda eriu\r\nddfs fdff fgfh ddda dakk jnjn jnkd jujg euhs" //}, }; foreach (var test in tests) { byte[] input = Encoding.UTF8.GetBytes(test.Input); string encoded = test.Encoder.EncodeData(input); Assert.Equal(test.Expected, encoded); try { byte[] decoded = test.Encoder.DecodeData(encoded); AssertEx.CollectionEquals(input, decoded); } catch (NotSupportedException) { } } string expectedText = "2189xoVGsHC6VbVPUrKeH3fhT429VDruzdgUJFk37PNskG"; byte[] input1 = Encoding.UTF8.GetBytes("---é ^ç hello \"12345\" wooorld---"); string encoded1 = Encoders.Base58Check.EncodeData(input1, 3, input1.Length - 6); Assert.Equal(expectedText, encoded1); byte[] decoded1 = Encoders.Base58Check.DecodeData(encoded1); var arr = new byte[input1.Length - 6]; Array.Copy(input1, 3, arr, 0, arr.Length); AssertEx.CollectionEquals(input1.SafeSubarray(3, input1.Length - 6), decoded1); }
public void ShouldPassTheLongestTestInBIP174() { JObject testcase = (JObject)testdata["final"]; var network = Network.TestNet; var master = ExtKey.Parse((string)testcase["master"], network); var masterFP = BitConverter.ToUInt32(master.PrivateKey.PubKey.Hash.ToBytes().SafeSubarray(0, 4), 0); var tx = network.CreateTransaction(); tx.Version = 2; var scriptPubKey1 = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)testcase["out1"]["script"])); var money1 = Money.Coins((decimal)testcase["out1"]["value"]); var scriptPubKey2 = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)testcase["out2"]["script"])); var money2 = Money.Coins((decimal)testcase["out2"]["value"]); tx.Outputs.Add(new TxOut(value: money1, scriptPubKey: scriptPubKey1)); tx.Outputs.Add(new TxOut(value: money2, scriptPubKey: scriptPubKey2)); tx.Inputs.Add(new OutPoint(uint256.Parse((string)testcase["in1"]["txid"]), (uint)testcase["in1"]["index"])); tx.Inputs.Add(new OutPoint(uint256.Parse((string)testcase["in2"]["txid"]), (uint)testcase["in2"]["index"])); var expected = PSBT.Parse((string)testcase["psbt1"], Network.Main); var psbt = PSBT.FromTransaction(tx); Assert.Equal(expected, psbt, ComparerInstance); var prevtx1 = Transaction.Parse((string)testcase["prevtx1"], network); var prevtx2 = Transaction.Parse((string)testcase["prevtx2"], network); psbt.AddTransactions(prevtx1, prevtx2); var redeem1 = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)testcase["redeem1"])); var redeem2 = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)testcase["redeem2"])); var witness_script1 = Script.FromBytesUnsafe(Encoders.Hex.DecodeData((string)testcase["witness1"])); foreach (var sc in new Script[] { redeem1, redeem2, witness_script1 }) { psbt.AddScript(sc); } for (int i = 0; i < 6; i++) { var pk = testcase[$"pubkey{i}"]; var pubkey = new PubKey((string)pk["hex"]); var path = KeyPath.Parse((string)pk["path"]); psbt.AddKeyPath(pubkey, Tuple.Create(masterFP, path)); } expected = PSBT.Parse((string)testcase["psbt2"], Network.Main); Assert.Equal(expected, psbt, ComparerInstance); foreach (var psbtin in psbt.Inputs) { psbtin.SighashType = SigHash.All; } expected = PSBT.Parse((string)testcase["psbt3"], Network.Main); Assert.Equal(expected, psbt, ComparerInstance); psbt.CheckSanity(); var psbtForBob = psbt.Clone(); // path 1 ... alice Assert.Equal(psbt, psbtForBob, ComparerInstance); var aliceKey1 = master.Derive(new KeyPath((string)testcase["key7"]["path"])).PrivateKey; var aliceKey2 = master.Derive(new KeyPath((string)testcase["key8"]["path"])).PrivateKey; psbt.SignAll(aliceKey1, aliceKey2); expected = PSBT.Parse((string)testcase["psbt4"], Network.Main); Assert.Equal(expected, psbt); // path 2 ... bob. var bobKey1 = master.Derive(new KeyPath((string)testcase["key9"]["path"])).PrivateKey; var bobKey2 = master.Derive(new KeyPath((string)testcase["key10"]["path"])).PrivateKey; var bobKeyhex1 = (string)testcase["key9"]["wif"]; var bobKeyhex2 = (string)testcase["key10"]["wif"]; Assert.Equal(bobKey1, new BitcoinSecret(bobKeyhex1, network).PrivateKey); Assert.Equal(bobKey2, new BitcoinSecret(bobKeyhex2, network).PrivateKey); psbtForBob.UseLowR = false; psbtForBob.SignAll(bobKey1, bobKey2); expected = PSBT.Parse((string)testcase["psbt5"], Network.Main); Assert.Equal(expected, psbtForBob); // merge above 2 var combined = psbt.Combine(psbtForBob); expected = PSBT.Parse((string)testcase["psbtcombined"], Network.Main); Assert.Equal(expected, combined); var finalized = psbt.Finalize(); expected = PSBT.Parse((string)testcase["psbtfinalized"], Network.Main); Assert.Equal(expected, finalized); var finalTX = psbt.ExtractTX(); var expectedTX = Transaction.Parse((string)testcase["txextracted"], network); AssertEx.CollectionEquals(expectedTX.ToBytes(), finalTX.ToBytes()); }
public void AddingScriptCoinShouldResultMoreInfoThanAddingSeparatelyInCaseOfP2SH() { var keys = new Key[] { new Key(), new Key(), new Key() }; var redeem = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(3, keys.Select(k => k.PubKey).ToArray()); var network = Network.Main; var funds = CreateDummyFunds(network, keys, redeem); var tx = CreateTxToSpendFunds(funds, keys, redeem, false, false); var psbt = PSBT.FromTransaction(tx); // case 1: Check that it will result to more info by adding ScriptCoin in case of p2sh-p2wpkh var coins1 = DummyFundsToCoins(funds, null, null); // without script var scriptCoins2 = DummyFundsToCoins(funds, null, keys[0]); // only with p2sh-p2wpkh redeem. var psbt1 = psbt.Clone().AddCoins(coins1).AddScript(redeem); var psbt2 = psbt.Clone().AddCoins(scriptCoins2).AddScript(redeem); for (int i = 0; i < 6; i++) { Output.WriteLine($"Testing {i}"); var a = psbt1.Inputs[i]; var e = psbt2.Inputs[i]; // Since there are no way psbt can know p2sh-p2wpkh is actually a witness input in case we add coins and scripts separately, // coin will not be added to the inputs[4]. if (i == 4) // p2sh-p2wpkh { Assert.NotEqual(a.ToBytes(), e.ToBytes()); Assert.Null(a.RedeemScript); Assert.Null(a.WitnessUtxo); Assert.NotNull(e.RedeemScript); Assert.NotNull(e.WitnessUtxo); } // but otherwise, it will be the same. else { AssertEx.CollectionEquals(a.ToBytes(), e.ToBytes()); } } // case 2: bare p2sh and p2sh-pw2sh var scriptCoins3 = DummyFundsToCoins(funds, redeem, keys[0]); // with full scripts. var psbt3 = psbt.Clone().AddCoins(scriptCoins3); for (int i = 0; i < 6; i++) { Output.WriteLine($"Testing {i}"); var a = psbt2.Inputs[i]; var e = psbt3.Inputs[i]; if (i == 2 || i == 5) // p2sh or p2sh-p2wsh { Assert.NotEqual <byte[]>(a.ToBytes(), e.ToBytes()); Assert.Null(a.WitnessUtxo); Assert.Null(a.RedeemScript); Assert.NotNull(e.RedeemScript); if (i == 5) // p2sh-p2wsh { Assert.NotNull(e.WitnessUtxo); Assert.NotNull(e.WitnessScript); } } else { AssertEx.CollectionEquals(a.ToBytes(), e.ToBytes()); } } }
public void ShouldDecodeProperly(string data, string encoded) { var testBytes = Encoders.Base58.DecodeData(encoded); AssertEx.CollectionEquals(Encoders.Hex.DecodeData(data), testBytes); }
internal static void StackEquals(ContextStack <byte[]> stack1, ContextStack <byte[]> stack2) { uint256[] hash1 = stack1.Select(o => Hashes.Hash256(o)).ToArray(); uint256[] hash2 = stack2.Select(o => Hashes.Hash256(o)).ToArray(); AssertEx.CollectionEquals(hash1, hash2); }