能点进这里的我就默认知道conflux是什么了(一个DAG型的高性能低成本区块链)
前排提示:建议chorme浏览器先下一个钱包,然后至少有个账户有点CFX代币,testnet的也行,不然有的地方会报错或没参数写
前排提示2:Dapp都需要一个服务器,nodejs+JavaScript开发的话,向用户发送前端用户数据即可上链,去中心化程度更高,java开发的话上链操作也是后台在做,去中心化程度降低,主要胜在java后端的应用相对比其他语言更普遍。所以用java还是js是很大的区别,建议先考虑清楚
先下载依赖包,建议用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包的引用
如下网站有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钱包插件的开启密码
总结一下事件监听的概念,更详细的建议看这个链接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实例化监听器接口
}
本实验是用spring boot的测试,class挂上@component放入容器,函数挂上@test
// 出钱人
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("###############################");
}
不需要个人地址
@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);
}
需要发动者个人私钥公钥
@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);
}
如果有大佬看到这里,如果可以请指导一下下面两个需求完成方法,不胜感激,联系方式qq如名字,也可以下面留言
因为之前没有写过保活,网上的看了觉得不知道怎么带入
大佬原话:
“这个是订阅,有数据后会回调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();
}