以太坊之如何用infura发行自己的ERC20代币

继续区块链的学习了,今天来学习如何发一个ERC20标准的代币

什么是ERC20标准

然后就可以开始写合约了

pragma solidity ^0.4.11;

contract ERC20Standard {
	uint256 public totalSupply;
	string public name;
	uint256 public decimals;
	string public symbol;
	address public owner;

	mapping (address => uint256) balances;
	mapping (address => mapping (address => uint256)) allowed;

  function ERC20Standard(uint256 _totalSupply, string _symbol, string _name) public {
		decimals = 18;
		symbol = _symbol;
		name = _name;
		owner = msg.sender;
        totalSupply = _totalSupply * (10 ** decimals);
        balances[msg.sender] = totalSupply;
  }
	//Fix for short address attack against ERC20,避免短地址攻击
	modifier onlyPayloadSize(uint size) {
		assert(msg.data.length == size + 4);
		_;
	} 


	function balanceOf(address _owner) constant public returns (uint256) {
		return balances[_owner];
	}


	function transfer(address _recipient, uint256 _value) onlyPayloadSize(2*32) public {
		require(balances[msg.sender] >= _value && _value > 0);
	    balances[msg.sender] -= _value;
	    balances[_recipient] += _value;
	    Transfer(msg.sender, _recipient, _value);        
    }


	function transferFrom(address _from, address _to, uint256 _value) public {
		require(balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0);
        balances[_to] += _value;
        balances[_from] -= _value;
        allowed[_from][msg.sender] -= _value;
        Transfer(_from, _to, _value);
    }


	function approve(address _spender, uint256 _value) public {
		allowed[msg.sender][_spender] = _value;
		Approval(msg.sender, _spender, _value);
	}


	function allowance(address _owner, address _spender) constant public returns (uint256) {
		return allowed[_owner][_spender];
	}

	event Transfer(
		address indexed _from,
		address indexed _to,
		uint256 _value
		);
		
	event Approval(
		address indexed _owner,
		address indexed _spender,
		uint256 _value
		);
}

知道基本的solidity语法应该就能看懂这个合约了,除了实现基本的ERC20标准以外还增加了一个修改器,用来限制参数位数,防止短地址攻击

关于短地址攻击,因为EVM在识别参数时并没有严格地校验参数的位数,而且还会自动补充消失的位数,如果调用合约的tranferFrom方法时有一个地址结尾是0的参数,当有人故意少写结尾的0时,EVM会把value前面的0当作地址的结尾0,而value缺少的位数就会自动补充,这时如果方法里还没有校验参数那就杯具了。

合约有了,接下来就开始编译和部署了,因为全节点太大,所以选择用infura去部署

编译合约我们需要用到solc(注意web3.eth.compile.solidity等相关编译方法在新版的geth中已经移除了),infura的使用可以参考我的另一篇文章

除了基本模块以外还需要引入以下几个模块

var fs                  = require("fs");  
var Web3                = require('web3');
var solc                = require('solc');
var Tx = require('ethereumjs-tx');

接下来就是运行代码

app.get('/Compile',function(req,res){
	var sourceCode = fs.readFileSync('source.sol');//读取合约文件
	var output = solc.compile(sourceCode.toString(), 1);//编译合约
	var bytecode = output.contracts[':ERC20Standard'].bytecode;//提取编译成的bytecode
	var abi = output.contracts[':ERC20Standard'].interface;//提取编译成的abi
	var ERC20Standard =new web3.eth.Contract( JSON.parse(abi));//通过abi创建合约实例
	var transactionObject=ERC20Standard.deploy({//获取合约部署交易对象
	    data: '0x'+bytecode,
	    arguments: [10000000, 'MET',"MyERC20StandardToken"]//合约构造方法的参数
	})

	var transactiondata=transactionObject.encodeABI();//转化成交易代码
	web3.eth.estimateGas({//估算gas,estimateGas估算的代码不准却,一般都会少一些,所以gaslimit要加上一点gas,大概加上十万
	    data: '0x'+bytecode
	}).then(function(gas){
		var privateKey = new Buffer('这里是你的密钥', 'hex');//infura不掌控账户,发起任何交易都需要自己打包签名
	        var rawTx = {
		  nonce: '0x0C',//nonce代表这个账户的交易次数,查看一下你账户的交易次数再填,nonce填错了也会报错
		  gasPrice: '0x3B9ACA00',//1gwei
		  gasLimit: gas+100000,
		  data: transactiondata
		}

		var tx = new Tx(rawTx);
	        tx.sign(privateKey);//打包并用私钥签名

	        var serializedTx = tx.serialize();//序列化交易编码
	        var r= web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'),function(err,hash){//发送交易
	            if(err!=null){
	                console.log(err);
	            }
	            else{
	                console.log("success"+hash);
	                web3.eth.getTransaction(hash).then(console.log);
	            }
	        });
		console.log(gas);//打印一下估算的gas
	});
	res.send("智能合约");
})

node运行代码后浏览器访问端口/Compile就会在控制台打印交易发送信息,结果是

以太坊之如何用infura发行自己的ERC20代币_第1张图片

可以看到gas估算是519836

因为是测试网络,我设置的gas是3000000,实际上也只需要大概600000就行了,交易发送后可以在etherscan上查看,可以在测试网络实验一下


这是刚刚发送的交易,到这里一个ERC20代币合约就创建成功了

你可能感兴趣的:(区块链,区块链)