HPB主網接入最佳實踐之Java版

一、開始準備html

1.1 學習門檻java

  • 熟悉Java的基本語法和使用
  • 熟悉Java的IDE工具基本使用(Eclipse,IDEA)
  • 熟悉Git版本管理的基本語法和使用
  • 熟悉SpingBoot開發(本Demo提供的是基於Springboot的源碼)
  • 熟悉區塊鏈的基本原理
  • HPB主網如何介入請前往https://www.hpb.io/client瞭解

1.2 環境準備node

  • JDK1.8以上版本
  • Eclipse4.7或者以上
  • Eclipse安裝了Git插件
  • Eclipse安裝了Spring插件
  • HPB主網接入的JAVA SDK請前往這裏地址下載:https://www.hpb.io/client
  • 由於是maven工程,會從網絡中下載工程依賴的jar寶,因此須要機器處於聯網狀態

1.3 源碼地址git

https://github.com/loglos/web3-hpb-test.git

二、開始實踐github

2.1 經過Eclipse Import 演示代碼web

  • 由於上傳到Github的代碼是不包括代碼工程配置信息的,因此須要進行簡單的調整。
  • 源碼工程是基於maven的類型,能夠右鍵工程代碼,選擇「configure/convert to maven projects"。
  • 轉換成功後,系統就能識別爲maven類型的工程了。
  • 提醒:轉換爲maven工程後,不少依賴的jar包都是經過pom.xml來配置管理的,同時若是本地沒安裝過maven的本地倉庫,第一次會默認從遠程的拉取依賴jar包,速度比較慢,若是工程報錯,須要多嘗試幾回。

2.2 改變代碼工程的屬性spring

  • 由於上傳到Github的代碼是不包括代碼工程配置信息的,因此須要進行簡單的調整。
  • 源碼工程是基於maven的類型,能夠右鍵工程代碼,選擇「configure/convert to maven projects"。
  • 轉換成功後,系統就能識別爲maven類型的工程了。
  • 提醒:轉換爲maven工程後,不少依賴的jar包都是經過pom.xml來配置管理的,同時若是本地沒安裝過maven的本地倉庫,第一次會默認從遠程的拉取依賴jar包,速度比較慢,若是工程報錯,須要多嘗試幾回。

2.3 源碼關鍵配置信息說明
打開maven配置文件pom.xml
<!--
其餘的配置不須要修改,這裏說明下,引用的事HPB主網的JAVA版本SDK
-->網絡

<dependency>
        <groupId>io.hpb.web3</groupId>
        <artifactId>web3-hpb</artifactId>
        <version>1.0.0</version>
    </dependency>

打開application.properties文件,配置文件能夠根據須要進行修改,也能夠不進行修改。 這裏羅列了重要的幾個配置屬性進行說明。併發

指定工程發佈後訪問名稱
spring.application.name=HpbWeb3Test

工程發佈後的訪問服務端口
server.port=9988
server.servlet.path=/
server.use-forward-headers=true
server.servlet.context-path=/HpbWeb3Test
server.servlet.application-display-name=hpb web3 test application
web3.admin-client=true
web3.httpTimeoutSeconds=600

指定的鏈接HPB主網的RPC網址,這裏是主網正式網的開放的RPC地址
經過訪問這個地址,能夠進行經過Java操做RPC命令,直接和HPB主網進行交互。
web3.client-address=http://pub.node.hpb.io/

打開HpbWeb3Controller.java文件,這裏是本次演示的具體代碼,這裏對關鍵代碼進行下說明。app

