基础开发环境
本教程是技术大牛 luofei614 的DApp开发学习笔记,编成教程分享给开发者。
1、用remix部署第一个合约
remix是一个以太坊官方的在线合约编辑器。 地址: https://remix.ethereum.org/
以太坊编写智能合约的语言一般是用solidity。
我们动手自己实现一个水龙头的合约,调用合约的withdraw方法可以向自己账号充币
在contracts文件夹下新建Faucet.sol文件
代码如下:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.5;
contract Faucet{
function withdraw(uint withdraw_amont) public {
require(withdraw_amont<0.1 ether);
msg.sender.transfer(withdraw_amont);
}
function() public payable{}
}
1处是选择编译器版本, solidity语言有很多版本,而且更新很快,新版本会出现很多不向下兼容版本的情况(以太坊官方说自己的开发文化是敢于创新也体现在此),所以这里选择编译器版本很关键, 如果你是在网上找到代码来调试,一定看看代码中声明适合什么版本的,这里编译器选择到对应的版本。
2处点击即可开始编译
3处可以复制编译好的bytecode和ABI, bytecode就是在创建合约时需要像以太坊传递的参数data中的内容, ABI是向机器指令层面编码和解密传送数据的主要方式, ABI有点类似类的反射,通过ABI知道合约有哪些方法和传参。
1处选择编译环境, JavascriptVM 是Remix自带的虚拟机环境,用这个环境可以不用连接钱包就可以调试。 injected Web3 可以连接MetaMask钱包进行调试。 Web3 Provider是连接本地的Ganache测试环境。
点击Deploy按钮进行部署
2处是部署完成后返回的合约地址 ,点开合约地址可以调试合约的函数调用。 (PS:我们也可以在At Address处输入已知的合约地址,调试合约)
我们可以看见因为合约定义了withdraw函数, 所以点开合约地址后下面会有withdraw的调用的地方。
在withdraw旁边输入框输入数字,点击 withdraw按钮可以调试 withdraw函数。 此时调用withdraw会失败,因为这个合约上没有余额
增加余额的方式:
1,给合约地址充币
可以在remix编辑器控制台命令行输入:
web3.eth.sendTransaction({from:"账号地址",to:"合约地址",value:'1000000000000000000'});
上面命令为打1ETH到合约地址。
2,可以在部署合约时输入Value的值(PS:这需要合约的构造函数声明payable才可以接受支付,上面示例代码还没有支持, 后面的演示示例中演示怎么支持payable)
2、Ganache本地区块链测试网络安装
https://www.trufflesuite.com/ganache 在这里下载安装。
Ganache可视化界面用的非常方便。他是本地的以太坊区块链测试环境, 会自动建立十个账号,并每个账号有100ETH,供我们调试程序。 可以在本地测试链上部署合约。 注意每次Ganache重启后会恢复初始状态,合约需要重新部署, 反复的部署合约需要管理起来, 所以下面我们介绍truffle工具管理合约。
3、安装truffle
安装:
npm install -g truffle
初始化truffle项目:
truffle init
目录结构:
├── contracts //存放合约
│ └── Migrations.sol
├── migrations //存放迁移文件
│ └── 1_initial_migration.js
├── test //存放测试脚本
└── truffle-config.js //配置文件
编译合约:
truffle compile
部署合约:
truflle migrate
进入命令行:
truffle console
在有truffle配置文件的项目中运行这个命令
4、用truffle部署合约
contracts目录下建立合约, 我们还是拿水龙头合约来测试。 建立文件名为:Faucet.sol
代码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.5;
contract Faucet{
constructor() public payable {}
function withdraw(uint withdraw_amont) public {
require(withdraw_amont<0.1 ether);
msg.sender.transfer(withdraw_amont);
}
function() public payable{}
truffle 支持的编译器的版本是 0.5.16 , 上面合约是0.4.5版本的, 需要编译器版本可以在 truffle-config.js 配置文件中配置项compilers->solc->version 进行配置,修改为0.4.26。
上面代码增加了contructor为payable属性,主要是让等会创建合约时就可以打以太坊。
在migration文件中建立迁移文件: 2_Faucet.js
const Faucet = artifacts.require("Faucet");
module.exports = function (deployer) {
deployer.deploy(Faucet);
};
1_initial_migration.js 是第一个初始化合约, 这个合约的作用是记录了迁移到哪步了,避免重复迁移。migration合约巧妙的把区块链环境当作了数据库。
编译:
truffle compile
编译生成的文件叫作artifacts是json格式文件, 会生成在build/contracts 文件夹下, 生成的json文件会包含编译的betycode,abi,以及在部署后网络合约地址也在生成的json中包含
部署:
truflle migrate
默认会部署到Ganache测试网络, Ganache默认会创建10个有私钥的账号, truflle能读取到Ganacache的私钥,默认会用第一个账户进行部署。
更改部署时的账户并向合约充值: 在2_Faucet.js文件代码修改如下:
const Faucet = artifacts.require("Faucet");
module.exports = function (deployer,network,accounts) {
deployer.deploy(Faucet,{from:accounts[1],value:web3.utils.toWei('1', 'ether')});
};
或者代码写为:
const Faucet = artifacts.require("Faucet");
module.exports = function (deployer,network,accounts) {
deployer.deploy(Faucet).then(function(instance){
//先部署,部署成功后充值
web3.eth.sendTransaction({from:accounts[1],to:instance.address,value:web3.utils.toWei('1', 'ether')});
});
};
重新部署:
truffle migrate --reset
用truflle console命令行控制台也给合约账户充值:
truffle console
>let accounts=await web3.eth.getAccounts()
>let instance=await Faucet.deployed()
>web3.eth.sendTransaction({from:accounts[1],to:instance.address,value:web3.utils.toWei('1', 'ether')})
5、用VUE开发水龙头合约界面
安装vue命令行
npm install -g @vue/cli
用vue命令行创建一个应用
vue create myapp
安装依赖
cd myapp
yarn add web3
yarn add @truffle/contract
复制上面合约编译生成的artifacts文件Faucet.json 到 Vue项目src/components/文件夹下。
编辑HelloWorld.vue文件,在默认的界面上增加一个点击按钮
<button @click="click">水龙头</button>
在VUM的javascript代码部分使用如下代码
<script>
import Web3 from "web3";
import contract from "@truffle/contract";
import FaucetJson from "./Faucet.json";
import { BigNumber } from '@ethersproject/bignumber';
export default {
data(){
return {
web3:false,
contract_instance:false,
accounts:[]
}
},
async created(){
//初始化web3
// Modern dapp browsers...
let web3Provider ;
if (window.ethereum) {
web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.enable();
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
}
// Legacy dapp browsers...
else if (window.web3) {
web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
this.web3 = new Web3(web3Provider);
//初始化合约
const FaucetContract=contract(FaucetJson);
FaucetContract.setProvider(web3Provider);
this.contract_instance=await FaucetContract.deployed();
this.accounts=await this.web3.eth.getAccounts();
},
methods:{
click(){
//调用合约的withdraw函数 this.contract_instance.withdraw(this.web3.utils.toWei('1','ether'),{from:this.accounts[0]});
}
},
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
JS代码中一般调用的步骤是:初始化web3实例-> 初始化合约实例->调用合约
在调用withdraw,不用将值做BigNumber的转换, 因为truflle-contract 底层会做BigNumber转换
运行环境:
yarn serve
这时候在浏览器点击按钮可以试用水龙头功能。
注意,如果出现报错: Error: the tx doesn't have the correct nonce. account has nonce of: 14 tx has nonce of: 0 , 是钱包的问题,不是代码的问题。 关闭浏览器重启一下MetaMask钱包。
6、结合火币链开发
MetaMask添加自定义RPC,添加火币生态链测试地址:
chainid 256
RPC https://http-testnet.hecochain.com
区块浏览:https://scan-testnet.hecochain.com/home/index (PS: 火币生态的浏览器地址可以清晰看到合约的源码,这里是学习合约的一个好地方)
到水龙头下去领币:
https://scan-testnet.hecochain.com/faucet
火币链是基于EOS的,出块速度更快,也兼用以太坊的EVM,部署合约的操作步骤和以太坊没有区别。
truffle配置火币链生态链
在truffle项目中安装依赖
yarn add @truffle/hdwallet-provider@1.0.18
然后编辑配置文件truffle-config.js
去掉下面几行注释
const HDWalletProvider = require('@truffle/hdwallet-provider');
const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();
在.secret 文件中添加账号的私钥, 私钥可以从metamask的账号详情导出。
在 networks下添加:
hecotest: {
provider: () => new HDWalletProvider(mnemonic, `https://http-testnet.hecochain.com`),
network_id: 256
},
hecomain: {
provider: () => new HDWalletProvider(mnemonic, "https://http-mainnet.hecochain.com"),
network_id: 128
}
部署合约时指定网络名称:
truffle migrate --network=hecotest
hdwallet-provider一定要安装1.0.18版本的,不然会有报错:invalid sender , 可能是新版本用法不一样, truffle配置文件中的实例代码是老版本用户。
Last updated