<?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>1314521.eth</title>
        <link>https://paragraph.com/@1314521</link>
        <description>undefined</description>
        <lastBuildDate>Sat, 16 May 2026 16:05:39 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[撸毛的文章]]></title>
            <link>https://paragraph.com/@1314521/VkFODV00sIm5DUW0TZky</link>
            <guid>VkFODV00sIm5DUW0TZky</guid>
            <pubDate>Thu, 06 Apr 2023 13:25:42 GMT</pubDate>
            <description><![CDATA[撸毛的文章]]></description>
            <content:encoded><![CDATA[<p>撸毛的文章</p>]]></content:encoded>
            <author>1314521@newsletter.paragraph.com (1314521.eth)</author>
        </item>
        <item>
            <title><![CDATA[学习ERC-20]]></title>
            <link>https://paragraph.com/@1314521/erc-20</link>
            <guid>KTxEiMpGENiQJH0XUlfa</guid>
            <pubDate>Sat, 12 Mar 2022 08:31:07 GMT</pubDate>
            <description><![CDATA[ERC20 标准，是ETH上的一种合约标准。固定了事件和对应的接口contract ERC20Interface { function totalSupply() public constant returns (uint); function balanceOf(address tokenOwner) public constant returns (uint balance); function allowance(address tokenOwner, address spender) public constant returns (uint remaining); function transfer(address to, uint tokens) public returns (bool success); function approve(address spender, uint tokens) public returns (bool success); function transferFrom(address from, address to, uint t...]]></description>
            <content:encoded><![CDATA[<p>ERC20 标准，是ETH上的一种合约标准。固定了事件和对应的接口</p><pre data-type="codeBlock" text="contract ERC20Interface {
      function totalSupply() public constant returns (uint);  
      function balanceOf(address tokenOwner) public constant returns (uint balance);
       function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
       function transfer(address to, uint tokens) public returns (bool success); 
      function approve(address spender, uint tokens) public returns (bool success); 
      function transferFrom(address from, address to, uint tokens) public returns (bool success);

      event Transfer(address indexed from, address indexed to, uint tokens);  
      event Approval(address indexed tokenOwner, address indexed spender, uint tokens);

    string public constant name = &quot;TEST Token&quot;;
    string public constant symbol = &quot;TST&quot;;
    uint8 public constant decimals = 18;  // 18 is the most common number of decimal places
        uint256 public _totalSupply;
}
"><code><span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">ERC20Interface</span> </span>{
      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">totalSupply</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">constant</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>)</span>;  
      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">balanceOf</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> tokenOwner</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">constant</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span> balance</span>)</span>;
       <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">allowance</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> tokenOwner, <span class="hljs-keyword">address</span> spender</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">constant</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span> remaining</span>)</span>;
       <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transfer</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> to, <span class="hljs-keyword">uint</span> tokens</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span> success</span>)</span>; 
      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">approve</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> spender, <span class="hljs-keyword">uint</span> tokens</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span> success</span>)</span>; 
      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferFrom</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">from</span>, <span class="hljs-keyword">address</span> to, <span class="hljs-keyword">uint</span> tokens</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span> success</span>)</span>;

      <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">Transfer</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> <span class="hljs-keyword">from</span>, <span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> to, <span class="hljs-keyword">uint</span> tokens</span>)</span>;  
      <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">Approval</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> tokenOwner, <span class="hljs-keyword">address</span> <span class="hljs-keyword">indexed</span> spender, <span class="hljs-keyword">uint</span> tokens</span>)</span>;

    <span class="hljs-keyword">string</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> name <span class="hljs-operator">=</span> <span class="hljs-string">"TEST Token"</span>;
    <span class="hljs-keyword">string</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> symbol <span class="hljs-operator">=</span> <span class="hljs-string">"TST"</span>;
    <span class="hljs-keyword">uint8</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">constant</span> decimals <span class="hljs-operator">=</span> <span class="hljs-number">18</span>;  <span class="hljs-comment">// 18 is the most common number of decimal places</span>
        <span class="hljs-keyword">uint256</span> <span class="hljs-keyword">public</span> _totalSupply;
}
</code></pre><p>合约分为 函数和事件变量，三个部分，</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">变量</h2><p>变量在 contract 里面是全局的。定义了Token 的名称符号和精度。</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">函数</h2><h3 id="h-totalsupply" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">totalSupply</h3><p>可以看到函数部分，只是规定了接口名称。其中的实现逻辑就是开发者自行定义了。</p><p>比如这里的totalSupply 就是一个可以自定义的函数，这里的返回逻辑可以是一个定值。 或者是一个自动Burn的逻辑。</p><h3 id="h-balanceof" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">balanceOf</h3><p>这里的balanceOf，就要说到 ETH 的模型了。ETH 是账户模型，不是UTXO 的模型。所以这里的 balance 在合约里面是有状态的。地址和与余额之间有着对应的关系。</p><pre data-type="codeBlock" text="// 这里保存着这个账户下的该Token的余额
mapping (address =&gt; uint256) public balances
// 这里是一个重要的授权额度，也就是允许 外层addr 操作 内层 addr 的该Token 的数量。
// 所以一般的 授权额度就是这里。
mapping (address =&gt; mapping (address =&gt; uint256)) public allowed
"><code><span class="hljs-comment">// 这里保存着这个账户下的该Token的余额</span>
<span class="hljs-keyword">mapping</span> (<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">uint256</span>) <span class="hljs-keyword">public</span> balances
<span class="hljs-comment">// 这里是一个重要的授权额度，也就是允许 外层addr 操作 内层 addr 的该Token 的数量。</span>
<span class="hljs-comment">// 所以一般的 授权额度就是这里。</span>
<span class="hljs-keyword">mapping</span> (<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">mapping</span> (<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">uint256</span>)) <span class="hljs-keyword">public</span> allowed
</code></pre><p>那么balanceOf这个就很好实现了，传入地址，返回地址在这个map 中的数量即可</p><pre data-type="codeBlock" text="function balanceOf(address tokenOwner) public constant returns (uint balance) {
       return balances[tokenOwner];
}
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">balanceOf</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> tokenOwner</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">constant</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span> balance</span>) </span>{
       <span class="hljs-keyword">return</span> balances[tokenOwner];
}
</code></pre><h3 id="h-transfer" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">transfer</h3><p>前面提到的 Token 实际上只是一个 账户的mapping，我们可以理解这个合约存储了每个人的账户以及余额。你的 Token 实际上只是这张合约里面的数据而已，实际上并没有进行转出。所以在这里的逻辑其实和在支付宝中进行转账一样。直接对db中的数据进行操作。</p><pre data-type="codeBlock" text="function transfer(address to, uint tokens) public returns (bool success) {
    balances[msg.sender] = balances[msg.sender].sub(tokens);
    balances[to] = balances[to].add(tokens);
    emit Transfer(msg.sender, to, tokens);
    return true;
}
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transfer</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> to, <span class="hljs-keyword">uint</span> tokens</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span> success</span>) </span>{
    balances[<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>] <span class="hljs-operator">=</span> balances[<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>].sub(tokens);
    balances[to] <span class="hljs-operator">=</span> balances[to].add(tokens);
    <span class="hljs-keyword">emit</span> Transfer(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, to, tokens);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre><p>这里的msg.sender 是 保留字，实际上就是调用这个合约的账户（钱包 或者 另一个合约）</p><p>可以通过代码看到，在sender 的账户上 减去一定数量的token， 接受转账的账户上再增加一定的数量。就完成了最简单的转账操作。如果想实现，收5% 的转账手续费这种逻辑的话，就直接在前面加上一行转给合约方的逻辑就好。</p><p><strong>所以这里实现的是本人向另一个账户来进行转账</strong></p><p>另外这里emit了 Transfer ，在转账逻辑中没有实际的功能。在这里是一个事件。</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://segmentfault.com/a/1190000014882480">详解Solidity事件Event - 完全搞懂事件的使用</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://segmentfault.com/a/1190000014882480">Solidity 是以太坊智能合约编程语言，阅读本文前，你应该对以太坊、智能合约有所了解，如果你还不了解，建议你先看以太坊是什么，另外本文在监听合约事件是对上一篇Web3与智能合约交互实战进行补充，如果阅读了上一篇可以更好的理解本文。</a></p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://segmentfault.com/a/1190000014882480">segmentfault.com</a></p><p>如果我们不emit 这个事件的话，实际上我们的逻辑是已经完成了。但是，如果我们想，把完成转账的事件让大家知道，那么这里就需要去emit 这该事件。</p><pre data-type="codeBlock" text="
var infoContract = web3.eth.contract(ABI INFO);
var info = infoContract.at(&apos;CONTRACT ADDRESS&apos;);
// 这里的Transfer 是通过ABI 获取的
var transferEvent = info.Transfer();
// 这里进行事件的监听，如果触发了 Transfer 就执行
var transferEvent.watch(function(error, result){
    // handle result.args.from  result.args.to
});
"><code>
<span class="hljs-keyword">var</span> infoContract <span class="hljs-operator">=</span> web3.eth.contract(ABI INFO);
<span class="hljs-keyword">var</span> info <span class="hljs-operator">=</span> infoContract.at(<span class="hljs-string">'CONTRACT ADDRESS'</span>);
<span class="hljs-comment">// 这里的Transfer 是通过ABI 获取的</span>
<span class="hljs-keyword">var</span> transferEvent <span class="hljs-operator">=</span> info.Transfer();
<span class="hljs-comment">// 这里进行事件的监听，如果触发了 Transfer 就执行</span>
<span class="hljs-keyword">var</span> transferEvent.watch(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"><span class="hljs-keyword">error</span>, result</span>)</span>{
    <span class="hljs-comment">// handle result.args.from  result.args.to</span>
});
</code></pre><h3 id="h-transferfrom" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">transferFrom</h3><p>有了上面的Transfer 逻辑，这里的TransferFrom 也好理解了，其函数基本定义如下</p><pre data-type="codeBlock" text="function transferFrom(address from, address to, uint tokens) public returns (bool success){
        balances[from] = balances[from].sub(tokens);
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);
        balances[to] = balances[to].add(tokens);
        Transfer(from, to, tokens);
        return true;
 }
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">transferFrom</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> <span class="hljs-keyword">from</span>, <span class="hljs-keyword">address</span> to, <span class="hljs-keyword">uint</span> tokens</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span> success</span>)</span>{
        balances[<span class="hljs-keyword">from</span>] <span class="hljs-operator">=</span> balances[<span class="hljs-keyword">from</span>].sub(tokens);
        allowed[<span class="hljs-keyword">from</span>][<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>] <span class="hljs-operator">=</span> allowed[<span class="hljs-keyword">from</span>][<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>].sub(tokens);
        balances[to] <span class="hljs-operator">=</span> balances[to].add(tokens);
        Transfer(<span class="hljs-keyword">from</span>, to, tokens);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
 }
