本文介绍怎么使用以太坊智能合约树立自己的代币。
这篇文章来源于以太坊官网中的资料,本文是作者经过阅览资料,亲身试验后写的中文版资料,仅供初学者参阅。
本文不是对原文进行完好的翻译,主要是作者消化后整理出来的文档,需求看原文的请直接拜访原文地址https://ethereum.org/token。

一、什么是代币?

代币是使用以太坊的智能合约编写的数字钱银。程序员能够经过编写智能合约代码,创立一种新的数字钱银。
你能够完成的功用:

基本功用:
-创立数字钱银,设置钱银的称号、钱银总量、钱银图标等基本参数。
-创立钱银买卖功用。完成钱银在不同用户之间的搬运。

上面的是基本功用,现已能够完成基本的代表沟通,下面是高档功用,能够完成愈加复杂的使用。
高档功用:
-创立钱银的办理者。尽管区块链是去中心化的,可是能够完成合约的办理者,这在许多使用中是有需求的。
-完成数字钱银的是非名单。经过设置是非名单,能够冻住某些账户。财物仍在账户,可是不允许买卖。
-完成钱银增发。就好像美联储狂印钞票相同,你作为钱银的创立者,也能够完成钱银增发的功用,能够在原有钱银总量以外,添加额定的钞票。(想想都是很激动了)
-完成挖矿。比特币、以太币的挖矿机制非常知名,矿工、矿机、矿池等概念咱们都很了解。你能够在自己的钱银中完成挖矿机制,奖励完成挖矿目的的用户一些代币。我现在还没有想到这个功用的用处,可是读这部分的内容有助于理解比特币、以太币的挖矿机制。
-完成代币和其他钱银的主动兑换。你能够在自己的钱银中完成代币与其他数字钱银的兑换机制。这个很激动人心哦,你能够像银行相同收买卖费啦。例如,买入代币的价格是1ETH,卖出代笔的价格是0.8ETH,这意味着每个代币的流入流出,你能够收取0.2ETH的买卖费。是不是很激动,前提是你要忽悠咱们用你的代币。
-完成gas的主动弥补。以太坊中的买卖时需求gas汽油(实践上便是eth)。为了处理某些用户没有ETH,只需代币的状况,能够规划主动弥补gas的功用。这个功用将使你的代币愈加好用。(用的人越多,收买卖费越多,嘿嘿)

以上便是以太坊官方教程中说到的功用。经过学习这些功用的写法,你将学会基本的智能合约编程办法,能够开宣布愈加多样化的功用。

接下来,我将介绍怎么编程智能合约的代码,完成上述功用。

二、完成代币的基本功用

从简略下手,首要完成一个包括基本功用的代币。只需完成代币界说和买卖功用。
完成代币的进程是编写智能合约的代码。智能合约你能够理解为是一种程序,类似于C,C++。不要怕,这种言语很好懂,略微看看就懂啦。
下面是完好的代码,能够直接布置。
-------------------------------------我是分割线,不要复制我-----------------------------------------------

/* contract 类似于C++中的类 */contract MyToken https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg/* 设置一个数组存储每个账户的代币信息 */mapping (address => uint256) public balanceOf;/* 设置变量 *//* name 代币称号 *//* symbol 代币图标 *//* decimals 代币小数点位数 */string public name;string public symbol;uint8 public decimals;/* event事情,它的作用是提示客户端发生了这个事情,你会留意到钱包有时候会在右下角弹出信息 */event Transfer(address indexed from, address indexed to, uint256 value);/* 下面这个类似于C++的构造函数,接纳用户输入,完成代币的初始化 */function MyToken(uint256 initialSupply, string tokenName, uint8 decimalUnits, string tokenSymbol) https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgbalanceOf[msg.sender] = initialSupply; // Give the creator all initial tokensname = tokenName; // Set the name for display purposessymbol = tokenSymbol; // Set the symbol for display purposesdecimals = decimalUnits; // Amount of decimals for display purposes}/* 代币买卖的函数 */function transfer(address _to, uint256 _value) https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg/* 检查发送方有没有满足的代币 */if (balanceOf[msg.sender] < _value || balanceOf[_to] + _value < balanceOf[_to])throw;/* 买卖进程,发送方减去代币,接纳方添加代币 */balanceOf[msg.sender] -= _value;balanceOf[_to] += _value;/* 提示客户端发生了买卖事情 */Transfer(msg.sender, _to, _value);}}

