本文将详细介绍如何在本地搭建以太坊私有测试链,并基于此创建和部署符合ERC20标准的自定义代币。通过分步操作,您将掌握区块链开发的核心流程。
环境准备与工具安装
获取以太坊钱包
首先需要下载以太坊官方钱包客户端。Ethereum Wallet(或Mist)是常用选择,两者功能基本一致,任选其一即可。
安装Geth客户端
Geth是以太坊的官方命令行客户端,用于与区块链进行交互。
macOS系统:推荐使用Homebrew进行安装
brew install geth- 其他平台:请参考官方文档的安装指南
创建私有链网络
配置创世区块
创世区块是区块链的起点,需要创建genesis.json文件来定义私有链的初始参数:
{
"config": {
"chainId": 33,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"nonce": "0x0000000000000033",
"timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x8000000",
"difficulty": "0x100",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333",
"alloc": {}
}初始化与启动私有链
执行以下命令初始化区块链数据目录:
geth init genesis.json --datadir ~/Library/Ethereum启动私有链节点:
geth --networkid 10 --rpc --rpcapi "admin,debug,eth,miner,net,personal,shh,txpool,web3" --rpcaddr "0.0.0.0" --rpccorsdomain "*" --nodiscover --dev console设置挖矿账户
在新终端窗口中连接节点并启动挖矿:
geth attach 'http://127.0.0.1:8545'
miner.start(1)若出现账户错误,需指定挖矿收益地址:
miner.setEtherbase("您的钱包地址")验证连接
启动以太坊钱包应用,确认已成功连接到私有链网络。如果显示同步节点数据,请检查私链是否正常启动。
开发ERC20代币合约
合约代码结构
ERC20是以太坊上最流行的代币标准,定义了代币的基本功能和接口。以下是一个固定供应量代币的实现示例:
pragma solidity ^0.4.19;
contract ERC20Interface {
function totalSupply() constant returns (uint256 totalSupply);
function balanceOf(address _owner) constant returns (uint256 balance);
function transfer(address _to, uint256 _value) returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
function approve(address _spender, uint256 _value) returns (bool success);
function allowance(address _owner, address _spender) constant returns (uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract FixedSupplyToken is ERC20Interface {
string public constant symbol = "XC";
string public constant name = "X Coin";
uint8 public constant decimals = 18;
uint256 _totalSupply = 100000000000000000000000000000;
address public owner;
mapping(address => uint256) balances;
mapping(address => mapping (address => uint256)) allowed;
modifier onlyOwner() {
assert(msg.sender == owner);
_;
}
function FixedSupplyToken(string _symbol, string _name) public {
owner = msg.sender;
balances[owner] = _totalSupply;
}
// 其余接口实现...
}将上述代码保存为FixedSupplyToken.sol文件。
构建部署环境
初始化Node.js项目
创建项目目录并初始化:
mkdir contract-project
cd contract-project
npm init -y安装必要的开发依赖:
npm install ganache-cli solc web3项目结构安排
创建以下目录结构:
project-root/
├── build/ # 编译输出目录
├── contracts/ # 智能合约文件
├── compile.js # 编译脚本
├── deploy.js # 部署脚本
└── package.json编写编译脚本
创建compile.js文件处理合约编译:
const solc = require('solc');
const fs = require('fs');
const path = require('path');
const contractPath = path.resolve(__dirname, 'contracts', 'FixedSupplyToken.sol');
const sourceCode = fs.readFileSync(contractPath, 'utf8');
const output = solc.compile(sourceCode, 1);
for (let contractName in output.contracts) {
const bytecode = output.contracts[contractName].bytecode;
const abi = JSON.parse(output.contracts[contractName].interface);
const buildPath = path.resolve(__dirname, 'build', contractName.replace(':', '') + '.json');
fs.writeFileSync(buildPath, JSON.stringify({ bytecode, abi }, null, 2));
}编写部署脚本
创建deploy.js处理合约部署:
const Web3 = require('web3');
const fs = require('fs');
const path = require('path');
const web3 = new Web3('http://127.0.0.1:8545');
const contractPath = path.resolve(__dirname, 'build', 'FixedSupplyToken.json');
const contractData = JSON.parse(fs.readFileSync(contractPath, 'utf8'));
async function deploy() {
const accounts = await web3.eth.getAccounts();
// 解锁账户(如果需要)
await web3.eth.personal.unlockAccount(accounts[0], "您的密码", 15000);
const contract = new web3.eth.Contract(contractData.abi);
const deployedContract = await contract.deploy({
data: '0x' + contractData.bytecode,
arguments: ["MT", "My TOKEN"]
}).send({
from: accounts[0],
gas: 1500000,
gasPrice: web3.utils.toWei('0.0000002', 'ether')
});
console.log('合约部署地址:', deployedContract.options.address);
}
deploy();执行部署操作
编译智能合约
运行编译脚本:
node compile.js成功编译后,将在build目录生成包含ABI和字节码的JSON文件。
部署到私有链
执行部署命令:
node deploy.js部署过程中,挖矿终端会显示区块打包信息。部署成功后,会返回合约地址。
添加代币到钱包
将返回的合约地址添加到以太坊钱包的代币跟踪列表中,即可查看代币余额和进行转账操作。
测试与验证
创建多个测试账户进行代币转账测试,验证合约功能是否正常:
- 检查余额查询功能
- 测试代币转账交易
- 验证授权机制工作正常
常见问题
私有链连接失败怎么办?
确保geth节点正常运行且网络ID配置正确。检查防火墙设置,确保8545端口可用。
合约部署时显示账户锁定错误?
需要先解锁发送交易的账户:
web3.eth.personal.unlockAccount(账户地址, "密码", 解锁时长)如何修改代币参数?
直接修改Solidity合约代码中的常量值,如代币名称、符号、总供应量等,然后重新编译和部署。
交易一直处于pending状态?
确认私有链的挖矿功能已开启,需要有活跃的矿工处理交易。
如何与其他DApp交互?
通过合约ABI和地址,任何Web3兼容的应用都可以与您的代币合约进行交互。
ERC20标准必须实现哪些方法?
必须实现balanceOf、transfer、transferFrom、approve、allowance等核心方法,以及相应的Transfer和Approval事件。
通过本指南,您已经掌握了创建以太坊私有链和部署自定义代币的完整流程。这些技能为进一步开发区块链应用奠定了坚实基础。