以太坊钱包erc20_xvg币智能合约

以太坊钱包erc20_xvg币智能合约以太坊被称为区块链2.0,就是因为以太坊在应用层提供了虚拟机,使得开发者可以基于它自定义逻辑,通常被称为智能合约,合约中的公共接口可以作为区块链中的普通交易执行。本文就智能合约发代币流程作一完整介绍(

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

以太坊被称为区块链2.0,就是因为以太坊在应用层提供了虚拟机,使得开发者可以基于它自定义逻辑,通常被称为智能合约,合约中的公共接口可以作为区块链中的普通交易执行。本文就智能合约发代币流程作一完整介绍(当然智能合约不局限于发代币)。内容如下:

  1. Solidity
  2. ERC20
  3. 合约编写与发布
  4. 合约源码上传
  5. 其它

Solidity

Solidity是用于在以太坊编写智能合约的语言,目前最新版本0.5.11。这里对几个关键概念作一介绍。

library

library常用于提供可复用方法,可以随合约[作为合约的一部分]发布,不过最终它是单独部署[到链上]的,有自己的地址。外部可以使用delegatecall方法调用库函数。

我们使用library关键字来创建一个library,这和创建contract十分类似。但不像contract,在library中我们不能定义任何storage类型的变量。因为library只是意味着代码的重用而不是进行state的状态管理。

internal的库函数对所有合约可见。

using for:指令using A for B;用来附着库A里定义的函数到任意类型B,函数的第一个参数应是B的实例。可以使用using A for *,将库函数赋予任意类型。库函数可以重载的,你可以定义好几个同名函数,但是第一个参数的类型不同,调用的时候自动的根据调用类型选择某一种方法。

address indexed

The indexed parameters for logged events will allow you to search for these events using the indexed parameters as filters.

The indexed keyword is only relevant to logged events.

几个预定义字段

address.balance:地址余额,指该地址相关的以太币数额。

msg.sender:交易发起人。

this:合约地址。

msg.value:发起这笔交易支付的以太币数额,和payable搭配使用。

似乎还有msg.sig、msg.data、msg.gas。

payable

修饰函数,表示在调用函数时,可以给这个合约充以太币(合约也是一种账户,也有自己的地址)。合约本身持有以太币,可使得用户基于此合约进行跨币交易更方便。

constant、view、pure

constant修饰常量或函数,修饰函数时表示该函数不修改合约状态,即不产生需广播的交易,也就不会消耗gas,一般用于读状态或状态无关操作。0.4.17开始,改为view和pure修饰函数,前者表示读状态,后者表示状态无关。

存储区

storage:状态变量,将存储在链上;

memory:临时变量

interface:搭配传入的不同address,实现多态。

event,应用层(web3)可通过watch监听,应该是用轮询实现。

modifier,简单的aop,编译时会将代码替换合并。


ERC20

我们可以在智能合约里随意开发各种功能,相当一部分以代币合约的形式存在。既然是代币,自然有转账、余额查询等功能,大家苦于对不同的代币合约开发不同的钱包,于是有了一些规范的出现,其中最普遍的是ERC20。

ERC20定义了若干方法,网上有很多资料,这里不再赘述。稍微不好理解的是approve、transferFrom及allowance三个方法,这里举例说明——账户A有1000个ETH,想授权B账户随意调用A账户的100个ETH,则需调用approve(B,100)。当B账户想用这100个ETH中的10个ETH给C账户时,则调用transferFrom(A, C, 10)。这时调用allowance(A, B)可以查看B账户还能够调用A账户多少个token。

本人试用了若干本地钱包和在线钱包,都支持转账,但鲜有支持授权的。

有人在github上汇总了众多ERC20合约代码,see 基于以太坊发行的ERC20代币合约代码大集合


合约编写与发布

一个简单的合约demo如下:

以太坊钱包erc20_xvg币智能合约
以太坊钱包erc20_xvg币智能合约

 1 pragma solidity ^0.5.7;  2  3 import './safemath.sol';  4  5 contract ErbCoin {  6 using SafeMath for uint256;  7  8 string constant public name = "Mask Coin"; // token name  9 string constant public symbol = "MASK"; // token symbol  10 uint256 public decimals = 18; // token digit  11  12 //mapping (address => uint256) public balanceOf;  13 mapping (address => mapping (address => uint256)) public allowance; //a授权给b表示b可转账给其他人的代币数  14 mapping (address => uint256) public frozenBalances; //冻结余额  15 mapping (address => uint256) public balances; //可操作余额  16  17 uint256 public totalSupply = 0;  18 bool public stopped = false;  19  20 //uint256 constant valueFounder = 1000000;  21 address constant zeroaddr = address(0);  22 address owner = zeroaddr; //合约所有者  23 address founder = zeroaddr; //初始代币持有者  24  25  modifier isOwner {  26 assert(owner == msg.sender);  27  _;  28  }  29  30  modifier isFounder {  31 assert(founder == msg.sender);  32  _;  33  }  34  35  modifier isAdmin {  36 assert(owner == msg.sender || founder == msg.sender);  37  _;  38  }  39  40  modifier isRunning {  41 assert (!stopped);  42  _;  43  }  44  45  modifier validAddress {  46 assert(zeroaddr != msg.sender);  47  _;  48  }  49  50 constructor(address _addressFounder,uint256 _valueFounder) public {  51 owner = msg.sender;  52 founder = _addressFounder;  53 totalSupply = _valueFounder*10**decimals;  54 balances[founder] = totalSupply;  55  emit Transfer(zeroaddr, founder, totalSupply);  56  }  57  58 function balanceOf(address _owner) public view returns (uint256) {  59 //账户余额 = 可操作余额 + 被冻结余额  60 return balances[_owner] + frozenBalances[_owner];  61  }  62  63 function transfer(address _to, uint256 _value) public isRunning validAddress returns (bool success) {  64 balances[msg.sender] = balances[msg.sender].sub(_value);  65 balances[_to] = balances[_to].add(_value);  66  emit Transfer(msg.sender, _to, _value);  67 return true;  68  }  69  70 //msg.sender 将 _from 授权给他(msg.sender)的代币转给 _to  71 function transferFrom(address _from, address _to, uint256 _value) public isRunning validAddress returns (bool success) {  72 balances[_from] = balances[_from].sub(_value);  73 //balances[_to] = balances[_to].add(_value);  74 frozenBalances[_to] = frozenBalances[_to].add(_value); //代币为冻结状态  75 allowance[_from][msg.sender] = allowance[_from][msg.sender].sub(_value);  76  emit TransferFrozen(_to, _value);  77 return true;  78  }  79  80 //msg.sender 授权 _spender 可操作代币数  81 function approve(address _spender, uint256 _value) public isRunning isFounder returns (bool success) {  82 require(_value == 0 || allowance[msg.sender][_spender] == 0,"illegal operation");  83 allowance[msg.sender][_spender] = _value;  84  emit Approval(msg.sender, _spender, _value);  85 return true;  86  }  87  88 //冻结部分释放  89 function release(address _target, uint256 _value) public isRunning isAdmin returns(bool){  90 frozenBalances[_target] = frozenBalances[_target].sub(_value);  91 balances[_target] = balances[_target].add(_value);  92  emit Release(_target, _value);  93 return true;  94  }  95  96 function stop() public isAdmin {  97 stopped = true;  98  }  99 100 function start() public isAdmin { 101 stopped = false; 102  } 103 104 event Transfer(address indexed _from, address indexed _to, uint256 _value); 105 event Approval(address indexed _owner, address indexed _spender, uint256 _value); 106 event TransferFrozen(address _target, uint256 _value); 107 event Release(address _target, uint256 _value); 108 }

View Code

细心的朋友会发现,ERC20规范定义的都是函数,而这里的代码并没有name()、symbol()、decimals(),而只有同名字段,这是因为编译器会自动将公共字段编译为函数。

代码里还import了一个库文件,是为了避免数值溢出导致的bug,具体可看关于ERC20 Token智能合约的SafeMath安全

发布合约我们可以直接在浏览器端操作,需要用到:

MetaMask:一款以浏览器插件形式存在的以太坊钱包,能接入主链和多个测试链。

Remix:https://remix.ethereum.org,编写编译发布合约的一个站点,能和MetaMask无缝合作。

具体如何操作就不作介绍了,网上已有较多资料。

本人踩过一个坑,发币多次在imToken(一个较流行的钱包App)上显示的代币名称都是XXX_UNKOWN,后面多了_UNKOWN后缀;后有一次将contract名称和代币name、symbol保持一致,才显示正常,但不知是否是名称不一致导致的问题。

另合约部署成功后,可以在Remix上调用合约接口。如果你知道其它人的合约代码和合约地址,也可以在Remix上编译后,输入地址调用,如下图:

以太坊钱包erc20_xvg币智能合约

如果你知道合约的ABI,那么使用https://www.myetherwallet.com调用合约接口则更方便,如下图:

以太坊钱包erc20_xvg币智能合约

别人的合约代码和ABI从哪里来?请看下节。


合约源码上传

为什么要上传智能合约的代码呢?

  • 公开token的源码,增加透明度和投资人的信任度;
  • 上传源码后,人们可以在Etherscan查看当前token的源码,同时也可以很方便的看到token的相关信息;
  • 上述所说,如果不是标准接口,市面上的各类钱包不支持,那么可以通过Remix或myetherwallet直接调用接口,而不用另外开发定制化钱包。

代码上传是在https://etherscan.io上完成的,目前上传很简单,基本上上传代码文件(有几个传几个)后next即可(不像网上有些资料说的需要另外输入byteCode和ABI)。不过需要注意的是国内网络问题(你懂的),在提交验证合约时,总是提示 “Sorry! We encountered an unexpected error. Please try back again shortly ”,这是因为验证码被墙了,如何操作不需要我教了吧。


其它

在智能合约中,只能等待外部的调用,而无法执行定时任务。同时也无法主动发起外部请求。

默认情况下,geth创建的账户是被锁住的,可以转入不能转出,除非解锁(geth –unlock)。尽量避免在对外的节点服务器上做解锁操作,否则将有被盗币的风险。具体可看金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘,本人亦有教训,所幸损失不大。实际对外提供服务的全节点,做到以下一点或几点,就能显著降低风险:

不使用默认端口;

RPC只对内开放,对外须网关协议转换;

服务器上不存储账户,或不直接在服务器上使用账户。

助记词(BIP32/BIP39/BIP44)的原理可参看 比特币源码研读(7)—— 钱包的原理

智能合约的同一个接口,gas used 未必相同,要看实际执行到的步骤和对存储的操作,规则如下:

以太坊钱包erc20_xvg币智能合约

 

EVM智能合约的实现原理:solidity虽然是编译后上链的,但执行时依旧是由EVM(其实也是以太坊内的若干函数)解释执行的,EVM通过字节码确定操作符和操作数,然后其自身执行相应逻辑。从这个角度说,EVM就是solidity的解释器。若将EVM看作操作系统,solidity编译后即能被EVM运行,那么solidity也可认为是编译型语言。可看EVM原理及其功能扩展

将数据存储在event产生的log中,比存在storage变量中划算的多,可参看在Java中监听以太坊智能合约事件

区块链一般都应该是达成共识之后再执行交易。

 

 

其它参考资料:

智能合约的局限性   智能合约中存在的3种最常见的误解

Solidity Doc   solidity的语法结构

实现一个可管理、增发、兑换、冻结等高级功能的代币

以太坊中的账户、交易、Gas和区块Gas Limit

 

 

转载请注明本文出处:https://www.cnblogs.com/newton/p/11367710.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/168041.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • ssm框架过时了吗_spring实战

    ssm框架过时了吗_spring实战SpringSpring是一个开源的免费的框架Spring是一个轻量级的,非入侵式的框架控制反转(IOC),面向切面编程(AOP)支持事务的处理,对框架整合的支持IOC理论UserDaoUserDaoImpUserSeviceUserServiceImp在之前,用户的需求可能会影响原来的代码。使用一个set。public void setUserDao(UserDao userDao){ this.userDao = userDao;}之前是主动创建对象,控制

  • JQuery的delegate事件参数说明[通俗易懂]

    JQuery的delegate事件参数说明[通俗易懂]JQuery的delegate事件: delegate()方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。 使用delegate()方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)。 $(selector).delegate(childSelector,event,dat

    2022年10月21日
  • mysql中not exists用法_not exists用法

    mysql中not exists用法_not exists用法notexists是sql中的一个语法,常用在子查询和主查询之间,用于条件判断,根据一个条件返回一个布尔值,从而来确定下一步操作如何进行,notexists也是exists或in的对立面。notexists是exists的对立面,所以要了解notexists的用法,我们首先了解下exists、in的区别和特点:exists:强调的是是否返回结果集,不要求知道返回什么,比如:sele…

  • 《画解数据结构》(0 – 1)- 算法时间复杂度[通俗易懂]

    《画解数据结构》(0 – 1)- 算法时间复杂度[通俗易懂]《算法和数据结构》学习前的开胃小文

  • 安卓微信本地数据库解密[通俗易懂]

    安卓微信本地数据库解密[通俗易懂]安卓微信数据库解密

  • 关于W25Q128地址的定义

    1.W25Q128将16M的内存分为256个块,每个块是64K;又将一个块分为16个扇区,一个扇区是4K;又将一个扇区分为16个页,一个页是256字节地址。话不多说,上图:2.在图上右边的红框中可以看到Block0(块0)的地址是000000-00FFFF,再看到左边红框中Block0的16个扇区,地址范围对应的就是Block0的地址范围了,第一个扇区的起始地址就是0000,终止地址是0F…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号