TransTrust使用示例

案例:土地证可流转凭证及流转管理

背景

土地证是由地方人民政府颁发的,证明持证人对一定面积的土地享有所有权或使用权的书面文件,是持证人享有土地所有权或使用权的法律凭证。纸质土地证不易管理和保存,遗失补办程序和流转变更程序复杂,土地证持有者需要提供各种有效证明;在土地证抵押贷款等场景中,土地证的持有人身份变更不透明,不利于监管。通过使用TransTrust签发土地证可流转凭证,结合经过KYC验证的TransTrust DID,对于政府部门而言,可以提高土地证签发管理效率,在保护民众的隐私基础上增加了土地证的流转透明性,土地证的真实性验证也更加方便可靠。

参与方

  • 国家土地管理部门
  • 各地方政府部门
  • 土地拥有者(民众或企业)
  • 土地证验证机构

解决方案及基本流程

本示例以国家土地管理部门作为TransTrust整体服务的系统管理员,逐步描述各个参与方如何通过使用TransTrust SDK来完成各个流程的操作。假设已经搭建了FISCOBCOS区块链,在Java项目中引入TransTrust SDK后直接调用SDK接口。TransTrust SDK的使用可以参考 TransTrust-demo

1.TransTrust服务部署

本示例以 TransTrust-demo服务进行说明。通过swagger进行接口展示。

../../_images/view.png

2.公私钥生成

各参与方生成各自的公私钥,自己保存。

../../_images/key_create.png

../../_images/key_info.png

3.TransTrust服务部署

国家土地管理部门作为系统管理员,部署WeID相关合约。使用自己的私钥,并设置链编号。合约部署后合约地址等相关信息会保存到工程根目录。

../../_images/deploy.png

4.DID创建

TransTrust服务初始化后,各个参与方都需要创建一个DID身份才能参与。

/**
 * 根据公私钥创建weid.
 */
public ResponseData<String> createWeIdAndSetAttr(String publicKey, String privateKey) {
    // create weId using the incoming public and private keys
    CreateWeIdArgs createWeIdArgs = new CreateWeIdArgs();
    createWeIdArgs.setPublicKey(publicKey);
    createWeIdArgs.setWeIdPrivateKey(new WeIdPrivateKey());
    createWeIdArgs.getWeIdPrivateKey().setPrivateKey(privateKey);
    ResponseData<String> createResult = ctDIDClient.createWeId(createWeIdArgs);
    logger.info("createWeIdAndSetAttr response:{}", createResult);
    if (createResult.getErrorCode().intValue() != ErrorCode.SUCCESS.getCode()) {
        return createResult;
    }
    return createResult;
}

创建示例

../../_images/did_create.png

../../_images/did_info.png

5.创建土地证CPT

国家土地管理部门首先要创建土地证的凭证模板CPT,即所有的土地证凭证都以土地证CPT的格式显示。在创建之前根据json-schema的格式,确定土地证特有属性字段及其数据类型和描述,示例:

{
  "cptDescription": "unit land certificate",
  "cptId": 2000000,
  "cptManagment": "0x57bc072ab8af771c0978f94bd3c9c76ad0cc6eff",
  "cptName": "landcertificate",
  "credentialType": {
    "cptTradeToken": "0x45d617c5157e9a07ac570d18692d362c3e50c852"
  },
  "privateKey": "28354348400257293578085204282790324607891232742724770334587266909072589459877",
  "properties": {
    "claim": {
      "certificateNumber": {
        "type": "string",
        "description": "certificate number"
      },
      "landType": {
        "type": "string",
        "description": "land type"
      },
      "totalArea": {
        "type": "string",
        "description": "total area"
      },
      "exclusiveArea": {
        "type": "string",
        "description": "exclusive area"
      },
      "sharingArea": {
        "type": "string",
        "description": "sharing area"
      },
      "useType": {
        "type": "string",
        "description": "use type"
      },
      "landNumber": {
        "type": "string",
        "description": "land number"
      },
      "holder": {
        "type": "string",
        "description": "holder"
      },
      "gettingPrice": {
        "type": "string",
        "description": "getting price"
      },
      "site": {
        "type": "string",
        "description": "site"
      }
    }
  },
  "required": [
    "landType",
    "totalArea"
  ],
  "supervisable": false,
  "url": "http://TransTrust.com",
  "weId": "did:weid:100:0x1cd7fa8518c82d5b87fd5a150930a30471b58906"
}

