java与conflux区块链结合的智能合约-开发-布置-参数获取与存储-交互全流程实
现教程:
Conflux java区块链智能合约-开发-布置-参数获取与存储-交互全流程实现教程:
前⾔:感谢conflux开发⼤佬,尤其是 孤独的开发者-acuilab,宇智波斑,pana ,曹宏宇等⼏位⼤佬的耐⼼交流。
本教程是⽤java-conflux-jdk 在conflux区块链进⾏智能合约的设计,部署,参数获取,交互等的教程,如果你已经熟悉了solidity智能合约,看完本⽂,可以让java后端与conflux区块链⾃由交互、添加智能合约、与智能合约交互、存储包括合约地址等区块链参数的完整⼀套⾏为了。
废话不多说:
0.前排提⽰:
另外,即使是Dapp也⼀般需要⼀个服务器,nodejs+JavaScript开发的话,向⽤户发送前端⽤户数据即可上链,去中⼼化程度更⾼;java 开发的话上链操作也是后台在做,去中⼼化程度降低,主要胜在java后端的应⽤相对⽐其他语⾔更普遍。所以⽤java还是js是很⼤的区别,建议先考虑清楚
1.Java-conflux-JDK 引⽤
先下载依赖包,建议⽤maven项⽬,在pom的dependencies中加⼊conflux包的引⽤
引⽤地址如下:
点击版本号,跳转页⾯如下
页⾯右侧Apache Maven框中代码复制进⾃⼰spring boot项⽬ pom的dependencies中刷新即可调⽤conflux包的引⽤
2.智能合约的编写和编译
(1)编写智能合约
要发布合约当然要先写好合约,这⾥推荐conflux studio,测试地址测试币获取到编译合约⽣成字节码乃⾄字节码上链成合约⼀条龙,下载连接如下,注意⼀定下最新版,⽼版本bug太多(貌似新⽼都要先安装docker):
然后不会的建议看下简单案例教程:
这⾥的例⼦是js-conflux-sdk写DAPP的教程,不是java的,但是没关系,我看前⼀部分,即智能合约的编写和编译。
(2)编译合约和通过java布置合约
⾸先要⽤conflux studio编译(⽤remix编译其实⼀个道理,但是对新⼿studio感觉友好⼀点),就是左上⾓的锤⼦
编译过后会出现build-contracts中的json⽂件js获取json的key和value
ctrl+f搜索字段“bytecode”
⼀⼤串bytecode就是编译后的合约(别问deployedbytecode是啥,我也不知道)
然后打开你的java项⽬(我这⾥是springboot的test⽂件做测试)复制bytecode作为java调⽤的参数
直接上我的实际的java代码:
@Test
public void try_new_contract()throws Exception{
String privateKey ="0x0e3f7f3219dd154e1b4887123ccb8472ef35341cb3c1f86d08c42b43117d776d";
Cfx cfx = ate("/v2",3,1000);
Account account = ate(cfx, privateKey);
Account.Option opt =new Account.Option();
// opt要设置⽤户参数的id!!不然报错chainIdMismatch
opt.withChainId(1);
String smart_contract_file ="0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021*********ffffffff ffffffffffffffffffffffffffffffff16021790555061083a806100606000396000f3fe6080604052600436106100555760003560e01c8063075461721461005a57806315a 9b727146100b157806340c10f19146100f557806370a08231146101505780638735cc70146101b5578063d0679d34146101f9575b600080fd5b348015610
06657600080fd5b5061006f610254565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35 b6100f3600480360360208110156100c757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610279565b005b348015 61010157600080fd5b5061014e6004803603604081101561011857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906 02001909291905050506103ba565b005b34801561015c57600080fd5b5061019f6004803603602081101561017357600080fd5b81019080803573ffffffffffffff ffffffffffffffffffffffffff169060200190929190505050610489565b6040518082815260200191505060405180910390f35b6101f7600480360360208110156101cb 57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104d2565b005b34801561020557600080fd5b506102526004803 603604081101561021c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610613565b005b 6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b606060016040519080825280602002602001820160405280156102ab578160200160 2082028038833980820191505090505b50905081816000815181106102bc57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffff ffffffffffffffffff168152505073088800000000000000000000000000000000000173ffffffffffffffffffffffffffffffffffffffff166310128d3e826040518263ffffffff1660e01b815 26004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015610379578082015181840152602081019 05061035e565b5050505090500192505050600060405180830381600087803b158********e57600080fd5b505af11580156103b2573d6000803e3d6000f d5b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610 41357600080fd5b789f4f2726179a224501d762422c946590d91000000000000000811061043857600080fd5b80600160008473ffffffffffffffffffffffffffffffffffffffff1 673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505050565b6000600160008373fffffffffffffffffffffffffffffffffffffff f1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6060600160405190808252806020026020018201604052801561 05045781602001602082028038833980820191505090505b509050818160008151811061051557fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff169
08173ffffffffffffffffffffffffffffffffffffffff168152505073088800000000000000000000000000000000000173ffffffffffffffffffffffffffffffffffffffff1663d2932db682604051826 3ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b838110156105d257808201518 18401526020810190506105b7565b5050505090500192505050600060405180830381600087803b1580156105f757600080fd5b505af115801561060b573 d6000803e3d6000fd5b505050505050565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054 8111156106c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526015815 2602001807f496e73756666696369656e742062616c616e63652e000000000000000000000081525060200191505060405180910390fd5b806001600033 73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473fffffffffffff fffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507f3990db2d31862302a685e8086b5 755072a6e2b5b780af1ee81ece35ee3cd3345338383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffff ffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505056fea265627a7a7231582020957a5d4d4 60f692efeb5b3f0a5813bb78842f7a7f7a437397f82f8546a82ab64736f6c63430005100032";
String deploye_hash = account.deploy(opt,smart_contract_file);
System.out.println(deploye_hash);
}
注意:
1)发布合约的私钥对应区块链账户有(测试⽹络也要免费先获取测试币)
2)创建cfx对象(理解为socket对象)注意连接的⽹络,这⾥是测试⽹
3)必须account option对象写⼊参数chainid否则报错,哪怕其实参数已经再cfx对象写了,重写⼀遍
4)合约就是那串乱码,即图中“smart_contract_file”
5)返回位交易哈希,不是发布的合约地址
3.通过rpc与conflux区块链交互
可能新⼿不知道rpc是啥
简单的说,可以下载curl,普通的⽹页请求返回⼀个⽹页,curl进⾏远程程序控制(rpc)解析你的请求,返回⼀个json字段,包含你要的信息。
举个例⼦,我们刚刚发布了合约,收到了合约布置哈希,但是我们不知道新的合约地址啊!!在和⽤java与合约交互的时候就没有定位,程序不知道和那个合约交互。
翻了两天源码,应该是有函数可以直接请求的(有函数痕迹),但是⽆奈没到合适函数。于是⽤rpc
获取。
1)到conflux jsonrpc开发⽂档寻想要的接⼝函数
我们想要的,看到⼀个函数“cfx_getTransactionByHash”
另外,注意curl访问地址和参数
访问rpc的url见下⽅⽹址:
访问端⼝见下⽅⽹址:
2)编写curl请求语句测试
就是⽤简单⽅式尝试看这个接⼝是否可以访问。
下载curl请求器后,打开cmd,以我发布过的合约为例:
linux内核系统curl访问语句:
curl -X POST --data '{"jsonrpc":"2.0","method":"cfx_getTransactionByHash","params":["0xefcdb73434
576d64aa5482632f2cc4a862ab831c872f30582f5c2c a8ee95207e"],"id":1}' -H "Content-Type: application/json" /v2:12537
windows要加转义字符,不然报错:
curl -X POST --data “{\"jsonrpc\":\"2.0\",\"method\":\"cfx_getTransactionByHash\",\"params\":[\"0xefcdb73434576d64aa5482632f2cc4a862ab831c872f3058 2f5c2ca8ee95207e\"],\"id\":1}" -H "Content-Type: application/json" /v2:12537
返回
{"blockHash":"0x1dada5a8d1afd0190dd27ac1c8441a7a42cc531f4acbc6e007268ba3038efc85","chainId":"0x1","contractCreated":"CFXTEST:TYPE.CONT RACT:ACCXFUN724PN2V46AUDTE3156P1DREP5VUTE8UZKGG","data":"合约字节码","epochHeight":"0x1469aef","from":"CFXTEST:TYPE.USER:AATN4 YSG9NFE92FT1SVE2J84XN2M6EBJBYU075M5RG","gas":"0xc4e06","gasPrice":"0x1","hash":"0xefcdb73434576d64aa5482632f2cc4a862ab831c872f305 82f5c2ca8ee95207e","nonce":"0x19","r":"0x522ab0f8a1be3cf99e2fad5822488fdd9cad72b7f562dcd98ad1d6badd1b224d","s":"0x168284eab39988614619 c667b57528e1e024c1ac367ae647f6ecdaffd6ae6e42","status":"0x0","storageLimit":"0xc80","to":null,"transactionIndex":"0x0","v":"0x0","value":"0x0"}
可以看到确实返回了我们需要的合约地址“contractCreated:
CFXTEST:TYPE.CONTRACT:ACCXFUN724PN2V46AUDTE3156P1DREP5VUTE8UZKGG”
3)java中实现rpc请求,并解析得到参数
这⾥我们使⽤okhttp3进⾏rpc请求,因为貌似有传⾔httpClient要被劝退了(?)
pom写⼊引⽤
<!-- mvnrepository/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>
java代码(springboot 的测试⽂件测试):
public void try_okhttp_conflux()throws  IOException {
// 请求体请求参数
String url ="/v2:12537";
String json ="{\"jsonrpc\":\"2.0\",\"method\":\"cfx_getTransactionByHash\",\"params\":[\"0xefcdb73434576d64aa5482632f2cc4a862ab831c872f30582f5 c2ca8ee95207e\"],\"id\":1}";
RequestBody body = ate(
MediaType.parse("application/json"), json);
//请求
Request request =new Request.Builder()
.url(url)
.post(body)
.build();
final Call call = wCall(request);
Response response = ute();
返回responce转为string,解析返回json string
String obj = response.body().string();
System.out.println(obj);
// 从返回json string中获取参数
JSONObject object_res=JSONObject.fromObject(obj);
System.out.println(String("result"));
System.out.println(JSONObject("result").getString("contractCreated"));
4.智能合约函数的交互
现在编写-布置了智能合约,那怎么交互呢?怎么调⽤合约函数呢?
如下⽹站有JDK开发者贴出的使⽤代码,可以在boot项⽬test中看情况复制以实验
⽂档中的⽰范代码有些未说明的细节或⼩错误,包括:
1)测试-查看现有epoch中url参数错误,可能报错RPC链接错误,下⽂链接有很多url,对应不同⽹络,⼀般建议学习⽤test先
我⽤的链接:/v2
2)有些类不知道在哪⾥,介绍也⽐较模糊,建议IDE直接ctrl+⽅法or类名,⽐如 RawTransaction类,ctrl+调⽤其的test_addtrss ,看到函数原型,再点参数就可看到类原型
3)有个参数是“password”,这个 AccountManager.import(privateKey, password);需要密码,这⾥是 chorme钱包插件的开启密码
4. ⼀个很重要的应⽤就是事件监听,⽐如我写了个智能合约,希望新区块如果是调⽤了我的合约,我后台可以⾃动更新内容到数据库,
对⽤户进⾏选择性推送⽽不是区块链合约调⽤信息不排序直接混乱全推(虽然⽬前最⼤的问题就是监听不知道怎么保活。。。⽽且⼤佬指点了两次还是不会,所以这⾥不写了)
下⽅实验是⽤spring boot的测试,class挂上@component放⼊容器,函数挂上@test
4.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 = ate(":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.TxHash());
// 也可以分开,先加密签名,再传送
String hexEncodedTx = account.sign(rawTx);
String txHash = cfx.sendRawTransaction(hexEncodedTx).sendAndGet();
System.out.println(txHash);
System.out.println(">>>>>>#");
}
4.2 使⽤view(仅查)类型合约函数的函数调⽤实例:
不需要个⼈地址

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论