主页 > imtoken钱包官网客服 > erc20代币发行教程_以太坊智能合约【ERC20】代币发行记录

erc20代币发行教程_以太坊智能合约【ERC20】代币发行记录

imtoken钱包官网客服 2023-10-16 05:12:20

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

坚固性

ERC20

合同撰写和发布

合约源码上传

其他

坚固性

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

图书馆

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

我们使用 library 关键字来创建库,这与创建合约非常相似。 但与合约不同的是,我们不能在库中定义任何存储类型的变量。 因为库只是意味着代码重用而不是状态的状态管理。

内部库函数对所有合约都是可见的。

using for: 指令使用 A for B; 用于将库 A 中定义的函数附加到任何类型 B,函数的第一个参数应该是 B 的实例。您可以使用 A for * 将库函数分配给任意类型。 库函数可以重载。 可以定义多个同名函数,但第一个参数的类型不同。 调用时,会根据调用类型自动选择某种方法。

地址索引

记录事件的索引参数将允许您使用索引参数作为过滤器来搜索这些事件。

索引关键字仅与记录的事件相关。

几个预定义字段

address.balance:地址余额,指的是该地址关联的以太坊数量。

以太坊转账多久到账_sitebtc112.com 以太坊转账查询_以太坊批量转账教程

msg.sender:交易的发送者。

this:合约地址。

msg.value:本次交易支付的以太坊金额,与payable配合使用。

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

应付款

修改后的函数是指调用该函数时,合约可以充值以太币(合约也是一种账户,有自己的地址)。 合约本身持有ETH,这使得用户可以更方便地基于该合约进行跨币种交易。

恒、观、纯

constant 修饰常量或函数。 当修改一个函数时,意味着该函数不修改合约状态,即不产生需要广播的交易,不消耗gas。 它通常用于读取状态或与状态无关的操作。 从0.4.17开始改为查看和纯修改函数,前者表示读取状态,后者表示状态无关。

储藏区域

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

内存:临时变量

interface:通过传入不同的地址实现多态。

event,应用层(web3)可以通过watch进行监听,应该是轮询的方式实现。

修饰符,一个简单的aop,编译时会替换和合并代码。

ERC20

我们可以在智能合约中自由开发各种功能,其中相当一部分以代币合约的形式存在。 既然是token,自然有转账、余额查询等功能。 每个人都在努力为不同的代币合约开发不同的钱包,因此出现了一些规范,其中最常见的是 ERC20。

ERC20定义了几种方法,网上的资料很多,这里就不赘述了。 approve、transferFrom、allowance这三个方法有点难理解。 举个例子——A账户有1000个ETH以太坊批量转账教程,如果想授权B账户随意从A账户转出100ETH,需要调用approve(B,100)。 当账户 B 想使用 100 ETH 中的 10 ETH 到账户 C 时,调用 transferFrom(A, C, 10)。 此时调用allowance(A, B)查看B账户还能调用A账户多少token。

我试过好几个本地钱包和在线钱包,都支持转账,但支持授权的很少。

以太坊转账多久到账_sitebtc112.com 以太坊转账查询_以太坊批量转账教程

有人在github上总结了很多ERC20合约代码,看到基于以太坊发行的ERC20代币合约代码大合集。

合同撰写和发布

一个简单的合约demo如下:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 编译指示 solidity ^0.5.7;2

3 导入 './safemath.sol';4