-------------------------------------我是分割线,不要复制我-----------------------------------------------
下面是布置方法,我使用以太坊钱包mist布置合约。
为了节约资金,我使用以太坊测验网络,测验网络是能够用以太坊钱包挖矿的,挖矿难度不大,我现已挖到20个了。做试验够用了。假如你真实挖不到币的话,请在下方留下你的地址,我能够资助你1个以太币做试验(是测验网络的以太币哦)。
其他方法有许多,这儿不讲。我觉得初学者用mist最简略。下面是布置的界面。

这个页面是以太坊钱包“CONTRACTS”页面,点击"DEPLAY NEW CONTRACT"按钮就能看见。
图片的最上面是给合约输入以太币,现在不用设置,保持0即可。图中心的左边是放置代码的当地,将复制的代码粘贴到这儿即可。右侧的红圈方位能够挑选合约,请点击下拉框挑选“My Token”。挑选今后,会呈现图片上的姿态,这儿能够输入代币的总数(Initial supply),代币的称号(Token name),代币的小数点数目(Decimal units),代币的符号(Token symbol)。你能够依照图上的来填,也能够试着随便填,理解用途。
填写完成后,点击最下面的“DEPLOY”按钮,假如成功,则在钱包主页面能够看到合约正在等待验证,假如失利,会提示原因,请检查输入。

假如你的网络正常,通常1分钟内合约就验证经过,这是能够在以太坊钱包“CONTRACTS”页面看到咱们树立的代币TESTCOIN.

上图标红的便是我树立的代币,点击进入代币的办理页面。

这个图便是我树立的代币的办理页面,这个页面能够检查合约持有的代币数量,每个用户持有的代币数量,履行代币买卖等等。
图中左边能够检查代币的基本信息,称号,小数点位数,符号。
图中左边标红的方位能够检查指定用户代币的持有数量,只需将指定用户的地址填入红圈中的方位,即可主动显现。
图中右侧是代币的买卖函数,能够进行代币买卖。
“Select function”,这个挑选transfer函数
“To-address”,这个是指接纳代币用户的地址
"Value",发送代币数量
“Execute from”,这个当地能够挑选发送方的地址。
点击“EXECUTE”按钮,就能够发送。

收到钱银的人想要检查代币,只需求在“CONTRACTS”页面的"Watch token"输入对应的代币合约地址即可。

截止到这儿,一个具备基本功用的代币就完成了。这个代币能够用于积分办理,简略的买卖。
等后续完成更多功用后,能够有更多用途。

三、完成代币的高档功用

接下来,咱们要在上文的基础上添加下列高档功用:
1、创立钱银的办理者。尽管区块链是去中心化的,可是能够完成合约的办理者,这在许多使用中是有需求的。
2、完成钱银增发。就好像美联储狂印钞票相同,你作为钱银的创立者,也能够完成钱银增发的功用,能够在原有钱银总量以外,添加额定的钞票。(想想都是很激动了)
3、完成数字钱银的是非名单。经过设置是非名单,能够冻住某些账户。财物仍在账户,可是不允许买卖。
4、完成代币和其他钱银的主动兑换。你能够在自己的钱银中完成代币与其他数字钱银的兑换机制。这个很激动人心哦,你能够像银行相同收买卖费啦。例如,买入代币的价格是1ETH,卖出代笔的价格是0.8ETH,这意味着每个代币的流入流出,你能够收取0.2ETH的买卖费。是不是很激动,前提是你要忽悠咱们用你的代币。
5、完成gas的主动弥补。以太坊中的买卖时需求gas汽油(实践上便是eth)。为了处理某些用户没有ETH,只需代币的状况,能够规划主动弥补gas的功用。这个功用将使你的代币愈加好用。(用的人越多,收买卖费越多,嘿嘿)

我介绍的思路是这样的:
首要给出悉数的代码,这个代码包括了上述一切功用,能够直接布置。
然后,依照功用别离介绍代码和相关知识。

以下是代码,具备一切的高档功用,能够直接布置在以太坊钱包mist。具体的办法可参阅上一篇文章。

-------------------------------------我是分割线,不要复制我-----------------------------------------------

