注:通常你们都广泛喜欢把 Token 叫成 代币,可是这样讲很不许确,若是非要叫成中文,我更认同 通证 这种理解。但为了保持原汁原味,没必要非得翻译过来叫,因此本文统一保持英文的形式。编程
通常 Token 制做的门槛其实没有多高,因此你们彻底都有能力能够去制做出本身命名的 Token。浏览器
不过你也别期望啥也不学就能作出一些拥有额外逻辑的 Token,好比众筹合约等,因此想要作的不同凡响,那么就须要花些成本。bash
下面就直奔主题,咱们不须要了解如何编写智能合约,由于以太坊提供的 ERC20 协议已经足够傻瓜式了,作一个简单的 Token 官方就有一个标准的智能合约代码做为示例,那么咱们只须要知道制做的流程就好了。网络
啰嗦一句,其实学习其余的技术知识也是如此,咱们不要急于追求很内在的东西,咱们须要 正反馈 式学习法,先作出一些简单的 Demo,逐步在创建自信心和激发热情的同时不断深刻学习。app
咱们首先须要安装一个浏览器的插件 MetaMask,该插件做者很是 nice,主流的三大浏览器(Google、FireFox、Opera)上均可以安装这款实用的插件。安装这款插件的过程就不赘述了,如今假定咱们已经装好了,点开该插件,通过两次 Accept 赞成条款的操做后,进入建立帐户的页面。 编程语言
在建立帐户页面上输入本身的大于八位字符的密码后,进入 助记词 页面,这些助记词是惟一能帮助你保存本身帐户合约的密钥,妥善保管。 工具
不要慌,不是让你真的花钱去买,只须要在 MetaMask 提供的网站上点几下按钮就能获取到以太币(毕竟这些测试网络上的以太币没有实际价值)。学习
保存完助记词后咱们就会进入到帐户主页面, 区块链
OK,咱们先暂时放一放 MetaMask,接下来让咱们去玩玩 Remix!测试
Remix 是一个基于浏览器的 Solidity IDE,基本的智能合约代码的开发调试在这上面进行是至关舒服的。Remix - Solidity IDE
须要熟悉这个工具吗?固然,并且越熟悉越好,但不是如今,别忘了咱们如今的目标是制做本身的 Token。
以太坊官方网站上有一份标准的 Token 合约供学习者参考,并且也有很详细的教程教你们如何去部署本身的 Token。Create a cryptocurrency contract in Ethereum
本文与官方不一样的是咱们使用 轻钱包 MetaMask 和在线开发环境 Remix 进行开发调试部署,官方的以太坊钱包对于初学者来讲有个挺苦恼的地方,同步主网络或者测试网络的全节点数据很慢,并且占用磁盘空间较大。初次体验尽可能仍是选择轻松的方式,不要给本身留下坏心情 :)
咱们将官方的 Token 合约代码拷贝到 Remix 的代码栏中,合约代码这里也贴一下:
pragma solidity ^0.4.16;
interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; }
contract TokenERC20 {
// Public variables of the token
string public name;
string public symbol;
uint8 public decimals = 18;
// 18 decimals is the strongly suggested default, avoid changing it
uint256 public totalSupply;
// This creates an array with all balances
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
// This generates a public event on the blockchain that will notify clients
event Transfer(address indexed from, address indexed to, uint256 value);
// This notifies clients about the amount burnt
event Burn(address indexed from, uint256 value);
/**
* Constructor function
*
* Initializes contract with initial supply tokens to the creator of the contract
*/
function TokenERC20(
uint256 initialSupply,
string tokenName,
string tokenSymbol
) public {
totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount
balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens
name = tokenName; // Set the name for display purposes
symbol = tokenSymbol; // Set the symbol for display purposes
}
/**
* Internal transfer, only can be called by this contract
*/
function _transfer(address _from, address _to, uint _value) internal {
// Prevent transfer to 0x0 address. Use burn() instead
require(_to != 0x0);
// Check if the sender has enough
require(balanceOf[_from] >= _value);
// Check for overflows
require(balanceOf[_to] + _value > balanceOf[_to]);
// Save this for an assertion in the future
uint previousBalances = balanceOf[_from] + balanceOf[_to];
// Subtract from the sender
balanceOf[_from] -= _value;
// Add the same to the recipient
balanceOf[_to] += _value;
Transfer(_from, _to, _value);
// Asserts are used to use static analysis to find bugs in your code. They should never fail
assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}
/**
* Transfer tokens
*
* Send `_value` tokens to `_to` from your account
*
* @param _to The address of the recipient
* @param _value the amount to send
*/
function transfer(address _to, uint256 _value) public {
_transfer(msg.sender, _to, _value);
}
/**
* Transfer tokens from other address
*
* Send `_value` tokens to `_to` on behalf of `_from`
*
* @param _from The address of the sender
* @param _to The address of the recipient
* @param _value the amount to send
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= allowance[_from][msg.sender]); // Check allowance
allowance[_from][msg.sender] -= _value;
_transfer(_from, _to, _value);
return true;
}
/**
* Set allowance for other address
*
* Allows `_spender` to spend no more than `_value` tokens on your behalf
*
* @param _spender The address authorized to spend
* @param _value the max amount they can spend
*/
function approve(address _spender, uint256 _value) public
returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
/**
* Set allowance for other address and notify
*
* Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
*
* @param _spender The address authorized to spend
* @param _value the max amount they can spend
* @param _extraData some extra information to send to the approved contract
*/
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
public
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
/**
* Destroy tokens
*
* Remove `_value` tokens from the system irreversibly
*
* @param _value the amount of money to burn
*/
function burn(uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
Burn(msg.sender, _value);
return true;
}
/**
* Destroy tokens from other account
*
* Remove `_value` tokens from the system irreversibly on behalf of `_from`.
*
* @param _from the address of the sender
* @param _value the amount of money to burn
*/
function burnFrom(address _from, uint256 _value) public returns (bool success) {
require(balanceOf[_from] >= _value); // Check if the targeted balance is enough
require(_value <= allowance[_from][msg.sender]); // Check allowance
balanceOf[_from] -= _value; // Subtract from the targeted balance
allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance totalSupply -= _value; // Update totalSupply Burn(_from, _value); return true; } } 复制代码
接下来咱们先选择好咱们的编译器的版本,对应合约代码首行的版本号 pragma solidity ^0.4.16
点击箭头1的标签页,进入设置界面,而后点击箭头2选择相应的编译器版本,这里即选择 0.4.16。
而后点击编译标签(Compile),会看到已经编译成功
而后点击运行标签(Run),进行部署操做
这里惟一能够改的是 Gas Limit 和 Gas Price,通常来说这两个数据会自动根据当前合约的复杂度和市场平均水准生成。因此通常不须要去改这两个值,若是是囊中羞涩,改低一点也是能够的,可是可能会出现 Gas 被消耗完的状况(Gas 一旦被消耗完而合约仍未部署到网络上,那么全部操做都会进行回滚,除了你支付的矿工费)。
点击发布按钮(SUBMIT),静静等待发布成功吧!
此时打开 MetaMask 页面
上图为发布中状态,下图为发布结束的状态,此时会发现咱们的帐户余额减小了一些,由于被用于支付发布合约的矿工费了。
到这里还不清楚是否成功发布了,点击交易单进入交易详情页面,当你看到箭头1处的 Success 时就表示咱们的 Token 发布成功啦!
点击箭头2处的合约地址连接,进入合约详情页
点击箭头处的 Token 地址连接,进入 Token 详情页
至此咱们的 Token 就作完啦!
咱们以 MetaMask 为例演示一下,其余钱包好比 ImToken 一样的只须要将 Token 地址复制过去就能看到了。
先切换到 Token 标签页
点击添加 Token,输入刚才的 Token 合约地址
点击添加按钮,就能在 MetaMask 上看到咱们本身的 Token 了。
在制做 Token 的整个过程当中,并无难点,只是大多数人不清楚流程,当本身实操一遍后立马就能上手。后面咱们会去玩一些复杂一点的智能合约,但一样的,须要一些基本的 Solidity 编程语言的知识以及区块链相关的知识。Solidity 这门以太坊的标准编程语言以后的文章也会详细讲解,你们尽请期待~
欢迎关注公众号:『比特扣』,与我一块儿探索区块链的世界。