springboot中使用web3j監(jiān)聽智能合約事件

智能合約執(zhí)行后有時需要在后臺監(jiān)聽相應的事件。本文將介紹下如何在springboot中使用web3j庫監(jiān)聽智能合約的事件

導入web3j的包

在 pom.xml 文件中添加如下依賴

<dependency>
            <groupId>org.web3j</groupId>
            <artifactId>core</artifactId>
            <version>3.3.1</version>
</dependency>

將web3j對象放入spring容器中管理

新建 ContractConfig.java 文件,代碼注釋比較詳細,參考注釋
注意不能是單例模式,還有合約地址的格式也要注意。

package io.liqiangz.config;

import io.liqiangz.contract.Trace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.admin.Admin;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.Request;
import org.web3j.protocol.core.methods.request;
import org.web3j.protocol.core.methods.request.EthFilter;
import org.web3j.protocol.core.methods.response.AnmoBlockNumber;
import org.web3j.protocol.core.methods.response.EthBlockNumber;
import org.web3j.protocol.core.methods.response.Web3ClientVersion;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.ClientTransactionManager;
import org.web3j.tx.ManagedTransaction;
import org.web3j.tx.TransactionManager;

import java.io.IOException;
import java.math.BigInteger;

/**
 * 智能合約
 */
@Configuration
public class ContractConfig {

    //智能合約部署地址
    private String contractAddress = "0xaf0895260ef377ceea0086c99e3eff7999f742c9";

    @Bean
    @Scope("prototype")
    public Web3j web3j() {
        return Web3j.build(new HttpService("http://192.168.0.104:15450"));
    }

    @Bean
    @Autowired
    public Trace trace(Web3j web3j) throws IOException {
        Trace contract;
        try {
            Web3ClientVersion web3ClientVersion = web3j.web3ClientVersion().send();
            String clientVersion = web3ClientVersion.getWeb3ClientVersion();
            System.out.println("clientVersion" + clientVersion);
            // 以某個用戶的身份調(diào)用合約
            TransactionManager transactionManager = new ClientTransactionManager(web3j, "0x24602722816b6cad0e143ce9fabf31f6026ec622"); 
            //加載智能合約
            contract = Trace.load(contractAddress, web3j, transactionManager, ManagedTransaction.GAS_PRICE, org.web3j.tx.Contract.GAS_LIMIT);
            return contract;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
            //throw new RRException("連接智能合約異常");
        }
    }

    @Bean
    //監(jiān)聽這里才用每次都生成一個新的對象,因為同時監(jiān)聽多個事件不能使用同一個實例
    @Scope("prototype")
    @Autowired
    public EthFilter ethFilter(Trace trace, Web3j  web3j) throws IOException {
        //獲取啟動時監(jiān)聽的區(qū)塊
        Request<?, EthBlockNumber> request = web3j.ethBlockNumber();
        BigInteger fromblock = request.send().getBlockNumber();
        return new EthFilter(DefaultBlockParameter.valueOf(fromblock),
                //如果監(jiān)聽不到這里的地址可以把 0x 給去掉
                DefaultBlockParameterName.LATEST, trace.getContractAddress());
    }

}

在spring啟動時啟動監(jiān)聽

啟動監(jiān)聽,注意監(jiān)聽一個就要注入一個監(jiān)聽器,不能共用一個監(jiān)聽器。

/**
 * 服務監(jiān)聽器,繼承ApplicationRunner,在spring啟動時啟動
 * @author liqiang
 */
@Component
public class ServiceRunner implements ApplicationRunner {
    /**
     * 日志記錄
     */
    private Logger log = LoggerFactory.getLogger(ServiceRunner.class);
    

    @Autowired
    private Web3j web3j;

    //如果多個監(jiān)聽,必須要注入新的過濾器
    @Autowired
    private EthFilter uploadProAuth;

    @Override
    public void run(ApplicationArguments var1) throws Exception{
        uploadProAuth();
        this.log.info("This will be execute when the project was started!");
    }


    /**
     * 收到上鏈事件
     */
    public void uploadProAuth(){
        Event event = new Event("uploadProAuthEvent",
                Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}),
                Arrays.<TypeReference<?>>asList(new TypeReference<Bytes32>() {},
                        new TypeReference<Uint32>() {}));

        uploadProAuth.addSingleTopic(EventEncoder.encode(event));
        log.info("啟動監(jiān)聽uploadProAuthEvent");
        web3j.ethLogObservable(uploadProAuth).subscribe(log -> {
            this.log.info("收到事件uploadProAuthEvent");
            EventValues eventValues = staticExtractEventParameters(event, log);
            Trace.UploadProAuthEventEventResponse typedResponse = new Trace.UploadProAuthEventEventResponse();
            typedResponse._fromaddr = (String) eventValues.getIndexedValues().get(0).getValue();
            typedResponse._product_id = (byte[]) eventValues.getNonIndexedValues().get(0).getValue();
            typedResponse._rand_number =  (BigInteger)eventValues.getNonIndexedValues().get(1).getValue();
        });

    }
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 希望明天是美好的一天??
    Fortytwoy閱讀 143評論 0 0
  • 這幾天生理期,沒怎么監(jiān)測體重,元旦那天有一天稱重,102.8。離自己預計目標100差不多還有3斤。相當于12月份,...
    綻蕊向陽閱讀 349評論 0 1
  • [強]完美成交的十大步驟之五:塑造產(chǎn)品的價值。[OK][OK][OK] 顧客如果感覺貴,就是因為你沒有把產(chǎn)品的價值...
    簡易讀書閱讀 663評論 0 0
  • 特別珍惜的是那份真心, 愛娘老遠從武穴過來看我了, 幫我解決我的問題。 今天4點多到火車站接她, 然后一路過來看我...
    作家阿紫閱讀 366評論 0 0

友情鏈接更多精彩內(nèi)容