sb版 java后端(spring boot)应用Conflux Java SDK尝试交互Conflux实录

sb版 java后端(spring boot)应用Conflux-java-尝试链接Conflux实录

能点进这里的我就默认知道conflux是什么了(一个DAG型的高性能低成本区块链)

前排提示:建议chorme浏览器先下一个钱包,然后至少有个账户有点CFX代币,testnet的也行,不然有的地方会报错或没参数写

前排提示2:Dapp都需要一个服务器,nodejs+JavaScript开发的话,向用户发送前端用户数据即可上链,去中心化程度更高,java开发的话上链操作也是后台在做,去中心化程度降低,主要胜在java后端的应用相对比其他语言更普遍。所以用java还是js是很大的区别,建议先考虑清楚

1.Java-conflux-JDK 引用

先下载依赖包,建议用maven项目,在pom的dependencies中加入conflux包的引用

引用地址如下:

https://search.maven.org/search?q=conflux

点击版本号,跳转页面如下

https://search.maven.org/artifact/io.github.conflux-chain/conflux.web3j/1.0.4/jar

页面右侧Apache Maven框中代码复制进自己spring boot项目 pom的dependencies中刷新即可调用conflux包的引用

2.test测试学习和conflux区块链的交互

如下网站有JDK开发者贴出的使用代码,可以在boot项目test中看情况复制实验

https://github.com/Conflux-Chain/java-conflux-sdk

文档中的示范代码有些未说明的细节或小错误,包括:

1)测试–查看现有epoch中url参数错误,可能报错RPC链接错误,下文链接有很多url,对应不同网络,一般建议学习用test先

https://github.com/conflux-fans/conflux-rpc-endpoints

我用的链接:http://testnet.cfxchain.xyz:12537/rpc/

2)有些类不知道在哪里,介绍也比较模糊,建议IDE直接ctrl+方法or类名,比如 RawTransaction类,ctrl+调用其的test_addtrss ,看到函数原型,再点参数就可看到类原型

3)有个参数是“password”,这个 AccountManager.import(privateKey, password);需要密码,这里是 chorme钱包插件的开启密码

  1. 一个很重要的应用就是事件监听,比如我写了个智能合约,希望新区块如果是调用了我的合约,我后台可以自动更新内容到数据库,对用户进行选择性推送而不是区块链合约调用信息不排序直接混乱全推(虽然目前最大的问题就是监听不知道怎么保活。。。)

​ 总结一下事件监听的概念,更详细的建议看这个链接https://segmentfault.com/a/1190000013240470

​ 分为三个部件----事件源(被监听对象)事件event(封装事件源和动作)开发人员编写的监听器对象

​ 很明显,事件源是一个实体类,调用方法的时候发出event类;事实上,事件源本身一般包含监听器,而监听器本事只是接口,监听到对象后再实例化接口的操作,上一个网住中核心的例子代码如下

    public static void main(String[] args) {
     
		// 事件源,有 PersonListener 监听器,两个动作,调用 PersonListener的 两个动作(因为是接口,现在只是空,参数为event)
        Person person = new Person();
        // 注册监听器(),person中这个函数只是 this.personListener = personListener;
        // 可以看到只是接口的 personListener 这里用lambda的方式,重载接口,实例化接口方法
        person.registerLister(new PersonListener() {
     
            @Override
            public void doEat(Event event) {
     
                Person person1 = event.getResource();
                System.out.println(person1 + "正在吃饭呢!");
            }
            @Override
            public void doSleep(Event event) {
     
                Person person1 = event.getResource();
                System.out.println(person1 + "正在睡觉呢!");
            }
        });
        //当调用eat方法时,触发事件(调用person内含doEat函数+执行上述lambda行为)
        //将事件对象传递给监听器,最后监听器获得事件源,对事件源进行操作
        person.Eat();
        // 综上,事件源保存监听器接口,对事件的编程应该在于lambda实例化监听器接口
    }