其中privateKeyweId为国家土地管理部门的私钥和DID。其他相关字段意义可以查看TransTrust CPT规范。调用CPT的registerCpt接口将CPT上传到区块链,返回创建的CPT的基本信息。

/**
 * 注册cpt.
 */
 public ResponseData<CptBaseInfo> registerCpt(CptModel cptModel) {
    CTCptMapArgs ctCptMapArgs = new CTCptMapArgs();
    BeanUtils.copyProperties(cptModel, ctCptMapArgs);
    // 将CPT创建者的DID放进Credential构建参数对象
    WeIdAuthentication weIdAuthentication = new WeIdAuthentication();
    weIdAuthentication.setWeId(cptModel.getWeId());
    weIdAuthentication.setWeIdPrivateKey(new WeIdPrivateKey());
    weIdAuthentication.getWeIdPrivateKey().setPrivateKey(cptModel.getPrivateKey());
    ctCptMapArgs.setWeIdAuthentication(weIdAuthentication);
    // 是否指定CptId
    ResponseData<CptBaseInfo> response = new ResponseData<CptBaseInfo>();
    if (cptModel.getCptId() == null) {
    response = ctCptClient.registerCpt(ctCptMapArgs);
    } else {
    response = ctCptClient.registerCpt(ctCptMapArgs, cptModel.getCptId());
    }
    return response;
}

创建示例:

../../_images/cpt_create.png

../../_images/cpt_create_back.png

可以通过查询接口查询详细信息:

../../_images/cpt_info.png

6.签发土地证可流转凭证

各地方政府部门(issuer)可以根据已创建的土地证CPT向土地拥有者(recipient)签发土地证可流转凭证。调用Credential服务的createCredential接口,生成一个完整的土地证可流转凭证以及转化成规范化格式,即TransTrust CPT所规定的格式。规范化的土地证可流转凭证可以通过转化成json字符串导出到文件中,用户可以直接使用该文件来流转,展示和验证。模板:

{
  "claim": {
    "certificateNumber": "123456",
    "landType": "commerce",
    "totalArea": "15568.26m^2",
    "exclusiveArea": "14000m^2",
    "sharingArea": "1568.26m^2",
    "useType": "selling",
    "landNumber": "56-20-12",
    "holder": "China Evergrande",
    "gettingPrice": "500,000,000RMB",
    "site": "ShaHe XiLu 001"
  },
  "cptId": 2000000,
  "issuer": "did:weid:100:0x6e97e5ba180a78cbf8f31ff4925d5072ceeb0c26",
  "issuerName": "China Land Managment",
  "privateKey": "30119508104847753222987231185900755642033370932964041072306491196350521581647",
  "recipient": "did:weid:100:0x05485b6415dfbcaa370a5b2724646e97ff7a7ac2",
  "recipientName": "China Evergrande"
}
/**
 * 创建电子凭证.
 */
public ResponseData<CTCredentialPojo> createCredential(
    CreateCredentialPojoModel createCredentialPojoModel) {
    // 设置CPT相关信息
    CTCreateCredentialPojoArgs ctCreateCredentialPojoArgs = new CTCreateCredentialPojoArgs();
    BeanUtils.copyProperties(createCredentialPojoModel, ctCreateCredentialPojoArgs);
    String weId = createCredentialPojoModel.getIssuer();
    // 将地方政府部门的DID放进Credential构建参数对象
    WeIdAuthentication weIdAuthentication = new WeIdAuthentication();
    weIdAuthentication.setWeId(weId);
    weIdAuthentication.setWeIdPrivateKey(new WeIdPrivateKey());
    weIdAuthentication.getWeIdPrivateKey()
        .setPrivateKey(createCredentialPojoModel.getPrivateKey());
    weIdAuthentication.setWeIdPublicKeyId(weId + "key-0");
    ctCreateCredentialPojoArgs.setWeIdAuthentication(weIdAuthentication);
    // 设置凭证超时时间
    ctCreateCredentialPojoArgs
        .setExpirationDate(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 365 * 100);
    // 设置发行者
    Map<String, String> issuer = new HashMap<String, String>(2);
    issuer.put("WeID", weId);
    issuer.put("name", createCredentialPojoModel.getIssuerName());
    ctCreateCredentialPojoArgs.setIssuer(issuer);
    // 设置接收者
    Map<String, String> recipient = new HashMap<String, String>(2);
    recipient.put("WeID", createCredentialPojoModel.getRecipient());
    recipient.put("name", createCredentialPojoModel.getRecipientName());
    ctCreateCredentialPojoArgs.setRecipient(recipient);
    // 创建凭证
    ResponseData<CTCredentialPojo> data =
        ctCredentialClient.createCredential(ctCreateCredentialPojoArgs);
    log.info("createCredential CTCredentialPojo:{}", DataToolUtils.serialize(data.getResult()));
    return data;
}

创建示例:

../../_images/credential_create.png

../../_images/credential_info.png

7.验证电子凭证

验证电子凭证,模板:

{
  "credential": {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "context": "https://github.com/WeBankFinTech/WeIdentity/blob/master/context/v1",
    "cptBaseInfo": {
      "cptId": 2000000,
      "cptVersion": 1
    },
    "ctCptMapArgs": {
      "cptDescription": "unit land certificate",
      "cptManagment": "0x57bc072ab8af771c0978f94bd3c9c76ad0cc6eff",
      "cptName": "landcertificate",
      "cptType": "ORIGINAL",
      "credentialType": {
        "cptTradeToken": "0x45d617c5157e9a07ac570d18692d362c3e50c852"
      },
      "properties": {},
      "required": [
        "landType",
        "totalArea"
      ],
      "supervisable": "false",
      "url": "http://TransTrust.com",
      "weIdAuthentication": {}
    },
    "docType": [
      "VerifiableCredential",
      "original"
    ],
    "metaData": {
      "cptPublisher": "did:weid:100:0x1cd7fa8518c82d5b87fd5a150930a30471b58906",
      "cptSignature": "ATdzmrl6hLaKW3RH/peDNiXnJolMQbCvPTt7PVklWPpnc5ZlGcUA3S08mbZG8aEvST6gLKBhPRQ5DpM/rdZbOmM=",
      "created": 1636710016,
      "updated": 0
    },
    "proof": {
      "created": 1636714893,
      "creator": "did:weid:100:0x6e97e5ba180a78cbf8f31ff4925d5072ceeb0c26key-0",
      "salt": {
        "certificateNumber": "xaIml",
        "exclusiveArea": "4sHra",
        "gettingPrice": "6B4kI",
        "holder": "Ys7eO",
        "landNumber": "DDoNN",
        "landType": "jPWy9",
        "sharingArea": "9ieHs",
        "site": "AHu5c",
        "totalArea": "rjIpJ",
        "useType": "Re4fL"
      },
      "signatureValue": "zTiHgyHMWf6kQw+6sg/OGTiinb4/3vTb0zfCGToDrqVN6vAbkS2AnirAhW74GbxeR6cikyMY16pbq/gNxIRwqwA=",
      "type": "Secp256k1"
    },
    "properties": {
      "claim": {
        "certificateNumber": "123456",
        "exclusiveArea": "14000m^2",
        "gettingPrice": "500,000,000RMB",
        "holder": "China Evergrande",
        "landNumber": "56-20-12",
        "landType": "commerce",
        "sharingArea": "1568.26m^2",
        "site": "ShaHe XiLu 001",
        "totalArea": "15568.26m^2",
        "useType": "selling"
      },
      "expirationDate": 4790314893,
      "id": "1dc6d2b1-a7f6-4eed-82d0-af31363efe7c",
      "issuanceDate": 1636714893,
      "issuer": {
        "WeID": "did:weid:100:0x6e97e5ba180a78cbf8f31ff4925d5072ceeb0c26",
        "name": "China Land Managment"
      },
      "recipient": {
        "WeID": "did:weid:100:0x05485b6415dfbcaa370a5b2724646e97ff7a7ac2",
        "name": "China Evergrande"
      }
    },
    "type": "object"
  },
  "issuerWeId": "did:weid:100:0x6e97e5ba180a78cbf8f31ff4925d5072ceeb0c26"
}

验证:

../../_images/credential_verify.png

../../_images/credential_result.png

8.选择性披露

创建选择性披露电子凭证,模板:

{
  "credential": {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "context": "https://github.com/WeBankFinTech/WeIdentity/blob/master/context/v1",
    "cptBaseInfo": {
      "cptId": 2000000,
      "cptVersion": 1
    },
    "ctCptMapArgs": {
      "cptDescription": "unit land certificate",
      "cptManagment": "0x57bc072ab8af771c0978f94bd3c9c76ad0cc6eff",
      "cptName": "landcertificate",
      "cptType": "ORIGINAL",
      "credentialType": {
        "cptTradeToken": "0x45d617c5157e9a07ac570d18692d362c3e50c852"
      },
      "properties": {},
      "required": [
        "landType",
        "totalArea"
      ],
      "supervisable": "false",
      "url": "http://chinatrust.com",
      "weIdAuthentication": {}
    },
    "docType": [
      "VerifiableCredential",
      "original"
    ],
    "metaData": {
      "cptPublisher": "did:weid:100:0x1cd7fa8518c82d5b87fd5a150930a30471b58906",
      "cptSignature": "ATdzmrl6hLaKW3RH/peDNiXnJolMQbCvPTt7PVklWPpnc5ZlGcUA3S08mbZG8aEvST6gLKBhPRQ5DpM/rdZbOmM=",
      "created": 1636710016,
      "updated": 0
    },
    "proof": {
      "created": 1636714893,
      "creator": "did:weid:100:0x6e97e5ba180a78cbf8f31ff4925d5072ceeb0c26key-0",
      "salt": {
        "certificateNumber": "xaIml",
        "exclusiveArea": "4sHra",
        "gettingPrice": "6B4kI",
        "holder": "Ys7eO",
        "landNumber": "DDoNN",
        "landType": "jPWy9",
        "sharingArea": "9ieHs",
        "site": "AHu5c",
        "totalArea": "rjIpJ",
        "useType": "Re4fL"
      },
      "signatureValue": "zTiHgyHMWf6kQw+6sg/OGTiinb4/3vTb0zfCGToDrqVN6vAbkS2AnirAhW74GbxeR6cikyMY16pbq/gNxIRwqwA=",
      "type": "Secp256k1"
    },
    "properties": {
      "claim": {
        "certificateNumber": "123456",
        "exclusiveArea": "14000m^2",
        "gettingPrice": "500,000,000RMB",
        "holder": "China Evergrande",
        "landNumber": "56-20-12",
        "landType": "commerce",
        "sharingArea": "1568.26m^2",
        "site": "ShaHe XiLu 001",
        "totalArea": "15568.26m^2",
        "useType": "selling"
      },
      "expirationDate": 4790314893,
      "id": "1dc6d2b1-a7f6-4eed-82d0-af31363efe7c",
      "issuanceDate": 1636714893,
      "issuer": {
        "WeID": "did:weid:100:0x6e97e5ba180a78cbf8f31ff4925d5072ceeb0c26",
        "name": "China Land Managment"
      },
      "recipient": {
        "WeID": "did:weid:100:0x05485b6415dfbcaa370a5b2724646e97ff7a7ac2",
        "name": "China Evergrande"
      }
    },
    "type": "object"
  },
  "fieldsToBeDisclosed": {
    "landNumber": 1,
    "gettingPrice": 1,
    "totalArea": 1
  }
}
/**
 * 通过原始凭证和披漏策略,创建选择性披露的电子凭证.
 */
public ResponseData<CTCredentialPojo> createSelectiveCredential(
    CreateSelectiveCredentialModel model) {
    try {
        if (null == model || null == model.getCredential() || model.getCredential().isEmpty()
            || null == model.getFieldsToBeDisclosed()
            || model.getFieldsToBeDisclosed().isEmpty()) {
            return new ResponseData<>(null, ErrorCode.ILLEGAL_INPUT);
        }
        CTCredentialPojo ctCredentialPojo =
            DataToolUtils.mapToObj(model.getCredential(), CTCredentialPojo.class);

        // 选择性披露
        ClaimPolicy claimPolicy = new ClaimPolicy();
        claimPolicy.setFieldsToBeDisclosed(
            DataToolUtils.objToJsonStrWithNoPretty(model.getFieldsToBeDisclosed()));
        ResponseData<CTCredentialPojo> data =
            ctCredentialClient.createSelectiveCredential(ctCredentialPojo, claimPolicy);

        log.info("createSelectiveCredential CTCredentialPojo:{}",
                 DataToolUtils.serialize(data.getResult()));
        return data;
    } catch (Exception e) {
        logger.error("{} error", e);
        return new ResponseData<>(null, ErrorCode.TRANSACTION_EXECUTE_ERROR);
    }
}

创建示例:

../../_images/selective_credential_create.png