<?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>moonly</title>
        <link>https://paragraph.com/@moonly</link>
        <description>undefined</description>
        <lastBuildDate>Thu, 11 Jun 2026 16:33:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Geth客户端使用笔记]]></title>
            <link>https://paragraph.com/@moonly/geth</link>
            <guid>ZOgqrM9Fn01a7JiTWtem</guid>
            <pubDate>Mon, 08 Aug 2022 03:29:36 GMT</pubDate>
            <description><![CDATA[前言最近在研究链上的交易数据，尝试做一些简单的分析，立个flag同步更新笔记来记录自己的学习过程。]]></description>
            <content:encoded><![CDATA[<h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">前言</h2><p>最近在研究链上的交易数据，尝试做一些简单的分析，立个flag同步更新笔记来记录自己的学习过程。</p>]]></content:encoded>
            <author>moonly@newsletter.paragraph.com (moonly)</author>
        </item>
        <item>
            <title><![CDATA[构建我的aptos move 开发环境]]></title>
            <link>https://paragraph.com/@moonly/aptos-move</link>
            <guid>BTqeauJvp20zcMxkIKdj</guid>
            <pubDate>Sun, 17 Jul 2022 17:22:43 GMT</pubDate>
            <description><![CDATA[0x0、简介MOVE是一个大家同样在过程中，以安全性的编写记录下来的语言，个人正在慢慢发现目前并没有形成学习结构的探索教程，所以打算将自己的探索，帮助踩到坑，这是第一个篇记录寻找aptos的MOVE IDE配置的笔记，如有错误欢迎大家指正。 联系我：Discord:k8ssssss#16730x1、浏览器开发环境如果你只是想简单的体验一下move的语法，那么推荐使用浏览器开发环境Move Playground 地址：https://playground.pontem.network/ 先来看下全景图的功能。通过一个简单的脚本来演示如何使用 首先收集所有数据，然后创建我们的新项目test_script然后我们点击项目目录，展开目录树，工程目录结构如下项目名称（项目名称）脚本（存放脚本目录）来源（加载模块）测试（存放测试文件）分别在scripts和sources目录下创建文件test_script.move和test_module.move创建完成后，点击文件就可以在打开的文件中打开编辑窗口，我们在下面的test_module.move代码中module 0x01::Math { p...]]></description>
            <content:encoded><![CDATA[<h2 id="h-0x0" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">0x0、简介</h2><p>MOVE是一个大家同样在过程中，以安全性的编写记录下来的语言，个人正在慢慢发现目前并没有形成学习结构的探索教程，所以打算将自己的探索，帮助踩到坑，这是第一个篇记录寻找aptos的MOVE IDE配置的笔记，如有错误欢迎大家指正。</p><p>联系我：Discord:k8ssssss#1673</p><h2 id="h-0x1" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">0x1、浏览器开发环境</h2><p>如果你只是想简单的体验一下move的语法，那么推荐使用浏览器开发环境<code>Move Playground</code></p><p>地址：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://playground.pontem.network/">https://playground.pontem.network/</a></p><p>先来看下全景图的功能。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/894b9307e935ebd267df5da13afea6eabb989857bbdc5ffcb42ce46bc23dc223.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/299a711eaf803d1ce99a7e5a3dc3790da1320889ca4eeb5c79acc97cee0c8d5f.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>通过一个简单的脚本来演示如何使用</p><p>首先收集所有数据，然后创建我们的新项目<code>test_script</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/51157e6d37de1a1121e7aeb0dddf5d4e33f32fcd663140e3bb066b6f69a92c59.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>然后我们点击项目目录，展开目录树，工程目录结构如下</p><ul><li><p>项目名称（项目名称）</p><ul><li><p>脚本（存放脚本目录）</p></li><li><p>来源（加载模块）</p></li><li><p>测试（存放测试文件）</p></li></ul></li></ul><p>分别在<code>scripts</code>和<code>sources</code>目录下创建文件<code>test_script.move</code>和<code>test_module.move</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/664d3c9f471712234517bf86b44f8f9107fa7fd1f0ff79ad128f4aeba51e8974.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>创建完成后，点击文件就可以在打开的文件中打开编辑窗口，我们在下面的<code>test_module.move</code>代码中</p><pre data-type="codeBlock" text="module 0x01::Math {
    public fun sum(a: u64, b: u64): u64 {
        a + b
    }
}
"><code>module <span class="hljs-number">0x01</span>::Math {
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">sum</span><span class="hljs-params">(a: <span class="hljs-type">u64</span>, b: <span class="hljs-type">u64</span>)</span></span>: u64 {
        a + b
    }
}
</code></pre><p>由于目前这个编辑器不支持中文注释，下面带注解版本方便新手理解。</p><pre data-type="codeBlock" text="module 0x01::Math {		//在0x01地址下定义一个名为Math的module
    public fun sum(a: u64, b: u64): u64 {		//定义一个公开的函数，名为sum 需要输入u64类型的a、b 返回一个u64类型的值
        a + b
    }
}
"><code>module <span class="hljs-number">0x01</span>::Math {		<span class="hljs-comment">//在0x01地址下定义一个名为Math的module</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">sum</span><span class="hljs-params">(a: <span class="hljs-type">u64</span>, b: <span class="hljs-type">u64</span>)</span></span>: u64 {		<span class="hljs-comment">//定义一个公开的函数，名为sum 需要输入u64类型的a、b 返回一个u64类型的值</span>
        a + b
    }
}
</code></pre><p>在<code>test_script.move</code>中写入以下代码</p><pre data-type="codeBlock" text="script {
    use 0x01::Math;
    use 0x1::Debug;

   fun test_script(a: u64, b: u64) {
     let c = Math::sum(a,b);
     Debug::print(&amp;c);
   }
}
"><code>script {
    <span class="hljs-keyword">use</span> <span class="hljs-number">0x01</span>::Math;
    <span class="hljs-keyword">use</span> <span class="hljs-number">0x1</span>::<span class="hljs-built_in">Debug</span>;

   fun <span class="hljs-title function_ invoke__">test_script</span>(a: <span class="hljs-type">u64</span>, b: <span class="hljs-type">u64</span>) {
     <span class="hljs-keyword">let</span> <span class="hljs-variable">c</span> = Math::<span class="hljs-title function_ invoke__">sum</span>(a,b);
     <span class="hljs-built_in">Debug</span>::<span class="hljs-title function_ invoke__">print</span>(&#x26;c);
   }
}
</code></pre><p>简单的注解</p><pre data-type="codeBlock" text="script {			//定义一个script
    use 0x01::Math;			//	引入Math module
    use 0x1::Debug;			//  引入内置module Debug

   fun test_script(a: u64, b: u64) {	//定义 一个函数要求输入a、b两u64类型的值
     let c = Math::sum(a,b);		//定义一个变量c 赋值为a、b之和
     Debug::print(&amp;c);			//输出变量c
   }
}
"><code>script {			<span class="hljs-comment">//定义一个script</span>
    <span class="hljs-keyword">use</span> <span class="hljs-number">0x01</span>::Math;			<span class="hljs-comment">//	引入Math module</span>
    <span class="hljs-keyword">use</span> <span class="hljs-number">0x1</span>::<span class="hljs-built_in">Debug</span>;			<span class="hljs-comment">//  引入内置module Debug</span>

   fun <span class="hljs-title function_ invoke__">test_script</span>(a: <span class="hljs-type">u64</span>, b: <span class="hljs-type">u64</span>) {	<span class="hljs-comment">//定义 一个函数要求输入a、b两u64类型的值</span>
     <span class="hljs-keyword">let</span> <span class="hljs-variable">c</span> = Math::<span class="hljs-title function_ invoke__">sum</span>(a,b);		<span class="hljs-comment">//定义一个变量c 赋值为a、b之和</span>
     <span class="hljs-built_in">Debug</span>::<span class="hljs-title function_ invoke__">print</span>(&#x26;c);			<span class="hljs-comment">//输出变量c</span>
   }
}
</code></pre><p>在Run Script功能栏执行<code>test_script(2,3)</code>，就可以获得结果等于5，同时可以看到消耗的gas数量。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/c9a06a86744d87d9336917fc7c3612072dd967e7c54bf274a451272082fc5213.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-0x2" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">0x2、本地开发环境构建</h2><h3 id="h-clion" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">基于Clion</h3><h4 id="h-1aptos-cli" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">1、安装aptos CLI</h4><p>前往发布页面下载最新的二进制文件，当前最新的发布版本是V0.2.0</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/aptos-labs/aptos-core/releases">https://github.com/aptos-labs/aptos-core/releases</a></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/31038d31b7583ae45a9706e9d760706d8e14f602ea68c75d4fa27c9e32e5c182.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>下载解压之后放到你想要的目录下面，由于Mac的安全策略问题需要手动有右键打开一次。然后需要把<code>apts</code>添加进环境变量</p><p>我这里终端配置的是zsh，所以我直接写入了家目录下的`.zshrz`文件，可以根据自己的环境来。</p><p><code>export PATH=&quot;/Users/moonly/aptos:$PATH&quot;</code></p><p>完成之后重新打开终端，执行`aptos`，显示如下信息就是完成安装了</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/caa559d8f0eff8450449ec04ceef9c3cbfedfabe35df1c5fc2e5529c45dfbcc3.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>CLI的具体操作说明可以看官方的文档：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/aptos-labs/aptos-core/blob/main/crates/aptos/README.md#install-the-aptos-cli">https://github.com/aptos-labs/aptos-core/blob/main/crates/aptos/README.md#install-the-aptos-cli</a></p><h4 id="h-2clion-cli" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">2、Clion 联动CLI</h4><p>安装 Move Language插件</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/637f93ba23ecd246c44682a137d1f56a6943509fcf601b7f56f77217438823a3.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>安装中文插件</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/d7d1ed6efbbe0d3498f200b2d561e42ad943d2ed12c24bb8fe16b6444958e13e.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>完成后重启CLion，新建项目时就可以选择MOVE了。新建一个项目</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6b2edac9dbc3247581a336fce0b3319dec5d93b595ea8b79a9e90a794e2874ff.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>然后我们需要对aptos进行初始化，点击左下角的<code>终端</code>打开命令行，输入<code>aptos init</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f5981d01529fe9add10da0b4c6eaa3b42a596fccfddb5f948db4ca630d15c08e.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>命令会交互式的让你提交REST地址、水龙头地址和钱包私钥，如果全部直接回车，则会默认使用公共开发网的地址。</p><p>最终会返回一个钱包地址，需要复制这个钱包地址。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/9f1f87f5e2ed89982dc6a9c973d456da8c2121e4baa19eb18f56bb6bd98e1525.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>将上面的钱包地址写入项目目录中的<code>Move.toml</code>文件中</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/25c49438b88cdfcbb2f9ab633aaf526404e24705233520935dcd21727f3b78d6.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>这样我们就完成了IDE的配置。</p><h4 id="h-3" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">3、编写测试</h4><p>在sources目录下右键新建MOVE文件</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/59c3cc41d1a19a2c8e0692a3bdfef32e271d7d10deb1ba87df97c9a72b804162.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>选择<code>Module</code>然后输入文件名<code>test_module</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/80fe3506568c8e3d4c758441fca05a26802fad3445628bcf7ce9d68ffb7af252.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>写入以下代码，一个简单的加法</p><pre data-type="codeBlock" text="module Sender::Math {
    public fun sum(a: u64, b: u64): u64 {
        a + b
    }
}
"><code>module Sender::Math {
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">sum</span><span class="hljs-params">(a: <span class="hljs-type">u64</span>, b: <span class="hljs-type">u64</span>)</span></span>: u64 {
        a + b
    }
}
</code></pre><p>然后创建<code>tests</code>目录</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/bd249e3b374458e021ec212a01a77041bc6b2377cd864c36233599c63599fcd2.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>然后在<code>tests</code>目录下创建文件<code>test_script.move</code>,类型选择Test</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/0e5ff6f0eda7850a938206f059861c5caaa8d1703123b41a2028f7308dd889e7.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>写入以下代码，引入刚刚我们的<code>Math</code>,然后计算a+b 并验证结果是否等于50</p><pre data-type="codeBlock" text="#[test_only]
module Sender::MathTest {
    use Sender::Math;

