智能合约开发实践:代币与DApp构建
1. ERC20代币标准实现
根据EIP-20标准文档:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
pragma solidity ^0.4.24;
contract ERC20Token {
string public tokenName;
string public tokenSymbol;
uint8 public decimalUnits;
uint256 public totalSupply;
mapping(address => uint256) public balances;
mapping(address => mapping(address => uint256)) public allowances;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor() public {
tokenName = "DigitalCoin";
tokenSymbol = "DGC";
decimalUnits = 0;
totalSupply = 50000;
balances[msg.sender] = totalSupply;
}
function transfer(address to, uint256 amount) public returns (bool) {
require(to != address(0));
require(balances[msg.sender] >= amount);
require(balances[to] + amount > balances[to]);
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public returns (bool) {
require(from != address(0));
require(to != address(0));
require(balances[from] >= amount);
require(allowances[from][msg.sender] >= amount);
require(balances[to] + amount > balances[to]);
balances[from] -= amount;
balances[to] += amount;
allowances[from][msg.sender] -= amount;
emit Transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function remainingAllowance(address owner, address spender) public view returns (uint256) {
return allowances[owner][spender];
}
}
2. DApp开发流程
核心技术栈:
- web3.js
- Solidity
- Truffle框架:安装指南
- Ganache测试网络
标准开发流程:
- 项目初始化
- 智能合约开发
- 合约编译、部署与测试
- 前端与合约交互
环境搭建:
npm install -g truffle
truffle version
项目初始化:
mkdir my-dapp
cd my-dapp
truffle init
truffle unbox pet-shop
示例合约:PetAdoption.sol
pragma solidity ^0.4.24;
contract PetAdoption {
address[16] public adopters;
function adoptPet(uint petId) public returns (uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
function getAdoptersList() public view returns (address[16]) {
return adopters;
}
}
部署脚本:2_deploy_contracts.js
var Adoption = artifacts.require("./PetAdoption.sol");
module.exports = function(deployer) {
deployer.deploy(Adoption);
};
网络配置:truffle-config.js
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 7545,
network_id: "*"
}
}
};
部署命令:
truffle migrate
3. Web3交互示例
let contractInstance;
PetAdoption.deployed().then(instance => contractInstance = instance);
// 查询余额
web3.eth.getBalance("0x627306090abab3a6e1400e9345bc60c78a8bef57").then(balance => {
console.log(web3.utils.fromWei(balance, "ether"));
});
// 账户列表
web3.eth.getAccounts().then(accounts => console.log(accounts));
// 发起交易
web3.eth.sendTransaction({
from: accounts[0],
to: accounts[1],
value: web3.utils.toWei("1", "ether")
});
4. 代币合约实现
pragma solidity ^0.4.24;
contract CryptoToken {
uint256 public constant INITIAL_SUPPLY = 20000;
mapping(address => uint256) public balances;
constructor() public {
balances[msg.sender] = INITIAL_SUPPLY;
}
function send(address to, uint256 amount) public {
require(to != address(0));
require(balances[msg.sender] >= amount);
require(balances[to] + amount > balances[to]);
balances[msg.sender] -= amount;
balances[to] += amount;
}
function checkBalance(address account) public view returns (uint256) {
return balances[account];
}
}
部署脚本:2_deploy_token.js
var CryptoToken = artifacts.require("./CryptoToken.sol");
module.exports = function(deployer) {
deployer.deploy(CryptoToken);
};
5. 前端集成
项目初始化:
npm init -y
npm install lite-server
配置文件:bs-config.json
{
"server": {
"baseDir": ["./src", "./build/contracts"]
}
}
启动命令:
npm run dev