本文尝试发行一款基于以太坊区块链的数字货币,在此之前你需要先熟悉Solidity
这门合约语言,并拥有Metamask
钱包和账户。
「本文仅做技术探讨,如有上主网需求,请遵循当地国家的法律法规,后果自负」
数字货币基本认识
世界上第一个基于去中心区块链技术,点对点网络且有共识能力的开源数字货币应用就是大名鼎鼎的Bitcoin,我个人一直认为比特币是中本聪送给全世界的礼物,也是迄今为止唯一的真正去中心数字货币,其它的山寨币或多或少都有局部的中心化亦或根本就是财阀控制。比特币最早诞生于2008年,一篇论文详细描述了这款划时代的产品。尽管不是所有的国家承认这是一款货币替代品(实际上只有很少的国家承认),而只是将其认作一种虚拟资产,类似股票。仍然开创了一种新形态的经济模型和生态,随之而崛起的挖矿,数字货币交易所应运而生,同时它也启发了众多投身于去中心事业的科学家、工程师、用户,也在后续产生了以太坊等功能更加完善的区块链。
10多年来,比特币俨然构成了一种新的亚文化,影响着整个人类社会。有关于它的精彩故事太多太多,这里不再一一列举,欢迎大家投身于去中心事业,一同探索属于每一个人的新世界。
以太坊
发行数字货币有很多种方式,一种传统的方法是我们从零开始自己开发一款区块链,然后在上面部署数字货币;当然还可以基于现有的链发行代币,比如在以太坊生态上面。这里涉及到一个重要的合约:ERC20。其严格定义了代币的相关合约和接口,如果我们实现自己的ERC20,那么至少要知晓这个协议的全部细节,特别是接口IERC20实现细节:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function name() public view returns (string) // 数字货币的符号,通常是缩写,例:BTC function symbol() public view returns (string) // 默认是18,num Token * (10 ** decimals) function decimals() public view returns (uint8) // 返回现存的代币数量 function totalSupply() public view returns (uint256) // 获取账户_owner拥有的代币的数量 function balanceOf(address _owner) public view returns (uint256 balance) // 从msg.sender账户转移_value数量的代币到_to账户 function transfer(address _to, uint256 _value) public returns (bool success) // 从账户_from中往账户_to转数量为_value的代币,与approve方法配合使用,需要approve获取权限 function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) // msg.sender设置账户_spender能从msg.sender中转出数量为_value的代币 function approve(address _spender, uint256 _value) public returns (bool success) // 获取账户_spender可以从账户_owner中转出代币的数量 function allowance(address _owner, address _spender) public view returns (uint256 remaining)
// 发生转账时,必须要触发Transfer事件 event Transfer(address indexed _from, address indexed _to, uint256 _value) // approve(address _spender, uint256 _value) 运行成功时必须要触发事件Approval event Approval(address indexed _owner, address indexed _spender, uint256 _value)
|
OpenZeppelin的ERC20
我们不需要完全自己从头实现IERC20
,基于OpenZeppelin的优秀实现是一个不错的选择,我们使用Hardhat
工作流,有关于工作流的配置,可以参考这篇文章相关部分。合约代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract ZY_Bitcoin is ERC20, Ownable { constructor() ERC20("ZY Bitcoin", "ZBT") { uint256 supply = 10 ** decimals(); _mint(msg.sender, 9000 * supply); _mint(block.coinbase, 1000 * supply ); } }
|
编写部署脚本scripts/erc20.js
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const hre = require("hardhat");
async function main() { const COIN = await hre.ethers.getContractFactory("ZY_Bitcoin"); const coin = await COIN.deploy(); await coin.deployed(); console.log("My Token deployed to:", coin.address); }
main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
|
部署到rinkeby
测试网络中,在此之前你需要先设置好Relay
测试网,可以使用Infura的服务,同时要配置好Metamask
钱包的公钥和私钥到我们的Hardhat
项目中。这个过程如果不熟悉,可以参考这篇文章当中的Infura
测试部署的部分,终端命令行如下:
1
| $ npx hardhat --network rinkeby run scripts/erc20.js
|
部署好后,我们在Etherscan上面查询我们的合约:
因为我们是rinkeby
测试网络,所以我们需要切换钱包网络,并且点击页面上的导入代币
链接(在主页靠下的位置),点击后输入我们的合约地址:
我们可以看到,有9000枚ZBT
币铸造到账户当中了:
后记
任何人都可以基于ERC20发行自己的代币,同时伴随着Crypto
圈子疯狂的炒币浪潮,其与法定货币锚定的价格令人心醉神迷。现如今大饼(比特币)已然可以看做大盘的指数,而各个项目方发行的代币本质就是上市,你所购买的山寨币可以视同购买股票。这里面当然伴随着监管和法律的问题,其背后的意义也值得深刻探讨。本文仅讨论技术实现,对于法律法规还请读者遵循本国的有关规定。祝福大家可以迎接美好的时代~