    #[test]
    fun test_add() {
        let a = 20;
        let b = 30;

        let r = Math::sum(a, b);
        assert!(r == 50, 1);
    }
}
"><code><span class="hljs-comment">#[test_only]</span>
module Sender::MathTest {
    use Sender::Math<span class="hljs-comment">;</span>

    <span class="hljs-comment">#[test]</span>
    fun test_add() {
        let <span class="hljs-attr">a</span> = <span class="hljs-number">20</span><span class="hljs-comment">;</span>
        let <span class="hljs-attr">b</span> = <span class="hljs-number">30</span><span class="hljs-comment">;</span>

        let <span class="hljs-attr">r</span> = Math::sum(a, b)<span class="hljs-comment">;</span>
        assert!(<span class="hljs-attr">r</span> == <span class="hljs-number">50</span>, <span class="hljs-number">1</span>)<span class="hljs-comment">;</span>
    }
}
</code></pre><p>切换回<code>test_module.move</code>文件，然后点击右上角Build后的三角形按钮进行本地编译</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/958d7e7cb8269a56b603ce89ce3502023a9671cebd05f7e528867e5641422bd5.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>下方会显示结果，如果有报错也会在下面显示，可以看到我们的Math以及发布在我们的钱包地址下了。然后我们之前在<code>Move.toml</code>文件中将地址设置为别名<code>Sender</code>,现在就可以在脚本中用<code>use Sender::Math;</code>来引入Math了。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/eb7d811a9c3ec3a11dab826b0ce97cf00f8a5374a6dbdb8bb6cb655622c6712a.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>切换到<code>test_script.move</code>文件，点击方法旁边的绿色三角形可以直接运行函数</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f7711ca7ec1a35ea1fcd8479f055ab1c8ef46eb4c0dd12163d742d0f9973e202.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>也可以通过右上角进行运行</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/70f042fe00f655f6b03f989b8d4fc8a52e793289ff641c93fdd7d344877d19cb.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>可以看到运行成功</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/bb42e1fe7aa8938bafe93ff47f8bd2898473eb77877206a0559367fc37080de7.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p><code>assert!</code>关键字是一个类似于solidity中的<code>require</code>，它接受2个参数，第一个参数是一个布尔表达式，如果结果为假就会报错第二个参数的错误码，并终止执行回退操作，如果我们把代码修改一下，再次执行就会报错了。</p><pre data-type="codeBlock" text="#[test_only]
module Sender::MathTest {
   use Sender::Math;
   #[test]
   fun test_add() {
       let a = 20;
       let b = 30;

       let r = Math::sum(a, b);
       assert!(r == 51, 1);
   }
}
"><code><span class="hljs-comment">#[test_only]</span>
module Sender::MathTest {
   use Sender::Math<span class="hljs-comment">;</span>
   <span class="hljs-comment">#[test]</span>
   fun test_add() {
       let <span class="hljs-attr">a</span> = <span class="hljs-number">20</span><span class="hljs-comment">;</span>
       let <span class="hljs-attr">b</span> = <span class="hljs-number">30</span><span class="hljs-comment">;</span>

       let <span class="hljs-attr">r</span> = Math::sum(a, b)<span class="hljs-comment">;</span>
       assert!(<span class="hljs-attr">r</span> == <span class="hljs-number">51</span>, <span class="hljs-number">1</span>)<span class="hljs-comment">;</span>
   }
}
</code></pre><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/0ecf8c9530d75033eebedb3044c66d43223d9746f9cc9b106e972befb79a51b1.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h3 id="h-0x3vs-code" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">0x3、基于VS Code</h3><h4 id="h-1" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">1、安装插件</h4><p>VS Code中有两个Move插件</p><p>一个是Move核心团队维护的<code>move-analyzer</code>，一个是由Pontem 团队维护的<code>Move Language</code></p><p>这里我选择了<code>move-analyzer</code>，插件依赖组件<code>move-analyzer</code>语言服务器,<code>move-analyzer</code>语言服务器是一个 Rust 程序,所以需要先安装Rust 的包管理器<code>cargo</code>.安装完成后执行<code>cargo -V</code>查看版本</p><pre data-type="codeBlock" text="curl https://sh.rustup.rs -sSf | sh
"><code>curl https:<span class="hljs-comment">//sh.rustup.rs -sSf | sh</span>
</code></pre><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/3b9389d75802a3ae15bcb58a5904e3f3028433e4c54c0a1ad674cbc9be0dbd43.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>开始安装<code>move-analyzer</code>,由于aptos与Move标准风格的地址格式不同，所以需要加上参数<code>--features &quot;address32&quot;</code>,安装完成后执行<code>move-analyzer --version</code>查看版本,然后执行<code>where is move-analyzer</code>找到二进制文件的路径，待会配置插件需要用到。</p><pre data-type="codeBlock" text="cargo install --git https://github.com/move-language/move move-analyzer --features &quot;address32&quot;
"><code>cargo install <span class="hljs-operator">-</span><span class="hljs-operator">-</span>git https:<span class="hljs-comment">//github.com/move-language/move move-analyzer --features "address32"</span>
</code></pre><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/d01e6bc4205971968368995713786442e5a6debe6e8ccceb37f3a51ac324bdaa.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>打开VS Code搜索安装插件，安装完成后点击小齿轮选择扩展设置。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/4f738995abffca32364811d1550a8bbafdd00a989983f9a111989f048d0f6009.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>写入刚刚获取的二进制文件路径，然后重启VS Code</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/66efa65374cde454d19040ee914922491936d30448c736149182a485029215bf.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h4 id="h-2aptos-cli" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">2、安装aptos CLI并初始化项目文件夹</h4><p>安装方法可以看上面Clion的章节。安装完成后用VS Code打开一个新的文件夹，此时它应该是空的。打开终端执行<code>aptos move init --name &lt;项目名称&gt;</code>就会生成项目结构，同时包含一个<code>Move.toml</code>文件。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/89db2b79e3f87e74cd0860b1caa149b040a4bbe02075c70057e7e3abe9690c6f.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>然后执行<code>aptos init </code>命令会交互式的让你提交REST地址、水龙头地址和钱包私钥，如果全部直接回车，则会默认使用公共开发网的地址。最终会返回一个钱包地址，需要复制这个钱包地址。写入<code>Move.toml</code>文件中格式为<code>&lt;钱包别名&gt; = “0x&lt;钱包地址&gt;” </code>,如果你想修改这个配置可以在项目目录下<code>.aptos/config.yaml</code>找到它</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/d1092946acc4b875a5fe64f551a2acea93c7968060cb6982816404c6297b3314.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>用一个官方的<code>HelloBlockchain</code>来演示一下如何进行编译和运行代码，源码github地址：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/move-examples/hello_blockchain">https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/move-examples/hello_blockchain</a></p><p>这个用例的核心功能就是为你的钱包中保存一条文本信息。</p><p>由于我们刚刚设置的地址别名是<code>Sender</code>，所以这里第一行被我修改为了<code>Sender</code>。</p><pre data-type="codeBlock" text="module Sender::Message {
    use Std::ASCII;
    use Std::Errors;
    use Std::Event;
    use Std::Signer;

    struct MessageHolder has key {
        message: ASCII::String,
        message_change_events: Event::EventHandle&lt;MessageChangeEvent&gt;,
    }

    struct MessageChangeEvent has drop, store {
        from_message: ASCII::String,
        to_message: ASCII::String,
    }

    /// There is no message present
    const ENO_MESSAGE: u64 = 0;

    public fun get_message(addr: address): ASCII::String acquires MessageHolder {
        assert!(exists&lt;MessageHolder&gt;(addr), Errors::not_published(ENO_MESSAGE));
        *&amp;borrow_global&lt;MessageHolder&gt;(addr).message
    }

    public(script) fun set_message(account: signer, message_bytes: vector&lt;u8&gt;)
    acquires MessageHolder {
        let message = ASCII::string(message_bytes);
        let account_addr = Signer::address_of(&amp;account);
        if (!exists&lt;MessageHolder&gt;(account_addr)) {
            move_to(&amp;account, MessageHolder {
                message,
                message_change_events: Event::new_event_handle&lt;MessageChangeEvent&gt;(&amp;account),
            })
        } else {
            let old_message_holder = borrow_global_mut&lt;MessageHolder&gt;(account_addr);
            let from_message = *&amp;old_message_holder.message;
            Event::emit_event(&amp;mut old_message_holder.message_change_events, MessageChangeEvent {
                from_message,
                to_message: copy message,
            });
            old_message_holder.message = message;
        }
    }

    #[test(account = @0x1)]
    public(script) fun sender_can_set_message(account: signer) acquires MessageHolder {
        let addr = Signer::address_of(&amp;account);
        set_message(account,  b&quot;Hello, Blockchain&quot;);

        assert!(
          get_message(addr) == ASCII::string(b&quot;Hello, Blockchain&quot;),
          ENO_MESSAGE
        
    }
}
"><code>module Sender::Message {
    use Std::ASCII;
    use Std::Errors;
    use Std::Event;
    use Std::Signer;

    <span class="hljs-keyword">struct</span> <span class="hljs-title">MessageHolder</span> <span class="hljs-title">has</span> <span class="hljs-title">key</span> {
        message: ASCII::String,
        message_change_events: Event::EventHandle<span class="hljs-operator">&#x3C;</span>MessageChangeEvent<span class="hljs-operator">></span>,
    }

    <span class="hljs-keyword">struct</span> <span class="hljs-title">MessageChangeEvent</span> <span class="hljs-title">has</span> <span class="hljs-title">drop</span>, <span class="hljs-title">store</span> {
        from_message: ASCII::String,
        to_message: ASCII::String,
    }

    <span class="hljs-comment">/// There is no message present</span>
    const ENO_MESSAGE: u64 <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;

    <span class="hljs-keyword">public</span> fun get_message(addr: <span class="hljs-keyword">address</span>): ASCII::String acquires MessageHolder {
        <span class="hljs-built_in">assert</span><span class="hljs-operator">!</span>(exists<span class="hljs-operator">&#x3C;</span>MessageHolder<span class="hljs-operator">></span>(addr), Errors::not_published(ENO_MESSAGE));
        <span class="hljs-operator">*</span><span class="hljs-operator">&#x26;</span>borrow_global<span class="hljs-operator">&#x3C;</span>MessageHolder<span class="hljs-operator">></span>(addr).message
    }

    <span class="hljs-keyword">public</span>(script) fun set_message(account: signer, message_bytes: vector<span class="hljs-operator">&#x3C;</span>u8<span class="hljs-operator">></span>)
    acquires MessageHolder {
        let message <span class="hljs-operator">=</span> ASCII::<span class="hljs-keyword">string</span>(message_bytes);
        let account_addr <span class="hljs-operator">=</span> Signer::address_of(<span class="hljs-operator">&#x26;</span>account);
        <span class="hljs-keyword">if</span> (<span class="hljs-operator">!</span>exists<span class="hljs-operator">&#x3C;</span>MessageHolder<span class="hljs-operator">></span>(account_addr)) {
            move_to(<span class="hljs-operator">&#x26;</span>account, MessageHolder {
                message,
                message_change_events: Event::new_event_handle<span class="hljs-operator">&#x3C;</span>MessageChangeEvent<span class="hljs-operator">></span>(<span class="hljs-operator">&#x26;</span>account),
            })
        } <span class="hljs-keyword">else</span> {
            let old_message_holder <span class="hljs-operator">=</span> borrow_global_mut<span class="hljs-operator">&#x3C;</span>MessageHolder<span class="hljs-operator">></span>(account_addr);
            let from_message <span class="hljs-operator">=</span> <span class="hljs-operator">*</span><span class="hljs-operator">&#x26;</span>old_message_holder.message;
            Event::emit_event(<span class="hljs-operator">&#x26;</span>mut old_message_holder.message_change_events, MessageChangeEvent {
                from_message,
                to_message: copy message,
            });
            old_message_holder.message <span class="hljs-operator">=</span> message;
        }
    }

    #[test(account <span class="hljs-operator">=</span> @<span class="hljs-number">0x1</span>)]
    <span class="hljs-keyword">public</span>(script) fun sender_can_set_message(account: signer) acquires MessageHolder {
        let addr <span class="hljs-operator">=</span> Signer::address_of(<span class="hljs-operator">&#x26;</span>account);
        set_message(account,  b<span class="hljs-string">"Hello, Blockchain"</span>);

        <span class="hljs-built_in">assert</span><span class="hljs-operator">!</span>(
          get_message(addr) <span class="hljs-operator">=</span><span class="hljs-operator">=</span> ASCII::<span class="hljs-keyword">string</span>(b<span class="hljs-string">"Hello, Blockchain"</span>),
          ENO_MESSAGE
        
    }
}
</code></pre><p>在本地编译移动包，参数<code>--package-dir</code>指定项目目录，如果在项目根目录执行可以省去</p><p><code>aptos move compile</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f46b2024fb3173658f778bc12a8abb46c7df8c791d6b3f575bd7e4e08deaf36c.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>在本地编译并进行执行单元测试，可选参数<code>--package-dir</code>指定项目目录，如果在项目根目录执行可以省去</p><p><code>aptos move test</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/0f40cadb52a621e4a1b516e562eedba511ad2b78a4347789356d2ab6ab316556.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>发布移动包</p><p><code>aptos move publish</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ca810c94c639e283d145f71f34408719a9279758de0c0e1dee6f5bf69a2c2a1e.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>发布完成后，可以去我们发布的多个链浏览器，就可以看到我们的钱包地址，就可以看到已经绑定到我们的钱包地址了</p><p>区块浏览器地址：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://explorer.devnet.aptos.dev/">https://explorer.devnet.aptos.dev/</a></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/813019034b2fdfbbc1ffb28cf49ededfc31edfe2b2fe23009e4f928b3c93c094.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>函数运行</p><pre data-type="codeBlock" text="aptos move run --function-id &lt;钱包地址&gt;::&lt;模块名&gt;::&lt;函数名&gt; --args &lt;参数类型&gt;:&lt;参数值&gt;
"><code><span class="xml">aptos move run --function-id <span class="hljs-tag">&#x3C;<span class="hljs-name">钱包地址</span>></span>::<span class="hljs-tag">&#x3C;<span class="hljs-name">模块名</span>></span>::<span class="hljs-tag">&#x3C;<span class="hljs-name">函数名</span>></span> --args <span class="hljs-tag">&#x3C;<span class="hljs-name">参数类型</span>></span>:<span class="hljs-tag">&#x3C;<span class="hljs-name">参数值</span>></span>
</span></code></pre><p>执行<code>set_message</code>参数<code>hello move!</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/02e125958f151bc06f78708c8315bca33c1deb3fd2513e7e705fb6414edde643.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>已经可以在结果中参数写入账户中查看了。在区块链器上查看。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/53fcfcd9456e7a462eaa7a85c329fc9cae7e65d5d7c924e6d4d52ec095db19c5.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h3 id="h-0x4" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">0x4、结束</h3><p>感谢中文小组成员在创作过程中的帮助。@Boyu_Chen#697、@lshoo#1959、@ruyisu#5492</p><p>参考链接：</p><p>aptos官方开发者文档：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://aptos.dev/guides/getting-started">https://aptos.dev/guides/getting-started</a></p><p>Aptos CLI官方文档：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/aptos-labs/aptos-core/tree/main/crates/aptos">https://github.com/aptos-labs/aptos-core/tree/main/crates/aptos</a></p><p>pontem官方文档：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.pontem.network/">https://docs.pontem.network/</a></p>]]></content:encoded>
            <author>moonly@newsletter.paragraph.com (moonly)</author>
        </item>
        <item>
            <title><![CDATA[以太坊学习笔记]]></title>
            <link>https://paragraph.com/@moonly/l4PQHe2dWdO6isOO6V4W</link>
            <guid>l4PQHe2dWdO6isOO6V4W</guid>
            <pubDate>Sat, 07 May 2022 12:06:59 GMT</pubDate>
            <description><![CDATA[以太坊账户在以太坊系统中，状态是由被称为“账户”（每个账户由一个20字节的地址）的对象和在两个账户之间转移价值和信息的状态转换构成的。以太坊的账户包含四个部分：随机数，用于确定每笔交易只能被处理一次的计数器账户目前的以太币余额账户的合约代码，如果有的话账户的存储（默认为空）以太坊有两种类型的账户：外部所有的账户（由私钥控制的）和合约账户（由合约代码控制）。消息和交易以太坊中“交易”是指存储从外部账户发出的消息的签名数据包。交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和两个被称为STARTGAS和GASPRICE的数值。 STARTGAS:是用来限制合约执行步骤的，每一步都需要消耗GAS，GAS消耗完交易未完成则强制失败，如果执行交易中止时还剩余瓦斯，那么这些瓦斯将退还给发送者。 GASPRICE是每一计算步骤需要支付矿工的费用以太坊状态转换函数https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/ethertransition.png以...]]></description>
            <content:encoded><![CDATA[<h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">以太坊账户</h2><p>在以太坊系统中，状态是由被称为“账户”（每个账户由一个20字节的地址）的对象和在两个账户之间转移价值和信息的状态转换构成的。以太坊的账户包含四个部分：</p><ul><li><p>随机数，用于确定每笔交易只能被处理一次的计数器</p></li><li><p>账户目前的以太币余额</p></li><li><p>账户的合约代码，如果有的话</p></li><li><p>账户的存储（默认为空）</p></li></ul><p>以太坊有两种类型的账户：外部所有的账户（由私钥控制的）和合约账户（由合约代码控制）。</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">消息和交易</h2><p>以太坊中“交易”是指存储从外部账户发出的消息的签名数据包。交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和两个被称为STARTGAS和GASPRICE的数值。</p><p>STARTGAS:是用来限制合约执行步骤的，每一步都需要消耗GAS，GAS消耗完交易未完成则强制失败，如果执行交易中止时还剩余瓦斯，那么这些瓦斯将退还给发送者。</p><p>GASPRICE是每一计算步骤需要支付矿工的费用</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><strong>以太坊状态转换函数</strong></h2><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/bab54b09132fe57459e2b350e5e622a094cb9e97ce5ff0c9e3cc9f46a2972e4a.png" alt="https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/ethertransition.png" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">https://raw.githubusercontent.com/ethereumbuilders/GitBook/master/en/vitalik-diagrams/ethertransition.png</figcaption></figure><p>以太坊的状态转换函数：<code>APPLY(S,TX) -&gt; S&apos;</code>，可以定义如下：</p><ol><li><p>检查交易的格式是否正确（即有正确数值）、签名是否有效和随机数是否与发送者账户的随机数匹配。如否，返回错误。</p></li><li><p>计算交易费用:<code>fee=STARTGAS * GASPRICE</code>，并从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。如果账户余额不足，返回错误。</p></li><li><p>设定初值<code>GAS = STARTGAS</code>，并根据交易中的字节数减去一定量的瓦斯值。</p></li><li><p>从发送者的账户转移价值到接收者账户。如果接收账户还不存在，创建此账户。如果接收账户是一个合约，运行合约的代码，直到代码运行结束或者瓦斯用完。</p></li><li><p>如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败，恢复原来的状态，但是还需要支付交易费用，交易费用加至矿工账户。</p></li><li><p>否则，将所有剩余的瓦斯归还给发送者，消耗掉的瓦斯作为交易费用发送给矿工。</p></li></ol><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><strong>代码执行</strong></h2><p>EVM代码由一系列字节构成，每一个字节代表一种操作。代码执行是无限循环，程序计数器每增加一（初始值为零）就执行一次操作，直到代码执行完毕或者遇到错误，<code>STOP</code>或者<code>RETURN</code>指令。</p><p>操作可以访问三种存储数据的空间：</p><ul><li><p><strong>堆栈</strong>，一种后进先出的数据存储，32字节的数值可以入栈，出栈。</p></li><li><p><strong>内存</strong>，可无限扩展的字节队列。</p></li><li><p><strong>合约的长期存储</strong>，一个秘钥/数值的存储，其中秘钥和数值都是32字节大小，与计算结束即重置的堆栈和内存不同，存储内容将长期保持。</p></li></ul><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">区块链三难困境</h2><ol><li><p>去中心化：创建一个不依赖中央控制点的区块链系统</p></li><li><p>可扩展性：区块链系统处理越来越多的交易的能力</p></li><li><p>安全：区块链系统按预期运行、保护自己免受攻击、错误和其他不可预见问题的能力</p></li></ol>]]></content:encoded>
            <author>moonly@newsletter.paragraph.com (moonly)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/e75c4cf3222623d4d650edede6546401244d44183beb8d6e75d498c5e3a09462.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>