3.转账函数+调用"查"(view和pure)型合约+“增or改”型合约实例

本实验是用spring boot的测试,class挂上@component放入容器,函数挂上@test

3.1 转账
// 出钱人
public static String confluxWalletAddress = "0x1d23e8060f646bad1b4bb9125a5d1e71f56cb32f";
@Test
    void ConfluxBase_and_Transact() throws Exception {
     
        // 确定基础参数 公钥私钥和密码,密码不能乱写!必须是浏览器conflux钱包插件的密码!!
        int testNetId = 1;
        // 出钱人私钥
        String privateKey = "0x2e0d3e928841568bcfcc2eaa5bf2424321abe3ae6ac2bdfea6786b659e2e5d51";
        String password = "c45521669";
        // 出钱人公钥
        String publickKey = "0x1d23e8060f646bad1b4bb9125a5d1e71f56cb32f";
        // Address 封装的对象可以用 getABIAddress()获取被封装账号的公钥地址
        Address test_address = new Address(publickKey, testNetId);
        // initialize  an accountManager
        Cfx cfx = Cfx.create("http://testnet.cfxchain.xyz:12537/rpc/ ", 3, 1000);
        AccountManager am = new AccountManager(testNetId);
        // import private key
        am.imports(privateKey, password);
        // 整合一个账户信息,是条链,插件密码和公私钥
        Account account = Account.unlock(cfx,am,test_address,password);
        // 还有一种封印的account函数,详见上文jdk链接
        // 尝试发送部分代币
        // 1.建立交易信息 2.私钥签名 3.发送给本地或公用节点
        // 交易值,前面10进制字符串,单位为drip!!=10^-18 个cfx
        BigInteger value = new BigInteger("1000000", 10);
        // 创建交易,参数发送者地址
        TransactionBuilder txBuilder = new TransactionBuilder(test_address);
        // 参数--链号!!容易遗忘,报bug:chainIdMissed
        txBuilder.withChainId(testNetId);
        // 参数 接收地址和链号
        Address receiverAddress = new Address("0x173329e2a911b3849bf41e65c807ceaefa2b11d1",testNetId);
        // 设置接收者的地址
        txBuilder.withTo(receiverAddress);
        // 交易值确认,类型为biginteger
        txBuilder.withValue(value);
        // 根据之前的交易信息实例化交易
        RawTransaction rawTx = txBuilder.build(cfx);
//        // 交易上传区块链,完成流程,收到确认区块地址哈希
        //这种上传包括加密签名和发送
//        SendTransactionResult result = account.send(rawTx);
//        System.out.println(result.getTxHash());
        // 也可以分开,先加密签名,再传送
        String hexEncodedTx = account.sign(rawTx);
        String txHash = cfx.sendRawTransaction(hexEncodedTx).sendAndGet();
        System.out.println(txHash);
        System.out.println("###############################");
    }
3.2 使用view类型合约函数的函数调用实例:

不需要个人地址

    @Test
    void Call_contract_methods(){
     
        // 建立链接
        Cfx cfx = Cfx.create("https://testnet-rpc.conflux-chain.org.cn/v2",3, 1000);
        // 建立合约链接对象!!地址0x8开头
        ContractCall contract = new ContractCall(cfx, new Address("0x8284e5a2087628d3a278d2336cdc883d2a98b032", 1));
        // passing method name and parameter to `contract.call`
        // note: parameters should use web3j.abi.datatypes type
        // 这里参数又几个要注意的地方
        // 1.有的view函数没有参数需要输入,如下即可实现合约调用返回值
        // call第一个参数是合约写的方法名,区分大小写,这里是显示合约布置者的函数,没有上传参数
        String amount = contract.call("minter").sendAndGet();
        System.out.print("contract minter: ");
        System.out.println(amount);
        // 2.有参数的view,这里函数balanceOf是指定用户信息查询余额函数,第二个或后面对应参数加上即可
        // 所有参数参考 conflux.web3j.abi.datatypes,不建议java自带格式
//        String amount = contract.call("balanceOf", new Address("0x1d23e8060f646bad1b4bb9125a5d1e71f56cb32f", 1).getABIAddress()).sendAndGet();
//        BigInteger balance = DecodeUtil.decode(amount, Uint256.class);
//        System.out.print("account balance: ");
//        System.out.println(balance);
    }
