如何在智能合约中处理事件

时间:2021-01-14 17:19:48

标签: blockchain tronweb

我正在 Shasta 区块链中开发智能合约。我使用 TronWeb 作为前端,TronBox 用于编译和部署,TronLink 用于从我的前端到智能合约的连接。我的问题是,当我将智能合约部署到 Shasta 时,该智能合约的事件不起作用。我不知道这是智能合约的问题还是 TronWeb 库的问题。这是我从 Codeexpert 教程 https://www.youtube.com/watch?v=ESTzlJjp5Dk&list=PLL5pYVd8AWtRDnTTKWzPpFcBT9nrPCQt6&index=5 中获取的智能合约。您可以在此处查看完整的项目https://github.com/ThisIsCodeXpert/Tron-TRX-DApp-Tutorial-Series/tree/master/Tutorial_11/TronLink-Demo-Messages

这是合同:

@Bean
public GsonHttpMessageConverter gsonHttpMessageConverter() {
    GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
    converter.setGson(gson());
    return converter;
}

private Gson gson() {
    final GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(Json.class, new SpringfoxJsonToGsonAdapter());
    return builder.create();
}

public class SpringfoxJsonToGsonAdapter implements JsonSerializer<Json> {

    @Override
    public JsonElement serialize(Json json, Type type, JsonSerializationContext context) {
        return JsonParser.parseString(json.value());
    } 
}

我只想看到 eventVote 被触发并从前端看到它但它不起作用。

这是我在 react 中的 index.js 文件:

pragma solidity >=0.4.22 <0.6.0;

contract Election{

    struct Candidate{
        uint id;
        string name;
        uint voteCount;
    }
    mapping (uint => Candidate) public candidates;
    uint public candidatecount;
    mapping (address => bool) public voter;

    event eventVote(
        uint indexed _candidateid
    );

    constructor () public {
        addCandidate("Alice");
        addCandidate("Bob");
    }

    function addCandidate(string memory _name) private {
        candidatecount++;
        candidates[candidatecount] = Candidate(candidatecount,_name,0);
    }

    function vote(uint _candidateid) public {

        require(!voter[msg.sender]);

        require(_candidateid > 0 && _candidateid <= candidatecount);

        voter[msg.sender] = true;

        candidates[_candidateid].voteCount ++;

        emit eventVote(_candidateid);
    }

}

和utils文件:

import React from 'react';
import TronLinkGuide from 'components/TronLinkGuide';
import TronWeb from 'tronweb';
import Utils from 'utils';
import Swal from 'sweetalert2';
import Content from './Content';

import './App.scss';

const FOUNDATION_ADDRESS = CONTRACT_ADDRESS;

class App extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
              candidates:[],
              hasVoted: false,
              loading: false,

              tronWeb: {
                  installed: false,
                  loggedIn: false
              },
            }

            this.voteCandidate = this.voteCandidate.bind(this)
    }

    async componentDidMount() {

        this.setState({loading:true})
        await new Promise(resolve => {
            const tronWebState = {
                installed: !!window.tronWeb,
                loggedIn: window.tronWeb && window.tronWeb.ready
            };

            if(tronWebState.installed) {
                this.setState({
                    tronWeb:
                    tronWebState
                });

                return resolve();
            }

            let tries = 0;

            const timer = setInterval(() => {
                if(tries >= 10) {
                    const TRONGRID_API = 'https://api.trongrid.io';

                    window.tronWeb = new TronWeb(
                        TRONGRID_API,
                        TRONGRID_API,
                        TRONGRID_API,
                        API_KEY
                    );

                    this.setState({
                        tronWeb: {
                            installed: false,
                            loggedIn: false
                        }
                    });

                    clearInterval(timer);
                    return resolve();
                }

                tronWebState.installed = !!window.tronWeb;
                tronWebState.loggedIn = window.tronWeb && window.tronWeb.ready;

                if(!tronWebState.installed)
                    return tries++;

                this.setState({
                    tronWeb: tronWebState
                });

                resolve();
            }, 100);
        });

        if(!this.state.tronWeb.loggedIn) {
            // Set default address (foundation address) used for contract calls
            // Directly overwrites the address object as TronLink disabled the
            // function call
            window.tronWeb.defaultAddress = {
                hex: window.tronWeb.address.toHex(FOUNDATION_ADDRESS),
                base58: FOUNDATION_ADDRESS
            };

            window.tronWeb.on('addressChanged', () => {
                if(this.state.tronWeb.loggedIn)
                    return;

                this.setState({
                    tronWeb: {
                        installed: true,
                        loggedIn: true
                    }
                });
            });
        }
        await Utils.setTronWeb(window.tronWeb);
        this.fetchData();
        this.startEventListener();
        this.setState({loading:false})

    }

    startEventListener(){
        Utils.contract.eventVote().watch((err) => {

            if(err){
            return console.log('Failed to bind the event', err);
            }

            window.location.reload();
        });

    }

    async fetchData(){
        const CandidateCount = (await Utils.contract.candidatecount().call()).toNumber();
        console.log('CandidateCount', CandidateCount);

        for(var i=1; i<=CandidateCount; i++){

            const candidate_tmp = await Utils.contract.candidates(i).call();
            console.log('candidate_tmp', candidate_tmp);

            const candidates = [...this.state.candidates];

            candidates.push({
                            id: candidate_tmp.id.toNumber(),
                            name: candidate_tmp.name,
                            voteCount: candidate_tmp.voteCount.toNumber()
            });

            this.setState({candidates:candidates})



        }

    }

    voteCandidate(candidateId){

        Utils.contract.vote(candidateId).send({
            shouldPollResponse: true,
            callValue: 0
        }).then(res => Swal({
            title:'Vote Casted',
            type: 'success'
        })).catch(err => Swal({
            title:'Vote Failed',
            type: 'error'

        }));

        this.setState({hasVoted:true})
    }


    render() {
        if(!this.state.tronWeb.installed)
            return <TronLinkGuide />;

        if(!this.state.tronWeb.loggedIn)
            return <TronLinkGuide installed />;

        return (
              <div className='row'>
                <div className='col-lg-12 text-center' >
                  <h1>DAPP Election</h1>
                  <br/>
                  { this.state.loading
                    ? <p className='text-center'>Loading...</p>
                    : <Content
                        candidates={this.state.candidates}
                        hasVoted={this.state.hasVoted}
                        castVote={this.voteCandidate} />
                  }
                </div>
              </div>
        );
    }
}

export default App;

有谁知道为什么我投票时事件没有执行? 感谢您的帮助。

0 个答案:

没有答案