示例#1
0
        static TapBranch GetBranchData(ErrorHandle handle, TreeHandle treeHandle)
        {
            TapBranch branch = new TapBranch();
            var       ret    = NativeMethods.CfdGetTapBranchCount(
                handle.GetHandle(), treeHandle.GetHandle(), out uint count);

            if (ret != CfdErrorCode.Success)
            {
                handle.ThrowError(ret);
            }
            TapBranch[] branchList = new TapBranch[count];
            ret = NativeMethods.CfdGetBaseTapLeaf(handle.GetHandle(),
                                                  treeHandle.GetHandle(), out byte leafVersion,
                                                  out IntPtr tapscript, out IntPtr tapLeafHash);
            if (ret != CfdErrorCode.Success)
            {
                handle.ThrowError(ret);
            }
            string tapscriptStr   = CCommon.ConvertToString(tapscript);
            string tapLeafHashStr = CCommon.ConvertToString(tapLeafHash);

            if (count == 0)
            {
                branch.topHash = new ByteData256(tapLeafHashStr);
            }
            branch.branches = branchList;
            if (tapscriptStr.Length != 0)
            {
                branch.tapscript   = new Script(tapscriptStr);
                branch.leafVersion = leafVersion;
                branch.targetNodes = new ByteData256[count];
            }
            branch.UpdateBranchData(handle, treeHandle);
            return(branch);
        }
        /// <summary>
        /// Get taproot data.
        /// </summary>
        /// <param name="internalPubkey">internal pubkey</param>
        /// <returns>taproot data</returns>
        public TaprootScriptData GetTaprootData(SchnorrPubkey internalPubkey)
        {
            if (internalPubkey is null)
            {
                throw new ArgumentNullException(nameof(internalPubkey));
            }
            using (var handle = new ErrorHandle())
                using (var treeHandle = new TreeHandle(handle))
                {
                    Load(handle, treeHandle);
                    var ret = NativeMethods.CfdGetTaprootScriptTreeHash(
                        handle.GetHandle(), treeHandle.GetHandle(), internalPubkey.ToHexString(),
                        out IntPtr witnessProgram, out IntPtr tapLeafHashPtr, out IntPtr controlBlockStr);
                    if (ret != CfdErrorCode.Success)
                    {
                        handle.ThrowError(ret);
                    }
                    var witnessProgramStr = CCommon.ConvertToString(witnessProgram);
                    var tapLeafHash       = CCommon.ConvertToString(tapLeafHashPtr);
                    var controlBlock      = CCommon.ConvertToString(controlBlockStr);

                    return(new TaprootScriptData(
                               new SchnorrPubkey(witnessProgramStr), new ByteData(controlBlock),
                               new ByteData256(tapLeafHash), GetTapScript()));
                }
        }