</code></pre><p>这里的逻辑比上面复杂一点，第一行是在from 的账户来减去转账的份额。这点很好理解。</p><p>第二行稍稍复杂慢慢讲，刚刚前面提到来授权额度。</p><p>allowed[from][msg.sender] 这里表示的是 From 账户对 sender（合约调用者）的授权额度，也就是说允许 sender 来对我这一部分钱来进行操作。</p><p>所以这里有两个sub，一个是从From 账户中减去这一部分转账额，另一部分是从授权额度中减去from对该sender 的授权额度。（如果失败那么触发回滚，后面再讲）</p><p><strong>所以简单来说这部分实现的是一个委托转账的功能</strong></p><p>后面的就是换汤不换药的， To 账户增加对应的Token，触发Transfer 事件。</p><h3 id="h-approve" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">approve</h3><p>刚刚已经讲了授权额度的事情，就是 A允许B对自己的一部分Token 来进行操作。那么这里的approve 就是来进行这一部分授权的。</p><pre data-type="codeBlock" text="function approve(address spender, uint tokens) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        Approval(msg.sender, spender, tokens);
        return true;
 }
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">approve</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> spender, <span class="hljs-keyword">uint</span> tokens</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span> success</span>) </span>{
        allowed[<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>][spender] <span class="hljs-operator">=</span> tokens;
        Approval(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, spender, tokens);
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
 }