/* 树立一个新合约,类似于C++中的类,完成合约办理者的功用 */contract owned https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg    address public owner;    function owned() https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg        owner = msg.sender;    }    modifier onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg        if (msg.sender != owner) throw;        _    }        /* 办理者的权限能够搬运 */    function transferOwnership(address newOwner) onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg        owner = newOwner;    }}/* 留意“contract MyToken is owned”,这类似于C++中的派生类的概念 */contract MyToken is ownedhttps://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg    /* Public variables of the token */    string public standard = 'Token 0.1';    string public name;    string public symbol;    uint8 public decimals;    uint256 public totalSupply;        uint256 public sellPrice;        uint256 public buyPrice;        uint minBalanceForAccounts;                                         //threshold amount    /* This creates an array with all balances */    mapping (address => uint256) public balanceOf;        mapping (address => bool) public frozenAccount;    /* This generates a public event on the blockchain that will notify clients */    event Transfer(address indexed from, address indexed to, uint256 value);        event FrozenFunds(address target, bool frozen);    /* Initializes contract with initial supply tokens to the creator of the contract */    function MyToken(    uint256 initialSupply,    string tokenName,    uint8 decimalUnits,    string tokenSymbol,    address centralMinter    ) https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg    if(centralMinter != 0 ) owner = msg.sender;        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens        totalSupply = initialSupply;                        // Update total supply        name = tokenName;                                   // Set the name for display purposes        symbol = tokenSymbol;                               // Set the symbol for display purposes        decimals = decimalUnits;                            // Amount of decimals for display purposes    }    /* 代币搬运的函数 */    function transfer(address _to, uint256 _value) https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg            if (frozenAccount[msg.sender]) throw;        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows        if(msg.sender.balance)>

-------------------------------------我是分割线,不要复制我-----------------------------------------------

接着,咱们依照功用别离介绍
3.1创立钱银的办理者。
尽管区块链是去中心化的,可是能够完成合约的办理者,这在许多使用中是有需求的。能够经过设置,给智能合约添加办理人员。
添加的进程能够使用继承的概念。
3.1.1代码解析
首要界说一个父类

contract owned https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgaddress public owner;function owned() https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgowner = msg.sender;}

上述代码界说一个变量“owner”,这个变量的类型是address,这是用于存储代币的办理者。
owned()类似于C++中的构造函数,功用是给owner赋值。

接下来界说一个modifier(修正标志),能够理解为函数的附属条件。这个条件的内容是假设发送者不是owner(办理者),就跳出。起到一个身份鉴别的作用。

modifier onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgif (msg.sender != owner) throw;_}

接着界说一个transferOwnership函数,这个函数是用于搬运办理者的身份。

function transferOwnership(address newOwner) onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgowner = newOwner;}

留意,transferOwnership后边跟着 “onlyOwner”。所以这个函数的前提是,发送者有必要是owner。

接着修正MyToken.
contract MyToken is ownedhttps://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg
//在mytoken中添加了地址变量centralMinter,这个变量是有输入方位的。

function MyToken(uint256 initialSupply,string tokenName,uint8 decimalUnits,string tokenSymbol,address centralMinter) https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgif(centraMinter != 0) owner=msg.sender;

上述的if从句,只需输入地址不为0,拥有者便是发送者,所以这儿输入什么都没联系。这个if从句,现在没看到有什么用处。
3.1.2代码功用测验
试验内容:
1、树立合约,设置合约的办理者为账号1。
试验成功,试验进程很简略,就不说了。
2、将办理者从账号1搬运给账号2.
试验成功。搬运成功后能够在代币页面检查,“OWNER”是否现已更改。

3.2完成钱银增发
就好像美联储狂印钞票相同,你作为钱银的创立者,也能够完成钱银增发的功用,能够在原有钱银总量以外,添加额定的钞票。(想想都是很激动了)。
能够完成钱银增发。经过代码能够完成办理者给特定人员增发代币。这个代币是凭空发生的,这将导致代币总量发生变化。
这个函数能够完成挖矿的功用。当矿工到达必定方针后,办理者能够经过调用函数给矿工搬运必定的资金。
3.2.1代码解析

1 function mintToken(address target, uint256 mintedAmount) onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg2 balanceOf[target] += mintedAmount;3 totalSupply += mintedAmount;4 Transfer(0, owner, mintedAmount);5 Transfer(owner, target, mintedAmount);6 }

第2句代码给指定方针添加代币数量;
第3句代码给代币总量添加相应的数目;
第4句和第5句代码的意义仅仅提示客户端发生了这样的买卖。
领会:
但凡public参数都能够在钱包看;
但凡函数都能够在钱包中调用
3.2.2代码功用测验
规划试验:
1、给指定地址增发代币。
功用完成成功,办理者能够增发钱银给指定地址。
2、使用费办理者调用增发函数
失利。非办理者无法增发。

