【重磅推荐】vue之web3.js以太坊开发总结与完整案例!

【重磅推荐】vue之web3.js以太坊开发总结与完整案例!

 

一个完整的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();