</code></pre><p>可以看到，两个参数一个是 被授权的地址，还有一个是 授权的 Token 份额。前面的委托转账的部分，就是需要在这里进行份额的扣除。</p><p>同样的这里有 Approval 事件，用于通知Dapp，这里的动作完成。</p><h3 id="h-allowance" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">allowance</h3><p>用于检查当前的授权额度，直接进行return来进行返回。</p><pre data-type="codeBlock" text="function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
                reutrn allowed[_owner][_spender]
}
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">allowance</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _owner, <span class="hljs-keyword">address</span> _spender</span>) <span class="hljs-title"><span class="hljs-keyword">constant</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint256</span> remaining</span>) </span>{
                reutrn allowed[_owner][_spender]
}
</code></pre><h3 id="h-totalbalance" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">totalBalance</h3><p>这里返回总的调用量，经典的实现，就是直接返回 <code>_totalSupply</code></p><pre data-type="codeBlock" text="function totalSupply() public constant returns (uint) {
                return _totalSupply
}
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">totalSupply</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">constant</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>) </span>{
                <span class="hljs-keyword">return</span> _totalSupply
}
</code></pre><p>当然，这里拓展一下，除了协议的本身逻辑我们也可以进行自我拓展。</p><p>比如我这里就可以搞一个增发的逻辑，之前的total 的数量不够。</p><pre data-type="codeBlock" text="function mintToken(address target, uint256 mintedAmount) onlyOwner public {
        balances[target] += mintedAmount;
        _totalSupply += mintedAmount;
        emit Transfer(address(0), address(this), mintedAmount);
        emit Transfer(address(this), target, mintedAmount);
    }
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mintToken</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> target, <span class="hljs-keyword">uint256</span> mintedAmount</span>) <span class="hljs-title">onlyOwner</span> <span class="hljs-title"><span class="hljs-keyword">public</span></span> </span>{
        balances[target] <span class="hljs-operator">+</span><span class="hljs-operator">=</span> mintedAmount;
        _totalSupply <span class="hljs-operator">+</span><span class="hljs-operator">=</span> mintedAmount;
        <span class="hljs-keyword">emit</span> Transfer(<span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>), <span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>), mintedAmount);
        <span class="hljs-keyword">emit</span> Transfer(<span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>), target, mintedAmount);
    }
</code></pre>]]></content:encoded>
            <author>1314521@newsletter.paragraph.com (1314521.eth)</author>
        </item>
        <item>
            <title><![CDATA["hello world xyz~~~"]]></title>
            <link>https://paragraph.com/@1314521/hello-world-xyz</link>
            <guid>RtWcdfq14vByxjsvvcJU</guid>
            <pubDate>Fri, 03 Dec 2021 09:51:30 GMT</pubDate>
            <description><![CDATA[13年起，区块链投资第7个年头，经历第三个大牛市~~~~~]]></description>
            <content:encoded><![CDATA[<h3 id="h-137" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">13年起，区块链投资第7个年头，经历第三个大牛市~~~~~</h3>]]></content:encoded>
            <author>1314521@newsletter.paragraph.com (1314521.eth)</author>
        </item>
    </channel>
</rss>