<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Code1024</title>
        <link>https://paragraph.com/@code1024</link>
        <description>undefined</description>
        <lastBuildDate>Mon, 13 Apr 2026 09:57:29 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Code1024</title>
            <url>https://storage.googleapis.com/papyrus_images/c7fd1ffd9ecfa982b85bd48a0be48125a5fb431ee32b324b1177f00dc5849397.jpg</url>
            <link>https://paragraph.com/@code1024</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Web3 薪酬大揭秘：「触手可及」的百万年薪？
]]></title>
            <link>https://paragraph.com/@code1024/web3</link>
            <guid>VQRivt9B0HxRE7Hgqzhf</guid>
            <pubDate>Fri, 02 Sep 2022 04:41:11 GMT</pubDate>
            <description><![CDATA[原标题：Navigating Web3 Compensation: A Framework Report 撰文：Framework Ventures 编译：派蒙，Foresight News Framework 一直将促进加密货币行业发展作为各方面业务发展的重心。为了达成这一目标，Framework 不断进行尝试，为整个加密货币社区提供了很多颇有意义的资源。尽管去年已经有大量人才涌入 Web3，但对于公司和潜在员工而言，这个新生领域的招聘过程仍然是零碎和不透明的。因此，根据从一年两次的薪酬调查中获取的数据，Framework 总结了加密货币社区薪酬指南。这份报告收集了背靠风投的初创企业的全面薪酬数据，因此对于想要进入加密货币领域的群体颇具参考价值。 虽然 The Framework Tent 下的创始人能够用他们持有的 Founder Pass NFTs 获取更完整的数据和报告，但本文将为公众提供一些关键性的线索。这些数据对以下群体很有价值： 正在招聘早期员工并扩大其团队规模的创始人 求职者申请工作或在工资一事和老板反复拉扯 考虑从事加密货币相关工作的学生党 研究方法和几个关键词...]]></description>
            <content:encoded><![CDATA[<p>原标题：Navigating Web3 Compensation: A Framework Report</p><p>撰文：Framework Ventures</p><p>编译：派蒙，Foresight News</p><p>Framework 一直将促进加密货币行业发展作为各方面业务发展的重心。为了达成这一目标，Framework 不断进行尝试，为整个加密货币社区提供了很多颇有意义的资源。尽管去年已经有大量人才涌入 Web3，但对于公司和潜在员工而言，这个新生领域的招聘过程仍然是零碎和不透明的。因此，根据从一年两次的薪酬调查中获取的数据，Framework 总结了加密货币社区薪酬指南。这份报告收集了背靠风投的初创企业的全面薪酬数据，因此对于想要进入加密货币领域的群体颇具参考价值。</p><p>虽然 The Framework Tent 下的创始人能够用他们持有的 Founder Pass NFTs 获取更完整的数据和报告，但本文将为公众提供一些关键性的线索。这些数据对以下群体很有价值：</p><p>正在招聘早期员工并扩大其团队规模的创始人 求职者申请工作或在工资一事和老板反复拉扯 考虑从事加密货币相关工作的学生党</p><p>研究方法和几个关键词定义</p><p>Framework 调查了投资组合中的 18 家公司，其规模从 2 名到 80 名员工不等。因此，这些数据代表了早期和中期公司的报酬，通常都是由风投基金支持的。 虽然没有细分到具体领域，但 Framework 的投资组合中多数是 DeFi、基础设施和 Web3 游戏公司。 在本报告中，「管理层 Executives 」指的是 CXO 头衔和主要职能部门（工程、BD、运营等）的负责人。「工程师 Engineers 」代表工程和技术研究角色，「业务运营 Business Operations 」涵盖所有非执行、非工程的角色。 所有数据都是在 2022 年 5 月和 6 月收集的。数据来自企业（下文写做「受访企业」）、去中心化协议以及 DAO（下文写做「受访项目」）。</p><p>主要研究结果</p><p>法币在美国仍然是王道，但稳定币在国际上已经有了很大的影响力</p><p>超过 80% 的公司总部都设在美国，这些受访者都将美元作为主要支付方式，这通常是为了保障员工更便捷地处置薪资收入以及消费，以及更方便地向员工发放福利，毕竟一般情况下福利供应商都不会支持稳定币 。但也有向劳务合同甚至全职员工以 USDC 形式发放薪资的公司。</p><p>对于国际团队来说，就没有这么统一了。约 50% 的受访公司提供 USDC 或其他稳定币作为所有员工的主要报酬形式，几乎所有公司都为无论合同工还是全职员工提供 USDC 支付选项。大约一半的国际公司以美元结算，而另一半则以其他当地货币计价。</p><p>股权和代币分配的具体模式，由公司所处阶段和实体结构决定。</p><p>代币为持有人提供了利用和参与社交网络和 DAO 的机会。股权代表在一个中心化公司或实体中的所有权。代币和股权都可以用来激励和补偿网络或公司中的贡献者以及雇员。然而，代币与股权的分配方式可能有很大不同。虽然调查显示，代币和股权补偿高度依赖于公司个体，但仍能从中获取一些有价值的信息。 总部设在美国的团队不太可能推出代币，甚至也没有计划在未来推出代币。在国际上的项目中，超过 25% 的项目已经推出了代币，而且大多数项目正在考虑在未来推出。早期阶段的公司推出代币的可能性要小得多。 对于去中心化网络或 DAO，代币所有权（与股权）是激励员工的标准方式。 比较提供股权和代币所有权的公司，股权提供比例约为代币所有权比例的二倍。 例如，一个在 DAO 工作的早期软件工程师获得的补偿方案可能包括该协议代币最大供应量的约 0.5%。如果同一个软件工程师在一个基于股权的公司工作，她可能会得到该公司 1% 的股权。 随着时间的推移，股权会被大大稀释，而代币所有权是根据最大的代币供应量来设定的。公司的股权和 DAO 的代币所有权都是由「阶段」决定的（即早期=更多的所有权），但这在 DAO 中几乎不存在的「稀释」尤为引人注目。例如，B/C 阶段的公司高级员工可能获得 2% 的股权，而同一员工获得后期 DAO 最大代币供应量的 1% 几乎是天方夜谭。 值得注意的是，上面提到的稀释数据只适用于有代币总量固定的项目。在具有通胀特色的项目中，代币所有权的稀释仍有可能。 调查结果显示， Web3 的股权和代币的释放时间表大多还有 Web2 的影子，即一般会设置长达 4 年的归属期和 1 年的 cliff。然而，值得注意的是，代币的归属时间表因项目而异，有些项目提供 2 年的归属期，但有 1 年的 cliff 或根本没有 cliff。此外，在以 2 年和 4 年归属期的代币中，尽管代币可以在协议本身上用于押注、委托、投票等方面，但已归属的代币有时也会被锁定在未来一段时间内。 分布式办公成了新常态</p><p>大多数接受调查的公司认为自己是 「分布式办公完全体」，并将远程工作作为其业务的主要运营模式。根据调查结果，即使是总部设在美国的公司，也有超过 33% 的员工来自世界各地，鉴于加密货币的汇集「全球劳动力」的特点，这种运作模式似乎是必要的。早期阶段的公司更倾向于是远程办公，而已经获得 A 轮或 B 轮融资的公司则有可能拥有一个或多个正式办公室。</p><p>创始人的薪酬趋于一致，主要由公司阶段决定</p><p>创始人的工资因多种因素影响而有很大差异，其中最显著的因素是公司所处的阶段。对于早期公司，创始人倾向于给自己支付最低工资，以维持舒适但基本的生活质量。对于大多数早期阶段的创始人来说，年薪在 10 万美元和 17.5 万美元之间，最高年薪在 13-16 万美元左右。这个数字对美国的创始人来说比较高，对国际创始人来说略低，主要取决于地点和生活成本。处于后期阶段的公司的创始人获得的工资更高，大约在 17.5 万至 22.5 万美元之间。</p><p>公司创始人集体拥有大量的股权，在公司成立初期约占 80%，在后来的几轮融资中被稀释到 30-50%，持有比例取决于融资金额和条款。独立创始人显然比团队拥有更多的股权，在创始团队中，股权由所有创始人分享。不过，创始团队往往不会雇太多高管稀释他们手中的股权。DAO 或协议创始人拥有的代币占最大代币供应量的比例较少。调查显示中，独立创始人代币所有权最大值是 10%，来自一个早期公司的独立创始人。就整体而言，创始人通常拥有最大代币供应量的 8-12%，独立创始人拥有 2.5-7.5%，其中 4-6% 是所有权分配最为集中的区间。</p><p>非创始人、高管薪酬</p><p>早期阶段公司的非创始人高管薪酬通常与创始人处于同一水平。薪水通常从 12 万到 16 万不等。对于这些早期聘用的非创始人高管来说，股权待遇要丰富得多，根据角色、公司和阶段的不同，可获得 1.0-4.0% 的公司所有权。工程师和 BD/ 合伙人身份的高管往往是这些团队中收入最高的角色。</p><p>对于处于后期阶段的公司，非创始人高管的薪酬通常比创始人的薪酬高得多，多数在 22.5 万美元以上。与所有其他角色一样，美国高管的最低薪酬较高——没有一个美国非创始人高管会拿到低于 10 万美金的工资。高管薪酬对地点的依赖性较小，尤其是 CTO 或工程主管的职位，国际雇员的薪酬与美国雇员的薪酬几乎持平。薪酬最高的高管、非创始人职位是 CTO（工程主管）和 CRO（销售主管）。许多高管销售职位都能获得大量基于业绩的可变报酬。后期阶段公司雇用的高管通常获得公司股权的 1.0%-2.0%，而 DAO 或协议的高管通常获得最大代币供应量的 0.5%-1.0%。</p><p>加密工程师的薪水</p><p>这是整个加密货币社区中最让人关心的问题之一。尽管有大量学习 Solidity、Rust 或其他语言的新工程师涌入，但加密货币领域的技术人才仍然匮乏。</p><p>事实是，无论是从基本工资还是从所有权的角度来看，加密货币工程师薪酬水平对比高管而言范围较大。在所有的工程岗位中（包括在加密货币公司工作的非加密货币工程师），超过 55% 的人能拿到 10-17 万美元的薪酬。低于 10 万美元的工程师主要在生活成本较低的国家工作。</p><p>对于 Solidity、Rust、区块链架构师等「加密货币限定」工种，则可以无视地区生活成本的差异，超过 65% 的工作者分布在全球各地，但他们的工资都非常可观。虽然大多数加密货币工程师的工资仍在 10-17 万之间，但有超过 15% 的人突破了上限，最高拿到了接近 30 万年薪的基本工资。这些工程师同时有可能在 DAO 或去中心化网络「搞搞副业」，因此还能持有 0.1%-0.4% 的项目代币。</p><p>非执行层业务运营（市场、销售 /BD、产品、运营等）的薪酬</p><p>与工程师、创始人或高管职位相比，非执行业务运营职位的报酬更依赖于员工的工作地点。那些在国际上生活成本较低的地区工作的人，通常比在美国（或英国 / 欧洲）工作的人的薪水低得多。</p><p>在这个分类中，薪酬最高的角色是 BD/ 合伙人：中层为 6-12 万美元，高级为 15 万美元左右。市场营销 / 公共关系 / 通信的薪酬范围类似：中级 8-10 万美元；高级约 14 万美元。产品和财务人员的薪酬也在此范围内，但通常只有后期阶段的公司有此需求。薪酬较低的职位是运营、设计、人力资源和社区管理，非执行层人员的最高薪酬通常为 12-13 万美元。</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.defidaonews.com/article/6774898">https://www.defidaonews.com/article/6774898</a></p>]]></content:encoded>
            <author>code1024@newsletter.paragraph.com (Code1024)</author>
        </item>
        <item>
            <title><![CDATA[YODO: You Only Depeg Once
]]></title>
            <link>https://paragraph.com/@code1024/yodo-you-only-depeg-once</link>
            <guid>ARaQz4q62cQkBTNk2GNv</guid>
            <pubDate>Sat, 20 Aug 2022 08:53:04 GMT</pubDate>
            <description><![CDATA[A lot of interesting stuff has been written about the blacklisting of Tornado Cash by OFAC and its implications on DeFi, crypto, financial markets, freedom of speech, and the history of mankind. On one side we have had decentralisation maxis hinting at the blacklisting of a piece of software as universal acid on its way to destroy the universe, while on the other hurried pragmatists were pointing fingers to the reality of things and the use of such technological tool to mainly do dodgy stuff,...]]></description>
            <content:encoded><![CDATA[<p>A lot of interesting stuff has been written about the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://home.treasury.gov/news/press-releases/jy0916">blacklisting of Tornado Cash by OFAC</a> and its implications on DeFi, crypto, financial markets, freedom of speech, and the history of mankind. On one side we have had decentralisation maxis hinting at the blacklisting of a piece of software as universal acid on its way to destroy the universe, while on the other hurried pragmatists were pointing fingers to the reality of things and the use of such technological tool to mainly do dodgy stuff, buy weed, finance terrorism, and promote chaos. You won’t get anything else on the matter from me. Extrapolating the motivations and implications of the event on the medium-to-long term future of financial intermediation and political freedom is twenty percent perspiration and eighty percent inspiration. We might as well indulge in guessing the effects of the recent FBI raid at Mar-a-Lago on the 2024 US presidential elections. Guessing is good to sell papers, and it’s not for me.</p><p><strong>Subscribe</strong></p><h2 id="h-currency-market-fit-understanding-stablecoins" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Currency Market Fit: Understanding Stablecoins</h2><p>A currency is not very different from any other immaterial, man-designed, product. The magic that minted a physical, or at least measurable, object out of a whirlpool of beliefs and intentions is fascinating enough to deserve thousands of pages, but that isn’t the spirit of this piece. I am a currency junkie, as I admitted a few times here already, and I don’t intend to fall into yet another yes-just-one-last-time-I-know-when-to-stop-if-I-want epic of currencies as the ultimate philosophical achievement. But then I just did it, some might say. Anyway, a lot has been said lately about the opportunity or not of having one of the most prominent crypto currency projects out there, $DAI, pegged to its most powerful sibling the dollar, that I figured it would have made sense to put some order in the house and remind myself, and others, about the functionality of the pegging attribute. Rather than about magic, it should be about product market fit.</p><h4 id="h-elastic-and-inelastic-money" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">Elastic and Inelastic Money</h4><p>Talking about a peg is talking about the elasticity of monetary purchasing power—price. But the elasticity of a currency against a foreign sibling—or a basket of siblings, isn’t the only way we can look at monetary price elasticity. Another one, to which we are better accustomed, is via inflation, or in other words the (evolution of) purchasing power against a basket of domestically-available goods and services. The two concepts are connected and both charged up with often unnecessary rhetorical drama.</p><p><strong>Money elasticity →</strong> We have encountered inelastic money, and more specifically inelastic US dollars, before—i.e. before the Federal Reserve Act of 1913. In neoclassical economics the interactions between providers and consumers of money can be represented through supply and demand curves like for any other tradable good. The (simplified) relationship between quantity demanded and (exogenously set) prices is well researched: all other things remaining equal, consumers would require less quantity of something if its price increases. The relationship between supply and prices is opposite: I am willing to offer even more of something if its price increases. For suppliers, however, there are more interesting second-order effects at play given that the ability to directly influence aggregate availability and market prices is real; we can however ignore those, assuming for a moment that there is one and only one supplier of money, and that the supplier has some sort of monopoly over it.</p><p><strong>Inelastic monetary supply →</strong> The case of inelastic money is the easiest to grasp: the amount of money in circulation is fixed—or better doesn’t depend on prices and cannot be manipulated by the minter. There exists at any point in time an equilibrium in terms of purchasing power for each unit of currency. A shock in the demand function, driven by abrupt changes but also by standard economic expansion as well as evolving expectations, would translate in an increase or decrease of the purchasing power at equilibrium. Given the pro-cyclicality of human nature it is easy to see how those effects might become self-enforcing: e.g. expectations on future growth worsen → demand curves shift downward → equilibrium prices go down → incentives to produce goods diminish → expectations on slowing growth are fulfilled → and so on. The same can happen in the opposite direction. More importantly, the magnitude and consequences of those self-enforcing cycles are difficult to predict and make any economic activity linked to the quality of forecasting (e.g. <strong>credit</strong>) very difficult. Inelastic money is very bad in incentivising investments and protecting social stability.</p><p><strong>Elastic monetary supply →</strong> Let’s introduce the ability for currency minters to expand the monetary supply—what <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Federal_Reserve_Note">Federal Reserve Notes</a> did for the dollar. The ultimate effects on prices of changing demand conditions is now uncertain, given that the changes in the demand curve can be counterbalanced. We are at the early days of modern monetary theory. A regressive shift of the demand curve for money has been the main argument of post-2008 central bankers on why monetary easing measures have not been inflationary for the common citizen—although this cannot be said of their impact on investable assets.</p><p>An orderly market for money is of paramount importance for an economy that wants to shield citizens from speculative risks and provide economic agents with reasonably stable expectations to base their investment decisions on. The same reasoning can be applied when prices are measured not relatively to a basket of goods, but to another currency or basket of currencies. The effects of changing demand conditions are, in this case, even more easily assessable, thanks to the existence of a liquid foreign exchange market. The reasons behind active monetary manipulation, however, aren’t dissimilar: for economies that have a high relative exposure to (e.g.) dollar-denominated flows of goods and capital the stability of the local currency <em>vs.</em> the dollar is crucial. Foreign exchange stability in highly integrated economies facilitate foreign investment decisions and the purchasing of local goods—e.g. natural resources.</p><p>The monetary and economic interdependence between sovereign states and the United States of America has created huge governance and political distortion during the past century—I live most of the year in South America and I breathe a bit of that every day. Monetary connectivity, however, is more the effect than the origin of those concerns, since without economic, industrial (and military) independence it isn’t plausible to expect sovereignty of capital flows.</p><h4 id="h-elastic-and-inelastic-dollardai" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">Elastic and Inelastic $DAI</h4><p>The Tornado Cash drama turbocharged the debate around Maker’s relationships with the US dollar and its crypto proxies—mainly $USDC. It is renown how dollar crypto proxies represent today the vast majority (&gt;80%) of Maker’s assets. Maker is in other words an extremely dollarised monetary system, and not everybody likes it.</p><p>But what does dollarisation mean exactly for Maker? In <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dirtroads.substack.com/p/-40-pruning-memes-algo-stables-are">DR’s #40</a> we had defined $DAI as an anchored &amp; algorithmic stablecoin. Parking the algorithmic component aside, we identified $DAI as <strong><em>anchored</em></strong> because its collateral pool (so far mainly $ETH and $wBTC) easily passes our <strong><em>exogeneity test</em></strong>. As a reminder, below is our test.</p><blockquote><p>Defining what is exogenous and what is endogenous to a system is a tricky thing, as the boundaries of a system can get larger or narrower depending on the definition we adopt. $ETH, for example, is considered exogenous to the MakerDAO system in the chart above, but Maker is a project based on the Ethereum chain with currency printed through its technology; is $ETH truly exogenous then? <strong>I have a personal <em>exogeneity test</em>: is the project itself existential for the survival of such guarantee? If so, it is not an exogenous asset.</strong></p></blockquote><p>When we exclude dollar proxies, $ETH (and $wBTC) are Maker’s main guarantees to print $DAI. What should happen to $DAI following an increase in the dollar-denominated prices of this collateral? Given Maker’s design, and in alignment with neoclassical economics, we could expect a growth in the quantity of $DAI available, but with uncertain effects on $DAI prices relative to the dollar, as per the chart below.</p><p>With the amount of $DAI in circulation ranging within $5-10b, relative to $ETH’s $200-300b float, we can see how plausible it is for the upward pressure on $DAI to dominate—and even more so if we consider that straight $ETH is only 60-70% of $DAI’s non-stablecoin collateral pool. The picture doesn’t change during times of negative market sentiment: $DAI supply tends to reduce itself due to a decreasing demand for leverage while $DAI demand increases as traders chase less volatile assets to off-risk their portfolio. Both dynamics exercise upward pressure on $DAI relative prices.</p><p><strong>Tectonic pressures →</strong> Are those effects immutable? Of course they are not, but the immaturity of crypto markets has provided way more upward pressure (relative to the dollar) on $DAI than downward one. If, on the one hand, this is testament of Maker’s solid design when it comes to over-collateralisation and collateral auctioning—downward pressure on $DAI would materialise if the market expected the value of the liabilities to exceed that of the assets, a volatile currency comes with a lot of strings attached. First of all, and probably most importantly, with the suppliers of $DAI being traders looking for leverage, it isn’t ideal for those traders that the currency they are borrowing in tends to significantly appreciate <em>vs.</em> the rest of their assets. Would you borrow in $CHF if you were living, for example, in Poland? <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.europarl.europa.eu/RegData/etudes/BRIE/2021/689361/EPRS_BRI(2021)689361_EN.pdf">I hope not</a>.</p><p><strong>Enter the PSM →</strong> The introduction of Maker’s Peg Stability Module (or PSM) was exactly functional to ease upward pressure on $DAI relative prices. By giving the ability to arbitrageurs to deposit whitelisted proxies of the dollar (e.g. $USDC) in a contract minting $DAI in exchange, on a fixed one-for-one ratio and no fees, the protocol granted itself the possibility to inflate its monetary base (<em>vs.</em> the dollar) in order to keep prices stable. The PSM proved to be a much better design choice than others, like Luna’s, for pegging. While the constructive pressures on Terra-dollars translated into the burning of the ecosystem’s equity token, $LUNA, <em>de facto</em> transferring value directly to equity holders—that could crystallise such value anytime at will, in the case of Maker pressures remain stored in the PSM. In all shapes and forms the size of the PSM is a measure of the excess $DAI demand at any point in time. The advantage of Maker’s design choice is that the same value can later be used to protect the price of $DAI if and when downward price pressure dominates. <strong>If you think of $DAI as a product to engage in the crypto economy for traders that base most of their investment framing in US dollars, the PSM has been a great introduction.</strong></p><p><strong>The costs of dollarisation →</strong> Nothing, however, comes for free. The deep interdependence between $DAI and $USDC has had costs for Maker:</p><ul><li><p>Higher counterparty risk—<em>vs.</em> $USDC, especially considering that PSM mints $DAI without any over-collateralisation buffer</p></li><li><p>Less obvious differentiation as a decentralised product—<em>vs.</em> $USDC</p></li><li><p>Higher regulatory risk—<em>vs.</em> US regulators, considering that $USDC is a fractionalised and tokenised money market fund investing in US treasuries</p></li><li><p>Higher generic execution risk for Maker, without any impact on bottom line—Maker makes no money on PSM-minted $DAI</p></li></ul><p>What most miss, however, is that $USDC’s domination of Maker’s collateral pool tells more about Maker’s inability to spin out new and better products rather than about an embedded superiority of $USDC as collateral asset.</p><h4 id="h-execution-of-a-revolution" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">Execution of a Revolution</h4><p>We can assume for a second that it would be appropriate for Maker to reduce the dollarisation of its currency system. The assumption is non-trivial, but let’s put that aside for now. What would such de-dollarisation process look like? What would be the benefits of it, and what the threats?</p><p><strong>Phase 1: Stop the dollarisation →</strong> c. $5.4b of dollar proxy exposure is not the maximum Maker allows, based on the current governance-approved parameters. Aggregate debt ceiling for those vaults amounts to c. $12.8b—<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://makerburn.com/#/rundown">makerburn</a>, or almost exactly the double of what we have now. Of those, only the vaults related to Gelato Network provide a bit of yield (c. $630k/ year) while the others are there solely to sustain the peg. The first step of a de-dollarisation path should focus on drastically reducing available debt ceiling to stop the growth of those dollar reserves.</p><p><strong>Phase 2: Incentivise $DAI supply expansion →</strong> As a reminder, $DAI is over-collateralised by a pool of crypto assets—below a diagram of Maker’s balance sheet from <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dirtroads.substack.com/p/-40-pruning-memes-algo-stables-are">DR’s #40</a>.</p><p>The inability of Maker to expand the stable part of its balance sheet further might put upward pressure on the value of $DAI that could be (at least partially) counterbalanced by new crypto-backed/ over-collateralised minted $DAI. In order to incentivise this, Maker could, alternatively:</p><ul><li><p>Reduce the <strong>liquidation ratio</strong> or <strong>liquidation penalty</strong> for specific collateral types, thus increasing $DAI minting capacity—although the effects of this move are uncertain given the unpredictability of investors’ risk appetite</p></li><li><p>Reduce the <strong>stability fee</strong> for specific collateral types, thus making borrowing more attractive for seekers of leverage; this had been originally proposed by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/mhonkasalo/status/1559221490503061504?s=20&amp;t=scHyS_CkGCo8o4t8MDM2xA">Mika</a> and deployed on the stETH B pool by Maker—<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/MakerGrowth/status/1559220699578908672?s=20&amp;t=scHyS_CkGCo8o4t8MDM2xA">you can now mint $DAI against $stETH for no fees</a></p></li><li><p>Apply a negative <strong>DSR</strong> (Dai savings rate) on $DAI outstanding making it less attractive to hold $DAI—although theoretically doable it is extremely difficult to imagine how this could be applied in reality given Maker’s construct and the fact that it is not required for any user of the currency system to keep $DAI staked at the protocol level</p></li><li><p>Engage in <strong>open market operations</strong> by minting naked $DAI out of thin air and inflate money supply—there are several ways this could be mechanically done and each would require a detailed analysis</p></li></ul><p><strong>Phase 3: Dribble out existing dollars →</strong> PSM vaults (representing the vast majority of Maker’s proxy dollars) operate similarly to other vaults—albeit with no stability fee and a collateralisation ratio of 100%. Unlike regular vaults, however, users don&apos;t retain ownership of the asset and borrow $DAI, instead they swap the asset directly for $DAI, with MakerDAO owning the rights (and exposure) to the swapped asset. The cost for Maker of a (partial) devaluation of the underlying stable collateral could be devastating for the protocol—that in this case has no protection from over-collateralisation. Digesting (extremely) high levels of counterparty and market risks can be seen as the cost for the protocol to retain the excess $USDC liquidity. Again, there’s no free lunch. Although it might be prudent for the protocol to reduce the footprint of $USDC in the wider collateral pool, the unwinding comes with existential risk; while the protocol benefited from systemic liquidity by building up a treasury of billions of dollars, the decision to unleash the PSM in the first place might have been an irreversible one. No matter how you see it, the abrupt unwinding of all crypto dollars would come with huge execution risk and would have the de-pegging as the only plausible conclusion.</p><p>Below I listed three possible ways the $USDC legacy could be off-loaded. The description is non-technical, and the list is non-exhaustive.</p><p>Of the three methods, all with huge execution risk, it was #3 that was hinted at by Rune in Maker’s discord channels—although <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/RuneKek/status/1557775172878454784?s=20&amp;t=V6Q4_OT9_T-CTXxJo0hB7g">he U-turned immediately after in schizophrenic style</a>. #3 is definitely the riskiest yet most exciting of the bunch. YOLO-ing $3.5b into an asset is truly DeFi-esque, and difficult to grasp for anyone who hasn&apos;t spent significant time in the sector. More than that, discussing it openly on forum before executing is mind-blowing for anyone who knows how modern central banking operates, or for anyone who was paying attention to the Luna crash. For posterity, I opted for stating my opinion at the time.</p><p>I am not a currency or macro trader and don’t want to make it too easy for those guys to figure out how to exploit a system that announces size and direction of its future trades right in the open. The master $UST-$BTC-$USD triangulated trade that killed the Terra project should still be vivid in our memories. The effects of the unwinding, however, even if orderly executed, are evident and should be discussed at length by community and investors. Unwinding (and limiting) present (and future) dollar exposure out of the Maker monetary system would mean a currency that floats freely against the dollar, most probably with a smaller currency base and, given the relative small size of $DAI float, with brutal volatility.</p><p>Is this a good market fit? It depends. I want to end by asking readers this and other questions, hoping that some of the $MKR whales would be among those readers too.</p>]]></content:encoded>
            <author>code1024@newsletter.paragraph.com (Code1024)</author>
        </item>
        <item>
            <title><![CDATA[软着陆后，加密市场下阶段趋势与核心叙事
]]></title>
            <link>https://paragraph.com/@code1024/cNat93YhejvnVgp80Q5F</link>
            <guid>cNat93YhejvnVgp80Q5F</guid>
            <pubDate>Thu, 18 Aug 2022 11:50:37 GMT</pubDate>
            <description><![CDATA[原文作者：Ansem 原文编译：Amber，Foresight News 在过去的一周多的时间里，传统金融市场在美国通胀压力有所减轻的背景下出现了一些积极的信号，而加密货币市场也「追随」其迎来了阶段性的复苏。 7 月美国 CPI 数据录得 8.5% 水平低于市场预期。 而一个月前公布的前值创出了 9.6% 的创纪录高点，数据发布时大多数市场参与者都会如此糟糕的数据发布后金融市场出现的猛烈反弹感到惊讶，但实际上这是因为市场对于「数据不会更差了」进行的前瞻性定价，而从结果上来看，这种看似与当期数据背离的判断是准确的。不过至于 CPI 究竟能否就此迎来拐点，我们只能继续观察下去。 如果从纯粹的「财富破坏」角度来看，今年相比于加密货币历史上任何一个周期的熊市都更加猛烈。Luna 在 5 月份的暴雷事件直接从加密货币市场中抹去了 600 亿美元的总市值，并进而在整个生态中造成了一系列的连锁反应。比特币和以太坊价格的快速跳水导致对冲基金 Three Arrows Capital 遭遇危机，6 月加密市场总市值再度跌去 100 亿美元，多家规模很大的加密领域 CeFi 机构破产，市场经历了一轮...]]></description>
            <content:encoded><![CDATA[<p>原文作者：Ansem</p><p>原文编译：Amber，Foresight News</p><p>在过去的一周多的时间里，传统金融市场在美国通胀压力有所减轻的背景下出现了一些积极的信号，而加密货币市场也「追随」其迎来了阶段性的复苏。</p><p>7 月美国 CPI 数据录得 8.5% 水平低于市场预期。</p><p>而一个月前公布的前值创出了 9.6% 的创纪录高点，数据发布时大多数市场参与者都会如此糟糕的数据发布后金融市场出现的猛烈反弹感到惊讶，但实际上这是因为市场对于「数据不会更差了」进行的前瞻性定价，而从结果上来看，这种看似与当期数据背离的判断是准确的。不过至于 CPI 究竟能否就此迎来拐点，我们只能继续观察下去。</p><p>如果从纯粹的「财富破坏」角度来看，今年相比于加密货币历史上任何一个周期的熊市都更加猛烈。Luna 在 5 月份的暴雷事件直接从加密货币市场中抹去了 600 亿美元的总市值，并进而在整个生态中造成了一系列的连锁反应。比特币和以太坊价格的快速跳水导致对冲基金 Three Arrows Capital 遭遇危机，6 月加密市场总市值再度跌去 100 亿美元，多家规模很大的加密领域 CeFi 机构破产，市场经历了一轮狂风骤雨般的去杠杆。</p><p>如果从好的方面来看，那就是我们几乎不可能再在短期内看到如此大规模的抛售潮了，此外这种事件发生后形成的底部往往会成为未来强有力的支撑。本文并不是交易指导，只是通过市场上的蛛丝马迹寻找市场下一步走向的大概率结果。</p><p>宏观金融市场和 BTC500</p><p>今年大部分时间里，加密货币与传统金融市场的相关性达到了一个史无前例的水平。传统金融市场在美联储收紧货币政策和通胀境况愈发严峻的背景下持续承压，而加密货币市场则是在下跌趋势看似已经接近尾声时因为连续的黑天鹅事件而再度遭受重创。不过随着市场逐渐趋于平稳，风险偏好正在逐渐回归，而加密市场同样也已经出现了一些回暖的迹象。不过我认为接下来的一段时间里行情还会有一个横向震荡的阶段，尤其是对于比特币来说，反弹可能要比那些叙事更加清晰的山寨币来的更晚一些。</p><p>从技术分析的角度来看，标普 500、纳斯达克和纳斯达克 100 最近都在其周线图上恢复了看涨结构，目前价格已经突破了最近一轮加速下跌启动前的高点位置。相比于 4 月的那一波反弹行情而言，当下这波上涨的强度和图形层面上的「收获」都更加清晰。</p><p>虽然从日线图上来看目前价格走到了一个强阻力区域附近，二季度高点一线附近首度触及时行情有可能走出新一轮的回调，不过这次回调有可能带来绝佳的上车机会。不过至于是否是起跳前的最后一次深蹲需要取决于这轮回调的强度，标普 500 指数如若能够守住 4080 一线，那么上涨势头将得以延续，不过一旦该位置失守，那么本轮反弹预计将就此宣告终结。</p><p>市场一直在盼着鲍威尔能够把那个难以捉摸的「软着陆」搞定，美联储当下仍处在高利率、高债务以及高通胀的困境下走钢丝，任何货币政策上不慎的处理都可能会造成严重的负面影响。近期的反弹得益于强劲的就业数据和有所下滑的 CPI 数值，只有这些数据保持向好的势头，美联储才能在货币政策的调整上获得更大的灵活性。不过像欧元区能源危机恶化、俄乌冲突升级甚至中国的台海问题等等风险事件都很难被提前定价，这些仍然会为市场添加不确定性。不过当下大多数人对于不断变化的经济状况仍然保持着相对乐观的态度，多数人并不认为 08 年那场全球性的金融危机会重现。</p><p>值得一提的是，美国 7 月就业数据表现抢眼，虽然市场对于就业状况的定价效率不高，毕竟多数观点认为就业好转会导致美联储在加息上更加激进。但是我认为一旦市场开始正常定价就业指标的变化，那么通胀很可能会受到健康的就业状况影响而迎来拐点。</p><p>重要事件：</p><p>8 月 25 日：杰克逊霍尔年会 9 月 2 日：8 月非农就业数据 9 月 13 日：8 月 CPI 9 月 15 日至 16 日：ETH 合并 9 月 22 日：美联储议息会议 在美联储下一次议息会议到来前，我们还有一个大约 4-5 周的时间窗口，在这期间行情很可能走出先跌后反弹的表现，并以此来提前消化以太坊合并和美联储利率决议等重大风险事件的影响。如果下个月非农和 CPI 数据仍然表现良好，那么回调预计不会很强。不过由于今年整个金融市场非常情绪化，因此在这种不确定性仍然很高的阶段，一定需要保证自身的流动性。未来一段时间里行情预计将给出一些更明确的指向性信号，这种时候我们需要做的就是相信自己的判断并坚定执行。</p><p>图表、叙事和其他有趣的东西</p><p>以太坊 ETH 自一个月前 CPI 出现下滑以来一直占据整个加密市场的领跑位置，以太坊不仅跑赢了比特币，近期表现也明显优于各大公链以及其他市值靠前的大盘币种。近期只有与合并相关的一些代币能够跟上以太坊的节奏，比如 OP、Lido 以及 GMX 等等。</p><p>我认为二层相关的代币在合并周期中更具关注价值，因为 Rollup 需要更高的活跃度来帮助以太坊获得更高的市场定价，而 OP 已经很好地印证了这一判断，Arbitrum 未来预计也会走上相同的道路。</p><p>此外，当下以太坊是加密货币市场大玩家们在合并中可以用于下注的唯一流动性资产，因此当前阶段以太坊拥有比比特币好得多的叙事。另外一点在于，加密市场的独立性正在上升，最近这波反弹行情走出后，目前市场出现了非常明显的分化，一众山寨币截止今天甚至都还没有收复 Luna 暴雷后第一波反弹的高点，相比之下比特币和以太坊的状况要好上不少。这种比特币和以太坊引领下跌但最后「只有」山寨币遭受毁灭性打击的剧情，之前并不多见。</p><p>盘面上来看，我认为低于 1800 美元的以太坊都是值得买入的，当然如果价格再度出现快速跳水并且击穿 1650 一线的话，我们在抄底时机的选择上需要更慎重，一旦如此行情可能会再度下探 1000 美元整数关口。不过只要 1650 一线支撑不破，那么在 9 月中旬合并落地的时候，以太坊收复 2000 美元几乎是板上钉钉的事情。</p><p>DOGE &amp; SHIBA INU 上周六我收到了 SHIB 突破阻力位置的行情异动提醒，DOGE/BTC 开始走平意味着我们即将迎来市场的新一轮选择，要么熊市反弹中山寨币的最后一波轮动，要么新一轮爆发式行情会很快到来。结合市场近况我认为后者发生的可能性会更高。</p><p>如果你回顾一下加密货币市场并不算久的历史你会发现，DOGE/BTC 是一个可以用于判断散户入场的神奇指标。在过去一周左右的时间里，因为包括 AMC 在内的几个散户抱团的股票讨论热度的上升，WallStreetBets 这个曾经在 2021 年初的那一轮行情中一夜蹿红的 Reddit 社区又活跃了起来，如果你经历过 2021 年初的市场，相信对于 GameStop 和狗狗币 的故事一定不会陌生。目前狗狗币生态中还有了一个狗狗链，让狗狗币可讲的故事又多了一层。Shiba 和狗狗在加密技术创新、DeFi 或者元宇宙游戏等方面几乎没有任何底层支撑，驱动其上涨的几乎完全是 Meme、社区 FOMO 情绪以及加密原生资本属性等因素。不过狗狗币在每一轮加密市场的行情出现之前总能够提前抢跑。不过历史也并不一定会完美重演，这波上涨也有可能仅仅是牛市反弹过程中的山寨轮动而已。</p><p>技术图形上来看也非常简单，行情在迫近去年夏天的低点后实现了止跌反弹，并且已经突破了最近几个月震荡所处的箱体上沿，不过如若行情在短时间内再度跌回至这个箱体内部将是一个糟糕的信号，因此短期内对于这个刚刚被突破，由阻力转为支撑的位置回踩确认时的表现至关重要。</p><p>而谷歌趋势的变化和币价高度相关，每次价格除顶都伴随着谷歌搜索趋势的峰值，从这一点来看，目前狗狗币还没有来到要逆转涨势的位置，市场对其关注度还相对很低。</p><p>Solana Solana 是 2021 年我最喜欢的加密货币，作为之前公链竞赛中除 BNB 以外的另一个胜出者，一度引领了上一个市场周期，随着以太坊过渡到模块化网络架构并将大部分执行转移到 Rollup 上，Solana 将成为在一层上直接处理所有事务的代表性公链。Solana 在发展的过程中经历了很多坎坷，其非常低的网络使用成本对于普通用户仍然非常具有吸引力，Solana 生态 NFT 的蓬勃发展也印证了这一点。不过也正因如此，网络经常会被机器人滥用而导致了不止一次的宕机崩溃。为了让 Solana 能够更进一步，他们必须要让 DeFi 应用发展起来，目前 Solana 上的 Drift 以及 Friktion 已经取得了一些成绩。除此以外 Solana 上目前还没有任何高 TPS 的游戏类应用，该网络能否像雪崩的子网一样能处理高频的小额交易非常重要。</p><p>Solana 最近一次网络升级中实施的 Quic/Qos/ 本地化费用市场将有助于防止网络流量高峰期的拥堵状况，为用户提供更好的用户体验。我很愿意把这个升级称作 Solana 2.0，官方给出的补丁版本号是 1.10.32。Quic 是验证器使用的协议，该协议将允许块生产商对限制机器人进行评级，并处理 UDP 无法实现的拥塞。本地化费用市场将像以太坊上的收费市场一样运作，但费用不是在整个网络上受到全球影响，而是特定于正在被限制的部分，因此该规范之所以成为可能，因为 Solana 的运行时允许并行交易处理。例如，在 ETH 上，每当流行的 NFT 铸造进行时，就会把整个网络的 Gas 费推升，而 Solana 上的费用只会对与该特定铸造互动的用户激增，允许网络的其余部分继续运行，没有停顿。质押加权的服务质量确保节点有权获得相当于您质押的交付给领导者的数据包的百分比，这不允许持有高百分比或根本没有质押的机器人超过其他人。这些更改现在在主网上广播逻辑，因此我们将在未来几个月内看到这些更改是否对网络的性能产生重大影响。</p><p>技术分析方面，一旦 48.5 美元一线被有效突破，将快速打开上方空间，短期内回踩 40-42 支撑区域不破将是最理想的买入机会，不过如若上周低点 39.15 一线被跌破，那么需要注意防范新一轮快速下跌的风险。</p><p>Chilliz</p><p>Chilliz 一直是实现现实世界消费者市场最成功的加密团队之一。他们是一家专门针对体育和娱乐公司的金融科技提供商，他们的一些著名的合作项目包括巴塞罗那足球俱乐部、尤文图斯、UFC、13 支 NFL 球队等。许多体育俱乐部现在通过他们的 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://Socios.com">Socios.com</a> 应用程序拥有自己的 CHZ 相关代币，该应用程序允许球迷与他们最喜欢的球队互动。该应用程序尚未在美国上线，但计划很快推出。最近，他们宣布与巴塞罗那足球俱乐部合作，详细说明了他们 1 亿美元的投资，以帮助支持他们的 NFT 和元宇宙计划，自 8 月初以来，CHZ 的表现一直非常强势，跑赢了大多数 ERC20 代币。</p><p>目前，CHZ 作为 ERC-20 令牌存在，粉丝们用于在 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://Socios.com">Socios.com</a> 上购买在其侧链 Socios 上运营的关联团队的粉丝代币。今年晚些时候，他们将推出自己的公链 Chilliz 2.0，这将是一个一站式平台，供团队通过各种分散式应用程序与粉丝互动。如果他们能够在美国市场有效地复制他们的成功，他们就几乎可以实现对于大多数 NFT x 粉丝 x 体育市场的垄断了。</p><p>CHZ 近期走出了一波强势反弹，目前已经突破了过去近一年左右下跌的趋势线阻力，上方强阻力需要看到 0.30 美元左右，只要价格守稳 0.15-0.17 支撑区域不破，那么上涨势头暂时无虞。</p><p>XMON Sudoswap，被 Sisyphus 恰当地称为 NFT 市场的 Uniswap ，是一种试图使您的 jpegs 更具流动性的 AMM。在过去的一年里，NFT 可以说是加密市场新人上手的最佳选择，但除非你眼光毒辣，否则很难在 NFT 市场中一直取得成功。</p><p>Sudoswap 允许用户更有效地交易 NFT，用户能够创造性地构建不同的池，并在上面有自己的专用曲线。sudoSwap 不是每次交易时都会收取费用的中心化市场，而是完全去中心化且不收取任何费用的平台，为用户提供了更简单的买卖方式。这样做的主要障碍将是流动性是否转移，过去一个月左右该平台的数据增长趋势看起来不错。鉴于它只上线了大约 30 天后销量就已经达到了 OpenSea 约十分之一的水平，一旦市场热度回归，尤其是更多游戏道具类型的 NFT 被用户放入该平台流通的话，sudoswap 未来的成长空间仍然相当可观。</p><p>一些思考</p><p>我认为市场最糟糕的时候已经过去了，以太坊合并前我们不太会看到新的低点了，不过我们还是需要进行风险对冲，比特币在短期内缺乏新的叙事以及市场表现仍然欠佳的近况无疑是当下最适合的可用于对冲做空的资产。虽然比特币有一群忠实的信徒，但是这些人购买比特币往往只关注特别长的周期，并不会在意短期内的波动。目前宏观金融市场的状况仍然不够好，不过一旦经济衰退的焦虑情绪开始减弱，市场上的流动性会很快回归。而一旦市场出现向好迹象，那么跟进的最佳选择实际上是狗狗币、链上期权 以及一些 MEME 山寨币。当然，我也很喜欢 Chilliz，因为他提供了人们和自己喜欢的球队建立联系的最佳机会，我会非常愿意为自己喜欢的球队推出的链上资产买单。无论经济状况如何，人们总是喜欢竞技体育。我之前也关注了 StepN，但是并没有做太多研究，也没有搞清楚他的模型是否可持续。所以到目前为止我还没用过这个 App。我认为元宇宙赛道仍然充斥着 alpha，因为这个赛道仍然没有被深入挖掘，但是我并不打算在这里做过多展开，读者们可以多关注一下这个赛道的新项目。</p><p>在过去的两个月里，Lido Finance、OP、GMX、FOLD 等与合并相关的币种表现很好，不过接下来这些币会迎来考验，以太坊合并一旦顺利完成进而导致大规模减产，有可能会导致这类资产集体回调。接下来 9 月 Arbitrum Odyssey 的重启值得重视，而像最近这轮牛市中表现很好的 LINK 和 SNX 等看似已经度过了熊市最艰难的阶段逐渐开始复苏。不过当下现货买入以太坊可能是风险最低的选择，如果你想要更保险的选择，那么就请多去在二层上进行交互，并等待新项目未来公布发币计划。</p><p>即将到来的杰克逊霍尔年会预计将会让市场对于未来美国经济数据的解读思路更加清晰，也会给出一些美联储货币政策调整的前瞻性信号，这都是接下来必须要关注的重点。</p><p>重点关注的主流资产：ETH、SOL 重点关注的 MEME：SHIB、DOGE 具有较高上限的资产：CHZ 中等上限的可关注资产：XMON 用于风险对冲的选择：BTC、APE 观察列表：SNX、LINK、LDO、FOLD、GMX、SYN、SCRT、UNI、AAVE、IMX、OSMO、DPX、MATIC、BTRFLY</p><p>展望未来</p><p>当前市场关注的重点是将在第四季度到来的以太坊合并，不过我们还是应该进一步拓宽思维。考虑到宏观金融市场仍然具有很大的不确定性，因此我并不认为现在能够预判到美股接下来会如何发展。我们没必要去猜测 CPI 的具体数值，不过我们可以通过一些细节去分析美联储可能做出的反应和决策。如果我们真的能够重新迎来牛市或者至少迎来一轮更大规模的熊市反弹，那么我们需要应对的板块轮动将和 2021 年的市场状况完全不同，一旦趋势发生改变，我们需要尽快找到真正具有长期潜力的新的热点赛道。</p><p>未来市场值得关注的叙事：</p><p>Sol 2.0 与本地化帐户费用市场 Optimistic Rollups v2: Arbitrum Nitro 和 Optimism Bedrock privDeFi: Aztec Connect, Secret Network, Penumbra, Mina + zkApps sudoSwap &amp; 图狗 跨链 安全 应用链间的账户互操作性 链上期权的兴起 zkEVMs: Scroll vs. zkSync vs. Starknet vs. Polygon Hermez 新公链: Aptos &amp; Sui xApps &amp; 跨链通讯: CCIP vs. Stargate vs. Synapse Chain vs. Connext vs. Wormhole vs. IBC Celestia &amp; Sovereign Rollups dyMension and RollApps vs. Rollups 模块化执行 rollups / FuelVM 链游: Aurory, Illuvium, Treeverse, Strange Clans EIP 4844 总的来说，我认为我们处在一个不错的窗口，未来一个月左右市场预计还会保持在一个比较好的状况之中，一旦宏观金融市场的大环境进一步改善，我们就必须要及时抓住上述这些新的叙事。</p><p>本文链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.defidaonews.com/article/6772186">https://www.defidaonews.com/article/6772186</a></p>]]></content:encoded>
            <author>code1024@newsletter.paragraph.com (Code1024)</author>
        </item>
        <item>
            <title><![CDATA[WCF技术剖析之一：通过一个ASP.NET程序模拟WCF基础架构]]></title>
            <link>https://paragraph.com/@code1024/wcf-asp-net-wcf</link>
            <guid>A7js4sS0lo57ZO5XCoU2</guid>
            <pubDate>Thu, 14 Jul 2022 16:06:28 GMT</pubDate>
            <description><![CDATA[https://www.cnblogs.com/artech/archive/2009/06/18/1506163.html 本系列的第一篇，我将会对WCF的基本架构作一个大致的讲解。不过，一改传统对WCF的工作流程进行平铺直叙，我将另辟蹊径，借助于我们熟悉的ASP.NET作为请求处理平台，通过一个简单的托管程序模拟整个WCF客户端和服务端的架构。 Source Code下载：Artech.WcfFrameworkSimulator.zip WCF框架处理流程和涉及的组件 我们的模拟程序将你搭建一个迷你版的WCF框架，为了展示WCF整个处理流程中使用到一些特殊组件。我们首先来简单介绍一下对于一个简单的WCF服务调用，WCF的客户端和服务端框架的处理流程，和该流程的每一个阶段都使用那些重要组件。 下面的列表列出了WCF服务端框架对于处理一个简单的WCF服务调用请求所提供的功能，以及相应的功能承载的组件：**请求消息的接收和回复消息的发送：**服务端在传输层监听与接收来自客户的请求，并将经过编码后的回复消息通过传输层发送到客户端**请求消息的解码和回复消息的编码：**将接收到的字节数...]]></description>
            <content:encoded><![CDATA[<p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.cnblogs.com/artech/archive/2009/06/18/1506163.html">https://www.cnblogs.com/artech/archive/2009/06/18/1506163.html</a></p><p>本系列的第一篇，我将会对WCF的基本架构作一个大致的讲解。不过，一改传统对WCF的工作流程进行平铺直叙，我将另辟蹊径，借助于我们熟悉的ASP.NET作为请求处理平台，通过一个简单的托管程序模拟整个WCF客户端和服务端的架构。</p><p>Source Code下载：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://files.cnblogs.com/artech/Artech.WcfFrameworkSimulator.zip">Artech.WcfFrameworkSimulator.zip</a></p><p><strong>WCF框架处理流程和涉及的组件</strong></p><p>我们的模拟程序将你搭建一个迷你版的WCF框架，为了展示WCF整个处理流程中使用到一些特殊组件。我们首先来简单介绍一下对于一个简单的WCF服务调用，WCF的客户端和服务端框架的处理流程，和该流程的每一个阶段都使用那些重要组件。</p><p>下面的列表列出了WCF服务端框架对于处理一个简单的WCF服务调用请求所提供的功能，以及相应的功能承载的组件：</p><ul><li><p>**请求消息的接收和回复消息的发送：**服务端在传输层监听与接收来自客户的请求，并将经过编码后的回复消息通过传输层发送到客户端</p></li><li><p>**请求消息的解码和回复消息的编码：**将接收到的字节数组通过解码生成请求消息对象，并将回复消息通过编程转化成字节组。消息的编码和解码通过MessageEncoder完成，而MessageEncoderFactory负责创建该对象</p></li><li><p>**请求消息的反序列化和回复消息的序列化：**对请求消息进行反序列化，为服务操作的执行生成相应的输入参数，以及将服务操作执行的结果（返回值或者ref/out参数）序列化，并生成回复消息。序列化和反序列化通过DispatchMessageFormatter完成</p></li><li><p>**服务对象的创建：**创建或者激活服务对象实例，InstanceProvider用于服务对象的创建或获取</p></li><li><p><strong>服务操作的执行</strong>：调用创建的服务对象的操作方法，并传入经过反序列化生成的输入参数。OperationInvoker完成对服务操作的最终执行</p></li></ul><p>较之服务端的流程，客户端的流程显得相对简单，仅仅包含以下三个必需的阶段：</p><ul><li><p>**请求消息的序列化和回复消息的反序列化：**生成请求消息并将输入参数序列化到请求消息中，以及对回复消息进行反序列化，转化成方法调用的返回值或者ref/out参数。序列化和反序列化通过ClienthMessageFormatter完成</p></li><li><p>**请求消息的编码和回复消息的解码：**对请求消息进行编码生成字节数组供传输层发送，以及将传输层接收到的字节数组解码生成恢复消息。消息的编码和解码通过MessageEncoder完成，而MessageEncoderFactory负责创建该对象</p></li><li><p><strong>请求消息的发送和回复消息的接收</strong>：在传输层将经过编码的请求消息发送到服务端，以及将接收来自服务端的恢复消息</p></li></ul><p><strong>图1 精简版WCF客户端与服务端组件</strong></p><p><strong>图1</strong>反映了进行服务调用的必要步骤和使用到的相关WCF组件。在本案例演示中，我们需要做的就是手工创建这些组件，并通过我们自己的代码利用它们搭建一个简易版的WCF框架。如果读者能够对本案例的实现有一个清晰的理解，相信对于整个WCF的框架就不会感到陌生了。</p><p><strong>图2</strong>显示了本案例解决方案的基本结构，总共分三个项目。Contracts用于定义服务契约，被服务端和客户端引用。客户端通过一个Console应用模拟，而服务端则通过一个ASP.NET Website实现。</p><p><strong>图2 WCF框架模拟案例应用结构</strong></p><p><strong>步骤一、通过服务契约类型创建相关组件</strong></p><p>WCF在整个服务调用生命周期的不同阶段，会使用到不同的组件。我们通过一个方法将服务端和客户端所需的所有组件都创建出来，为此，我们在Contracts项目中添加了一个Utility类型，在Create方法中创建所有的组件并通过输出参数的形式返回，泛型类型T表示的是服务契约类型。在该方法中，输出参数encoderFactory被服务端和客户端用于消息的编码和解码，clientFormatters和dispatchFormatters以字典的形式包含了基于服务操作的IClientMessageFormatter和IDispatchMessageFormatter，其中clientFormatters和dispatchFormatters的Key分别为操作名称和操作对应的Action。同样通过字典形式返回的operationInvokers和methods用于在服务端执行相应的操作方法，Key同样为操作对应的Action。    1: public static class Utility
   2: {
   3:     public static void Create&lt;T&gt;(out MessageEncoderFactory encoderFactory,
   4:         out IDictionary&lt;string, IClientMessageFormatter&gt; clientFormatters,
   5:         out IDictionary&lt;string, IDispatchMessageFormatter&gt; dispatchFormatters,
   6:         out IDictionary&lt;string, IOperationInvoker&gt; operationInvokers,
   7:         out IDictionary&lt;string, MethodInfo&gt; methods)
   8:     {
   9:         //省略实现
  10:     }
  11: }
具体的实现如下，由于在WCF框架中使用的MessageEncoderFactory（TextMessageEncoderFactory）、MessageFormatter（DataContractSerializerOperationFormatter）和OperationInvoker（SyncMethodInvoker）都是一些内部类型，所以只能通过反射的方式创建它们。而操作名称和Action也主要通过反射的原理解析应用在服务方法上的OperationContractAttribute得到。
   1: public static void Create&lt;T&gt;(out MessageEncoderFactory encoderFactory,
   2:     out IDictionary&lt;string, IClientMessageFormatter&gt; clientFormatters,
   3:     out IDictionary&lt;string, IDispatchMessageFormatter&gt; dispatchFormatters,
   4:     out IDictionary&lt;string, IOperationInvoker&gt; operationInvokers,
   5:     out IDictionary&lt;string, MethodInfo&gt; methods)
   6: {
   7:     //确保类型T是应用了ServiceContractAttribute的服务契约
   8:     object[] attributes = typeof(T).GetCustomAttributes(typeof(ServiceContractAttribute), false);
   9:     if (attributes.Length == 0)
  10:     {
  11:         throw new InvalidOperationException(string.Format(&quot;The type \&quot;{0}\&quot; is not a ServiceContract!&quot;, typeof(T).AssemblyQualifiedName));
  12:     } 
  13:  
  14:     //创建字典保存IClientMessageFormatter、IDispatchMessageFormatter、IOperationInvoker和MethodInfo
  15:     clientFormatters = new Dictionary&lt;string, IClientMessageFormatter&gt;();
  16:     dispatchFormatters = new Dictionary&lt;string, IDispatchMessageFormatter&gt;();
  17:     operationInvokers = new Dictionary&lt;string, IOperationInvoker&gt;();
  18:     methods = new Dictionary&lt;string, MethodInfo&gt;(); 
  19:  
  20:     //MessageEncoderFactory
  21:     string encoderFactoryType = &quot;System.ServiceModel.Channels.TextMessageEncoderFactory,System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot;;
  22:     encoderFactory = (MessageEncoderFactory)Activator.CreateInstance(Type.GetType(encoderFactoryType), MessageVersion.Default, Encoding.UTF8, int.MaxValue, int.MaxValue, new XmlDictionaryReaderQuotas()); 
  23:  
  24: //得到OperationDecription列表
  25: string defaultNamespace = &quot;http://tempuri.org/&quot;;
  26:     ServiceContractAttribute serviceAttribute = (ServiceContractAttribute)attributes[0];
  27:     string serviceNamepace = string.IsNullOrEmpty(serviceAttribute.Namespace) ? defaultNamespace : serviceAttribute.Namespace;
  28:     string serviceName = string.IsNullOrEmpty(serviceAttribute.Name) ? typeof(T).Name : serviceAttribute.Name;
  29:     var operations = ContractDescription.GetContract(typeof(T)).Operations; 
  30:  
  31:     //得到具体的IClientMessageFormatter、IDispatchMessageFormatter和IOperationInvoker的具体类型
  32:     //IClientMessageFormatter+IDispatchMessageFormatter：DataContractSerializerOperationFormatter
  33:     //IOperationInvoker：SyncMethodInvoker
  34:     string formatterTypeName = &quot;System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter,System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot;;
  35:     Type formatterType = Type.GetType(formatterTypeName);
  36:     ConstructorInfo formatterConstructor = formatterType.GetConstructor(new Type[] { typeof(OperationDescription), typeof(DataContractFormatAttribute), typeof(DataContractSerializerOperationBehavior) });
  37:     string operationInvokerTypeName = &quot;System.ServiceModel.Dispatcher.SyncMethodInvoker,System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot;;
  38:     Type operationInvokerType = Type.GetType(operationInvokerTypeName); 
  39:  
  40:     foreach (MethodInfo method in typeof(T).GetMethods())
  41:     {
  42:         attributes = method.GetCustomAttributes(typeof(OperationContractAttribute), true);
  43:         if (attributes.Length &gt; 0)
  44:         {
  45:             OperationContractAttribute operationAttribute = (OperationContractAttribute)attributes[0];
  46:             string operationName = string.IsNullOrEmpty(operationAttribute.Name) ? method.Name : operationAttribute.Name;
  47:             //通过OperationContractAttribute得到Action
  48:             string action;
  49:             if (string.IsNullOrEmpty(operationAttribute.Action))
  50:             {
  51:                 action = string.Format(&quot;{0}{1}/{2}&quot;, serviceNamepace, serviceName, operationName);
  52:             }
  53:             else
  54:             {
  55:                 action = operationAttribute.Action;
  56:             } 
  57:  
  58:             OperationDescription operation = operations.Where(op =&gt; op.Name == operationName).ToArray&lt;OperationDescription&gt;()[0];
  59:             //通过反射创建DataContractSerializerOperationFormatter对象
  60:             object formatter = formatterConstructor.Invoke(new object[] { operation, new DataContractFormatAttribute(), null });
  61:             clientFormatters.Add(operationName, formatter as IClientMessageFormatter);
  62:             dispatchFormatters.Add(action, formatter as IDispatchMessageFormatter); 
  63:  
  64:             //通过反射创建SyncMethodInvoker对象
  65:             IOperationInvoker operationInvoker = (IOperationInvoker)Activator.CreateInstance(operationInvokerType, method);
  66:             operationInvokers.Add(action, operationInvoker);
  67:             methods.Add(action, method);
  68:         }
  69: }
<strong>步骤二、创建服务契约和实现服务</strong> 接下来为本案例创建一个服务契约和实现该契约。服务契约定义在Contracts项目，具体的服务实现在模拟服务端的ASP.NET Web站点中。简单起见，依然沿用计算服务的例子。    1: [ServiceContract(Namespace = &quot;http://www.artech.com/&quot;)]
   2:     public interface ICalculator
   3:     {
   4:         [OperationContract]
   5:         double Add(double x, double y);
   6:     }
     1: public class CalculatorService : ICalculator
   2: {
   3:     public double Add(double x, double y)
   4:     {
   5:         return x + y;
   6:     }
   7: }
<strong>步骤三、实现服务端对服务调用请求的处理</strong> 我们通过一个ASP.NET的Web Page来模拟WCF服务端对服务请求的处理，下面的Calculator类型相关的代码实际上就是Calculator.aspx的后台代码（Code Behind）。整个处理流程不算复杂。在构造函数中，调用Utility的Create方法，将所需的组件进行初始化，而具体的服务调用请求处理的逻辑在直接写在Web Page的Load事件中。 首先，通过MessageCoderFactory创建MessageEncoder对接收到的以HttpRequest形式体现的服务调用请求进行解码，并生成请求消息。通过请求消息得到当前服务操作的Action属性后，在初始化过程中得到的基于服务契约所有MethodInfo列表中，根据该Action得到当前操作对应的MethodInfo对象。借助于MethodInfo对象得到操作方法的输入参数和输出参数数量后，创建两个对象数组，分别用于保存通过DispatchMessageFormatter对象对于请求消息进行反序列化得到的输入参数，和通过OperationInvoker执行操作方法得到的输出参数。在OperationInvoker执行操作方法之前，通过反射的方式直接创建服务对象，这一步在真正的WCF框架中是通过InstanceProvider实现的。 通过OperationInvoker执行操作方法的结果有两种形式：返回值和输出参数（包括引用参数）。它们通过被传入DispatchMessageFormatter被序列化并生成回复消息对象。回复消息通过MessageCoderFactory创建MessageEncoder进行编码后通过HttpResponse返回。    1:  
   2: ublic partial class Calculator : System.Web.UI.Page
   3:  
   4:    private static MessageVersion messageversion = MessageVersion.Default;
   5:    private static MessageEncoderFactory encoderFactory;
   6:    private static IDictionary&lt;string, IDispatchMessageFormatter&gt; dispatchFormatters;
   7:    private static IDictionary&lt;string, IOperationInvoker&gt; operationInvokers;
   8:    private static IDictionary&lt;string, MethodInfo&gt; methods;
   9:  
  10:    protected Calculator()
  11:    {
  12:        IDictionary&lt;string, IClientMessageFormatter&gt; clientFormatters;
  13:        Utility.Create&lt;ICalculator&gt;(out encoderFactory, out clientFormatters, out dispatchFormatters, out operationInvokers, out methods);
  14:    }
  15:  
  16:    protected void Page_Load(object sender, EventArgs e)
  17:    {
  18:        //对HttpPRequest进行解码生成请求消息对象
  19:        Message request = encoderFactory.Encoder.ReadMessage(this.Request.InputStream, int.MaxValue, &quot;application/soap+xml; charset=utf-8&quot;);
  20:  
  21:        //通过请求消息得到代表服务操作的Action
  22:        string action = request.Headers.Action;
  23:  
  24:        //通过Action从MethodInfo字典中获取服务操作对应的MethodInfo对象
  25:        MethodInfo method = methods[action];
  26:  
  27:        //得到输出参数的数量
  28:        int outArgsCount = 0;
  29:        foreach (var parameter in method.GetParameters())
  30:        {
  31:            if (parameter.IsOut)
  32:            {
  33:                outArgsCount++;
  34:            }
  35:        }
  36:  
  37:        //创建数组容器，用于保存请求消息反序列后生成的输入参数对象
  38:        int inputArgsCount = method.GetParameters().Length - outArgsCount;
  39:        object[] parameters = new object[inputArgsCount];
  40:        dispatchFormatters[action].DeserializeRequest(request, parameters);
  41:  
  42:        List&lt;object&gt; inputArgs = new List&lt;object&gt;();
  43:        object[] outArgs = new object[outArgsCount];
  44:        //创建服务对象，在WCF中服务对象通过InstanceProvider创建
  45:        object serviceInstance = Activator.CreateInstance(typeof(CalculatorService));
  46:        //执行服务操作
  47:        object result = operationInvokers[action].Invoke(serviceInstance, parameters, out outArgs);
  48:        //将操作执行的结果（返回值或者输出参数）序列化生成回复消息
  49:        Message reply = dispatchFormatters[action].SerializeReply(messageversion, outArgs, result);
  50:        this.Response.ClearContent();
  51:        this.Response.ContentEncoding = Encoding.UTF8;
  52:        this.Response.ContentType = &quot;application/soap+xml; charset=utf-8&quot;;
  53:        //对回复消息进行编码，并将编码后的消息通过HttpResponse返回
  54:        encoderFactory.Encoder.WriteMessage(reply, this.Response.OutputStream);
  55:        this.Response.Flush();
  56:    }
  57:  
<strong>步骤四、实现客户端对服务调用请求的处理</strong> 由于在客户端对服务请求的处理是通过一个RealProxy（ServiceChannelFactory）实现的,为了真实模拟WCF处理框架，在这里通过一个自定义RealProxy来实现客户端相关的服务调用请求的处理。下面代码中定义的ServiceRealProxy就是这样一个自定义RealProxy。 用于处理服务调用请求的相关组件对象，比如MessageEncoderFactory和IClientMessageFormatter字典，以及所需的属性，比如消息的版本和服务的目的地址，通过构造函数指定。而具体的请求处理实现在重写的Invoke方法之中。首先通过解析应用在当前方法的上面的OperationContractAttribute得到服务操作的名称，以此为Key从IClientMessageFormatter字典中得到当前服务操作对应的IClientMessageFormatter对象。当前操作方法调用的输入参数通过IClientMessageFormatter对象进行序列化后生成请求消息。为请求消息添加必要的寻址报头后，通过MessageEncoderFactory创建的MessageEncoder对请求消息进行编码。经过编码的消息以HttpRequest的形式发送到服务端，从而完成了服务调用请求的发送。 服务调用的结果通过HttpResponse的形式返回后，先通过MessageEncoder对其解码，并生成回复消息。回复消息通过IClientMessageFormatter进行反序列化后，在消息中以XML InfoSet实行体现的结果被转化成具体的对象，这些对象被最终影射为方法调用的返回值和输出参数（包含引用参数）。    1: namespace Artech.WcfFrameworkSimulator.Client
   2: {
   3:     public class ServiceRealProxy&lt;IContract&gt; : RealProxy
   4:     {
   5:         private Uri _remoteAddress;
   6:         private IDictionary&lt;string, IClientMessageFormatter&gt; _messageFormatters;
   7:         private MessageVersion _messageVersion = MessageVersion.Default;
   8:         private MessageEncoderFactory _messageEncoderFactory;
   9:  
  10:         public ServiceRealProxy(MessageVersion messageVersion, Uri address, IDictionary&lt;string, IClientMessageFormatter&gt; messageFormaters, MessageEncoderFactory messageEncoderFactory)
  11:             : base(typeof(IContract))
  12:         {
  13:             object[] attribute = typeof(IContract).GetCustomAttributes(typeof(ServiceContractAttribute), false);
  14:             if (attribute.Length == 0)
  15:             {
  16:                 throw new InvalidOperationException(string.Format(&quot;The type \&quot;{0}\&quot; is not a ServiceContract!&quot;, typeof(IContract).AssemblyQualifiedName));
  17:             }
  18:             this._messageVersion = messageVersion;
  19:             this._remoteAddress = address;
  20:             this._messageFormatters = messageFormaters;
  21:             this._messageEncoderFactory = messageEncoderFactory;
  22:         }
  23:  
  24:         public override IMessage Invoke(IMessage msg)
  25:         {
  26:             IMethodCallMessage methodCall = (IMethodCallMessage)msg;
  27:  
  28:             //Get Operation name.
  29:             object[] attributes = methodCall.MethodBase.GetCustomAttributes(typeof(OperationContractAttribute), true);
  30:             if (attributes.Length == 0)
  31:             {
  32:                 throw new InvalidOperationException(string.Format(&quot;The method \&quot;{0}\&quot; is not a valid OperationContract.&quot;, methodCall.MethodName));
  33:             }
  34:             OperationContractAttribute attribute = (OperationContractAttribute)attributes[0];
  35:             string operationName = string.IsNullOrEmpty(attribute.Name) ? methodCall.MethodName : attribute.Name;
  36:  
  37:             //序列化请求消息
  38:             Message requestMessage = this._messageFormatters[operationName].SerializeRequest(this._messageVersion, methodCall.InArgs);
  39:  
  40:             //添加必要的WS-Address报头
  41:             EndpointAddress address = new EndpointAddress(this._remoteAddress);
  42:             requestMessage.Headers.MessageId = new UniqueId(Guid.NewGuid());
  43:             requestMessage.Headers.ReplyTo = new EndpointAddress(&quot;http://www.w3.org/2005/08/addressing/anonymous&quot;);
  44:             address.ApplyTo(requestMessage);
  45:  
  46:             //对请求消息进行编码，并将编码生成的字节发送通过HttpWebRequest向服务端发送
  47:             HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(this._remoteAddress);
  48:             webRequest.Method = &quot;Post&quot;;
  49:             webRequest.KeepAlive = true;
  50:             webRequest.ContentType = &quot;application/soap+xml; charset=utf-8&quot;;
  51:             ArraySegment&lt;byte&gt; bytes = this._messageEncoderFactory.Encoder.WriteMessage(requestMessage, int.MaxValue, BufferManager.CreateBufferManager(long.MaxValue, int.MaxValue));
  52:             webRequest.ContentLength = bytes.Array.Length;
  53:             webRequest.GetRequestStream().Write(bytes.Array, 0, bytes.Array.Length);
  54:             webRequest.GetRequestStream().Close();
  55:             WebResponse webResponse = webRequest.GetResponse();
  56:  
  57:             //对HttpResponse进行解码生成回复消息.
  58:             Message responseMessage = this._messageEncoderFactory.Encoder.ReadMessage(webResponse.GetResponseStream(), int.MaxValue);
  59:  
  60:             //回复消息进行反列化生成相应的对象，并映射为方法调用的返回值或者ref/out参数
  61:             object[] allArgs = (object[])Array.CreateInstance(typeof(object), methodCall.ArgCount);
  62:             Array.Copy(methodCall.Args, allArgs, methodCall.ArgCount);
  63:             object[] refOutParameters = new object[GetRefOutParameterCount(methodCall.MethodBase)];
  64:             object returnValue = this._messageFormatters[operationName].DeserializeReply(responseMessage, refOutParameters);
  65:             MapRefOutParameter(methodCall.MethodBase, allArgs, refOutParameters);
  66:  
  67:             //通过ReturnMessage的形式将返回值和ref/out参数返回
  68:             return new ReturnMessage(returnValue, allArgs, allArgs.Length, methodCall.LogicalCallContext, methodCall);
  69:         }
  70:  
  71:         private int GetRefOutParameterCount(MethodBase method)
  72:         {
  73:             int count = 0;
  74:             foreach (ParameterInfo parameter in method.GetParameters())
  75:             {
  76:                 if (parameter.IsOut || parameter.ParameterType.IsByRef)
  77:                 {
  78:                     count++;
  79:                 }
  80:             }
  81:             return count;
  82:         }
  83:  
  84:         private void MapRefOutParameter(MethodBase method, object[] allArgs, object[] refOutArgs)
  85:         {
  86:             List&lt;int&gt; refOutParamPositionsList = new List&lt;int&gt;();
  87:             foreach (ParameterInfo parameter in method.GetParameters())
  88:             {
  89:                 if (parameter.IsOut || parameter.ParameterType.IsByRef)
  90:                 {
  91:                     refOutParamPositionsList.Add(parameter.Position);
  92:                 }
  93:             }
  94:             int[] refOutParamPositionArray = refOutParamPositionsList.ToArray();
  95:             for (int i = 0; i &lt; refOutArgs.Length; i++)
  96:             {
  97:                 allArgs[refOutParamPositionArray[i]] = refOutArgs[i];
  98:             }
  99:         }
 100:     }
 101: }
在真正的WCF客户端框架下，客户端通过ChannelFactory创建服务代理对象进行服务的调用，在这里我们也创建一个完成相似功能的工厂类型: SerivceProxyFactory，泛型类型T代表服务契约类型。 用于创建服务代理的Create方法很简单：先通过Utility.Create方法创建客户端进行服务调用必须的相关组件对象，通过这些对象连同该方法的参数（消息版本和服务目的地址）创建ServiceRealProxy对象，最终返回的是该RealProxy的TransparentProxy。    1: namespace Artech.WcfFrameworkSimulator.Client
   2: {
   3:     public static class SerivceProxyFactory&lt;T&gt;
   4:     {
   5:         public static T Create(MessageVersion messageVersion, Uri remoteAddress)
   6:         {
   7:             MessageEncoderFactory encoderFactory; 
   8:             IDictionary&lt;string, IClientMessageFormatter&gt; clientFormatters; 
   9:             IDictionary&lt;string, IDispatchMessageFormatter&gt; dispatchFormatters; 
  10:             IDictionary&lt;string, IOperationInvoker&gt; operationInvokers; 
  11:             IDictionary&lt;string, MethodInfo&gt; methods; 
  12:             Utility.Create&lt;T&gt;(out encoderFactory, out clientFormatters, out dispatchFormatters, out operationInvokers, out methods); 
  13:             ServiceRealProxy&lt;T&gt; realProxy = new ServiceRealProxy&lt;T&gt;(messageVersion, remoteAddress, clientFormatters, encoderFactory); 
  14:             return (T)realProxy.GetTransparentProxy();
  15:         }
  16:     }
  17: }
那么在最终的客户端代码中就可以借助SerivceProxyFactory创建服务代理进行服务调用了，而这里服务的目标地址实际上是上面用于模拟WCF服务端框架的.aspx Web Page的地址。    1: namespace Artech.WcfFrameworkSimulator.Client
   2: {
   3:     class Program
   4:     {
   5:         static void Main(string[] args)
   6:         {
   7:             ICalculator calculator = SerivceProxyFactory&lt;ICalculator&gt;.Create(MessageVersion.Default, new Uri(&quot;http://localhost/Artech.WcfFrameworkSimulator/Calculator.aspx&quot;)); 
   8:             double result = calculator.Add(1, 2); 
   9:             Console.WriteLine(&quot;x + y = {2} when x = {0} and y = {1}&quot;, 1, 2, result);
  10:         }
  11:     }
  12: }
执行结果：    1: x + y = 3 when x = 1 and y = 2</p>]]></content:encoded>
            <author>code1024@newsletter.paragraph.com (Code1024)</author>
        </item>
    </channel>
</rss>