예제 #1
0
        public void CreateScriptTreeTest()
        {
            var sk  = new Privkey("305e293b010d29bf3c888b617763a438fee9054c8cab66eb12ad078f819d9f27");
            var spk = SchnorrPubkey.GetPubkeyFromPrivkey(sk, out bool _);

            Assert.Equal("1777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb", spk.ToHexString());

            var scriptCheckSig  = Script.CreateFromAsm(new string[] { spk.ToHexString(), "OP_CHECKSIG" });
            var scriptOpTrue    = Script.CreateFromAsm("OP_TRUE");
            var scriptCheckSig2 = Script.CreateFromAsm(new string[] {
                "ac52f50b28cdd4d3bcb7f0d5cb533f232e4c4ef12fbf3e718420b84d4e3c3440",
                "OP_CHECKSIG",
            });

            var tree = new TaprootScriptTree(scriptCheckSig);

            tree.AddBranch(scriptOpTrue);
            tree.AddBranch(scriptCheckSig2);
            output.WriteLine("tree1: " + tree.ToString());
            Assert.Equal(
                "{tl(20ac52f50b28cdd4d3bcb7f0d5cb533f232e4c4ef12fbf3e718420b84d4e3c3440ac),{tl(51),tl(201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac)}}",
                tree.ToString());
            var count = tree.GetBranchCount();

            Assert.Equal((uint)2, count);
        }
예제 #2
0
        public void DeserializeScriptTreeTest()
        {
            var scriptOpTrue = Script.CreateFromAsm("OP_TRUE");

            var treeStr      = "{{{tl(51),{tl(204a7af8660f2b0bdb92d2ce8b88ab30feb916343228d2e7bd15da02e1f6a31d47ac),tl(2000d134c42fd51c90fa82c6cfdaabd895474d979118525362c0cd236c857e29d9ac)}},{{tl(20ac52f50b28cdd4d3bcb7f0d5cb533f232e4c4ef12fbf3e718420b84d4e3c3440ac),{tl(2057bf643684f6c5c75e1cdf45990036502a0d897394013210858cdabcbb95a05aac),tl(51)}},tl(2057bf643684f6c5c75e1cdf45990036502a0d897394013210858cdabcbb95a05aad205bec1a08fa3443176edd0a08e2a64642f45e57543b62bffe43ec350edc33dc22ac)}},tl(2008f8280d68e02e807ccffee141c4a6b7ac31d3c283ae0921892d95f691742c44ad20b0f8ce3e1df406514a773414b5d9e5779d8e68ce816e9db39b8e53255ac3b406ac)}";
            var controlNodes = new ByteData256[] {
                new ByteData256("06b46c960d6824f0da5af71d9ecc55714de5b2d2da51be60bd12c77df20a20df"),
                new ByteData256("4691fbb1196f4675241c8958a7ab6378a63aa0cc008ed03d216fd038357f52fd"),
                new ByteData256("e47f58011f27e9046b8195d0ab6a2acbc68ce281437a8d5132dadf389b2a5ebb"),
                new ByteData256("32a0a039ec1412be2803fd7b5f5444c03d498e5e8e107ee431a9597c7b5b3a7c"),
                new ByteData256("d7b0b8d070638ff4f0b7e7d2aa930c58ec2d39853fd04c29c4c6688fdcb2ae75"),
            };

            var tree  = new TaprootScriptTree(treeStr, scriptOpTrue, controlNodes);
            var count = tree.GetBranchCount();

            Assert.Equal((uint)5, count);
            var nodeList = tree.GetTargetNodes();

            Assert.Equal(5, nodeList.Length);
            if (nodeList.Length == 5)
            {
                for (var index = 0; index < nodeList.Length; ++index)
                {
                    Assert.Equal(controlNodes[index].ToHexString(), nodeList[index].ToHexString());
                }
            }

            var branch = tree.GetBranch(3);

            Assert.Equal(
                "{tl(51),{tl(204a7af8660f2b0bdb92d2ce8b88ab30feb916343228d2e7bd15da02e1f6a31d47ac),tl(2000d134c42fd51c90fa82c6cfdaabd895474d979118525362c0cd236c857e29d9ac)}}",
                branch.ToString());

            var tree2 = new TapBranch(
                "{{tl(20ac52f50b28cdd4d3bcb7f0d5cb533f232e4c4ef12fbf3e718420b84d4e3c3440ac),{tl(2057bf643684f6c5c75e1cdf45990036502a0d897394013210858cdabcbb95a05aac),tl(51)}},tl(2057bf643684f6c5c75e1cdf45990036502a0d897394013210858cdabcbb95a05aad205bec1a08fa3443176edd0a08e2a64642f45e57543b62bffe43ec350edc33dc22ac)}",
                scriptOpTrue);

            tree2.AddBranch(branch);
            tree2.AddBranch("tl(2008f8280d68e02e807ccffee141c4a6b7ac31d3c283ae0921892d95f691742c44ad20b0f8ce3e1df406514a773414b5d9e5779d8e68ce816e9db39b8e53255ac3b406ac)");
            Assert.Equal(tree.ToString(), tree2.ToString());
        }
