一个完整的Vue+web3.js(基于Metamask开发测试和正式上线!)
FirstContract.sol文件
pragma solidity >=0.4.24 < 0.7.0;
contract FirstContract {
string public fName;
uint public age;
event eventInfo(string fName,uint age);
function setInfo(string memory _fName, uint _age) public {
fName = _fName;
age = _age;
emit eventInfo(fName,age);
}
function getInfo() public view returns (string memory, uint) {
return (fName, age);
}
}
eth_web.js文件
* 说明:Vue+truffle+web3.js(1.0版本)开发的以太坊区块链案例!
* 注意:本案例是vue+纯web3.js案例(不能同时导入truffle-contract库)
* vue中无法使用web3.js的HttpProvider;官方解释:因为它不支持订阅,所以被弃用!
* vue开发web3.js主要为了兼容Metamask,所以此案例仅保留了浏览器识别的Web3.givenProvider提供者!
const Web3 = require( 'web3' );
// 导入FirstContract.sol智能合约的ABI编码数据!
const first_contract_json = require( '@/plugins/my_plugins/web3/truffle/build/contracts/FirstContract.json' );
class FirstContractWeb3 {
constructor () {
this.contract_addr = '0x1224890D56aFb04F2b84151aa740ef4E8aF84cdb';
this.from_addr = '0xEB1b0DFFae2f691700d88E116b44e3C88FFE469F';
this.base_transaction = {
'from': this.from_addr,
'gas': 1000000,
};
this.init_web3_1_0_version();
// this.init_contract_web3_deploy_1_0_wersion();
this.init_contract_web3_at_1_0_wersion();
}
// web3对象初始化(仅兼容web3.js 1.0版本)
init_web3_1_0_version () {
// 自动使用Metamask插件来调试或正式上线主网!
if (!Web3.givenProvider) {
console.log( '请确保您的浏览器已经安装了MetaMask插件' );
return;
}
this.web3 = new Web3( Web3.givenProvider );
this.listening_web3();
console.log( 'this.web3', this.web3 );
}
listening_web3 () {
this.web3.eth.net.isListening().then( ( result ) => {
console.log( '您正在监听网络:', result );
} );
this.web3.eth.net.getId().then( ( result ) => {
console.log( '您当前网络ID:', result );
} );
}
event_contract ( contract_instance ) {
contract_instance.events.eventInfo( ( error, event ) => {
// 正常情况下这里的(error, event)不会返还任何数据!
console.log( 'eventInfo', error, event );
} ).on( 'data', ( result ) => {
// 这里返回事件的数据,并存放在数组returnValues对象中!
console.log( 'data', result.returnValues );
} ).on( 'changed', ( result ) => {
console.log( 'changed', result );
} ).on( 'error', console.error );
}
/**
* 1、初始化web3.eth.Contract合约
* 2、直接调用truffle手动部署成功的合约实例(合约地址)
* 注意:from发送账户务必注意两点:1、必须存在于区块链上; 2、浏览器访问Metamask的账户必须是发送地址账户!
*/
init_contract_web3_at_1_0_wersion () {
// 基于原生的web3.eth.Contract对象来创建合约(调用合约的方法)
let contract_instance = new this.web3.eth.Contract( first_contract_json.abi, this.contract_addr );
console.log( 'contract_instance合约实例:', contract_instance );
// 调用solidity合约的只读方法,并在EVM中直接执行方法,不需要发送任何交易。因此不会改变合约的状态。
contract_instance.methods.getInfo().call().then( ( result ) => {
console.log( 'get已经执行了' );
console.log( result );
} );
// 向solidity合约发送交易来执行指定方法,将改变合约的状态(必须输入发送交易的账户地址,需要消耗gas)
contract_instance.methods.setInfo( 'kirin2019', 18 ).send( this.base_transaction ).then( ( result ) => {
console.log( 'set已经执行了' );
console.log( 'setInfo返回对象:', result );
} );
/**
* 监听solidity事件一定是先触发在监听的原则
* 务必注意:合约方法内部触发的事件,web3.js先调用合约方法,才能监听到对应的合约事件
* 比如说:在合约内部setInfo方法调用了eventInfo事件,那么web3.js必须先调用了setInfo方法后,再监听events
*/
this.event_contract( contract_instance );
}
init_contract_web3_deploy_1_0_wersion () {
// 基于原生的web3.eth.Contract对象来创建合约(调用合约的方法)
let contract = new this.web3.eth.Contract( first_contract_json.abi );
contract.deploy( { data: first_contract_json.bytecode } )
.send( this.base_transaction ).then( ( instance ) => {
console.log( 'contract_instance合约实例为:', instance );
let contract_instance = instance;
// 调用solidity合约的只读方法,并在EVM中直接执行方法,不需要发送任何交易。因此不会改变合约的状态。
contract_instance.methods.getInfo().call().then( ( result ) => {
console.log( 'get已经执行了' );
console.log( result );
} );
// 向solidity合约发送交易来执行指定方法,将改变合约的状态(必须输入发送交易的账户地址,需要消耗gas)
contract_instance.methods.setInfo( 'kirin2019', 18 ).send( this.base_transaction ).then( ( result ) => {
console.log( 'set已经执行了' );
console.log( result );
} );
/**
* 监听solidity事件一定是先触发在监听的原则
* 务必注意:合约方法内部触发的事件,web3.js先调用合约方法,才能监听到对应的合约事件
* 比如说:在合约内部setInfo方法调用了eventInfo事件,那么web3.js必须先调用了setInfo方法后,再监听events
*/
this.event_contract( contract_instance );
} ).catch( ( error ) => {
throw error;
} );
}
}
// 测试执行!
let first_contract = new FirstContractWeb3();