当前位置: 首页 > 工具软件 > XuperChain > 使用案例 >

xuperchain java SDK笔记

汤跃
2023-12-01

百度超级链,测试笔记。
linux Ubuntu 18.04
首先需要安装go环境和g++环境,然后设置好gopath,我这里的gopath在~/go(通过go env查看)

# 建立下载源码目录并切换到目录下
mkdir ~/go/src/github.com/xuperchain/ 
cd ~/go/src/github.com/xuperchain/
# 下载代码
git clone https://github.com/xuperchain/xuperchain.git
# 切换带稳定版本
cd ./xuperchain
git checkout v3.9
# 编译文件-->编译成功后会在文件夹下多一个output文件夹
make
#  创建链
cd output
./xchain-cli createChain

运行成功会得到下面的结果:

# 根据系统合约开始创建区块链
t=2021-01-05T09:04:02+0000 lvl=dbug msg="create block chain by contract" module=xchain from=xuper toCreate=xuper
# 账本数据库配置
t=2021-01-05T09:04:02+0000 lvl=info msg="Allocated cache and path fds" database=data/blockchain/xuper/ledger cache=128 fds=1024
# 账本元设置
t=2021-01-05T09:04:02+0000 lvl=info msg="ledger meta" module=xchain genesis_block= tip_block= trunk_height=0
# 开始进行确认块的操作
t=2021-01-05T09:04:02+0000 lvl=trce msg="Start to ConfirmBlock" module=xchain
# 生成创世区块
t=2021-01-05T09:04:02+0000 lvl=info msg="begin format genesis block" module=xchain
t=2021-01-05T09:04:02+0000 lvl=info msg="start to confirm block" module=xchain blockid=0dc6bf376327ecffb01aaf1571c6282f0c262707b91058bffa790bf224d5004a txCount=1
t=2021-01-05T09:04:02+0000 lvl=dbug msg="print block size when confirm block" module=xchain blockSize=1563 blockid=0dc6bf376327ecffb01aaf1571c6282f0c262707b91058bffa790bf224d5004a
t=2021-01-05T09:04:02+0000 lvl=dbug msg="confirm block cost" module=xchain blkTimer="saveHeader: 0.08 ms,saveAllTxs: 0.12 ms,saveToDisk: 0.08 ms,total: 0.49ms"
t=2021-01-05T09:04:02+0000 lvl=info msg="ConfirmBlock Success" module=xchain Height=1
# utxoVM数据库配置
t=2021-01-05T09:04:02+0000 lvl=info msg="Allocated cache and path fds" database=data/blockchain/xuper/utxoVM cache=128 fds=1024
# utxo费用估计
t=2021-01-05T09:04:02+0000 lvl=info msg="utxo total is estimated" module=xchain total=0
t=2021-01-05T09:04:02+0000 lvl=dbug msg="debug tx" module=xchain txid=6abe2deac8f7ed97eb53806207775730d488ea7f8d3e1a63d241df8f822b1fec
t=2021-01-05T09:04:02+0000 lvl=dbug msg=txoutput module=xchain offset=0 addr=dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN amount=100000000000000000000
t=2021-01-05T09:04:02+0000 lvl=dbug msg="hit queryblock cache" module=xchain blkid=0dc6bf376327ecffb01aaf1571c6282f0c262707b91058bffa790bf224d5004a
t=2021-01-05T09:04:02+0000 lvl=info msg="unconfirm table size" module=xchain unconfirmTxMap=0
t=2021-01-05T09:04:02+0000 lvl=dbug msg="autogen tx list size, before play block" module=xchain len=0
# 执行交易
t=2021-01-05T09:04:02+0000 lvl=trce msg="  start to dotx" module=xchain txid=6abe2deac8f7ed97eb53806207775730d488ea7f8d3e1a63d241df8f822b1fec
t=2021-01-05T09:04:02+0000 lvl=trce msg="    insert utxo key" module=xchain utxoKey=UdpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN_6abe2deac8f7ed97eb53806207775730d488ea7f8d3e1a63d241df8f822b1fec_0 amount=100000000000000000000
t=2021-01-05T09:04:02+0000 lvl=dbug msg="autogen tx list size, after play block" module=xchain len=0
t=2021-01-05T09:04:02+0000 lvl=info msg="Database closed" database=data/blockchain/xuper/utxoVM
t=2021-01-05T09:04:02+0000 lvl=info msg="Database closed" database=data/blockchain/xuper/ledger