示例#3
0
        internal void Load(ErrorHandle handle, TreeHandle treeHandle)
        {
            if (handle is null)
            {
                throw new ArgumentNullException(nameof(handle));
            }
            if (treeHandle is null)
            {
                throw new ArgumentNullException(nameof(treeHandle));
            }

            string nodes = "";

            foreach (var node in targetNodes)
            {
                nodes += node.ToHexString();
            }
            var ret = NativeMethods.CfdSetScriptTreeFromString(handle.GetHandle(),
                                                               treeHandle.GetHandle(), treeString, tapscript.ToHexString(), leafVersion, nodes);

            if (ret != CfdErrorCode.Success)
            {
                handle.ThrowError(ret);
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="controlBlock">control block</param>
        /// <param name="tapscript">tapscript</param>
        public TaprootScriptTree(ByteData controlBlock, Script tapscript)
        {
            if (controlBlock is null)
            {
                throw new ArgumentNullException(nameof(controlBlock));
            }
            if (tapscript is null)
            {
                throw new ArgumentNullException(nameof(tapscript));
            }

            using (var handle = new ErrorHandle())
                using (var treeHandle = new TreeHandle(handle))
                {
                    var ret = NativeMethods.CfdSetTapScriptByWitnessStack(handle.GetHandle(),
                                                                          treeHandle.GetHandle(), controlBlock.ToHexString(), tapscript.ToHexString(),
                                                                          out IntPtr internalPubkeyPtr);
                    if (ret != CfdErrorCode.Success)
                    {
                        handle.ThrowError(ret);
                    }
                    internalPubkey = new SchnorrPubkey(CCommon.ConvertToString(internalPubkeyPtr));
                    GetAllData(handle, treeHandle);
                }
        }
示例#5
0
        void UpdateAllData(ErrorHandle handle, TreeHandle treeHandle)
        {
            var ret = NativeMethods.CfdGetTapBranchCount(
                handle.GetHandle(), treeHandle.GetHandle(), out uint count);

            if (ret != CfdErrorCode.Success)
            {
                handle.ThrowError(ret);
            }
            TapBranch[] branchList = new TapBranch[count];
            var         offset     = branches.Length;

            for (var index = offset; index < count; ++index)
            {
                ret = NativeMethods.CfdGetTapBranchHandle(
                    handle.GetHandle(), treeHandle.GetHandle(), (byte)index,
                    out IntPtr branchHash, out IntPtr branchTreeHandle);
                if (ret != CfdErrorCode.Success)
                {
                    handle.ThrowError(ret);
                }
                CCommon.ConvertToString(branchHash);
                using (var branchHandle = new TreeHandle(handle, branchTreeHandle))
                {
                    TapBranch branch = new TapBranch();
                    branch.GetAllData(handle, branchHandle);
                    branchList[index] = branch;
                }
            }
            if (count != 0)
            {
                var newTargetNodes = new ByteData256[count];
                for (var index = 0; index < offset; ++index)
                {
                    branchList[index]     = branches[index];
                    newTargetNodes[index] = targetNodes[index];
                }
                for (var index = offset; index < count; ++index)
                {
                    newTargetNodes[index] = branchList[index].topHash;
                }
                branches    = branchList;
                targetNodes = newTargetNodes;
            }
            UpdateBranchData(handle, treeHandle);
        }
示例#6
0
        void UpdateBranchData(ErrorHandle handle, TreeHandle treeHandle)
        {
            if (handle is null)
            {
                throw new ArgumentNullException(nameof(handle));
            }
            if (treeHandle is null)
            {
                throw new ArgumentNullException(nameof(treeHandle));
            }

            var ret = NativeMethods.CfdGetTaprootScriptTreeSrting(handle.GetHandle(),
                                                                  treeHandle.GetHandle(), out IntPtr treeString);

            if (ret != CfdErrorCode.Success)
            {
                handle.ThrowError(ret);
            }
            this.treeString = CCommon.ConvertToString(treeString);
            if (branches.Length != 0)
            {
                var index = branches.Length - 1;
                ret = NativeMethods.CfdGetTapBranchData(handle.GetHandle(),
                                                        treeHandle.GetHandle(), (byte)index, true, out IntPtr branchHash,
                                                        out _, out IntPtr tempScript, out byte _);
                if (ret != CfdErrorCode.Success)
                {
                    handle.ThrowError(ret);
                }
                CCommon.ConvertToString(tempScript);
                topHash = new ByteData256(CCommon.ConvertToString(branchHash));
            }
            else if (topHash.IsEmpty())
            {
                ret = NativeMethods.CfdGetBaseTapLeaf(handle.GetHandle(),
                                                      treeHandle.GetHandle(), out byte _,
                                                      out IntPtr tapscript, out IntPtr tapLeafHash);
                if (ret != CfdErrorCode.Success)
                {
                    handle.ThrowError(ret);
                }
                CCommon.ConvertToString(tapscript);
                string tapLeafHashStr = CCommon.ConvertToString(tapLeafHash);
                topHash = new ByteData256(tapLeafHashStr);
            }
        }
示例#7
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="hash">branch hash</param>
        public TapBranch(string treeStr)
        {
            if (treeStr is null)
            {
                throw new ArgumentNullException(nameof(treeStr));
            }
            treeString  = treeStr;
            targetNodes = Array.Empty <ByteData256>();
            branches    = Array.Empty <TapBranch>();
            topHash     = new ByteData256();
            tapscript   = new Script();
            leafVersion = 0;

            using (var handle = new ErrorHandle())
                using (var treeHandle = new TreeHandle(handle))
                {
                    Load(handle, treeHandle);
                    GetAllData(handle, treeHandle);
                }
        }
示例#8
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="tapscript">tapscript</param>
        /// <param name="leafVersion">leaf version</param>
        public TapBranch(Script tapscript, byte leafVersion)
        {
            if (tapscript is null)
            {
                throw new ArgumentNullException(nameof(tapscript));
            }
            this.tapscript   = tapscript;
            this.leafVersion = leafVersion;
            treeString       = ConvertTapscriptToString(tapscript, leafVersion);
            targetNodes      = Array.Empty <ByteData256>();
            branches         = Array.Empty <TapBranch>();
            topHash          = new ByteData256();

            using (var handle = new ErrorHandle())
                using (var treeHandle = new TreeHandle(handle))
                {
                    Load(handle, treeHandle);
                    UpdateBranchData(handle, treeHandle);
                }
        }
示例#9
0
        internal void GetAllData(ErrorHandle handle, TreeHandle treeHandle)
        {
            var tree  = GetBranchData(handle, treeHandle);
            var count = tree.branches.Length;

            TapBranch[]   branchList = new TapBranch[count];
            ByteData256[] nodeList   = new ByteData256[count];
            for (var index = 0; index < count; ++index)
            {
                var ret = NativeMethods.CfdGetTapBranchHandle(
                    handle.GetHandle(), treeHandle.GetHandle(), (byte)index,
                    out IntPtr branchHash, out IntPtr branchTreeHandle);
                if (ret != CfdErrorCode.Success)
                {
                    handle.ThrowError(ret);
                }
                CCommon.ConvertToString(branchHash);
                using (var branchHandle = new TreeHandle(handle, branchTreeHandle))
                {
                    TapBranch branch = new TapBranch();
                    branch.GetAllData(handle, branchHandle);
                    branchList[index] = branch;
                }
            }
            if (count != 0)
            {
                branches = branchList;
            }
            topHash    = tree.topHash;
            treeString = tree.treeString;
            if (!tree.tapscript.IsEmpty())
            {
                tapscript   = tree.tapscript;
                leafVersion = tree.leafVersion;
                for (var index = 0; index < count; ++index)
                {
                    nodeList[index] = branchList[index].topHash;
                }
                targetNodes = nodeList;
            }
        }
示例#10
0
 /// <summary>
 /// Add branches.
 /// </summary>
 /// <param name="treeStringList">tree string list</param>
 public void AddBranches(string[] treeStringList)
 {
     if (treeStringList is null)
     {
         throw new ArgumentNullException(nameof(treeStringList));
     }
     using (var handle = new ErrorHandle())
         using (var treeHandle = new TreeHandle(handle))
         {
             Load(handle, treeHandle);
             foreach (var treeStr in treeStringList)
             {
                 var ret = NativeMethods.CfdAddTapBranchByScriptTreeString(
                     handle.GetHandle(), treeHandle.GetHandle(), treeStr);
                 if (ret != CfdErrorCode.Success)
                 {
                     handle.ThrowError(ret);
                 }
             }
             UpdateAllData(handle, treeHandle);
         }
 }
        /// <summary>
        /// Get tweaked privkey from internal privkey.
        /// </summary>
        /// <param name="privkey">internal privkey.</param>
        /// <returns>tweaked privkey.</returns>
        public Privkey GetTweakedPrivkey(Privkey privkey)
        {
            if (privkey is null)
            {
                throw new ArgumentNullException(nameof(privkey));
            }
            using (var handle = new ErrorHandle())
                using (var treeHandle = new TreeHandle(handle))
                {
                    Load(handle, treeHandle);
                    var ret = NativeMethods.CfdGetTaprootTweakedPrivkey(
                        handle.GetHandle(), treeHandle.GetHandle(), privkey.ToHexString(),
                        out IntPtr tweakedPrivkey);
                    if (ret != CfdErrorCode.Success)
                    {
                        handle.ThrowError(ret);
                    }
                    var tweakedPrivkeyStr = CCommon.ConvertToString(tweakedPrivkey);

                    return(new Privkey(tweakedPrivkeyStr));
                }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="origin">source branch.</param>
        public TaprootScriptTree(TapBranch origin)
        {
            if (origin is null)
            {
                throw new ArgumentNullException(nameof(origin));
            }
            var script = new Script();

            if (origin.HasTapScript())
            {
                script = origin.GetTapScript();
            }
            Initialize(origin.ToString(), script, origin.GetTargetNodes());
            internalPubkey = new SchnorrPubkey();

            using (var handle = new ErrorHandle())
                using (var treeHandle = new TreeHandle(handle))
                {
                    Load(handle, treeHandle);
                    GetAllData(handle, treeHandle);
                }
        }
示例#13
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="treeStr">tree string</param>
        /// <param name="tapscript">tapscript</param>
        /// <param name="targetNodes">target node list</param>
        public TapBranch(string treeStr, Script tapscript, ByteData256[] targetNodes)
        {
            if (treeStr is null)
            {
                throw new ArgumentNullException(nameof(treeStr));
            }
            if (tapscript is null)
            {
                throw new ArgumentNullException(nameof(tapscript));
            }
            ByteData256[] nodes = Array.Empty <ByteData256>();
            if (!(targetNodes is null))
            {
                foreach (var node in targetNodes)
                {
                    if (node.GetSize() != 32)
                    {
                        CfdCommon.ThrowError(CfdErrorCode.IllegalArgumentError, "Invalid branch hash size.");
                    }
                }
                nodes = targetNodes;
            }
            treeString       = treeStr;
            this.targetNodes = nodes;
            branches         = Array.Empty <TapBranch>();
            topHash          = new ByteData256();
            this.tapscript   = tapscript;
            leafVersion      = tapscriptLeafVersion;

            using (var handle = new ErrorHandle())
                using (var treeHandle = new TreeHandle(handle))
                {
                    Load(handle, treeHandle);
                    GetAllData(handle, treeHandle);
                }
        }