3.3完成数字钱银的是非名单
经过设置是非名单,能够冻住某些账户。财物仍在账户,可是不允许买卖。
本文演示的是设置黑名单,即黑名单中的用户不能转账。
3.3.1代码解析

mapping (address => bool) public frozenAccount;event FrozenFunds(address target, bool frozen);function freezeAccount(address target, bool freeze) onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgfrozenAccount[target] = freeze;FrozenFunds(target, freeze);}

请求一个数组“freezeAccount”,存储冻住账户的地址和冻住信息
请求一个事情“FrozenFunds”,提示客户端发生了冻住
树立一个函数“freezeAccount”,设置冻住数组对应方位为freeze,
在transfer中添加冻住代码
function transfer(address _to, uint256 _value)
https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg if (frozenAccount[msg.sender]) throw;
假设账户冻住,则transfer函数跳出。
3.3.2代码功用测验
设置试验:
1、正常状况可买卖
试验成功
2、冻住后,不能买卖
试验成功
3、只需办理员能够冻住。
试验成功
4、能不能冻住自己
试验成功。能够冻住办理者自己。
5、能不能设置0,设置0是不是便是解锁
试验成功。设置0即解锁。
这个图是代币办理页面,在address中输入地址,即可检查是否冻住,NO代表没有冻住,YES代表冻住。

3.4完成代币和其他钱银的主动兑换。
你能够在自己的钱银中完成代币与其他数字钱银的兑换机制。这个很激动人心哦,你能够像银行相同收买卖费啦。
完成代币和数字钱银兑换的代码
3.4.1代码解析

function buy() returns (uint amount)https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgamount = msg.value / buyPrice; // 这个value是用户输入的购买代币付出的以太币数目。amount是根据汇率算出来的代币数目if (balanceOf[this] < amount) throw; // checks if it has enough to sellbalanceOf[msg.sender] += amount; // 购买者添加代币balanceOf[this] -= amount; // 合约削减代币Transfer(this, msg.sender, amount); // execute an event reflecting the changereturn amount; // ends function and returns}function sell(uint amount) returns (uint revenue)https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgif (balanceOf[msg.sender] < amount ) throw; // checks if the sender has enough to sellbalanceOf[this] += amount; // 合约添加代币balanceOf[msg.sender] -= amount; // 出售者削减代币revenue = amount * sellPrice; // amount是用户数输入的出售代币的数量msg.sender.send(revenue); // 用户取得由于输出代币得到的以太币Transfer(msg.sender, this, amount); // executes an event reflecting on the changereturn revenue; // ends function and returns}

这儿的代码完成的是简略的买卖。即合约本身作为中心银行,用户和合约做买卖。用户从合约购买代币,用户向合约出售代币。
留意:这儿的代码没有完成检测功用,即或许呈现合约没有代币和合约没有以太币,导致买卖异常。这个代码没有处理。实践使用时,请自行添加检测代码。

/* 设置代币买卖价格的函数 */

function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgsellPrice = newSellPrice;buyPrice = newBuyPrice;}