3.3 调用存储数据或更改数据合约函数实例:

需要发动者个人私钥公钥

@Test
void Update_Contract_state() throws Exception {
     
    // 调用者私钥
    String privateKey = "0x2e0d3e928841568bcfcc2eaa5bf2424321abe3ae6ac2bdfea6786b659e2e5d51";
    int netId = 1;
    // 合约地址
    Address contractAddress = new Address("0x8284e5a2087628d3a278d2336cdc883d2a98b032", netId);
    // 调用者地址
    Address recipient = new Address("0x1d23e8060f646bad1b4bb9125a5d1e71f56cb32f", netId);
    Cfx cfx = Cfx.create("https://testnet-rpc.conflux-chain.org.cn/v2", 3, 1000);
    // create account, then call contract's method
    // 链接+私钥=调用者账户
    Account account = Account.create(cfx, privateKey);
    // 估计这里写入各种字段,以次调用多种方法
    // 可以查看原型,发现可以定义update交易的gas
    // build transaction option info: nonce, gas, gasPrice and etc
    Account.Option opt = new Account.Option();
    // opt要设置用户参数的id!!不然报错chainIdMismatch
    opt.withChainId(1);
    BigInteger amount = BigInteger.valueOf(100);
    // 这里合约方法是给指定对象印发 amount 量的代币
    // 第三个参数是合约方法名,其后是合约方法参数,有几个,是啥看自己的合约
    String txHash = account.call(opt, contractAddress,
            "mint", recipient.getABIAddress(), new Uint256(amount));
    // 返回64位开头0x8的哈希交易地址
    // 具体内容可以在 https://testnet.confluxscan.io/ 输入返回哈希搜到
    System.out.println("tx hash: " + txHash);
}

4.未完成和接下来想解决的问题:

如果有大佬看到这里,如果可以请指导一下下面两个需求完成方法,不胜感激,联系方式qq如名字,也可以下面留言

4.1 监听订阅及其保活

因为之前没有写过保活,网上的看了觉得不知道怎么带入

大佬原话:

“这个是订阅,有数据后会回调event->()”

“只需要处理event数据即可”

“然后写个监听,保活这个订阅”

“意外停了,就重起”

然而看了java的监听感觉得监听器,事件源和事件相互嵌合。。。而且也不知道怎么个保活,更何况是lambda的event,我觉得一直while(true)大佬说不对,不知道怎么处理。。。若有大佬懂的,还请不吝赐教。

@Test
void pubsub_test() throws ConnectException {
     
    // websocket和一般通信的区别(据说不同在于双方平等)
    // 初始化 WebSocketService 链接,连接到CFX网络
    WebSocketService wsService = new WebSocketService("ws://testnet.cfxchain.xyz:12535", false);
    wsService.connect();
    Cfx cfx = Cfx.create(wsService);
    // 范例:可以调用CFX方法,和 http 无异
    BigInteger epoch = cfx.getEpochNumber().sendAndGet();
    System.out.println("Current epoch: " + epoch);
    // PubSub Subscribe to incoming events and process incoming events
    // PubSub 最重要的就是事件订阅(貌似?
    final Flowable<NewHeadsNotification> events = cfx.subscribeNewHeads();
    final Disposable disposable = events.subscribe(event -> {
     
        // You can get the detail through getters
        System.out.println("##############");
        while(true){
     
            System.out.println(event.getParams().getResult());
            System.out.println("##############");
        }
    });
    // close
    disposable.dispose();
}
4.2 ipfs和conflux的链接合作实现保存多文本

你可能感兴趣的:(区块链,JDK,教程,区块链,java,maven,web,接口)