应用开发指南¶
应用开发步骤¶
主要开发步骤
- 使用web3sdk开发区块链java应用主要包括如下过程:
- 数据结构和接口设计,编写合约,并将合约代码转换成java代码
- 编写应用程序:调用合约接口完成合约部署和调用逻辑
- 配置java应用
- 运行并测试java应用
编写合约¶
合约功能设计:实现简单计数器
- 实现一个简单的计数器,主要功能包括:
- 设置和读取计数器名字、增加计数、读取当前计数功能。
- 通过receipt log的方式,把修改记录log到区块中,供客户端查询。
(注: receipt log用处很大,是区块链和业务端同步交易处理过程和结果信息的有效渠道)
智能合约代码Counter.sol
根据合约功能要求可实现智能合约 Counter.sol ,合约代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 pragma solidity ^0.4.2; contract Counter{ string name; uint256 counter; //event handle event counted(uint256 c,uint256 oldvalue,uint256 currvalue,string memo); event changename(string oldname); function Counter(){ name="I'm counter"; counter = 0; } function setname(string n){ name=n; changename(n); } function getname()constant returns(string){ return name; } function addcount(uint256 c,string memo) { uint256 oldvalue = counter; counter = counter+c; counted(c,oldvalue,counter,memo); //event } function getcount()constant returns(uint256){ return counter; } }
将合约代码Counter.sol转换为java代码Counter.java
- web3sdk提供了
counter_compile.sh
脚本将Counter.sol转换成Counter.java: # 进入合约编译脚本所在目录 (设web3sdk位于~/mydata目录) $ cd ~/mydata/web3sdk/dist/bin # 执行合约编译脚本 # (com是java代码所属的包,转换后可手动修改) $ bash counter_compile.sh org.bcosliteclient
- 查看生成的java代码
$ cd ~/mydata/web3sdk/dist/output $ tree # ...此处省略若干输出... ├── Counter.abi # Counter.sol编译生成的abi文件 ├── Counter.bin # Counter.sol编译生成的bin文件 └── org └── bcosliteclient ├── Counter.java # Counter.sol转换成的java代码 ├── Evidence.java ├── EvidenceSignersData.java └── Ok.java
output目录生成了合约的.abi, .bin等文件,以及org/bcosliteclient/Counter.java文件。
这个java文件可以复制到客户端开发环境里,后续建立的java工程的对应的包路径下。
若转换成java代码时报错,请参考 faq【合约转换成java代码出错】 .
Counter.sol对应的Counter.java代码如下:
搭建并配置java应用¶
下载java应用bcosliteclient
FISCO-BCOS提供了示例应用bcosliteclient,该应用在 CounterClient.java 中提供Counter.sol合约部署和调用功能。应用下载链接如下:
编译bcosliteclient应用
# 解压应用程序(设下载的压缩包bcosliteclient.zip位于~/mydata目录下)
$ cd ~/mydata && unzip bcosliteclient.zip
# 编译bcosliteclient应用
$ cd bcosliteclient && gradle build
- 此时bcosliteclient应用目录如下:
$ tree -L 2 ├── bcosliteclient # 编译生成目录 │ ├── bin # 包含部署和调用Counter.sol合约的可执行脚本 │ ├── conf # 配置文件,包含客户端配置文件applicationContext.xml,客户端证书 │ └── lib # jar包目录 ├── build # 编译生成的临时目录 │ ├── ...省略若干行... ├── build.gradle ├── lib │ ├── fastjson-1.2.29.jar │ └── web3sdk.jar # 应用引用的web3sdk jar包 └── src ├── bin # 包含可执行程序bcosclient ├── contract |── org # 源码目录 └── resources # 配置文件目录
部署和调用合约¶
部署Counter.sol合约
- 按照上节操作配置好java应用工程后,可调用相关接口部署和调用Counter.sol合约。
# 设bcosliteclient应用位于~/mydata目录 $ cd ~/mydata/bcosliteclient/bcosliteclient/bin # 部署合约 $ chmod a+x bcosclient && ./bcosclient deploy -----> start test ! init AOMP ChannelEthereumService -->Got ethBlockNumber: 42 Deploy contract :null,address :0x8bc176465048ec377a824b7cf36f3cd7452cd093 <--start blockNumber = 42,finish blocknmber=43
由输出结果看出,合约部署成功,合约地址为
0x8bc176465048ec377a824b7cf36f3cd7452cd093
,且部署成功后,区块链系统区块高度由42增加为43.
调用Counter.sol合约
- 使用
bcosliteclient/bcosliteclient/bin
目录下的bcosclient
脚本调用Counter.sol合约: # 设bcosliteclient应用位于~/mydata目录 $ cd ~/mydata/bcosliteclient/bcosliteclient/bin # 调用合约(合约地址是0x8bc176465048ec377a824b7cf36f3cd7452cd093) $ chmod a+x bcosclient && ./bcosclient call_contract 0x8bc176465048ec377a824b7cf36f3cd7452cd093 -----> start test ! init AOMP ChannelEthereumService -->Got ethBlockNumber: 43 counter value before transaction:0 setname-->oldname:[MyCounter from:0,inc:100],newname=[MyCounter from:0,inc:100] Current Counter:100 addcount-->inc:100,before:0,after:100,memo=when tx done,counter inc 100 <--start blockNumber = 43,finish blocknmber=44
由输出结果可看出,计数器合约Counter.sol调用成功后,计数器值增加100,区块链系统块高由43增加为44.
gradle文件配置说明¶
gradle配置文件说明
- 应用SDK的【build.gradle】要通过【compile】和【runtime】添加web3sdk.jar依赖和应用外部依赖库:
一个完整的build.gradle示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | apply plugin: 'maven'
apply plugin: 'java'
apply plugin: 'eclipse'
//指定JDK版本,改成系统中版本
sourceCompatibility = 1.8
targetCompatibility = 1.8
[compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'
// In this section you declare where to find the dependencies of your project
repositories {
maven {
url "http://maven.aliyun.com/nexus/content/groups/public/"
}
mavenLocal()
mavenCentral()
}
List logger = [
"org.slf4j:jul-to-slf4j:1.7.10",
"org.apache.logging.log4j:log4j-api:2.1",
"org.apache.logging.log4j:log4j-core:2.1",
"org.apache.logging.log4j:log4j-slf4j-impl:2.1",
"org.apache.logging.log4j:log4j-web:2.1"
]
def spring_version="4.3.16.RELEASE"
List spring =[
"org.springframework:spring-core:$spring_version",
"org.springframework:spring-beans:$spring_version",
"org.springframework:spring-context:$spring_version",
"org.springframework:spring-tx:$spring_version",
"org.springframework:spring-jdbc:$spring_version",
"org.springframework:spring-test:$spring_version"
]
List alibaba = [
'com.alibaba:druid:1.0.29',
'com.alibaba:fastjson:1.2.29'
]
// In this section you declare the dependencies for your production and test code
dependencies {
compile logger,spring,alibaba
runtime logger,spring,alibaba
//【添加用户自定义jar包依赖】
compile 'org.apache.commons:commons-lang3:3.1'
compile "com.fasterxml.jackson.core:jackson-databind:2.9.6"
runtime "com.fasterxml.jackson.core:jackson-databind:2.9.6"
compile 'io.netty:netty-all:4.1.15.Final'
runtime 'io.netty:netty-all:4.1.15.Final'
compile 'io.netty:netty-tcnative:2.0.0.Final'
runtime 'io.netty:netty-tcnative:2.0.0.Final'
compile 'com.google.guava:guava:19.0'
runtime 'com.google.guava:guava:19.0'
//【添加web3sdk.jar包依赖】
compile 'lib/web3sdk.jar'
runtime 'lib/web3sdk.jar'
// web3j依赖
compile 'org.apache.httpcomponents:httpclient:4.5.5',
'org.bouncycastle:bcprov-jdk15on:1.54',
'com.lambdaworks:scrypt:1.4.0',
'com.squareup:javapoet:1.7.0',
'io.reactivex:rxjava:1.2.4',
'com.github.jnr:jnr-unixsocket:0.15'
//testCompile 'junit:junit:4.12'
}
sourceSets {
main {
java {
srcDir 'src/main/java'
srcDir 'src/test/java'
}
resources {
srcDir 'src/main/resources'
}
}
}
jar {
destinationDir file('dist/apps')
archiveName project.name + '.jar'
exclude '**/*.xml'
exclude '**/*.properties'
doLast {
copy {
from file('tools/')
into 'dist/'
}
copy {
from configurations.runtime
into 'dist/lib'
}
copy {
from file('src/test/resources/')
into 'dist/conf'
}
copy {
from file('.').listFiles().findAll{File f -> (f.name.endsWith('.crt') || f.name.endsWith('.keystore'))}
into 'dist/conf'
}
}
}
|
总结¶
SDK应用开发步骤总结
- 根据以上描述,使用web3sdk开发区块链应用主要包括如下过程:
- 根据应用功能设计合约数据结构和接口;
- 编写智能合约,可先用Nodejs简单验证合约代码逻辑是否正确,验证通过后,将合约代码转换成java代码
- 编写java应用,调用合约java接口完成合约部署和调用功能
- 配置并编译java应用
- 应用功能测试
SDK应用部署/调用合约主要流程
- 参考 CounterClient.java:
- 初始化AMOP的ChannelEthereumService
- 使用AMOP初始化Web3j
- 初始化交易签名密钥对
- 初始化交易参数
- 调用合约接口部署或调用合约
其他说明
- 从零开发SDK应用时,可使用eclipse新建java工程,编译配置文件build.gradle可参考bcosliteclient.zip中的编译配置;
- java应用跟目录的lib目录下要存放FISCO BCOS的web3sdk.jar,web3sdk升级时,直接替换java应用的web3sdk.jar到最新即可。
参考资料
AMOP: https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/features/AMOP/README.html
web3j JSON-RPC: https://github.com/ethereum/wiki/wiki/JSON-RPC
- FISCO dev团队提供的示例应用:
- 存证Demo: https://github.com/FISCO-BCOS/evidenceSample
- 群/环签名客户端Demo: https://github.com/FISCO-BCOS/sig-service-client
- depotSample服务Demo: https://github.com/FISCO-BCOS/depotSample