//注意這裏,是引用了HPB主網提供的Java SDK包,裏面封裝瞭如何經過RPC方式與底層交互的方法
import io.hpb.web3.abi.datatypes.Address;
import io.hpb.web3.abi.datatypes.DynamicArray;
import io.hpb.web3.abi.datatypes.generated.Bytes32;
import io.hpb.web3.contract.HpbNodes;
import io.hpb.web3.crypto.Credentials;
import io.hpb.web3.crypto.RawTransaction;
import io.hpb.web3.crypto.WalletUtils;
import io.hpb.web3.protocol.admin.Admin;
import io.hpb.web3.protocol.core.DefaultBlockParameterName;
import io.hpb.web3.protocol.core.methods.response.HpbBlockNumber;
import io.hpb.web3.protocol.core.methods.response.HpbGetBalance;
import io.hpb.web3.protocol.core.methods.response.HpbGetTransactionCount;
import io.hpb.web3.protocol.core.methods.response.HpbGetTransactionReceipt;
import io.hpb.web3.protocol.core.methods.response.HpbSendTransaction;
import io.hpb.web3.protocol.core.methods.response.TransactionReceipt;
import io.hpb.web3.tuples.generated.Tuple4;
import io.hpb.web3.tx.ChainId;
import io.hpb.web3.tx.RawTransactionManager;
import io.hpb.web3.utils.Convert;
import io.hpb.web3.utils.Numeric;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/")
public class HpbWeb3Controller{
    
    //輸出日誌
    private static Log log = LogFactory.getLog(HpbWeb3Controller.class);
    //超時時間
    private final long WEB3J_TIMEOUT = 3;
    
    //演示的HPB帳號地址
    private final String contractAddr = "0x7be6aa25600feed355b79b6a4e14dcdb0bd529cb";
    
    //設置帳號的餘額單位爲18GWEI
    private final BigInteger gasPrice = Convert.toWei("18", Convert.Unit.GWEI).toBigInteger();
    //設置默認的GasLimit
    private final BigInteger gasLimit = new BigInteger("95000000");
    
    
    @Autowired
    private Admin admin;
    @ApiOperation(value="經過根據交易hash查詢交易收據",notes = "過根據交易hash查詢交易收據"
            + " reqStrList [  參數1:交易hash]")
    @PostMapping("/QueryByHash")
    public List<Object> QueryByHash(@RequestBody List<String> reqStrList)throws Exception{
        List<Object> list=new ArrayList<Object>();
        if(reqStrList!=null&&reqStrList.size()>0) {
            String transactionHash = reqStrList.get(0);
            
            //初始化封裝的Java SDK包裏的方法;經過初始化HpbGetTransactionReceipt,能夠得到指定帳號的交易數據
            HpbGetTransactionReceipt receipt = admin.hpbGetTransactionReceipt(transactionHash).send();
            if(!receipt.hasError()) {
                TransactionReceipt transactionReceipt = receipt.getResult();
                if(transactionReceipt.isStatusOK()) {
                    list.add(transactionReceipt);
                }
            }
        }
        return list;
    }
    
    
    @ApiOperation(value="得到當前區塊號",notes = "得到當前區塊號")
    @PostMapping("/getCurrentBlock")
    public List<Object> getCurrentBlock()throws Exception{
        List<Object> list=new ArrayList<Object>();
        
        //初始化封裝的Java SDK包裏的方法;經過HpbBlockNumber獲取當前區塊的對象內容
        HpbBlockNumber blockNumber = admin.hpbBlockNumber().sendAsync().get(WEB3J_TIMEOUT, TimeUnit.MINUTES);
        list.add(blockNumber);
        return list;
    }
    @ApiOperation(value="得到當前帳戶的Nonce",notes = "得到當前帳戶的Nonce"
            + " reqStrList [ 參數1:帳戶地址;")
    @PostMapping("/getCurrentNonce")
    public List<Object> getCurrentNonce(@RequestBody List<String> reqStrList)throws Exception{
        List<Object> list=new ArrayList<Object>();
        if(reqStrList!=null&&reqStrList.size()>0) {
            String address =reqStrList.get(0);
            
            //初始化封裝的Java SDK包裏的方法;經過HpbGetTransactionCount獲取當前帳號Nonce
            //Nonce是帳戶的隨機數:在一個帳戶中的防止多重交易的用途。
            HpbGetTransactionCount transactionCount = admin.hpbGetTransactionCount(address, 
                    DefaultBlockParameterName.PENDING).sendAsync().get(WEB3J_TIMEOUT, TimeUnit.MINUTES);
            BigInteger nonce = transactionCount.getTransactionCount();
            log.info(nonce);
            list.add(nonce);
        }
        return list;
    }
    
    
    