**或者使用docker镜像:**目前在xuperchain目录下
没有fanqiang的化需要可能需要修改镜像源加速:
在当前目录下:

vi sources.list
# 添加下面两行后退出
deb http://mirrors.ustc.edu.cn/debian stable main contrib non-free
deb http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free

#然后需要编辑docker文件
vi Dockerfile
# 添加了第2、3行代码,然后保存退出
FROM golang:1.12.5 AS builder
WORKDIR /etc/apt/
ADD sources.list ./
RUN apt update
WORKDIR /go/src/github.com/xuperchain/xuperunion
COPY . .
RUN make

# ---
FROM ubuntu:16.04
WORKDIR /home/work/xuperunion/
COPY --from=builder /go/src/github.com/xuperchain/xuperunion/output/ .
EXPOSE 37101 47101
CMD ./xchain-cli createChain && ./xchain

修改完成后,开始创建镜像:最后得到成功标记==>Successfully tagged xuperchain:latest

# 创建镜像,使用-t设置镜像名字
docker build . -t xuperchain
# 运行镜像 :-d, 表示后台运行;-p,指定端口映射
docker run -d -p 37101:37101 -p 47101:47101 --rm --name xchain xuperchain

使用java SDK测试代码:

package cn.timechainer.xuperchain;

import com.baidu.xuper.api.Account;
import com.baidu.xuper.api.Transaction;
import com.baidu.xuper.api.XuperClient;
import com.baidu.xuper.pb.XchainOuterClass;
import org.bouncycastle.util.encoders.Hex;
import org.junit.Assert;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class HyperChain {

    private static Account account;
    private static XuperClient client;
    public static final String DEFAULT_URL = "192.168.182.10:37101";
//    public static final String SDK_PATH = "/Users/renhuikang/workspace/xuperchain/xuperchain/src/main/resources/conf/sdk.yaml";
    // 使用绝对路径
    public static final String KEYS_PATH = "/Users/renhuikang/workspace/xuperchain/xuperchain/src/main/resources/data/keys";
    public static final String CONTRACT_ACCOUNT = "1111111111111111";
    public static final String CODE_1_PATH = "/Users/renhuikang/workspace/xuperchain/xuperchain/src/main/resources/data/counter.wasm";

    public static void main(String[] args) throws IOException {
        System.out.println("Start Xuperchain.");
//        Config.setConfigPath(SDK_PATH);

        // 创建客户端
        client = new XuperClient(DEFAULT_URL);

//        getAccout();  //获取新账户

        // 导入用户密钥和账号,设置账号
        account = Account.create(KEYS_PATH);
        getAccout(account);

        // 创建合约账号并进行转账操作,然后查询余额
        String acntNm = "XC" + CONTRACT_ACCOUNT + "@xuper";
//        createContractAccount(acntNm);

        // 部署智能合约
        try {
            deployContract(acntNm);
        } catch (Exception e){
            System.out.println(e.toString());
        }

        // 调用智能合约
        for (int i=0; i < 0; i++) {
            invokeContract(acntNm);
        }

        // 查询智能合约
//        queryContract(acntNm);

        // 获取指定区块链的状态
//        XchainOuterClass.BCStatus statu = client.getBlockchainStatus("xuper");
//        System.out.println(statu);

    // 根据区块高度,获取区块
//        XchainOuterClass.SystemsStatus systemStatus = client.getSystemStatus();
//        System.out.println("获取系统状态:\n" + systemStatus);

        String blockID = "1a76703d9a0b807d74cf11f5a5d4eba5292b3f963de794a3f0e64bbaa72db218";
//        getRltByBlkID(blockID);
//      {"blockid":"1a76703d9a0b807d74cf11f5a5d4eba5292b3f963de794a3f0e64bbaa72db218"}

        //      根据tx ID查询交易内容
        String txid = "495a5ffcffc36ac4f5da0272d256ef4554d0c6d6f0b16101a10e2d47e52dbbb2";
//        getRltByTxID(txid);

//        38880
//        testEncoding();
    }

    private static void testEncoding() {
        XchainOuterClass.InternalBlock getBlockByID = client.queryBlock("1a76703d9a0b807d74cf11f5a5d4eba5292b3f963de794a3f0e64bbaa72db218");
        System.out.println(getBlockByID);
        // then I will get sign: "0E\002!\000\306M\331{fx\365\221g\333dr\320\376\214i-V\v#\356\231\333\3064\214\251pga\333\\\002 f\362\210AH\367%\0206\v\306\\\006\"\243?N#J\323\253-\350\216\v@\3106\233\'\324\023"

        // I use client to find this sign is as follows.
        String standard_sign = "3045022100c64dd97b6678f59167db6472d0fe8c692d560b23ee99dbc6348ca9706761db5c022066f" +
                "2884148f72510360bc65c0622a33f4e234ad3ab2de88e0b40c8369b27d413";
        // I find it`s not a String ==> "0E\002!\000\306M\331{fx\365\221g\333dr\320\376\214i-V\v#\356\231\333\3064\214\251pga\333\\\002 f\362\210AH\367%\0206\v\306\\\006\"\243?N#J\323\253-\350\216\v@\3106\233\'\324\023"
        // Maybe this is a bug
//       String sign = "0E\002!\000\306M\331{fx\365\221g\333dr\320\376\214i-V\v#\356\231\333\3064\214\251pg" +
//                "a\333\\\002 f\362\210AH\367%\0206\v\306\\\006\"\243?N#J\323\253-\350\216\v@\3106\233\'\324\023";
        // I try to transform the '\'
        String sign = "0E\002!\000\306M\331{fx\365\221g\333dr\320\376\214i-V\\v#\356\231\333\3064\214\251pg" +
                "a\333\\\002 f\362\210AH\367%\0206\\v\306\\\006\"\243?N#J\323\253-\350\216\\v@\3106\233\'\324\023";
//        String sign = "\017B@";
        // then encoding it to hex
        String strByByte = Hex.toHexString(sign.getBytes(StandardCharsets.ISO_8859_1));
        System.out.println("\"use ISO_8859_1 transform to standard format:\n" + strByByte);
        // find they are almost equal
        Assert.assertEquals(standard_sign, strByByte);
    }
    
    private static void getRltByTxID(String txid) {
        System.out.println("进行查询的tx ID:\n" + txid);
        System.out.println("根据tx ID查询Tx详情\n" + client.queryTx(txid));
        XchainOuterClass.Transaction txresult = client.queryTx(txid);
        // 得到的tx id等呈现以下的显示,需要hex编码一下,输出才是可读的
        System.out.println(txresult.toString());
        String gotStr = "IZ_\374\377\303j\304\365\332\002r\322V\357ET\320\306\326\360\261a\001\241\016-G\345-\273\262";
        // 设置的tx id号
        System.out.println("拿到的乱码Tx ID:\n" + gotStr);

        // 需要使用 ISO_8859_1 转换为标准的格式

//      // 或者可以直接拿到Tx ID
        System.out.println("根据client的查询结果拿到tx ID:\n" + Hex.toHexString(txresult.getTxid().toByteArray()));
        System.out.println("根据client的查询结果拿到block ID:\n" + Hex.toHexString(txresult.getBlockid().toByteArray()));

    }

    private static void getRltByBlkID(String blockID) {
        XchainOuterClass.InternalBlock getBlockByID = client.queryBlock(blockID);
        int blkTxCnt = getBlockByID.getTransactionsCount();
        System.out.println("根据block ID获取当前块的高度:\n" + getBlockByID.getHeight());
        System.out.println("获取当前块中交易总数:\n" + blkTxCnt);
        // 输出当前块中的每笔交易
        for(int i=0; i<blkTxCnt; i++)
            System.out.println("打印第" + (i + 1) + "笔交易:\n" + getBlockByID.getTransactions(i));
        System.out.println("打印整个块的内容:\n" + getBlockByID.toString());
        System.out.println("直接获取签名:\n" + Hex.toHexString(getBlockByID.getSign().toByteArray()));


    }

    private static void queryContract(String acntNm) throws IOException {
        account.setContractAccount(acntNm);
        Map<String, byte[]> args = new HashMap<>();
        args.put("creator", "TimeChainer".getBytes());

        byte[] code = Files.readAllBytes(Paths.get(CODE_1_PATH));
        Transaction queryResult = client.queryContract(account, "wasm", "counter", "increase", args);
        System.out.println(queryResult.getRawTx());
    }

    private static void invokeContract(String acntNm) {
        Map<String, byte[]> args = new HashMap<>();
        args.put("creator", "TimeChainer".getBytes());
        Transaction tx = client.invokeContract(account, "wasm", "counter", "increase", args);
        System.out.println("txid: " + tx.getTxid());
        System.out.println("response: " + tx.getContractResponse().getBodyStr());
        System.out.println(client.getBalance(account.getAddress()));
        System.out.println("gas: " + tx.getGasUsed());
        System.out.println(client.getBalance(account.getAddress()));

    }

    private static void deployContract(String acntNm) throws IOException {
        // 设置合约账户
        account.setContractAccount(acntNm);
        Map<String, byte[]> args = new HashMap<>();
        args.put("creator", "TimeChainer".getBytes());
        // 读取合约代码
        byte[] code = Files.readAllBytes(Paths.get(CODE_1_PATH));
        // 部署合约
        client.deployWasmContract(account, code, "counter", "c", args);
    }

    private static void createContractAccount(String acntNm) {
//        // 创建合约账号
//        client.createContractAccount(account, "1111111111111111");
        // 进行操作
        Transaction transaction = client.transfer(account, acntNm, BigInteger.valueOf(10), "1");

        // 查询账户余额
        BigInteger totalBalance = client.getBalance(acntNm);
        System.out.println("余额:" + totalBalance.toString());

        // 根据TXid进行查询
        XchainOuterClass.Transaction tx = client.queryTx(String.valueOf(transaction.getTxid()));
        System.out.println(tx.toString());

        // 查询账户余额细明
        XuperClient.BalDetails[] balanceDetails = client.getBalanceDetails(acntNm);
        System.out.println(Arrays.toString(balanceDetails));
    }

    private static void getAccout() {
        Account account1 = Account.create(2, 2);
        // 个人账号AK是根据公钥计算得出的
        System.out.println("new account:" + account1.getAddress());
        System.out.println("Mnemonic:" + account1.getMnemonic());
        System.out.println("Contract Account:" + account1.getContractAccount());
        System.out.println("AKAddress:" + account1.getAKAddress());
        System.out.println("Key Pair:" + account1.getKeyPair());
        System.out.println("Auth Require Id:" + account1.getAuthRequireId());
    }

    private static void getAccout(Account account) {
        // 个人账号AK是根据公钥计算得出的
        System.out.println("new account:" + account.getAddress());
        System.out.println("Mnemonic:" + account.getMnemonic());
        System.out.println("Contract Account:" + account.getContractAccount());
        System.out.println("AKAddress:" + account.getAKAddress());
        System.out.println("Key Pair:" + account.getKeyPair());
        System.out.println("Auth Require Id:" + account.getAuthRequireId());
    }

}
  • keys目录内容:
    • keys/address :
    bXkw4oZjFYCW73EosvCd5sAJxRMKQxUESA
    
    • keys/private.key :
    {"Curvname":"P-256","X":104082726948534932813204477920545959895835827891467170025712995456012291735024,"Y":65892841469516497066746293856979391691642178656783768469706183925618771224751,"D":15055248704862121515543626852270188975273362761271739917069698697953652540247}
    
    • keys/public.key :
    {"Curvname":"P-256","X":104082726948534932813204477920545959895835827891467170025712995456012291735024,"Y":65892841469516497066746293856979391691642178656783768469706183925618771224751}
    
 类似资料: