Coder Social home page Coder Social logo

evidencesample's Introduction

区块链存证案例使用说明

全新适配FISCO-BCOS 2.0+版本,如果使用FISCO-BCOS 1.2或1.3版本请用v1.0.0版本

一、 背景介绍

  • FISCO-BCOS区块链存证是聚焦于企业级应用服务的区块链技术平台,从电子数据的全生命周期介入,实现区块链存证、取证、维权、核证,让司法机构参与到业务过程中,实时见证,为后续的证据核实、纠纷解决、裁决送达提供了可信、可追溯、可证明的技术保障。适用场景:金融行业网络信贷、消费金融、理财等,重点解决可信和司法认可。

  • 区块链存证示例是基于FISCO-BCOS区块链开发的应用案例。示例使用智能合约对存证进行管理,使用分层的智能合约结构:
    1)工厂合约(EvidenceSignersData.sol),由存证各方事前约定,存储存证生效条件,并管理存证的生成。
    2)存证合约(Evidence.sol),由工厂合约生成,存储存证id,hash和各方签名(每张存证一个合约)。
    两层智能合约的设计,可以使系统获得更好的扩展性。示例使用三个角色(用户、存证机构、仲裁机构)来说明一个典型的电子存证场景。关键业务为证据上链,多方签署,链上取证。
  • 本存证样例展示的业务流程主要是:1、收集区块链上机构公钥信息(用户的公钥信息,存证机构的公钥信息,仲裁机构的公钥信息),部署工厂合约。2、用户发送签名存证信息,并发送存证请求。3、存证机构收到存证请求,取出存证内容校验(样例中没有展示),并签名确认。4、仲裁机构收到存证请求,取出存证内容校验(样例中没有展示),并签名确认。5、取证
  • 本文档旨在帮助开发者快速入门区块链存证应用开发。

二、存证案例运行环境搭建

  1. 本文档使用4个区块链节点来模拟区块链环境,请参考 安装文档 完成FISCO BCOS区块链的搭建和控制台的下载工作,本教程中的操作假设在该文档搭建的环境下进行。
  2. 更新签名机构公私钥(示例演示可以直接使用sample提供公私钥,jks文件),公钥在applicationContext.xml文件中配置,私钥需替换/evidence/src/main/resources下的.jks文件,配置和生成公私钥参照下一节中角色公钥配置说明。
  3. SDK证书
# 进入~目录
# 拷贝节点证书到项目的资源目录
$ cd ~
$ cp fisco/nodes/127.0.0.1/sdk/* evidence/src/main/resources    
  1. applicationContext关于节点的配置请参考:下面的存证案例配置文件说明。

三、 存证案例配置文件说明

evidence/src/main/resources/applicationContext.xml文件配置说明

1、角色公钥配置说明:

<bean id="addressConf" class="org.bcos.evidence.sample.PublicAddressConf">
	<property name="allPublicAddress">
		<map>
			<entry key="User" value="0x33674063c4618f4773fac75dc2f07e55f6f391ce">
			</entry>
			<entry key="Arbitrator" value="0x6bc952a2e4db9c0c86a368d83e9df0c6ab481102">
			</entry>
			<entry key="Depositor" value="0x5a6c7ccf9efa702f4e8888ff7e8a3310abcf8c51">
			</entry>
		</map>
	</property>
</bean>

配置解释:

  • 配置中key=User代表用户角色,对应的私钥文件为user.jks;key=Arbitrator代表仲裁机构,对应的私钥文件为arbitrator.jks;key=Depositor代表存证机构,对应的私钥文件为depositor.jks。

  • 按照上面的key-value的格式写入3个角色所对应的公钥,在/evidence/src/main/resources文件夹下放入角色所对应的私钥。 私钥是由linux系统下java JDK/bin中的keytool工具生成的(生成命令如下),私钥生成后,可以通过私钥调用接口生成需要的公钥,具体操作可参照4.6. 获取公钥

      keytool -genkeypair -alias ec -keyalg EC -keysize 256 -sigalg SHA256withECDSA  -validity 365 -storetype JKS -
      keystore user.jks -storepass 123456
    

2、区块链节点信息配置,SDK配置具体请参考。:

<bean id="groupChannelConnectionsConfig" class="org.fisco.bcos.channel.handler.GroupChannelConnectionsConfig">
    <property name="allChannelConnections">
        <list>
            <bean id="group1"  class="org.fisco.bcos.channel.handler.ChannelConnections">
                <property name="groupId" value="1" />
                <property name="connectionsStr"><!-- 配置群组区块链节点列表-->
                    <list>
                        <value>127.0.0.1:20200</value>
                    </list>
                </property>
            </bean>
        </list>
    </property>
</bean>

<bean id="channelService" class="org.fisco.bcos.channel.client.Service" depends-on="groupChannelConnectionsConfig">
    <property name="groupId" value="1" /><!-- 配置群组ID -->
    <property name="orgID" value="fisco" /><!-- 配置机构名称 -->
    <property name="allChannelConnections" ref="groupChannelConnectionsConfig"></property>
</bean>

四、存证案例工具包使用说明

本节提供使用示例工具包,以便开发者能够快速熟悉存证应用。在工具包中,bin文件下为执行脚本,conf文件夹下为工具包配置文件,lib文件下为存证案例依赖包,contracts中存放合约源码(合约java代码生成可以参照4.7

存证案例工具包环境初始化

  • 存证工具包可以通过存证客户端gradle build生成;或者直接下载,下载链接https://github.com/FISCO-BCOS/evidenceSample/tree/master/evidence_toolkit
  • 下载完成之后建议对bin文件夹下的文件执行chmod命令。
  • 根据实际需求更新公私钥(需要3组),公钥以key-value的形式在applicationContext.xml中配置,私钥更新需要替换conf文件下的.jks私钥文件。若无特殊需求可以不用更新公私钥,直接使用默认配置即可。
  • 替换工具包证书
# 进入~目录
# 拷贝节点证书
$ cd ~
$ cp fisco/nodes/127.0.0.1/sdk/* evidence_toolkit/conf
  • applicationContext.xml配置文件,请参考(上面第三节: 存证案例配置文件说明)

存证案例工具包一键脚本步骤

若想查看完整的执行过程,可执行存证工具包bin文件下runEvidence.sh脚本,runEvidence.sh为存证的一键默认执行脚本,脚本中将存证sample工具包的执行命令进行封装。

存证案例工具包分步操作步骤

1、工厂合约部署

进入到bin文件下,输入以下命令:

./evidence deploy keyStoreFileName keyStorePassword keyPassword
例子:./evidence deploy user.jks '123456' '123456'

参数说明:

  • 在上面的命令中需要传入4个参数,第一个参数固定不可修改。后面三个参数依赖conf中的私钥的文件(直接输入文件名,并非路径)。keyStoreFileName:私钥文件名;keyStorePassword、keyPassword分别为证书生成时输入的keyStore密码和key密码。

控制台显示结果:

deploy factoryContract success, address: deployAddress.(部署工厂合约返回地址)

2、用户创建新证据

进入到bin文件下,在控制台输入命令:

./evidence new  keyStoreFileName keyStorePassword keyPassword deployAddress evidence_id evidence_hash
例子:./evidence new user.jks '123456' '123456' '0x19e2f046f4fc6a02d732a3ffda6480c34214f57f' '1' '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'

参数说明:

  • 命令中第一个参数不可修改,deployAddress为工厂合约部署之后返回的地址,evidence_id和evidence_hash分别为证据ID和证据的hash值,长度无限制。证据的hash可以是合同的hash值,还款记录的hash等。计算方法可以是md5值,sha1,sha3等。

控制台显示结果:

newEvidence success, newEvidenceAddress: newEvidenceAddress(创建证据返回地址)	

3、发送签名上链

进入到bin文件下,在控制台输入命令:

 ./evidence send keyStoreFileName keyStorePassword keyPassword newEvidenceAddress

 例子:./evidence send arbitrator.jks '123456' '123456' '0x4437863afe7c9adce4e658c95666feaab1d996a2' 
      ./evidence send depositor.jks '123456' '123456' '0x4437863afe7c9adce4e658c95666feaab1d996a2' 

参数说明:

  • 注意:此命令需要执行两次,在newEvidence步骤时,用户已经签名,在这个步骤需要存证机构和仲裁机构双方签名,所以在执行这个命令时传入的keyStoreFileName、keyStorePassword、keyPassword分别为两个机构的私钥及密码。
  • 在这个步骤中同样需要用到evidence_hash值,程序中通过newEvidenceAddress查询证据的信息,然后获取evidence_hash值。
  • 命令中第一个参数不可修改,newEvidenceAddress为创建证据区块链返回的地址。

控制台显示结果:

sendSignatureToBlockChain success:true

4、获取证据

进入到bin文件下,在控制台输入命令:

./evidence get keyStoreFileName keyStorePassword keyPassword newEvidenceAddress
例子:./evidence get user.jks '123456' '123456' '0x4437863afe7c9adce4e658c95666feaab1d996a2'

参数说明:

  • 命令中第一个参数不可修改,在这个命令中依赖conf中的私钥文件和deploy操作相同,newEvidenceAddress为创建证据后区块链返回的地址。

控制台显示结果:

the evidenceID:evidence_id(创建证据时传入的evidence_id值)
the evidenceHash:evidence_hash( 创建证据时传入的evidence_hash值)
the signature[0-2]:(打印3个角色的签名)
the publicKey[0-2]:(打印3个角色的公钥)

5、校验证据和签名

进入到bin文件下,在控制台输入命令:

./evidence verify keyStoreFileName keyStorePassword keyPassword newEvidenceAddress
例子:./evidence verify user.jks '123456' '123456' '0x4437863afe7c9adce4e658c95666feaab1d996a2'

参数说明:

  • 命令中第一个参数不可修改,在这个命令中依赖conf中的私钥文件和deploy操作相同,newEvidenceAddress为创建证据后区块链返回的地址。

控制台结果显示:

若校验通过显示:verifyEvidence success:true
若校验失败显示:verifyEvidence failed:false

6、获取公钥 进入到bin文件下,在控制台输入命令:

./evidence getPublicKey keyStoreFileName keyStorePassword keyPassword 
例子:./evidence getPublicKey user.jks '123456' '123456'

参数说明:

  • 命令中第一个参数不可修改,通过读取对应的私钥文件,获取公钥。

控制台结果显示:

publicKey:公钥

7、合约编译及java Wrap代码生成

五、存证客户端使用

存证客户端用java编写,可将工程导入Eclipse做二次开发。二次开发工程URL为:https://github.com/FISCO-BCOS/evidenceSample/tree/master/evidence。 其入口为org.bcos.evidence.app.Main类,客户端中对合约的调用主要包括:web3j的初始化,合约对象部署,载入已经部署的合约,创建证据,发送签名数据,获取证据信息,以及证据校验。区块链应用程序实际是通过web3j生成的java Wrapper类(详细介绍参看4.7合约编译及java Wrap代码生成),通过jsonRPC调用和FISCO-BCOS客户端节点通信,再由客户端返回jsonRPC请求响应。

1、web3j初始化

注意:客户端调用智能合约首先必须初始化web3j,初始化关键代码如下:

    ChannelEthereumService channelEthereumService = new ChannelEthereumService();
    channelEthereumService.setChannelService(service);
    web3j = Web3j.build(channelEthereumService);

2、工厂合约部署

使用初始化的web3j对象来部署智能合约,如果工厂合约部署成功,Future对象会返回合约调用对象(即合约地址),合约部署关键代码如下:

EvidenceSignersData evidenceSignersData = EvidenceSignersData.deploy(web3j, credentials, new StaticGasProvider(gasPrice, gasLimited), arrayList).send();

3、载入已经部署的合约

合约部署成功后,可以获取到已经部署的合约地址:evidenceSignersData.getContractAddress();使用已经部署合约地址,初始化的web3j对象,可以载入智能合约调用对象。

EvidenceSignersData evidenceSignersData = EvidenceSignersData.load(address.toString(), web3j,  credentials, new StaticGasProvider(gasPrice, gasLimited));

注意:部署后可以直接使用返回的智能合约对象,而无需再load载入!

4、创建新证据

发送交易通过直接调用已经部署或载入的智能合约调用对象执行合约对应接口即可,交易执行成功后将返回Receipt,Receipt包含交易hash和其他信息。

Receipt receipt = evidenceSignersData.newEvidence(evidence_hash, evidence_id,evidence_id, BigInteger.valueOf(signatureData.getV()),signatureData.getR(),signatureData.getS()).sendAsync().get();

注意:调用此方法需要传入参数,参数为string[],长度为3即可。传入的三个参数分别模拟对应evidence_id(证据ID)、evidence_hash(证据hash值)、sign_data(签名数据),客户端将传入的三个参数生成一个完成的证据存入区块链中。

5、发送签名数据上链

在用户角色调用newEvidence()接口创建一个新的证据之后,存证机构和签名机构分别需要对证据进行签名,并且将签名的数据发送到区块链中进行存储,关键代码如下:

Evidence evidence = Evidence.load(address, web3j, credentials,  gasPrice, gasLimited);
TransactionReceipt receipt = evidence.addSignatures(BigInteger.valueOf(signature.getV()),
                            signature.getR(),
                            signature.getS()).sendAsync().get();

6、获取证据

创建证据一个,区块链会返回一个交易地址,使用已经部署或载入的智能合约对象调用getEvidence()接口传入交易返回的地址,可返回一个list,对list进行解析可以得到一个evidence对象。

Evidence evidence = Evidence.load(newEvidenceAddres, web3j, credentials,  gasPrice, gasLimited);
Tuple7<String, String, String, List<BigInteger>, List<byte[]>, List<byte[]>, List<String>> result2 = evidence.getEvidence().send();

7、校验证据和签名

通过调用步骤6中的接口可以获取到证据的完整信息,并且附带有3个角色对证据的签名信息,通过校验公钥是否相同来确定签名的信息是否准确。关键代码如下:

for (String str : data.getSignatures()) {
    try {
        addressList.add(verifySignedMessage(data.getEvidenceHash(), str));
    } catch (SignatureException e) {
        throw e;
    }
}
for (String addr : data.getPublicKeys()) {
    boolean flag = false;
    for (String str : addressList) {
        if (str.equals(addr)) {
            flag = true;
            break;
        }
    }
    if (!flag) {
        return false;
    }
}

如果您觉得本文不错,欢迎戳这里给FISCO BCOS打star:star:。

evidencesample's People

Contributors

chaychen2005 avatar codingcattwo avatar cyjseagull avatar jimmyshi22 avatar mingzhenliu avatar ywy2090 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

evidencesample's Issues

签名的疑问

您好!请教下存证为什么还需要自己手工去签名,理论上底层链共识的时候不是会有签名的机制,不太明白为何还要自己应用层再做多方签名

./evidence deploy user.jks '123456' '123456' 执行命令报错

Exception in thread "main" java.lang.Exception
at org.bcos.channel.client.Service.run(Service.java:242)
at org.bcos.evidence.app.BcosApp.loadConfig(BcosApp.java:56)
at org.bcos.evidence.app.Main.main(Main.java:24)
不知道是什么原因导致的 大神帮帮忙

执行./evidence deploy user.jks 出错

我执行./evidence deploy user.jks '123456' '123456' 命令,提醒错误“at org.bcos.evidence.app.BcosApp.deployContract(BcosApp.java:98)”,详见如下。
对应的代码是 evidenceSignersData = EvidenceSignersData.deploy(web3j, credentials, gasPrice, gasLimited, initialValue,evidenceSigners).get();
检查了applicationContext.xml按照要求的配置,读取也应该正常,烦请看一下原因。

333 + /root/mydata/evidenceSample-master/evidence_toolkit
22 + /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/bin/java
11 +  
四月 06, 2018 6:24:52 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@45ff54e6: startup date [Fri Apr 06 18:24:52 CST 2018]; root of context hierarchy
四月 06, 2018 6:24:52 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
四月 06, 2018 6:24:52 下午 org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor initialize
信息: Initializing ExecutorService  'pool'

命令输入参考如下! 
工厂合约部署:./evidence deploy keyStoreFileName keyStorePassword keyPassword  
创建新证据:./evidence new  keyStoreFileName keyStorePassword keyPassword deployAddress evidence_id evidence_hash  
发送签名:./evidence send keyStoreFileName keyStorePassword keyPassword newEvidenceAddress evidence_hash 
获取证据:./evidence get keyStoreFileName keyStorePassword keyPassword newEvidenceAddress 
证据和签名校验:./evidence verify keyStoreFileName keyStorePassword keyPassword newEvidenceAddress 
获取公钥:./evidence getPublicKey keyStoreFileName keyStorePassword keyPassword  

java.util.concurrent.ExecutionException: com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
 at [Source: ; line: 1, column: 0]
        at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
        at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
        at org.bcos.evidence.app.BcosApp.deployContract(BcosApp.java:98)
        at org.bcos.evidence.app.Main.main(Main.java:47)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
 at [Source: ; line: 1, column: 0]
        at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
        at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3854)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3799)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2858)
        at org.bcos.web3j.protocol.channel.ChannelEthereumService.send(ChannelEthereumService.java:50)
        at org.bcos.web3j.protocol.core.Request.send(Request.java:69)
        at org.bcos.web3j.tx.RawTransactionManager.signAndSend(RawTransactionManager.java:106)
        at org.bcos.web3j.tx.RawTransactionManager.sendTransaction(RawTransactionManager.java:90)
        at org.bcos.web3j.tx.TransactionManager.executeTransaction(TransactionManager.java:45)
        at org.bcos.web3j.tx.ManagedTransaction.send(ManagedTransaction.java:43)
        at org.bcos.web3j.tx.Contract.executeTransaction(Contract.java:207)
        at org.bcos.web3j.tx.Contract.create(Contract.java:309)
        at org.bcos.web3j.tx.Contract.deploy(Contract.java:284)
        at org.bcos.web3j.tx.Contract.lambda$deployAsync$25(Contract.java:326)
        at org.bcos.web3j.utils.Async.lambda$run$29(Async.java:22)
        at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1626)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Exception in thread "main" java.lang.NullPointerException
        at org.bcos.evidence.app.BcosApp.deployContract(BcosApp.java:102)
        at org.bcos.evidence.app.Main.main(Main.java:47)

存证案例调用返回结果很慢

我在同网段内网部署了两个fisco-bcos节点,每个8G内存+40G存储,发现证据上链、签名等几个功能执行返回结果平均要23秒,1、是因为要等底层交易共识上链整个过程结束才返回结果 导致的吗?
2、如果是,那么对于实际应用不可能等待2
3秒后才返回结果,生产是否有好的解决方法?
谢谢!

使用中出现警告 WARNING: An illegal reflective access operation has occurred

使用过程中出现如下的警告,不影响正常使用,但是很影响观感,希望可以修复。

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.bouncycastle.jcajce.provider.drbg.DRBG (file:/home/bencq/source_code/ProofOfExistence/evidenceSample/evidence_toolkit/lib/bcprov-jdk15on-1.60.jar) to constructor sun.security.provider.Sun()
WARNING: Please consider reporting this to the maintainers of org.bouncycastle.jcajce.provider.drbg.DRBG
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

我使用的JDK版本是openjdk-14
应该是JDK版本高导致的问题。

关于存证合约设计方案的疑问

请教2个问题:

  1. 合约工厂->无限制创建存证合约(1:N ) 这种模式导致同时存在多则千万个存证合约的实例
    另外一种模式: 在合约工厂内创建map存储Struct对象,来存储存证合约,废弃单个存证合约定义。
    哪种方式官方推荐?各有什么优缺点?
  2. 多方签名(用户、存证机构、仲裁机构),例子中通过人工来签名,在实际项目中是否多方自动签名为合理?推荐什么方式来实现? (event?)
    谢谢并期盼您们的回复。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.