    @ApiOperation(value="得到當前帳戶的餘額",notes = "得到當前帳戶的餘額"
            + " reqStrList [ 參數1:帳戶地址; ]")
    @PostMapping("/getBalance")
    public List<Object> getBalance(@RequestBody List<String> reqStrList)throws Exception{
        List<Object> list=new ArrayList<Object>();
        if(reqStrList!=null&&reqStrList.size()>0) {
            String address =reqStrList.get(0);
            
            //初始化封裝的Java SDK包裏的方法;經過HpbGetBalance獲取當前帳號的餘額。
            HpbGetBalance balance = admin.hpbGetBalance(address, DefaultBlockParameterName.LATEST).send();
            log.info(balance);
            list.add(balance);
        }
        return list;
    }
    
    
    
    @ApiOperation(value="發送交易",notes = "發送交易"
            + " reqStrList [ 參數1:帳戶keystore地址; 參數2:密碼; 參數3:接收帳戶地址;參數4:轉帳金額;]")
    @PostMapping("/sendTransaction")
    public List<Object> sendTransaction(@RequestBody List<String> reqStrList)throws Exception{
        List<Object> list=new ArrayList<Object>();
        if(reqStrList!=null&&reqStrList.size()>3) {
            //獲取指定帳號的keystore
            String keystore =reqStrList.get(0);
            
            //獲取用戶輸入發送交易的帳號密碼
            String password =reqStrList.get(1);
            
            //加載私鑰對象
            Credentials credentials = WalletUtils.loadCredentials(password, keystore);
            
            //建立交易管理對象
            RawTransactionManager transactionManager=new RawTransactionManager(admin, credentials, ChainId.MAINNET);
            
            //獲取nonce
            HpbGetTransactionCount transactionCount = admin.hpbGetTransactionCount(credentials.getAddress(), 
                    DefaultBlockParameterName.PENDING).sendAsync().get(WEB3J_TIMEOUT, TimeUnit.MINUTES);
            
            BigInteger nonce = transactionCount.getTransactionCount();
            
            //獲取目標地址
            String to =reqStrList.get(2);
            
            //轉帳金額
            String value =reqStrList.get(3);
            
            //建立交易對象
            RawTransaction rawTransaction = RawTransaction.createTransaction(
                    nonce,
                    gasPrice,
                    gasLimit,
                    to,
                    Convert.toWei(value, Convert.Unit.HPB).toBigInteger(),
                    "");
                
            //簽名併發送交易
            HpbSendTransaction transaction = transactionManager.signAndSend(rawTransaction);
            log.info(transaction.getTransactionHash());
            list.add(transaction);
        }
        return list;
    }
    
    
    
    @ApiOperation(value="調用HpbNodes智能合約",notes = "調用HpbNodes智能合約"
            + " reqStrList [ 參數1:帳戶keystore地址; 參數2:密碼]")
    @PostMapping("/invokeHpbNodes")
    public List<Object> invokeHpbNodes(@RequestBody List<String> reqStrList)throws Exception{
        List<Object> list=new ArrayList<Object>();
        if(reqStrList!=null&&reqStrList.size()>1) {
            String keystore =reqStrList.get(0);
            String password =reqStrList.get(1);
            Credentials credentials = WalletUtils.loadCredentials(password, keystore);
            RawTransactionManager transactionManager=new RawTransactionManager(admin, credentials, ChainId.MAINNET);
            HpbNodes hpbNodes = HpbNodes.load(contractAddr, admin, transactionManager, gasPrice, gasLimit);
            //調用智能合約
            Tuple4<DynamicArray<Address>, DynamicArray<Bytes32>, DynamicArray<Bytes32>, DynamicArray<Bytes32>> send = 
                    hpbNodes.getAllHpbNodes().send();
            Bytes32 bytes32 = send.getValue2().getValue().get(1);
            log.info(Numeric.toHexStringNoPrefix(bytes32.getValue()));
            Bytes32 bytes321 = send.getValue3().getValue().get(1);
            log.info(Numeric.toHexStringNoPrefix(bytes321.getValue()));
            Bytes32 bytes322 = send.getValue3().getValue().get(1);
            log.info(Numeric.toHexStringNoPrefix(bytes322.getValue()));
            list.add(send);
        }
        return list;
    }
    
}

