Truffle+Vue+MetaMask创建一个以太坊Dapp

参考资料
开发环境
  • Windows10
  • web3 1.0
编写第一个Solidity智能合约

一个简单的例子是编写一个可以注册,保存社区成员信息和简单电子钱包功能的账户合约

pragma solidity ^0.4.24;
import "./SafeMath.sol";//开源的安全操作unit256的合约

contract Account{
    using SafeMath for uint256;
    //新成员创建事件
    event NewMember(string _name, string _avator);
    //成员信息结构
    struct Member {
        string name;//名字
        string avatar;//头像
        bool isExist;//是否注册
        uint256 balance;//可周转余额
    }
    //地址到成员信息的mapping
    mapping(address => Member) internal addressToMember;
    //限制调用的条件
    modifier onlyMemberOf(address _from){
        require(addressToMember[_from].isExist);
        _;
    }
    // 注册
    function registerMember(string _name, string _avatar) public {
        require(!isMemberOf());
        addressToMember[msg.sender] = Member(_name, _avatar, true, 0);
        emit NewMember(_name, _avatar);
    }

    // 判断是否注册
    function isMemberOf() public view returns (bool) {
        return addressToMember[msg.sender].isExist;
    }

    // 获取个人信息
    function getMemberInfo() public view onlyMemberOf(msg.sender) returns (string name, string avatar, uint256 balance) {
        return (addressToMember[msg.sender].name,addressToMember[msg.sender].avatar, addressToMember[msg.sender].balance);
    }
    //获取当前合约中的总余额
    function getTotalBalance() public view returns (uint256) {
        return address(this).balance;
    }
    //取出可周转余额
    function withdraw(uint256 amount) public onlyMemberOf(msg.sender) returns (uint256) {
        require(address(this).balance >= amount);
        addressToMember[msg.sender].balance = addressToMember[msg.sender].balance.sub(amount);
        msg.sender.transfer(amount);
        return addressToMember[msg.sender].balance;
    }
}
复制代码
在Remix上部署合约
  • 安装Ganache
  • 使用Ganache本地测试:安装MetaMask Chrome插件, 选择Custom RPC创建RPC连接到http://127.0.0.1:7545
  • 或者要部署到私有节点,可以使用命令行,然后选择Custom RPC创建RPC连接到http://127.0.0.1:8545
$ geth --identity "MY Etherum" --rpc --rpccorsdomain "*" --datadir data --port "8545" --rpcapi "db,eth,net,web3,personal" --networkid 666 console
复制代码
  • 打开Remix在线编译,在compile选择合适的编译版本编译,在run选择Deploy部署得到合约地址
  • 可以在Remix上测试我们的合约(注册后getMemberInfo可以用户信息,isMemberOf为true)
  • 合约部署和测试成功后,将ABI和Deployed Contracts复制保存到本地文件夹(注意Ganache得到的地址是临时的,下次打开就会失效)
配置Truffle+Vue项目
  • 环境配置
    在windows下需要先安装node.js, 建议使用Git Bash或者PowerShell执行命令:
    $ npm install -g -production windows-build-tools
    $ npm install -g ganache-cli
    $ npm install -g truffle
    $ npm install -g vue-cli
    复制代码
  • Vue项目安装
    $ vue init webpack ecourse // vue init webpach + 你的项目名
    $ cd ecourse
    $ npm install --save element-ui vue-router vuex web3@1.0.0-beta.36 web3-net@1.0.0-beta.36
    复制代码
  • 添加文件及文件夹:① contracts放置.sol合约; ② store放置Vuex状态控制代码;③ util放置工具函数,util/constant放置上一步中编译好的合约地址和ABI,util/config放置一些配置
完善项目

具体的配置可以参考博客使用 Web3 和 Vue.js 来创建你的第一个以太坊 dAPP,这里我主要指出使用web3 1.0 标准的不同配置

  • getWeb3.js
import Web3 from 'web3'