예제 #3
0
        public void TapScriptSignTest1()
        {
            var sk  = new Privkey("305e293b010d29bf3c888b617763a438fee9054c8cab66eb12ad078f819d9f27");
            var spk = SchnorrPubkey.GetPubkeyFromPrivkey(sk, out bool _);

            Assert.Equal("1777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb", spk.ToHexString());

            var scriptCheckSig = Script.CreateFromAsm(new string[] { spk.ToHexString(), "OP_CHECKSIG" });

            var tree = new TaprootScriptTree(scriptCheckSig);

            tree.AddBranches(new string[] {
                "4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6d",
                "dc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54",
            });
            var taprootData = tree.GetTaprootData(spk);

            Assert.Equal("3dee5a5387a2b57902f3a6e9da077726d19c6cc8c8c7b04bcf5a197b2a9b01d2", taprootData.Pubkey.ToHexString());
            Assert.Equal("dfc43ba9fc5f8a9e1b6d6a50600c704bb9e41b741d9ed6de6559a53d2f38e513", taprootData.TapLeafHash.ToHexString());
            Assert.Equal(
                "c01777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6ddc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d54",
                taprootData.ControlBlock.ToHexString());
            var tweakedPrivkey = tree.GetTweakedPrivkey(sk);

            Assert.Equal("a7d17bee0b6313cf864a1ac6f203aafd74a40703ffc050f66517e4f83ff41a03", tweakedPrivkey.ToHexString());

            var addr = new Address(taprootData.Pubkey, CfdAddressType.Taproot, CfdNetworkType.Mainnet);

            Assert.Equal("bc1p8hh955u8526hjqhn5m5a5pmhymgecmxgerrmqj70tgvhk25mq8fqw77n40", addr.ToAddressString());

            var txHex    = "02000000015b80a1af0e00c700bee9c8e4442bec933fcdc0c686dac2dc336caaaf186c5d190000000000ffffffff0130f1029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d500000000";
            var outpoint = new OutPoint("195d6c18afaa6c33dcc2da86c6c0cd3f93ec2b44e4c8e9be00c7000eafa1805b", 0);
            var utxos    = new UtxoData[] {
                new UtxoData(outpoint, 2499999000, new Descriptor(addr.GetLockingScript(), CfdNetworkType.Mainnet)),
            };
            var tx = new Transaction(txHex);

            tx.SetTxInUtxoData(utxos);
            var sighashType = new SignatureHashType(CfdSighashType.All);
            var sighash     = tx.GetSigHashByUtxoData(outpoint, sighashType, taprootData.TapLeafHash, Transaction.codeSeparatorPositionFinal);

            Assert.Equal("80e53eaee13048aee9c6c13fa5a8529aad7fe2c362bfc16f1e2affc71f591d36", sighash.ToHexString());

            var signature = SchnorrUtil.Sign(sighash, sk);
            var sig       = signature.GetSignData(sighashType);

            Assert.Equal(
                "f5aa6b260f9df687786cd3813ba83b476e195041bccea800f2571212f4aae9848a538b6175a4f8ea291d38e351ea7f612a3d700dca63cd3aff05d315c5698ee901",
                sig.ToHexString());

            tx.AddTapScriptSign(outpoint, new SignParameter[] { sig }, taprootData.TapScript, taprootData.ControlBlock);
            Assert.Equal(
                "020000000001015b80a1af0e00c700bee9c8e4442bec933fcdc0c686dac2dc336caaaf186c5d190000000000ffffffff0130f1029500000000160014164e985d0fc92c927a66c0cbaf78e6ea389629d50341f5aa6b260f9df687786cd3813ba83b476e195041bccea800f2571212f4aae9848a538b6175a4f8ea291d38e351ea7f612a3d700dca63cd3aff05d315c5698ee90122201777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfbac61c01777701648fa4dd93c74edd9d58cfcc7bdc2fa30a2f6fa908b6fd70c92833cfb4d18084bb47027f47d428b2ed67e1ccace5520fdc36f308e272394e288d53b6ddc82121e4ff8d23745f3859e8939ecb0a38af63e6ddea2fff97a7fd61a1d2d5400000000",
                tx.ToHexString());

            try
            {
                tx.VerifySignByUtxoList(outpoint);
                Assert.True(false);
            }
            catch (InvalidOperationException ae)
            {
                Assert.Equal("CFD error[IllegalStateError] message:The script analysis of tapscript is not supported.", ae.Message);
            }
            catch (Exception e)
            {
                Assert.Null(e);
            }

            var isVerify = spk.Verify(signature, sighash);

            Assert.True(isVerify);
        }