2.4 運行程序和調試

2.4.1 發佈程序

找到和選擇好Web3HpbTestApplication類,右擊」Run as /Spring Boot App" 啓動成功後,系統會出現相似以下提示:
提示:

2019-01-09 10:49:18.538 HpbWeb3Test [main] INFO  io.hpb.web3.Web3HpbTestApplication Caller+0     at org.springframework.boot.StartupInfoLogger.logStarting(StartupInfoLogger.java:50)
 - Starting Web3HpbTestApplication on jason-hpbdeMBP with PID 46179 (/Users/hpb2017/git/web3-hpb-test/target/classes started by hpb2017 in /Users/hpb2017/git/web3-hpb-test)
2019-01-09 10:49:18.540 HpbWeb3Test [main] DEBUG io.hpb.web3.Web3HpbTestApplication Caller+0     at org.springframework.boot.StartupInfoLogger.logStarting(StartupInfoLogger.java:53)
 - Running with Spring Boot v2.1.1.RELEASE, Spring v5.1.3.RELEASE
2019-01-09 10:49:18.542 HpbWeb3Test [main] INFO  io.hpb.web3.Web3HpbTestApplication Caller+0     at org.springframework.boot.SpringApplication.logStartupProfileInfo(SpringApplication.java:675)
 - No active profile set, falling back to default profiles: default
2019-01-09 10:49:20.818 HpbWeb3Test [main] INFO  i.h.w.c.Web3AutoConfiguration Caller+0     at io.hpb.web3.configure.Web3AutoConfiguration.admin(Web3AutoConfiguration.java:51)
 - Building admin service for endpoint: http://pub.node.hpb.io/
2019-01-09 10:49:21.406 HpbWeb3Test [main] INFO  i.h.w.c.Web3AutoConfiguration Caller+0     at io.hpb.web3.configure.Web3AutoConfiguration.Web3(Web3AutoConfiguration.java:42)
 - Building service for endpoint: http://pub.node.hpb.io/
2019-01-09 10:49:22.057 HpbWeb3Test [main] INFO  io.hpb.web3.Web3HpbTestApplication Caller+0     at org.springframework.boot.StartupInfoLogger.logStarted(StartupInfoLogger.java:59)
 - Started Web3HpbTestApplication in 3.943 seconds (JVM running for 5.429)

2.4.2 測試驗證接口

Springboot的接口能夠經過自帶的swagger插件進行訪問和測試。 打開本地訪問地址:http://localhost:9988/HpbWeb3Test/swagger-ui.html#/ 會顯示如目前系統開放的測試接口,而後選擇點擊「hpb-web-3-controller」,接入該接口的具體方法測試界面。 點擊「/getBalance」方法,點擊「Try it out」開啓編輯模式,輸入你要查詢餘額的HPB地址;而後點擊「Execute」開始執行。 系統會顯示執行的結果,注意這裏獲取的餘額顯示的是科學計數法。 其餘的接口能夠依次根據接口的內容進行測試。

更多技術諮詢

1.若是你想了解更多關於HPB的技術信息,請訪問咱們的GitHub WiKi:

HPB WiKi of GitHub

2.若是你想得到更多HPB信息,請關注咱們的官方網站:

HPB Website

相關文章
相關標籤/搜索