let getWeb3 = new Promise(function (resolve, reject) {
  var web3js = window.web3;
  var web3Provider;
  if (typeof web3js !== 'undefined') {
  	web3Provider = web3js.currentProvider;
  } else {
  	web3Provider = new Web3.providers.HttpProvider('http://127.0.0.1:7545');
  }
  var web3 = new Web3(web3Provider);
  resolve({
  	injectedWeb3: web3.eth.net.isListening(), // 新的api
  	web3() {
  		return web3
  	}
  })
})
  .then(result => {
  	return new Promise(function (resolve, reject) {
  	  result.web3().eth.net.getId((err, networkId) => { // 新的api
  	  	if(err) {
  	  	  reject(new Error('Unable to retrieve network ID'))
  	  	} else {
  	  	  console.log('retrieve newworkId: ' + networkId)
  	  	  result = Object.assign({}, result, {networkId})
  	  	  resolve(result)
  	  	}
  	  })
  	})
  })
  .then(result => {
  	return new Promise(function (resolve, reject) {
  	  result.web3().eth.getCoinbase((err, coinbase) => {
  	  	if(err) {
  	  	reject(new Error('Unable to retrieve coinbase'))
  	  } else {
        coinbase = result.web3().utils.toChecksumAddress(coinbase);
  	  	console.log('retrieve coinbase: '+ coinbase);
  	  	result = Object.assign({}, result, {coinbase});
  	  	resolve(result)
  	  }})
  	})
  });

  export default getWeb3
复制代码
  • pollWeb3.js(web3 1.0 添加了新的api能够监听账户地址的变化,不需要使用setIntervel进行轮询)
import Web3 from 'web3'
import {store} from '../store/'

let web3 = window.web3;
web3 = new Web3(web3.currentProvider);
web3.currentProvider.publicConfigStore.on('update', ({selectedAddress, networkVersion}) => {
  store.dispatch('pollWeb3', {
    coinbase: selectedAddress
  })
});
复制代码
  • getContract.js
import Web3 from 'web3'
import {address, ABI} from './constant/ecourse_abi'
import {store} from '../store/'

let getContract = new Promise(function(resolve, reject) {
  let web3 = new Web3(window.web3.currentProvider);
  let ecourseContractInstance =  new web3.eth.Contract(ABI, address);//新的api
  if (!ecourseContractInstance) {
    reject("no contract instance build")
  }
  resolve(ecourseContractInstance);
});
export default getContract
复制代码
Dapp调用合约函数
  • App.vue(我们可以在入口文件注册web3和contract)
async beforeCreate() {
    if(!this.$store.state.web3.web3Instance) {
    await this.$store.dispatch('registerWeb3');
    await this.$store.dispatch('getContractInstance');
    }
},
复制代码
  • web3 1.0调用函数使用methods
// 为避免报错,可以在调用合约函数之前,进行一个判断
if(typeof this.$store.state.contractInstance !== "function") {
    await this.$store.dispatch('getContractInstance');
}
// 一个调用函数的例子
this.$store.state.contractInstance().methods.withdraw(this.formInline.balance)
    .send({from:this.$store.state.web3.coinbase, gas: 300000})
    .on('receipt', receipt => {
        this.$message('取款成功');
    })
    .on('error', error => {
        this.$message('取款失败');
    })
// 另一个调用函数的例子
this.$store.state.contractInstance().methods.getMemberInfo()
.call({from: state.web3.coinbase}) //注意!!!!!from不能省略,因为metamask默认的msg.sender是accounts[0]
.then(res => {
    console.log('account info: ' + res);
})
.catch(error => {
    console.log(error);
})
复制代码
其他
  • 之前没有学习过vue项目的,可以从一个最简单的Truffle PetShop项目学起,可以很快搭建并看到一个合约怎样调用。
  • 学习solidity的很好的网站:cryptozombies,大概两天可以把所有lesson过一遍,基本上编写合约就没什么问题了
  • 可以在truffle官网上找到很多框架,直接unbox使用,不过我觉得自己配置使用起来比较容易

我的项目地址:Github
有问题,可以随时提问

转载于:https://juejin.im/post/5c10b73d6fb9a049e82b5fff

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值