这个函数是设置代币的汇率。包括购买汇率buyPrice,出售汇率sellPrice。咱们在试验时,为了简略,设置buyPrice=sellPrice=0.01ETH。当然这个份额是自在设定的。在实践中,你能够规划买入代币buyPrice的价格是1ETH,卖出代币sellPrice的价格是0.8ETH,这意味着每个代币的流入流出,你能够收取0.2ETH的买卖费。是不是很激动,前提是你要忽悠咱们用你的代币。
3.4.2代码功用测验
规划试验:
1、调用setPrices函数,规划汇率。
试验成功。留意,智能合约汇率的单位是wei,1个以太币ETH=10的18次方个wei。
咱们规划buyPrice=sellPrice=0.01ETH=10000000000000000(10的16次方)
设置价格也是1次买卖。每一次价格变化都会写入区块链
2、账号1买入200代币,猜想买入不成功
试验不成功。显现不能买,由于合约没代币,只需eth
3、账号1售出100代币,猜想成功,账号1取得1ETH
试验成功.账号1得到1个代币,出售成功。当时显现gf1合约有100个代币,9个eth。
4、账号2售出800代币,猜想成功,取得8ETH,合约ETH为1
试验成功,账号2得到8个代币,出售成功。当时显现gf1合约有900个代币,1个eth。
5、账号2买入500代币,猜想成功,收取5ETH.
试验成功,账号2得到500个代币,购买成功。当时显现gf1合约有400个代币,6个eth。
6、修正价格,sell 修正为10的17次方。这意味着代币价格升值了。只需50个代币,就能换取5ETH。
试验成功。修正了sell价格。
7、账号1售出60代币,收取6ETH,合约还有0ETH,460个代币。
试验成功。成功买卖。当时显现gf1合约有460个代币,0个eth。
sell price 设置为100000000000000000,这意味着账号2能够用60个代币取得6ETH。合约破产了,无力付出剩下的代币。
留意,此时合约以及破产,合约没有以太币ETH,可是用户仍然有代币。合约无法承兑了。
8、账号2售出100代币,猜想不成功。
试验成功。然买卖成功,账号2削减100代币,gf1合约添加100代币,可是账号2没得到对应的eth。
猜想,或许的原因是, msg.sender.send(revenue); 这个函数,履行失利。
9、从头设置买卖价格,高价购入代币,看曾经的欠款会不会补交。 猜想不会补交。这是一个缝隙,或许经过修正价格。窃取资金。普通用户是没有权限的。
试验成功,的确没有补交,账户1花费5ETH购买50个代币。
11、账号2售出50个代币,取得合约剩下的5个ETH。
试验成功。
今后,假如账户1和账户2再售出代币,将不能得到ETH。
** 留意:这和现在白帽黑客在DAO上做的相同,合约本身现已没有钱了。代币就失去了价值。现在,还没有机制,能够检测是否还有满足的钱支撑代币兑换。**
实践的买卖系统需求考虑这个问题。至少要有提示。现在的DAO呈现了这个问题,DAO中的以太币现已被白猫黑客搬运到其他当地。现在假如经过割裂的方法兑换DAO币,会导致得不到以太币。造成资金丢失。具体内容请参阅http://ethfans.org/topics/404。

3.5完成gas的主动弥补。以太坊中的买卖时需求gas汽油(实践上便是eth)
为了处理某些用户没有ETH,只需代币的状况,能够规划主动弥补gas的功用。这个功用将使你的代币愈加好用。(用的人越多,收买卖费越多,嘿嘿)
以太坊中每一次买卖都需求付出必定的买卖费用(gas,eth)。在某些案例中,不期望客户去处理eth的事情。
所以能够经过代码完成代币和eth的主动兑换,当用户ETH比较少的时候,主动更换一部分代币,得到满足买卖的eth。
关于用户来说,只需处理代币,而不用了解背后的ETH。
3.5.1代码解析

uint minBalanceForAccounts;//留意,这个参数是一个私有变量,意味着钱包里看不见。function setMinBalance(uint minimumBalanceInFinney) onlyOwner https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgminBalanceForAccounts = minimumBalanceInFinney * 1 finney;}

请求一个变量minBalanceForAccounts,存储主动兑换gas的阈值
创立一个设置阈值的函数

/* Send coins */function transfer(address _to, uint256 _value) https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg...if(msg.sender.balance)sell((minbalanceforaccounts-msg.sender.balance)>

在买卖函数中,提前做一个检测,假如账户的eth不行阈值,则买卖。

还有一种做法是,发送者检测收款方有没有满足的ETH,假如没有,发送者则兑换一部分自己的代币,将得到的ETH发送给收款方(这种做法便是为收款方服务,收款方不用处理ETH、GAS的事情)。

/* Send coins */function transfer(address _to, uint256 _value) https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpg...if(_to.balance)_to.send(sell((minbalanceforaccounts-_to.balance)>

3.5.2代码功用测验
规划试验:
1、账户3给账户1转款,账户3没有eth。检查是否履行了主动兑换。
试验失利。发现过错原因,还没有设置价格。
首要设置价格
1代币=1000000000000000(16个0)
即使设置了价格,还是不能履行。原因是账户3现在没有ETH,因此不足以付出买卖的费用gas。所以,账户3有必要拥有满足的ETH来履行买卖。
从头规划试验。账户1给账户3转账0.005ETH. 成功
试验成功,账户主动兑换了4个代币,取得0.004个ETH。现在ETH总数是0.006ETH。
2、账户1给账户3转款,检查账户3的变化。前提条件,先将账户3的ETH清0.
试验成功。发现账户兑换了5个代币,发送给账户3。
有意思的是,收款方收到的不是0.005,而是0.0044,应该是扣除了手续费。

截止到这儿,一切的高档功用都现已完成了。
以太坊官网的TOKEN教程中还完成了挖矿的功用。有兴趣的能够直接看原文。
代币的教程就写到这儿,以上的试验我都在自己的电脑上进行了试验。欢迎沟通。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注