The resources

  • Use Web3 and vue.js to create your first Ethereum dAPP
  • 1.0 API web3

The development environment

  • Windows10
  • Web3 1.0

Write the first Solidity smart contract

A simple example is to write an account contract that allows you to register, store community member information, and have a simple e-wallet function

Pragma solidity ^ 0.4.24; import "./SafeMath.sol"; // Contract Account{using SafeMath for uint256; // NewMember creation event NewMember(string _name, string _avator); Struct Member {string name; // Name string avatar; // avatar bool isExist; // Whether to register uint256 balance; } // Address to Member information mapping(address => Member) internal addressToMember; // restrict the conditional 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(uint.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; }}Copy the code

Deploy the contract on Remix

  • Install the Ganache
  • Local Testing with Ganache: Install the MetaMask Chrome plugin and select Custom RPC to create an RPC connection to http://127.0.0.1:7545
  • Or to deploy to a private node, use the command line and then select Custom RPC to create an RPC connection to 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
Copy the code
  • Open Remix online compilation, select the appropriate compile version in compile, and select Deploy deployment in run to obtain the contract address
  • We can test our contract on Remix (after registration getMemberInfo can test the user information, isMemberOf is true)
  • Copy Deployed and tested ABI and Deployed Contracts to local folder (note that the address Ganache got is temporary and will be invalid the next time you open it)

Configure the Truffle+Vue project

  • Environment configuration

    In Windows, node.js needs to be installed first. You are advised to run Git Bash or PowerShell:
    $ npm install -g -production windows-build-tools
    $ npm install -g ganache-cli
    $ npm install -g truffle
    $ npm install -g vue-cli
    Copy the code
  • Vue project installation
    $vue init webpack ecourse // Vue init webpach + your project name $cdEcourse $NPM install --save element- UI vue-router vuex [email protected] [email protected]Copy the code
  • Add files and folders: ① Place contracts. ② Store Vuex state control code; Util /constant places the contract address and ABI compiled in the previous step,util/config places some configuration

Perfect project

See the blog to create your first Ethereum dAPP using Web3 and vue.js. Here I mainly point out the different configurations using the Web3 1.0 standard

  • getWeb3.js
import Web3 from 'web3'

let getWeb3 = new Promise(function (resolve, reject) {
  var web3js = window.web3;
  var web3Provider;
  if (typeofweb3js ! = ='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(), / / the new API
  	web3() {
  		return web3
  	}
  })
})
  .then(result= > {
  	return new Promise(function (resolve, reject) {
  	  result.web3().eth.net.getId((err, networkId) = > { / / the new 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
Copy the code
  • Pollweb3.js (Web3 1.0 added a new API to listen for account address changes without using setIntervel for polling)
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
  })
});
Copy the code
  • 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);/ / the new API
  if(! ecourseContractInstance) { reject("no contract instance build")
  }
  resolve(ecourseContractInstance);
});
export default getContract
Copy the code

The Dapp calls the contract function

  • App.vue(we can register web3 and contract in the entry file)
async beforeCreate() {
    if(!this.$store.state.web3.web3Instance) {
    await this.$store.dispatch('registerWeb3');
    await this.$store.dispatch('getContractInstance'); }},Copy the code
  • Web3 1.0 calls functions using methods
// To avoid errors, make a judgment before calling the contract function
if(typeof this.$store.state.contractInstance ! = ="function") {
    await this.$store.dispatch('getContractInstance');
}
// An example of calling a function
this.$store.state.contractInstance().methods.withdraw(this.formInline.balance)
    .send({from:this.$store.state.web3.coinbase, gas: 300000})
    .on('receipt', receipt => {
        this.$message('Withdrawal successful');
    })
    .on('error', error => {
        this.$message('Withdrawal failed');
    })
// Another example of calling a function
this.$store.state.contractInstance().methods.getMemberInfo()
.call({from: state.web3.coinbase}) / / attention!!!!!!!!!!! From cannot be omitted because metamask default msg.sender is accounts[0]
.then(res= > {
    console.log('account info: ' + res);
})
.catch(error= > {
    console.log(error);
})
Copy the code

other

  • For those of you who haven’t studied vue projects before, you can start with a simple Truffle PetShop project that will quickly set up and see how a contract is invoked.
  • You can go through all the lessons in about two days and basically have no problem writing the contract
  • You can find a lot of frameworks on the Truffle website and use them directly in Unbox, but I found it easier to configure and use them myself

My project address: Github, feel free to ask questions