5 合约 ErbCoin {6 使用 SafeMath foruint256;7

8串常量 public name = "Mask Coin"; //令牌名称

9 字符串常量 public symbol = "MASK"; //代币符号

10 uint256 公共小数 = 18; //令牌数字11

12 //映射(地址=> uint256)public balanceOf;

13 mapping (address => mapping (address => uint256)) 公共津贴; //a授权b表示b可以转给其他人的token数量

14 映射(地址 => uint256)public frozenBalances; // 冻结余额

15 映射(地址 => uint256)公共余额; //可操作余额

16

17 uint256 public totalSupply = 0;18 bool public stopped = false;19

20 //uint256 常量 valueFounder = 1000000;

sitebtc112.com 以太坊转账查询_以太坊批量转账教程_以太坊转账多久到账

21 地址常量 zeroaddr = address(0); 22 地址所有者 = zeroaddr; //合约所有者

23 地址 founder = zeroaddr; // 初始代币持有者

二十四

25 修饰符 isOwner {26 assert(owner ==msg.sender);27 _;28 }29

30 修饰符 isFounder {31 assert(founder ==msg.sender);32 _;33 }34

35 修饰符 isAdmin {36 assert(owner == msg.sender || founder == msg.sender);37 _;38 }39

40 修饰符 isRunning {41 assert (!stopped);42 _;43 }44

45 修饰符 validAddress {46 assert(zeroaddr !=msg.sender);47 _;48 }49

50 构造函数(地址 _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) publicview returns (uint256) {59 //账户余额=可操作余额+冻结余额

60 返回余额[_owner] +frozenBalances[_owner];61 }62

63 function transfer(address _to, uint256 _value) public isRunning validAddress returns (boolsuccess) {64 balances[msg.sender] =balances[msg.sender].sub(_value);65 余额[_to] =balances[_to].add (_value);66 emit Transfer(msg.sender, _to, _value);67 return true;68 }69

70 //msg.sender将_from授权给他的token(msg.sender)转给_to

71 function transferFrom(address _from, address _to, uint256 _value) public isRunning validAddress 返回 (boolsuccess) {72 balances[_from] =balances[_from].sub(_value);73 //balances[_to] = balances[_to]. 添加(_值);

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 authorized_spender 可操作令牌

81 function approve(address _spender, uint256 _value) public isRunning isFounder returns (boolsuccess) {82 require(_value == 0 || allowance[msg.sender][_spender] == 0,"非法操作");83 allowance[msg .sender][_spender] =_value;84 emit Approval(msg.sender, _spender, _value);85 return true;86 }87

sitebtc112.com 以太坊转账查询_以太坊批量转账教程_以太坊转账多久到账

88 //冻结部分释放

89 函数释放(地址 _target,uint256 _value)public isRunning isAdmin 返回(bool){90 frozenBalances[_target] =frozenBalances[_target].sub(_value);91 balances[_target] =balances[_target].add(_value); 92 emit Release(_target, _value);93 返回 true;94 }95

96 函数停止() publicisAdmin {97 stopped = true;98 }99

100 函数开始() publicisAdmin {101 停止 = false;102 }103

104 eventTransfer(地址索引 _from,地址索引 _to,uint256 _value);105 eventApproval(地址索引 _owner,地址索引 _spender,uint256 _value);106 eventTransferFrozen(地址 _target,uint256 _value);107 eventRelease(地址 _target,uint256 _value); 108}

查看代码

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

代码中还引入了一个库文件,避免了数值溢出导致的bug。 详情请参考ERC20 Token智能合约的SafeMath安全。

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

MetaMask:浏览器插件形式的以太坊钱包,可以接入主链和多条测试链。

Remix:一个用于编写、编译和发布合约的站点,可以与 MetaMask 无缝协作。

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

踩坑了,多次发token。 imToken(一个流行的钱包应用程序)上显示的令牌名称是 XXX_UNKOWN,后跟一个额外的 _UNKOWN 后缀; 只有一致才显示正常,不知道是不是名字不一致导致的问题。

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

37665e870fbefbaaf86c2d898c638793.png

如果知道合约的ABI,调用合约接口会更方便,如下图:

35165c4a38ff7ebea3aca7ed973d0b98.png

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

以太坊转账多久到账_以太坊批量转账教程_sitebtc112.com 以太坊转账查询

合约源码上传

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

开放代币的源代码以增加透明度和投资者信任;

上传源码后,人们可以在Etherscan中查看当前代币的源码,同时可以方便的看到该代币的相关信息;

上面说了,如果不是标准接口,市面上各种钱包都不支持,那么可以直接通过Remix或者myetherwallet调用接口,不用开发自定义钱包。

代码上传是在网上完成的,目前上传很简单。 基本上就是上传代码文件(几个)然后next(不像网上有些资料需要额外输入byteCode和ABI)。 不过需要注意国内网络问题(你懂的),提交验证合约时总是提示“抱歉!我们遇到了意外错误,请稍后再试”,这是因为验证码被屏蔽了,如何操作你不需要我教你。

其他

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

默认情况下,geth创建的账户是锁定的,只能转入不能转出,除非解锁(geth --unlock)。 尽量避免在外部节点服务器上解锁,否则会有被盗的风险。 详见钱难眠,贼独行——通过以太坊JSON-RPC接口的各种盗币方法的秘诀。 实际对外提供服务的全节点可以通过做以下一项或多项来显着降低风险:

不要使用默认端口;

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

帐户不存储在服务器上以太坊批量转账教程,或直接在服务器上使用。

助记词(BIP32/BIP39/BIP44)原理请参考比特币源码学习(七)-钱包原理

同一个智能合约接口,使用的gas不一定相同。 这取决于实际的执行步骤和存储操作。 规则如下:

39c771379fb8c70f005f1a61beae963b.png

EVM智能合约的实现原理:solidity虽然编译上传到链上,但仍然由EVM解释执行(其实就是以太坊中的几个函数)。 EVM通过字节码确定运算符和操作数,然后自己执行相应的逻辑。 从这个角度来看,EVM 是 solidity 的解释器。 如果把EVM看成一个操作系统,solidity编译后可以被EVM运行,那么solidity也可以看成是一种编译型语言。 可以看到EVM的原理和它的功能扩展。

将数据存储在事件生成的日志中比存储在变量中更具成本效益。 详情请参考Java监听以太坊智能合约事件。

区块链一般应在达成共识后执行交易。

其他参考: