diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8b2585dc0c78d8b06c415f95d6aa5a7cdda12790..5467c05254361388106132c7a42227eb90505d16 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -10,9 +10,12 @@ on: env: DOCKER_REPOSITORY: webase-front + DOCKER_FISCO_TAG: v2.8.0 + DOCKER_FISCO_REPOSITORY: fisco-webase jobs: + # webase-front main: runs-on: ubuntu-latest steps: @@ -78,11 +81,65 @@ jobs: - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} + # fisco-webase + fisco: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - uses: actions/setup-java@v1 + with: + java-version: 8 + - uses: eskatos/gradle-command-action@v1 + with: + arguments: clean build -x test + + - name: Get branch name + uses: nelonoel/branch-name@v1.0.1 + - name: Fetch tag + run: | + git fetch --tags --force + + - name: Get git tag + uses: little-core-labs/get-git-tag@v3.0.1 + id: tag_data + with: + tagRegex: (.*) # Optional. Returns specified group text as tag name. Full tag string is returned if regex is not defined. + tagRegexGroup: 1 # Optional. Default is 1. + + # todo get fisco's tag. temporarily use variable of DOCKER_FISCO_TAG + - name: Set docker tag from tag + id: set_docker_tag + run: | +# [[ ${{github.ref}} == */tags/* ]] && DOCKER_TAG="${GIT_TAG_NAME}" || DOCKER_TAG="${BRANCH_NAME}" +# DOCKER_TAG="${{ secrets.DOCKERHUB_ORG }}/${DOCKER_FISCO_REPOSITORY}:${DOCKER_FISCO_TAG}" + + echo "New docker tag is ${DOCKER_FISCO_TAG}" + echo "::set-output name=docker_tag::$(echo ${DOCKER_FISCO_TAG})" + + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + context: . + push: true + file: ./docker/fisco/Dockerfile + platforms: linux/amd64 + tags: ${{ steps.set_docker_tag.outputs.docker_tag }} + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} -# - name: send custom message with args -# uses: appleboy/telegram-action@master -# with: -# to: ${{ secrets.TELEGRAM_TO }} -# token: ${{ secrets.TELEGRAM_TOKEN }} -# args: ${{ steps.set_docker_tag.outputs.docker_tag }} of ${{github.repository }} build success. diff --git a/docker/fisco/Dockerfile b/docker/fisco/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..699f1535e9f77482e1d5e1e330ef6b081fbbde0c --- /dev/null +++ b/docker/fisco/Dockerfile @@ -0,0 +1,37 @@ +# choose bcos image +ARG BCOS_IMG_VERSION +FROM fiscoorg/fiscobcos:${BCOS_IMG_VERSION:-v2.8.0} +LABEL maintainer service@fisco.com.cn + +# bcos config files +WORKDIR /bcos +# WeBASE-Front files +WORKDIR /front + +# setup JDK +RUN apt-get update \ + && apt-get -y install openjdk-8-jdk \ + && rm -rf /var/lib/apt/lists/* + +ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64 +ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar +ENV PATH $JAVA_HOME/bin:$PATH + +# COPY start shell of bcos and front +COPY ["docker/fisco/docker-start.sh", "/docker-start.sh"] + +# COPY front files +# cache lib layer +# replace start.sh of front(use active profile) +COPY ["dist/*.sh", "/front/"] +COPY ["dist/lib/", "/front/lib/"] +COPY ["dist/conf_template/", "/front/conf/"] +COPY ["dist/static/", "/front/static/"] +COPY ["dist/gradle/", "/front/gradle/"] +COPY ["dist/apps/", "/front/apps/"] + +# expose port +EXPOSE 30300 20200 8545 5002 + +# start +ENTRYPOINT ["bash","/docker-start.sh"] diff --git a/docker/fisco/build.sh b/docker/fisco/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..d4b2c8c30528d9f48ac8f430d8f4eec6452bf2e1 --- /dev/null +++ b/docker/fisco/build.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +LOG_WARN() { + local content=${1} + echo -e "\033[31m[WARN] ${content}\033[0m" +} + +LOG_INFO() { + local content=${1} + echo -e "\033[32m[INFO] ${content}\033[0m" +} + +# 命令返回非 0 时,就退出 +set -o errexit +# 管道命令中任何一个失败,就退出 +set -o pipefail +# 遇到不存在的变量就会报错,并停止执行 +set -o nounset +# 在执行每一个命令之前把经过变量展开之后的命令打印出来,调试时很有用 +#set -o xtrace + +# 退出时,执行的命令,做一些收尾工作 +trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; exit 1' ERR + +# Set magic variables for current file & dir +# 脚本所在的目录 +__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# 脚本的全路径,包含脚本文件名 +__file="${__dir}/$(basename "${BASH_SOURCE[0]}")" +# 脚本的名称,不包含扩展名 +__base="$(basename ${__file} .sh)" +# 脚本所在的目录的父目录,一般脚本都会在父项目中的子目录, +# 比如: bin, script 等,需要根据场景修改 +__root="$(cd "$(dirname "${__dir}")" && pwd)"/../ # <-- change this as it depends on your app +__root=$(realpath -s "${__root}") + + +########################### properties config ########################## +image_organization=fiscoorg +image_name="fisco-webase" +docker_push="no" +latest_tag=latest +new_tag= +# 父镜像 FISCO-BCOS 的版本(默认版本) +bcos_image_tag="v2.8.0" + +########################### parse param ########################## +__cmd="$(basename $0)" +# 解析参数 +# usage help doc. +usage() { + cat << USAGE >&2 +Usage: + ${__cmd} [-h] [-t new_tag] [-p] [-i fiscoorg] + -t New tag for image, required. ex: fisco is v2.8.0, then tag is v2.8.0 + -c BCOS docker image tag, default v2.8.0, equal to fiscoorg/fiscobcos:v2.8.0. + -p Push image to docker hub, default no. + -i Default organization, default fiscoorg. + -h Show help info. +USAGE + exit 1 +} +while getopts t:i:c:ph OPT;do + case $OPT in + t) + new_tag=$OPTARG + ;; + c) + bcos_image_tag=${OPTARG} + ;; + p) + docker_push=yes + ;; + i) + image_organization=${OPTARG} + ;; + h) + usage + exit 3 + ;; + \?) + usage + exit 4 + ;; + esac +done + + +# 必须设置新镜像的版本 +if [[ "${new_tag}"x == "x" ]] ; then + LOG_WARN "Need a new_tag for new docker image!! " + usage + exit 1 +fi + +########################### build docker image ########################## +image_repository="${image_organization}/${image_name}" + +## compile project +cd "${__root}" && chmod +x ./gradlew && ./gradlew clean build -x test + +## docker build in project root +# cd "${__root}"/dist + +docker build -f "${__root}"/docker/fisco/Dockerfile --build-arg BCOS_IMG_VERSION="${bcos_image_tag}" -t ${image_repository}:${new_tag} . +docker tag "${image_repository}:${new_tag}" "${image_repository}:${latest_tag}" + + +########################### push docker image ########################## +if [[ "${docker_push}"x == "yesx" ]] ; then + docker push "${image_repository}:${new_tag}" + docker push "${image_repository}:${latest_tag}" +fi + + + + + + + diff --git a/docker/fisco/docker-start.sh b/docker/fisco/docker-start.sh new file mode 100644 index 0000000000000000000000000000000000000000..66a0df7e32add7205d389ec7f14dcc3ebd6a4730 --- /dev/null +++ b/docker/fisco/docker-start.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# start bcos +cd /data && /usr/local/bin/fisco-bcos -c /data/config.ini >>nohup.out & + +# start front +cp -r /data/sdk/* /front/conf/ +cd /front && bash start.sh + +# keep container running +tail -f /docker-start.sh + + diff --git a/release_note.txt b/release_note.txt index f1a2e631dadf73f9da480397049873930b3f8cdd..f074f24d22337ed3303f06d0393da83387cb97fb 100644 --- a/release_note.txt +++ b/release_note.txt @@ -1 +1 @@ -v1.5.3 +v1.5.4 diff --git a/src/main/java/com/webank/webase/front/contract/ContractService.java b/src/main/java/com/webank/webase/front/contract/ContractService.java index 6ec222a8e7156721085346dda68ed6f54bf0c1f3..da0c5d87d04a9da2f715762bf196cb49afd452c1 100644 --- a/src/main/java/com/webank/webase/front/contract/ContractService.java +++ b/src/main/java/com/webank/webase/front/contract/ContractService.java @@ -391,6 +391,7 @@ public class ContractService { /** * encode constructor function */ + @Deprecated private static String constructorEncoded(String contractName, ContractAbiUtil.VersionEvent versionEvent, List params) throws FrontException { // Constructor encoded diff --git a/src/main/java/com/webank/webase/front/contractStore/ContractStoreController.java b/src/main/java/com/webank/webase/front/contractStore/ContractStoreController.java index 6b8531c3a3d35bbe90bc4ccaedc2166966eff8d0..79e847dd1d94163028f7b15e341312638fa5d1d3 100644 --- a/src/main/java/com/webank/webase/front/contractStore/ContractStoreController.java +++ b/src/main/java/com/webank/webase/front/contractStore/ContractStoreController.java @@ -124,7 +124,7 @@ public class ContractStoreController extends BaseController { @GetMapping(value = "/getContractItemByFolderId/{folderId}") public BaseResponse getContractItemByFolderId(@PathVariable("folderId") Integer folderId) { log.info("getContractItemByFolderId start. storeId:{}", folderId); - List contractItemList = contractStoreService.getFolderItemListByFolderId(folderId.longValue()); + List contractItemList = contractStoreService.getContractItemListByFolderId(folderId.longValue()); BaseResponse response = new BaseResponse(ConstantCode.RET_SUCCEED); response.setData(contractItemList); return response; diff --git a/src/main/java/com/webank/webase/front/contractStore/ContractStoreService.java b/src/main/java/com/webank/webase/front/contractStore/ContractStoreService.java index bc8f061e7fb9e3f330dc86e544c2f0cd2d8ba87c..1fd16b705c5b514141cc405787d1201e053b5cf9 100644 --- a/src/main/java/com/webank/webase/front/contractStore/ContractStoreService.java +++ b/src/main/java/com/webank/webase/front/contractStore/ContractStoreService.java @@ -85,7 +85,7 @@ public class ContractStoreService { /** * */ - public List getFolderItemListByFolderId(Long folderId) { + public List getContractItemListByFolderId(Long folderId) { List contractItemList = contractItemRepository.findByContractFolderId(folderId); return contractItemList; } diff --git a/src/main/java/com/webank/webase/front/contractStore/ContractStroeStartupRunner.java b/src/main/java/com/webank/webase/front/contractStore/ContractStoreStartupRunner.java similarity index 86% rename from src/main/java/com/webank/webase/front/contractStore/ContractStroeStartupRunner.java rename to src/main/java/com/webank/webase/front/contractStore/ContractStoreStartupRunner.java index 4dc00adbbe063b5ffb59bba1d407a0bd368c37cc..84e7099332236cf146730f0010398c3d2445a4da 100644 --- a/src/main/java/com/webank/webase/front/contractStore/ContractStroeStartupRunner.java +++ b/src/main/java/com/webank/webase/front/contractStore/ContractStoreStartupRunner.java @@ -5,7 +5,7 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component -public class ContractStroeStartupRunner implements CommandLineRunner { +public class ContractStoreStartupRunner implements CommandLineRunner { @Autowired PresetDataService presetDataService; diff --git a/src/main/java/com/webank/webase/front/contractStore/PresetDataService.java b/src/main/java/com/webank/webase/front/contractStore/PresetDataService.java index efa9275ad20b193c0d577a2624cb93aeea894843..ea807920f12ba0096b319ba932f8ee62092eca55 100644 --- a/src/main/java/com/webank/webase/front/contractStore/PresetDataService.java +++ b/src/main/java/com/webank/webase/front/contractStore/PresetDataService.java @@ -1,11 +1,22 @@ package com.webank.webase.front.contractStore; +import com.webank.webase.front.base.exception.FrontException; import com.webank.webase.front.contractStore.constant.*; import com.webank.webase.front.contractStore.entity.ContractFolderItem; import com.webank.webase.front.contractStore.entity.ContractItem; import com.webank.webase.front.contractStore.entity.StoreItem; +import com.webank.webase.front.util.JsonUtils; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @@ -296,9 +307,83 @@ public class PresetDataService { public void initPresetData() { - initContractItem(); - initContractFolderItem(); - initStoreItem(); +// initContractItem(); +// initContractFolderItem(); +// initStoreItem(); + this.readAndInitContractItem(); + this.readAndInitFolderItem(); + this.readAndInitStoreItem(); } + /** + * read from ./resources/warehouse/*.json + */ + public void readAndInitStoreItem() { + String jsonStr = this.loadWarehouseJson("warehouse/warehouse.json"); + List storeItems = JsonUtils.toJavaObjectList(jsonStr, StoreItem.class); + if (storeItems == null) { + log.error("readAndInitStoreItem get null"); + return; + } + List item2Save = new ArrayList<>(); + for (StoreItem item : storeItems) { + if (!contractStoreRepository.exists(item.getStoreId())) { + item.setCreateTime(LocalDateTime.now()); + item.setModifyTime(item.getCreateTime()); + item2Save.add(item); + } + } + contractStoreRepository.save(item2Save); + log.info("readAndInitStoreItem save {} items", storeItems.size()); + } + + public void readAndInitFolderItem() { + String jsonStr = this.loadWarehouseJson("warehouse/folder.json"); + List folderItems = JsonUtils.toJavaObjectList(jsonStr, ContractFolderItem.class); + if (folderItems == null) { + log.error("readAndInitFolderItem get null"); + return; + } + List item2Save = new ArrayList<>(); + for (ContractFolderItem item : folderItems) { + if (!contractFolderRepository.exists(item.getContractFolderId())) { + item.setCreateTime(LocalDateTime.now()); + item.setModifyTime(item.getCreateTime()); + item2Save.add(item); + } + } + contractFolderRepository.save(item2Save); + log.info("readAndInitFolderItem save {} items", folderItems.size()); + } + + public void readAndInitContractItem() { + String jsonStr = this.loadWarehouseJson("warehouse/contract.json"); + List contractItems = JsonUtils.toJavaObjectList(jsonStr, ContractItem.class); + if (contractItems == null) { + log.error("readAndInitContractItem get null"); + return; + } + List item2Save = new ArrayList<>(); + for (ContractItem item : contractItems) { + if (!contractItemRepository.exists(item.getContractId())) { + item.setCreateTime(LocalDateTime.now()); + item.setModifyTime(item.getCreateTime()); + item2Save.add(item); + } + } + contractItemRepository.save(item2Save); + log.info("readAndInitContractItem save {} items", contractItems.size()); + } + + private String loadWarehouseJson(String jsonFilePath) { + log.info("loadWarehouseJson :{}", jsonFilePath); + try (InputStream nodeCrtInput = new ClassPathResource(jsonFilePath).getInputStream()) { + String jsonStr = IOUtils.toString(nodeCrtInput, StandardCharsets.UTF_8); + log.debug("loadCrtContentByPath itemList:{}", jsonStr); + return jsonStr; + } catch (Exception e) { + log.error("loadWarehouseJson error:[]", e); + return null; + } + } } diff --git a/src/main/java/com/webank/webase/front/event/EventController.java b/src/main/java/com/webank/webase/front/event/EventController.java index 09ae94d7ffda590a0818058acb222ec163b503e7..33aa65e5b2888ab0e9fd1b2e73bdbe7656556634 100644 --- a/src/main/java/com/webank/webase/front/event/EventController.java +++ b/src/main/java/com/webank/webase/front/event/EventController.java @@ -33,6 +33,7 @@ import com.webank.webase.front.event.entity.RspContractInfo; import com.webank.webase.front.util.AbiUtil; import com.webank.webase.front.util.CommonUtils; import com.webank.webase.front.util.JsonUtils; +import com.webank.webase.front.web3api.Web3ApiService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -69,11 +70,13 @@ public class EventController extends BaseController { @Autowired private EventService eventService; + @Autowired + private Web3ApiService web3ApiService; @ApiOperation(value = "registerNewBlockEvent", notes = "register registerNewBlockEvent and push message to mq") - @ApiImplicitParam(name = "ReqNewBlockEventRegister", value = "注册出块通知所需配置", + @ApiImplicitParam(name = "reqNewBlockEventRegister", value = "注册出块通知所需配置", required = true, dataType = "ReqNewBlockEventRegister") @PostMapping("newBlockEvent") public BaseResponse registerNewBlockEvent( @@ -96,7 +99,7 @@ public class EventController extends BaseController { @ApiOperation(value = "registerContractEvent", notes = "register contract event callback and push message to mq") - @ApiImplicitParam(name = "ReqContractEventRegister", value = "EventLogUserParams与消息队列所需配置", + @ApiImplicitParam(name = "reqContractEventRegister", value = "EventLogUserParams与消息队列所需配置", required = true, dataType = "ReqContractEventRegister") @PostMapping("contractEvent") public BaseResponse registerContractEvent( @@ -176,7 +179,7 @@ public class EventController extends BaseController { @ApiOperation(value = "unregisterNewBlockEvent", notes = "unregister NewBlockEvent") - @ApiImplicitParam(name = "ReqNewBlockEventRegister", value = "注册出块通知所需配置与数据表的id值", + @ApiImplicitParam(name = "reqUnregister", value = "注册出块通知所需配置与数据表的id值", required = true, dataType = "ReqNewBlockEventRegister") @DeleteMapping("newBlockEvent") public BaseResponse unregisterNewBlockEvent( @@ -234,7 +237,7 @@ public class EventController extends BaseController { @ApiOperation(value = "unregisterContractEvent", notes = "unregister contract event") - @ApiImplicitParam(name = "ReqContractEventRegister", value = "注册出块通知所需配置与数据表的id值", + @ApiImplicitParam(name = "reqUnregister", value = "注册出块通知所需配置与数据表的id值", required = true, dataType = "ReqContractEventRegister") @DeleteMapping("contractEvent") public BaseResponse unregisterContractEvent( @@ -254,7 +257,7 @@ public class EventController extends BaseController { @ApiOperation(value = "listContractEventLogs", notes = "get event logs from block's tx receipts") - @ApiImplicitParam(name = "ReqEventLogList", value = "获取区块EventLog所需参数", + @ApiImplicitParam(name = "reqEventLogList", value = "获取区块EventLog所需参数", required = true, dataType = "ReqEventLogList") @PostMapping("eventLogs/list") public BasePageResponse listContractEventLogs( @@ -262,15 +265,30 @@ public class EventController extends BaseController { log.debug("start listContractEventLogs. reqEventLogList:{}", reqEventLogList); checkParamResult(result); int groupId = reqEventLogList.getGroupId(); + // v1.5.4 support block auto set as latest block number by set value as -1 Integer fromBlock = reqEventLogList.getFromBlock(); Integer toBlock = reqEventLogList.getToBlock(); - // 0 < fromBlock <= toBlock, latest means latest block + // 0 < fromBlock <= toBlock, latest means block number now if (fromBlock == 0 || toBlock == 0) { return new BasePageResponse(ConstantCode.BLOCK_RANGE_PARAM_INVALID); } + // check block height + Integer blockHeight = web3ApiService.getBlockNumber(groupId).intValue(); + if (blockHeight < toBlock) { + log.error("getContractEventLog error for request blockHeight greater than blockHeight."); + throw new FrontException(ConstantCode.BLOCK_NUMBER_ERROR); + } + if (fromBlock == -1) { + fromBlock = blockHeight; + } + if (toBlock == -1) { + toBlock = blockHeight; + } + // is to is -1, all from can be greater than to; if (fromBlock > toBlock) { return new BasePageResponse(ConstantCode.BLOCK_RANGE_PARAM_INVALID); } + String contractAddress = reqEventLogList.getContractAddress(); EventTopicParam eventTopicParam = reqEventLogList.getTopics(); List contractAbi = reqEventLogList.getContractAbi(); diff --git a/src/main/java/com/webank/webase/front/event/EventService.java b/src/main/java/com/webank/webase/front/event/EventService.java index 7d63bd3a2f9beb8e546d920484e36ab5edd81a30..9f112e3a28688592efc66d055a405bceb60d53fb 100644 --- a/src/main/java/com/webank/webase/front/event/EventService.java +++ b/src/main/java/com/webank/webase/front/event/EventService.java @@ -378,12 +378,6 @@ public class EventService { Integer fromBlock, Integer toBlock, EventTopicParam eventTopicParam) { log.info("start getContractEventLog groupId:{},contractAddress:{},fromBlock:{},toBlock:{},eventTopicParam:{}", groupId, contractAddress, fromBlock, toBlock, eventTopicParam); - // check block height - Integer blockHeight = web3ApiService.getBlockNumber(groupId).intValue(); - if (blockHeight < toBlock) { - log.error("getContractEventLog error for request blockHeight greater than blockHeight."); - throw new FrontException(ConstantCode.BLOCK_NUMBER_ERROR); - } EventLogParams eventParam = RabbitMQUtils.initEventTopicParam(fromBlock, toBlock, contractAddress, eventTopicParam, cryptoSuite); @@ -424,6 +418,7 @@ public class EventService { /** * get abi info from both + * different from webase-node-mgr, abi and contract data is separated * @param groupId * @return * @throws IOException diff --git a/src/main/java/com/webank/webase/front/transaction/TransService.java b/src/main/java/com/webank/webase/front/transaction/TransService.java index c9ace0271a0c77267277c9c1b8c71dadce6ff112..2c87d803c5a748169a59b30950ed92554ef56c08 100644 --- a/src/main/java/com/webank/webase/front/transaction/TransService.java +++ b/src/main/java/com/webank/webase/front/transaction/TransService.java @@ -231,12 +231,10 @@ public class TransService { } } else { // data sign - String signMsg = - signMessage(groupId, client, signUserId, contractAddress, encodedFunction); + String signMsg = signMessage(groupId, client, signUserId, contractAddress, encodedFunction); Instant nodeStartTime = Instant.now(); // send transaction TransactionReceipt responseReceipt = sendMessage(client, signMsg); - this.decodeReceipt(responseReceipt); response = responseReceipt; log.info("***node cost time***: {}", Duration.between(nodeStartTime, Instant.now()).toMillis()); @@ -307,6 +305,7 @@ public class TransService { * @param function function * @param commonContract contract */ + @Deprecated public static TransactionReceipt execTransaction(Function function, CommonContract commonContract, TransactionDecoderService txDecoder) throws FrontException { Instant startTime = Instant.now(); @@ -565,7 +564,6 @@ public class TransService { Client client = web3ApiService.getWeb3j(groupId); if (sync) { TransactionReceipt receipt = sendMessage(client, signedStr); - this.decodeReceipt(receipt); return receipt; } else { TransactionPusherService txPusher = new TransactionPusherService(client); @@ -926,7 +924,6 @@ public class TransService { Instant nodeStartTime = Instant.now(); // send transaction TransactionReceipt receipt = sendMessage(client, signedMessageStr); - this.decodeReceipt(receipt); log.info("***node cost time***: {}", Duration.between(nodeStartTime, Instant.now()).toMillis()); return receipt; diff --git a/src/main/java/com/webank/webase/front/util/CommonUtils.java b/src/main/java/com/webank/webase/front/util/CommonUtils.java index 71b05d4a9929539b0cafdcf39e3df1ea907ca573..8e2cc555060f00742bb1ac9f71e95844506ab0b1 100644 --- a/src/main/java/com/webank/webase/front/util/CommonUtils.java +++ b/src/main/java/com/webank/webase/front/util/CommonUtils.java @@ -57,6 +57,7 @@ import org.fisco.bcos.sdk.crypto.signature.SM2SignatureResult; import org.fisco.bcos.sdk.crypto.signature.SignatureResult; import org.fisco.bcos.sdk.model.CryptoType; import org.fisco.bcos.sdk.model.TransactionReceipt; +import org.fisco.bcos.sdk.transaction.codec.decode.TransactionDecoderService; import org.fisco.bcos.sdk.utils.Numeric; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -688,6 +689,14 @@ public class CommonUtils { return flag; } + + public static void decodeReceipt(TransactionReceipt receipt, CryptoSuite cryptoSuite) { + // decode receipt + TransactionDecoderService txDecoder = new TransactionDecoderService(cryptoSuite); + String receiptMsg = txDecoder.decodeReceiptStatus(receipt).getReceiptMessages(); + receipt.setMessage(receiptMsg); + } + /** * convert hex number string to decimal number string * @param receipt diff --git a/src/main/java/com/webank/webase/front/web3api/Web3ApiService.java b/src/main/java/com/webank/webase/front/web3api/Web3ApiService.java index 0a993868405b53ac856546aa34ebb720313376c8..4615aedb14bbcccf26e019c0ae3158bc10149612 100644 --- a/src/main/java/com/webank/webase/front/web3api/Web3ApiService.java +++ b/src/main/java/com/webank/webase/front/web3api/Web3ApiService.java @@ -64,6 +64,7 @@ import org.fisco.bcos.sdk.model.NodeVersion.ClientVersion; import org.fisco.bcos.sdk.model.TransactionReceipt; import org.fisco.bcos.sdk.utils.Numeric; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Service; @@ -81,6 +82,7 @@ public class Web3ApiService { @Autowired private BcosSDK bcosSDK; @Autowired + @Qualifier("rpcClient") private Client rpcWeb3j; @Autowired private Web3Config web3ConfigConstants; @@ -169,6 +171,7 @@ public class Web3ApiService { if (opt.isPresent()) { transactionReceipt = opt.get(); } + CommonUtils.decodeReceipt(transactionReceipt, getWeb3j(groupId).getCryptoSuite()); CommonUtils.processReceiptHexNumber(transactionReceipt); return transactionReceipt; } @@ -194,8 +197,7 @@ public class Web3ApiService { * getClientVersion. */ public ClientVersion getClientVersion() { - ClientVersion version; - version = getWeb3j().getNodeVersion().getNodeVersion(); + ClientVersion version = getWeb3j().getNodeVersion(getNodeIpPort()).getNodeVersion(); return version; } @@ -449,8 +451,8 @@ public class Web3ApiService { * @return */ public List getGroupList() { - log.debug("getGroupList. "); - List groupIdList = getWeb3j().getGroupList().getGroupList(); + log.info("getGroupList. "); + List groupIdList = getWeb3j().getGroupList(getNodeIpPort()).getGroupList(); // check web3jMap, if not match groupIdList, refresh web3jMap in front refreshWeb3jMap(groupIdList); return groupIdList; @@ -458,7 +460,7 @@ public class Web3ApiService { public List getNodeIdList() { return getWeb3j() - .getNodeIDList() + .getNodeIDList(getNodeIpPort()) .getNodeIDList(); } @@ -526,8 +528,7 @@ public class Web3ApiService { * getNodeInfo. */ public NodeInformation getNodeInfo() { - String nodeIpPort = web3ConfigConstants.getIp() + ":" + web3ConfigConstants.getChannelPort(); - return getWeb3j().getNodeInfo(nodeIpPort).getNodeInfo(); + return getWeb3j().getNodeInfo(getNodeIpPort()).getNodeInfo(); } /** @@ -852,4 +853,8 @@ public class Web3ApiService { throw new FrontException(ConstantCode.SYSTEM_ERROR_NODE_INACTIVE); } } + + private String getNodeIpPort() { + return web3ConfigConstants.getIp() + ":" + web3ConfigConstants.getChannelPort(); + } } diff --git a/src/main/resources/application-docker.yml b/src/main/resources/application-docker.yml index 39713bcd8989f90ba4bd508b0d60d7380cc329b9..dde5fafaab7d091414761f5599327aec5e856448 100644 --- a/src/main/resources/application-docker.yml +++ b/src/main/resources/application-docker.yml @@ -1,5 +1,5 @@ # server version -version: v1.5.3 +version: v1.5.4 spring: datasource: diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 756d5c1dd74c7206613afb7ba174eac734bddeff..027571c24a8ef45ae9f38f09b68977f717c39a40 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,5 @@ # server version -version: v1.5.3 +version: v1.5.4 spring: datasource: diff --git a/src/main/resources/conf/gm/gmsdk.publickey b/src/main/resources/conf/gm/gmsdk.publickey deleted file mode 100644 index 46d9c60f4c813881baf584fead6eef0157ad982b..0000000000000000000000000000000000000000 --- a/src/main/resources/conf/gm/gmsdk.publickey +++ /dev/null @@ -1 +0,0 @@ -7e95dc204b7f83e686cb6317becba3e3a83e9e88c08f28c17e20db479b1abdb4b0629e1c3d40d5e696c518e4c857eb8cc2063cba159868c5b9f6f4287482d891 diff --git a/src/main/resources/conf/sdk.publickey b/src/main/resources/conf/sdk.publickey deleted file mode 100644 index 0eddc3691b7e5710d4818c25db5bcc111e64e4ba..0000000000000000000000000000000000000000 --- a/src/main/resources/conf/sdk.publickey +++ /dev/null @@ -1 +0,0 @@ -508ad0422c058db68ab6b36c62bb5ed6d41ec28bf3118a5de536877b4bd979d72d13b181aab08eb106ef6b2d55b9c4475021ed7c9ab9d0ee5e867a118b74d35c diff --git a/src/main/resources/warehouse/contract.json b/src/main/resources/warehouse/contract.json new file mode 100644 index 0000000000000000000000000000000000000000..c053992ab9eba0d9448b7232d17062277dc7ddf9 --- /dev/null +++ b/src/main/resources/warehouse/contract.json @@ -0,0 +1,346 @@ +[ + { + "contractId" : 1, + "contractFolderId" : 1, + "contractName" : "Address", + "contractDesc" : "# Address\n\nAddress library\n\nAddress contract usage methods can refer to the Points contract warehouse。\n\n1. Detect whether the address is a contract\n2. Detect if the address is 0x0", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=", + "contractDesc_en" : "# Address\n\nAddress library\n\nAddress contract usage methods can refer to the Points contract warehouse。\n\n1. Detect whether the address is a contract\n2. Detect if the address is 0x0" + }, + { + "contractId" : 2, + "contractFolderId" : 1, + "contractName" : "LibString", + "contractDesc" : "# String library\n\nString library\n\nProvides common string-related operations, including copying, finding, replacing, and so on。", + "contractSrc" : "Ci8qKgogKiBAZmlsZTogTGliU3RyaW5nCiAqIEBhdXRob3I6IGZpc2NvLWRldgogKiAKICogQGRhdGU6IDIwMTgKICovCgpwcmFnbWEgc29saWRpdHkgPj0wLjQuMjQgPDAuNi4xMDsKCmxpYnJhcnkgTGliU3RyaW5nIHsKICAgIAogICAgdXNpbmcgTGliU3RyaW5nIGZvciAqOwogICAgCiAgICBmdW5jdGlvbiBieXRlc1RvU3RyaW5nKGJ5dGVzIG1lbW9yeSBfYnl0ZXMpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IGJ5dGVzQXJyYXkgPSBuZXcgYnl0ZXMoX2J5dGVzLmxlbmd0aCk7CiAgICAgICAgZm9yICh1aW50MjU2IGk7IGkgPCBfYnl0ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgYnl0ZXNBcnJheVtpXSA9IF9ieXRlc1tpXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cmluZyhfYnl0ZXMpOwogICAgfQoKICAgIGZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyaW5nIG1lbW9yeSBfc3RyaW5nKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJ5dGVzIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IF9ieXRlcyA9IGJ5dGVzKF9zdHJpbmcpOwogICAgICAgIHJldHVybiBfYnl0ZXM7CiAgICB9CiAgICAKIAogICAgZnVuY3Rpb24gYnl0ZXMzMlRvU3RyaW5nKGJ5dGVzMzIgX2J5dGVzMzIpIGludGVybmFsIHB1cmUgcmV0dXJucyhzdHJpbmcgbWVtb3J5KXsKICAgICAgICBieXRlcyBtZW1vcnkgYnl0ZXNTdHJpbmcgPSBuZXcgYnl0ZXMoMzIpOwogICAgICAgIHVpbnQgY2hhckNvdW50ID0gMCA7CiAgICAgICAgZm9yKHVpbnQgaSA9IDAgOyBpPDMyO2krKyl7CiAgICAgICAgICAgIGJ5dGUgY2hhciA9IGJ5dGUoYnl0ZXMzMih1aW50KF9ieXRlczMyKSAqMiAqKig4KmkpKSk7CiAgICAgICAgICAgIGlmKGNoYXIgIT0wKXsKICAgICAgICAgICAgICAgIGJ5dGVzU3RyaW5nW2NoYXJDb3VudF0gPSBjaGFyOwogICAgICAgICAgICAgICAgY2hhckNvdW50Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnl0ZXMgbWVtb3J5IGJ5dGVzU3RyaW5nVHJpbW1lZCA9IG5ldyBieXRlcyhjaGFyQ291bnQpOwogICAgICAgIGZvcih1aW50IGo9MDtqPGNoYXJDb3VudDtqKyspewogICAgICAgICAgICBieXRlc1N0cmluZ1RyaW1tZWRbal09Ynl0ZXNTdHJpbmdbal07CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmcoYnl0ZXNTdHJpbmdUcmltbWVkKTsKICAgIH0KCgogICAgZnVuY3Rpb24gc3RyaW5nVG9CeXRlczMyKHN0cmluZyBtZW1vcnkgc291cmNlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoYnl0ZXMzMiByZXN1bHQpewogICAgICAgIGFzc2VtYmx5ewogICAgICAgICAgICByZXN1bHQgOj0gbWxvYWQoYWRkKHNvdXJjZSwzMikpCiAgICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBtZW1jcHkodWludCBkZXN0LCB1aW50IHNyYywgdWludCBsZW4pIHByaXZhdGUgewogICAgICAgIC8vIENvcHkgd29yZC1sZW5ndGggY2h1bmtzIHdoaWxlIHBvc3NpYmxlCiAgICAgICAgZm9yKDsgbGVuID49IDMyOyBsZW4gLT0gMzIpIHsKICAgICAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG1sb2FkKHNyYykpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVzdCArPSAzMjsKICAgICAgICAgICAgc3JjICs9IDMyOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29weSByZW1haW5pbmcgYnl0ZXMKICAgICAgICB1aW50IG1hc2sgPSAyNTYgKiogKDMyIC0gbGVuKSAtIDE7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgc3JjcGFydCA6PSBhbmQobWxvYWQoc3JjKSwgbm90KG1hc2spKQogICAgICAgICAgICBsZXQgZGVzdHBhcnQgOj0gYW5kKG1sb2FkKGRlc3QpLCBtYXNrKQogICAgICAgICAgICBtc3RvcmUoZGVzdCwgb3IoZGVzdHBhcnQsIHNyY3BhcnQpKQogICAgICAgIH0KICAgIH0KICAgIAogICAgCiAgICBmdW5jdGlvbiBjb21wYXJlKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChpbnQ4IF9yZXQpIHsKICAgICAgICBmb3IgKHVpbnQgaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGggJiYgaTxieXRlcyhfc3RyKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpW2ldID4gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKGJ5dGVzKF9zZWxmKVtpXSA8IGJ5dGVzKF9zdHIpW2ldKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggPiBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA8IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNvbXBhcmVOb0Nhc2Uoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nIG1lbW9yeSBfc3RyKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGludDggX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aCAmJiBpPGJ5dGVzKF9zdHIpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxID4gY2gyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoMSA8IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPiBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbaV0gPCBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA+IGJ5dGVzKF9zdHIpLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9IGlmIChieXRlcyhfc2VsZikubGVuZ3RoIDwgYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZXF1YWxzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChib29sIF9yZXQpIHsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCAhPSBieXRlcyhfc3RyKS5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSAhPSBieXRlcyhfc3RyKVtpXSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGVxdWFsc05vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGggIT0gYnl0ZXMoX3N0cikubGVuZ3RoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIGZvciAodWludCBpPTA7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGJ5dGUgY2gxID0gYnl0ZXMoX3NlbGYpW2ldfDB4MjA7CiAgICAgICAgICAgIGJ5dGUgY2gyID0gYnl0ZXMoX3N0cilbaV18MHgyMDsKICAgICAgICAgICAgaWYgKGNoMSA+PSAnYScgJiYgY2gxIDw9J3onICYmIGNoMiA+PSAnYScgJiYgY2gyIDw9J3onKSB7CiAgICAgICAgICAgICAgICBpZiAoY2gxICE9IGNoMikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gIT0gYnl0ZXMoX3N0cilbaV0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHN1YnN0cihzdHJpbmcgbWVtb3J5IF9zZWxmLCB1aW50IF9zdGFydCwgdWludCBfbGVuKSBpbnRlcm5hbCByZXR1cm5zIChzdHJpbmcgbWVtb3J5IF9yZXQpIHsKICAgICAgICBpZiAoX2xlbiA+IGJ5dGVzKF9zZWxmKS5sZW5ndGgtX3N0YXJ0KSB7CiAgICAgICAgICAgIF9sZW4gPSBieXRlcyhfc2VsZikubGVuZ3RoLV9zdGFydDsKICAgICAgICB9CgogICAgICAgIGlmIChfbGVuIDw9IDApIHsKICAgICAgICAgICAgX3JldCA9ICIiOwogICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoX2xlbik7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrX3N0YXJ0LCBfbGVuKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gY29uY2F0KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX3N0cikgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgX3JldCA9IG5ldyBzdHJpbmcoYnl0ZXMoX3NlbGYpLmxlbmd0aCArIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICBzdHJwdHIgOj0gYWRkKF9zdHIsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgbWVtY3B5KHJldHB0citieXRlcyhfc2VsZikubGVuZ3RoLCBzdHJwdHIsIGJ5dGVzKF9zdHIpLmxlbmd0aCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CgogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHN0cjFwdHI7CiAgICAgICAgdWludCBzdHIycHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHN0cjFwdHIgOj0gYWRkKF9zdHIxLCAweDIwKQogICAgICAgICAgICBzdHIycHRyIDo9IGFkZChfc3RyMiwgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNvbmNhdChzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9zdHIxLCBzdHJpbmcgbWVtb3J5IF9zdHIyLCBzdHJpbmcgbWVtb3J5IF9zdHIzKQogICAgICAgIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfc3RyMSkubGVuZ3RoICsgYnl0ZXMoX3N0cjIpLmxlbmd0aAogICAgICAgICAgICArIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwoKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBzdHIxcHRyOwogICAgICAgIHVpbnQgc3RyMnB0cjsKICAgICAgICB1aW50IHN0cjNwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAgc3RyMXB0ciA6PSBhZGQoX3N0cjEsIDB4MjApCiAgICAgICAgICAgIHN0cjJwdHIgOj0gYWRkKF9zdHIyLCAweDIwKQogICAgICAgICAgICBzdHIzcHRyIDo9IGFkZChfc3RyMywgMHgyMCkKICAgICAgICAgICAgcmV0cHRyIDo9IGFkZChfcmV0LCAweDIwKQogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50IHBvcyA9IDA7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHNlbGZwdHIsIGJ5dGVzKF9zZWxmKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc2VsZikubGVuZ3RoOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBzdHIxcHRyLCBieXRlcyhfc3RyMSkubGVuZ3RoKTsKICAgICAgICBwb3MgKz0gYnl0ZXMoX3N0cjEpLmxlbmd0aDsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc3RyMnB0ciwgYnl0ZXMoX3N0cjIpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zdHIyKS5sZW5ndGg7CiAgICAgICAgbWVtY3B5KHJldHB0citwb3MsIHN0cjNwdHIsIGJ5dGVzKF9zdHIzKS5sZW5ndGgpOwogICAgICAgIHBvcyArPSBieXRlcyhfc3RyMykubGVuZ3RoOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0cmltKHN0cmluZyBtZW1vcnkgX3NlbGYpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIHVpbnQgaTsKICAgICAgICB1aW50OCBjaDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgY2ggPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBzdGFydCA9IGk7CiAgICAgICAgCiAgICAgICAgZm9yIChpPWJ5dGVzKF9zZWxmKS5sZW5ndGg7IGk+MDsgLS1pKSB7CiAgICAgICAgICAgIGNoID0gdWludDgoYnl0ZXMoX3NlbGYpW2ktMV0pOwogICAgICAgICAgICBpZiAoIShjaCA9PSAweDIwIHx8IGNoID09IDB4MDkgfHwgY2ggPT0gMHgwRCB8fCBjaCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludCBlbmQgPSBpOwogICAgICAgIAogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGVuZC1zdGFydCk7CiAgICAgICAgCiAgICAgICAgdWludCBzZWxmcHRyOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgc2VsZnB0ciA6PSBhZGQoX3NlbGYsIDB4MjApCiAgICAgICAgICAgIHJldHB0ciA6PSBhZGQoX3JldCwgMHgyMCkKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZnB0citzdGFydCwgZW5kLXN0YXJ0KTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdHJpbShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9jaGFycykgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CiAgICAgICAgdWludDE2IGk7CiAgICAgICAgdWludDE2IGo7CiAgICAgICAgYm9vbCBtYXRjaGVkOwogICAgICAgIGZvciAoaT0wOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gYnl0ZXMoX2NoYXJzKVtqXSkgewogICAgICAgICAgICAgICAgICAgIG1hdGNoZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghbWF0Y2hlZCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdWludDE2IHN0YXJ0ID0gaTsKICAgICAgICAKICAgICAgICBmb3IgKGk9dWludDE2KGJ5dGVzKF9zZWxmKS5sZW5ndGgpOyBpPjA7IC0taSkgewogICAgICAgICAgICBtYXRjaGVkID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoaj0wOyBqPGJ5dGVzKF9jaGFycykubGVuZ3RoOyArK2opIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbaS0xXSA9PSBieXRlcyhfY2hhcnMpW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFtYXRjaGVkKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB1aW50MTYgZW5kID0gaTsKCiAgICAgICAgaWYgKGVuZCA8PSBzdGFydCkgewoJCSAgICBfcmV0ID0gIiI7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gbmV3IHN0cmluZyhlbmQtc3RhcnQpOwogICAgICAgIAogICAgICAgIHVpbnQgc2VsZnB0cjsKICAgICAgICB1aW50IHJldHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHNlbGZwdHIgOj0gYWRkKF9zZWxmLCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGZwdHIrc3RhcnQsIGVuZC1zdGFydCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nIG1lbW9yeSBzcmMsIHN0cmluZyBtZW1vcnkgdmFsdWUpCiAgICAgICAgaW50ZXJuYWwKICAgICAgICBwdXJlCiAgICAgICAgcmV0dXJucyAoaW50KSB7CiAgICAgICAgcmV0dXJuIGluZGV4T2Yoc3JjLCB2YWx1ZSwgMCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGluZGV4T2Yoc3RyaW5nICBtZW1vcnkgc3JjLCBzdHJpbmcgbWVtb3J5IHZhbHVlLCB1aW50IG9mZnNldCkKICAgICAgICBpbnRlcm5hbAogICAgICAgIHB1cmUKICAgICAgICByZXR1cm5zIChpbnQpIHsKICAgICAgICBieXRlcyBtZW1vcnkgc3JjQnl0ZXMgPSBieXRlcyhzcmMpOwogICAgICAgIGJ5dGVzIG1lbW9yeSB2YWx1ZUJ5dGVzID0gYnl0ZXModmFsdWUpOwoKICAgICAgICBhc3NlcnQodmFsdWVCeXRlcy5sZW5ndGggPT0gMSk7CgogICAgICAgIGZvciAodWludCBpID0gb2Zmc2V0OyBpIDwgc3JjQnl0ZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgaWYgKHNyY0J5dGVzW2ldID09IHZhbHVlQnl0ZXNbMF0pIHsKICAgICAgICAgICAgICAgIHJldHVybiBpbnQoaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcgbWVtb3J5IHNyYywgc3RyaW5nIG1lbW9yeSBzZXBhcmF0b3IpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nW10gbWVtb3J5IHNwbGl0QXJyKSB7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY0J5dGVzID0gYnl0ZXMoc3JjKTsKCiAgICAgICAgdWludCBvZmZzZXQgPSAwOwogICAgICAgIHVpbnQgc3BsaXRzQ291bnQgPSAxOwogICAgICAgIGludCBsaW1pdCA9IC0xOwogICAgICAgIHdoaWxlIChvZmZzZXQgPCBzcmNCeXRlcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICAgIGxpbWl0ID0gaW5kZXhPZihzcmMsIHNlcGFyYXRvciwgb2Zmc2V0KTsKICAgICAgICAgICAgaWYgKGxpbWl0ID09IC0xKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgc3BsaXRzQ291bnQrKzsKICAgICAgICAgICAgICAgIG9mZnNldCA9IHVpbnQobGltaXQpICsgMTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3BsaXRBcnIgPSBuZXcgc3RyaW5nW10oc3BsaXRzQ291bnQpOwoKICAgICAgICBvZmZzZXQgPSAwOwogICAgICAgIHNwbGl0c0NvdW50ID0gMDsKICAgICAgICB3aGlsZSAob2Zmc2V0IDwgc3JjQnl0ZXMubGVuZ3RoIC0gMSkgewoKICAgICAgICAgICAgbGltaXQgPSBpbmRleE9mKHNyYywgc2VwYXJhdG9yLCBvZmZzZXQpOwogICAgICAgICAgICBpZiAobGltaXQgPT0gLSAxKSB7CiAgICAgICAgICAgICAgICBsaW1pdCA9IGludChzcmNCeXRlcy5sZW5ndGgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHJpbmcgbWVtb3J5IHRtcCA9IG5ldyBzdHJpbmcodWludChsaW1pdCkgLSBvZmZzZXQpOwogICAgICAgICAgICBieXRlcyBtZW1vcnkgdG1wQnl0ZXMgPSBieXRlcyh0bXApOwoKICAgICAgICAgICAgdWludCBqID0gMDsKICAgICAgICAgICAgZm9yICh1aW50IGkgPSBvZmZzZXQ7IGkgPCB1aW50KGxpbWl0KTsgaSsrKSB7CiAgICAgICAgICAgICAgICB0bXBCeXRlc1tqKytdID0gc3JjQnl0ZXNbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb2Zmc2V0ID0gdWludChsaW1pdCkgKyAxOwogICAgICAgICAgICBzcGxpdEFycltzcGxpdHNDb3VudCsrXSA9IHN0cmluZyh0bXBCeXRlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzcGxpdEFycjsKICAgIH0KICAgIAoKICAgIAogICAgZnVuY3Rpb24gdG9JbnQoc3RyaW5nIG1lbW9yeSBfc2VsZikgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpZiAoYnl0ZXMoX3NlbGYpLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgYm9vbCBwb3NpdGl2ZSA9IHRydWU7CiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVtpXSA9PSAnKycpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgICAgICBpKys7CiAgICAgICAgfSBlbHNlIGlmKGJ5dGVzKF9zZWxmKVtpXSA9PSAnLScpIHsKICAgICAgICAgICAgcG9zaXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KCiAgICAgICAgZm9yICg7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKCEoZGlnaXQgPj0gMHgzMCAmJiBkaWdpdCA8PSAweDM5KSkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3JldCA9IF9yZXQqMTAgKyBpbnQoZGlnaXQtMHgzMCk7CiAgICAgICAgfSAgICAgICAgCiAgICAgICAgCiAgICAgICAgaWYgKCFwb3NpdGl2ZSkgewogICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIHRvQWRkcmVzcyhzdHJpbmcgbWVtb3J5IF9zZWxmKSBpbnRlcm5hbCByZXR1cm5zIChhZGRyZXNzIF9yZXQpIHsKICAgICAgICB1aW50MTYgaTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKGk9MDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBKSkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKS5sZW5ndGgtaSA8IDIpIHsKICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3MoMCk7CiAgICAgICAgfQoKICAgICAgICAvL211c3Qgc3RhcnQgd2l0aCAweAogICAgICAgIGlmICghKGJ5dGVzKF9zZWxmKVtpXSA9PSAnMCcgJiYgYnl0ZXMoX3NlbGYpW2krMV18MHgyMCA9PSAneCcpKSB7CiAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOwogICAgICAgIH0KCiAgICAgICAgdWludCBhZGRyID0gMDsKICAgICAgICAKICAgICAgICBmb3IgKGkrPTI7IGk8Ynl0ZXMoX3NlbGYpLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGRpZ2l0ID0gdWludDgoYnl0ZXMoX3NlbGYpW2ldKTsKICAgICAgICAgICAgaWYgKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkgLy8nMCctJzknCiAgICAgICAgICAgICAgICBkaWdpdCAtPSAweDMwOwogICAgICAgICAgICBlbHNlIGlmIChkaWdpdHwweDIwID49IDB4NjEgJiYgZGlnaXR8MHgyMCA8PSAweDY2KSAvLydhJy0nZicKICAgICAgICAgICAgICAgIGRpZ2l0ID0gZGlnaXQtMHg2MSsxMDsKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHJldHVybiBhZGRyZXNzKDApOyAKICAgICAgICAgICAgCiAgICAgICAgICAgIGFkZHIgPSBhZGRyKjE2K2RpZ2l0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gYWRkcmVzcyhhZGRyKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gdG9LZXlWYWx1ZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmcgbWVtb3J5IF9rZXkpIGludGVybmFsIHJldHVybnMgKHN0cmluZyBtZW1vcnkgX3JldCkgewogICAgICAgIF9yZXQgPSBuZXcgc3RyaW5nKGJ5dGVzKF9zZWxmKS5sZW5ndGggKyBieXRlcyhfa2V5KS5sZW5ndGggKyA1KTsKICAgICAgICAKICAgICAgICB1aW50IHNlbGZwdHI7CiAgICAgICAgdWludCBrZXlwdHI7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBzZWxmcHRyIDo9IGFkZChfc2VsZiwgMHgyMCkKICAgICAgICAgICAga2V5cHRyIDo9IGFkZChfa2V5LCAweDIwKQogICAgICAgICAgICByZXRwdHIgOj0gYWRkKF9yZXQsIDB4MjApCiAgICAgICAgfQogICAgICAgIAogICAgICAgIHVpbnQgcG9zID0gMDsKCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgICAgIG1lbWNweShyZXRwdHIrcG9zLCBrZXlwdHIsIGJ5dGVzKF9rZXkpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9rZXkpLmxlbmd0aDsKICAgICAgICBieXRlcyhfcmV0KVtwb3MrK10gPSAnIic7CiAgICAgICAgCiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJzonOwogICAgICAgIAogICAgICAgIGJ5dGVzKF9yZXQpW3BvcysrXSA9ICciJzsKICAgICAgICBtZW1jcHkocmV0cHRyK3Bvcywgc2VsZnB0ciwgYnl0ZXMoX3NlbGYpLmxlbmd0aCk7CiAgICAgICAgcG9zICs9IGJ5dGVzKF9zZWxmKS5sZW5ndGg7CiAgICAgICAgYnl0ZXMoX3JldClbcG9zKytdID0gJyInOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTdHJpbmdWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSBfcmV0KSB7CgkJX3JldCA9ICIiOwogICAgICAgIGludCBwb3MgPSAtMTsKICAgICAgICB1aW50IHNlYXJjaFN0YXJ0ID0gMDsKICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCJcIiIuY29uY2F0KF9rZXksICJcIiIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgICAgIHBvcyA9IF9zZWxmLmluZGV4T2YoIiciLmNvbmNhdChfa2V5LCAiJyIpLCBzZWFyY2hTdGFydCk7CiAgICAgICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHBvcyArPSBpbnQoYnl0ZXMoX2tleSkubGVuZ3RoKzIpOwoKICAgICAgICAgICAgYm9vbCBjb2xvbiA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAodWludChwb3MpIDwgYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgaWYgKGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICcgJyB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHQnIAogICAgICAgICAgICAgICAgICAgIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdccicgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1xuJykgewogICAgICAgICAgICAgICAgICAgIHBvcysrOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnOicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgICAgICBjb2xvbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih1aW50KHBvcykgPT0gYnl0ZXMoX3NlbGYpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF9yZXQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb2xvbikgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2hTdGFydCA9IHVpbnQocG9zKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBib29sIGRvdWJsZVF1b3RlcyA9IHRydWU7CiAgICAgICAgaW50IHN0YXJ0ID0gX3NlbGYuaW5kZXhPZigiXCIiLCB1aW50KHBvcykpOwogICAgICAgIGlmIChzdGFydCA9PSAtMSkgewogICAgICAgICAgICBkb3VibGVRdW90ZXMgPSBmYWxzZTsKICAgICAgICAgICAgc3RhcnQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChwb3MpKTsKICAgICAgICAgICAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzdGFydCArPSAxOwogICAgICAgIAogICAgICAgIGludCBlbmQ7CiAgICAgICAgaWYgKGRvdWJsZVF1b3RlcykgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCJcIiIsIHVpbnQoc3RhcnQpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbmQgPSBfc2VsZi5pbmRleE9mKCInIiwgdWludChzdGFydCkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW5kID09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgIH0KICAgICAgICAKICAgICAgICBfcmV0ID0gX3NlbGYuc3Vic3RyKHVpbnQoc3RhcnQpLCB1aW50KGVuZC1zdGFydCkpOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRJbnRWYWx1ZUJ5S2V5KHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoaW50IF9yZXQpIHsKICAgICAgICBfcmV0ID0gMDsKICAgICAgICBpbnQgcG9zID0gLTE7CiAgICAgICAgdWludCBzZWFyY2hTdGFydCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiXCIiLmNvbmNhdChfa2V5LCAiXCIiKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICBwb3MgPSBfc2VsZi5pbmRleE9mKCInIi5jb25jYXQoX2tleSwgIiciKSwgc2VhcmNoU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHBvcyA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwb3MgKz0gaW50KGJ5dGVzKF9rZXkpLmxlbmd0aCsyKTsKCiAgICAgICAgICAgIGJvb2wgY29sb24gPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKHVpbnQocG9zKSA8IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGlmIChieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnICcgfHwgYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJ1x0JyAKICAgICAgICAgICAgICAgICAgICB8fCBieXRlcyhfc2VsZilbdWludChwb3MpXSA9PSAnXHInIHx8IGJ5dGVzKF9zZWxmKVt1aW50KHBvcyldID09ICdcbicpIHsKICAgICAgICAgICAgICAgICAgICBwb3MrKzsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYnl0ZXMoX3NlbGYpW3VpbnQocG9zKV0gPT0gJzonKSB7CiAgICAgICAgICAgICAgICAgICAgcG9zKys7CiAgICAgICAgICAgICAgICAgICAgY29sb24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodWludChwb3MpID09IGJ5dGVzKF9zZWxmKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBfcmV0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29sb24pIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VhcmNoU3RhcnQgPSB1aW50KHBvcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHVpbnQgaSA9IHVpbnQocG9zKTsKICAgICAgICB1aW50OCBkaWdpdDsKICAgICAgICBmb3IgKDsgaTxieXRlcyhfc2VsZikubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgZGlnaXQgPSB1aW50OChieXRlcyhfc2VsZilbaV0pOwogICAgICAgICAgICBpZiAoIShkaWdpdCA9PSAweDIwIHx8IGRpZ2l0ID09IDB4MDkgfHwgZGlnaXQgPT0gMHgwRCB8fCBkaWdpdCA9PSAweDBBIAogICAgICAgICAgICB8fCBkaWdpdCA9PSAweDNBIC8qOiovIHx8IGRpZ2l0ID09IDB4MjIgLyoiKi8gfHwgZGlnaXQgPT0gMHgyNyAvKicqLykpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGJvb2wgcG9zaXRpdmUgPSB0cnVlOwogICAgICAgIGlmIChieXRlcyhfc2VsZilbaV0gPT0gJysnKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0gZWxzZSBpZihieXRlcyhfc2VsZilbaV0gPT0gJy0nKSB7CiAgICAgICAgICAgIHBvc2l0aXZlID0gZmFsc2U7CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9CgogICAgICAgIGZvciAoOyBpPGJ5dGVzKF9zZWxmKS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBkaWdpdCA9IHVpbnQ4KGJ5dGVzKF9zZWxmKVtpXSk7CiAgICAgICAgICAgIGlmICghKGRpZ2l0ID49IDB4MzAgJiYgZGlnaXQgPD0gMHgzOSkpIHsKICAgICAgICAgICAgICAgIGlmICghcG9zaXRpdmUpIHsKICAgICAgICAgICAgICAgICAgICBfcmV0ID0gLV9yZXQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3JldDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfcmV0ID0gX3JldCoxMCArIGludChkaWdpdC0weDMwKTsKICAgICAgICB9ICAgICAgICAKICAgICAgICAKICAgICAgICBpZiAoIXBvc2l0aXZlKSB7CiAgICAgICAgICAgIF9yZXQgPSAtX3JldDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHRvVXBwZXJjYXNlKHN0cmluZyBtZW1vcnkgc3JjKSBpbnRlcm5hbCBwdXJlIHJldHVybnMoc3RyaW5nIG1lbW9yeSl7CiAgICAgICAgYnl0ZXMgbWVtb3J5IHNyY2IgPSBieXRlcyhzcmMpOwogICAgICAgIGZvcih1aW50IGk9MDtpPHNyY2IubGVuZ3RoO2krKyl7CiAgICAgICAgICAgIGJ5dGUgYiA9IHNyY2JbaV07CiAgICAgICAgICAgIGlmKGIgPj0gJ2EnICYmIGIgPD0gJ3onKXsKICAgICAgICAgICAgICAgIGIgJj0gYnl0ZSgweERGKTsvLyAtMzIKICAgICAgICAgICAgICAgIHNyY2JbaV0gPSBiIDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQogICAgCiAgICBmdW5jdGlvbiB0b0xvd2VyY2FzZShzdHJpbmcgbWVtb3J5IHNyYykgaW50ZXJuYWwgcHVyZSByZXR1cm5zKHN0cmluZyBtZW1vcnkpewogICAgICAgIGJ5dGVzIG1lbW9yeSBzcmNiID0gYnl0ZXMoc3JjKTsKICAgICAgICBmb3IodWludCBpPTA7aTxzcmNiLmxlbmd0aDtpKyspewogICAgICAgICAgICBieXRlIGIgPSBzcmNiW2ldOwogICAgICAgICAgICBpZihiID49ICdBJyAmJiBiIDw9ICdaJyl7CiAgICAgICAgICAgICAgICBiIHw9IDB4MjA7CiAgICAgICAgICAgICAgICBzcmNiW2ldID0gYjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3JjOwogICAgfQoKCQogICAgZnVuY3Rpb24ga2V5RXhpc3RzKHN0cmluZyBtZW1vcnkgX3NlbGYsIHN0cmluZyBtZW1vcnkgX2tleSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgaW50IHBvcyA9IF9zZWxmLmluZGV4T2YoIlwiIi5jb25jYXQoX2tleSwgIlwiIikpOwogICAgICAgIGlmIChwb3MgPT0gLTEpIHsKICAgICAgICAgICAgcG9zID0gX3NlbGYuaW5kZXhPZigiJyIuY29uY2F0KF9rZXksICInIikpOwogICAgICAgICAgICBpZiAocG9zID09IC0xKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGluQXJyYXkoc3RyaW5nIG1lbW9yeSBfc2VsZiwgc3RyaW5nW10gc3RvcmFnZSBfYXJyYXkpIGludGVybmFsIHJldHVybnMgKGJvb2wgX3JldCkgewogICAgICAgIGZvciAodWludCBpPTA7IGk8X2FycmF5Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIGlmIChfc2VsZi5lcXVhbHMoX2FycmF5W2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KIAogICAgZnVuY3Rpb24gaW5BcnJheU5vQ2FzZShzdHJpbmcgbWVtb3J5IF9zZWxmLCBzdHJpbmdbXSBzdG9yYWdlIF9hcnJheSkgaW50ZXJuYWwgcmV0dXJucyAoYm9vbCBfcmV0KSB7CiAgICAgICAgZm9yICh1aW50IGk9MDsgaTxfYXJyYXkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgaWYgKF9zZWxmLmVxdWFsc05vQ2FzZShfYXJyYXlbaV0pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICB9", + "contractDesc_en" : "# String library\n\nString library\n\nProvides common string-related operations, including copying, finding, replacing, and so on。" + }, + { + "contractId" : 3, + "contractFolderId" : 1, + "contractName" : "SafeMath", + "contractDesc" : "# SafeMath\n\nSafeMath library\n\nA secure mathematical library that provides a safe addition, subtract, and divide。The use of secure mathematical contracts can refer to the Points contract warehouse。", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=", + "contractDesc_en" : "# SafeMath\n\nSafeMath library\n\nA secure mathematical library that provides a safe addition, subtract, and divide。The use of secure mathematical contracts can refer to the Points contract warehouse。" + }, + { + "contractId" : 4, + "contractFolderId" : 1, + "contractName" : "Table", + "contractDesc" : "# table\n\ntable library\n\nBCOS CRUD uses the base library, which you can reference by re-contract calling CRUD.Table contract usage methods can be described by referring to the assat example in the bcos document https://fisco-bcos-documentation.readthedocs.io.", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=", + "contractDesc_en" : "# table\n\ntable library\n\nBCOS CRUD uses the base library, which you can reference by re-contract calling CRUD.Table contract usage methods can be described by referring to the assat example in the bcos document https://fisco-bcos-documentation.readthedocs.io." + }, + { + "contractId" : 5, + "contractFolderId" : 1, + "contractName" : "Roles", + "contractDesc" : "# Roles\n\nRole permissions control contracts\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=", + "contractDesc_en" : "# Roles\n\nRole permissions control contracts\n" + }, + { + "contractId" : 6, + "contractFolderId" : 2, + "contractName" : "Evidence", + "contractDesc" : "# Evidence 合约\n\n## 简介\nEvidence 示例合约,使用分层的智能合约结构: \n1)工厂合约(EvidenceSignersData.sol),由存证各方事前约定,存储存证生效条件,并管理存证的生成。 \n2)存证合约(Evidence.sol),由工厂合约生成,存储存证id,hash和各方签名(每张存证一个合约)。 ", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YUFCSXsgZnVuY3Rpb24gdmVyaWZ5KGFkZHJlc3MgYWRkcilwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhib29sKXt9CmZ1bmN0aW9uIGdldFNpZ25lcih1aW50IGluZGV4KXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3Mpe30gCmZ1bmN0aW9uIGdldFNpZ25lcnNTaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnModWludCl7fQp9Cgpjb250cmFjdCBFdmlkZW5jZXsKICAgIAogICAgc3RyaW5nIGV2aWRlbmNlOwogICAgc3RyaW5nIGV2aWRlbmNlSW5mbzsKICAgIHN0cmluZyBldmlkZW5jZUlkOwogICAgdWludDhbXSBfdjsKICAgIGJ5dGVzMzJbXSBfcjsKICAgIGJ5dGVzMzJbXSBfczsKICAgIGFkZHJlc3NbXSBzaWduZXJzOwogICAgYWRkcmVzcyBwdWJsaWMgc2lnbmVyc0FkZHI7CiAgICAKICAgICAgICBldmVudCBhZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IG5ld1NpZ25hdHVyZXNFdmVudChzdHJpbmcgZXZpLCBzdHJpbmcgaW5mbywgc3RyaW5nIGlkLCB1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcyxhZGRyZXNzIGFkZHIpOwogICAgICAgIGV2ZW50IGVycm9yTmV3U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLGFkZHJlc3MgYWRkcik7CiAgICAgICAgZXZlbnQgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsYWRkcmVzcyBhZGRyKTsKICAgICAgICBldmVudCBhZGRSZXBlYXRTaWduYXR1cmVzRXZlbnQoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMpOwogICAgICAgIGV2ZW50IGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KHN0cmluZyBldmksIHN0cmluZyBpZCwgdWludDggdiwgYnl0ZXMzMiByLCBieXRlczMyIHMsIGFkZHJlc3MgYWRkcik7CgogICAgZnVuY3Rpb24gQ2FsbFZlcmlmeShhZGRyZXNzIGFkZHIpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpIHsKICAgICAgICByZXR1cm4gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikudmVyaWZ5KGFkZHIpOwogICAgfQoKICAgICAgIGZ1bmN0aW9uIEV2aWRlbmNlKHN0cmluZyBldmksIHN0cmluZyBpbmZvLCBzdHJpbmcgaWQsIHVpbnQ4IHYsIGJ5dGVzMzIgciwgYnl0ZXMzMiBzLCBhZGRyZXNzIGFkZHIsIGFkZHJlc3Mgc2VuZGVyKSBwdWJsaWMgewogICAgICAgc2lnbmVyc0FkZHIgPSBhZGRyOwogICAgICAgaWYoQ2FsbFZlcmlmeShzZW5kZXIpKQogICAgICAgewogICAgICAgICAgIGV2aWRlbmNlID0gZXZpOwogICAgICAgICAgIGV2aWRlbmNlSW5mbyA9IGluZm87CiAgICAgICAgICAgZXZpZGVuY2VJZCA9IGlkOwogICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgX3IucHVzaChyKTsKICAgICAgICAgICBfcy5wdXNoKHMpOwogICAgICAgICAgIHNpZ25lcnMucHVzaChzZW5kZXIpOwogICAgICAgICAgIG5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgICAgIGVsc2UKICAgICAgIHsKICAgICAgICAgICBlcnJvck5ld1NpZ25hdHVyZXNFdmVudChldmksaW5mbyxpZCx2LHIscyxhZGRyKTsKICAgICAgIH0KICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZ2V0RXZpZGVuY2VJbmZvKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoc3RyaW5nKXsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlSW5mbzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZSgpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKHN0cmluZyxzdHJpbmcsc3RyaW5nLHVpbnQ4W10sYnl0ZXMzMltdLGJ5dGVzMzJbXSxhZGRyZXNzW10pewogICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICByZXR1cm4oZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsX3YsX3IsX3Msc2lnbmVyTGlzdCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU2lnbmF0dXJlcyh1aW50OCB2LCBieXRlczMyIHIsIGJ5dGVzMzIgcykgcHVibGljIHJldHVybnMoYm9vbCkgewogICAgICAgIGZvcih1aW50IGk9IDAgO2k8c2lnbmVycy5sZW5ndGggO2krKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1zZy5zZW5kZXIgPT0gc2lnbmVyc1tpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoIF92W2ldID09IHYgJiYgX3JbaV0gPT0gciAmJiBfc1tpXSA9PSBzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFkZFJlcGVhdFNpZ25hdHVyZXNFdmVudChldmlkZW5jZSxldmlkZW5jZUluZm8sZXZpZGVuY2VJZCx2LHIscyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVwZWF0U2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgIGlmKENhbGxWZXJpZnkobXNnLnNlbmRlcikpCiAgICAgICB7CiAgICAgICAgICAgIF92LnB1c2godik7CiAgICAgICAgICAgIF9yLnB1c2gocik7CiAgICAgICAgICAgIF9zLnB1c2gocyk7CiAgICAgICAgICAgIHNpZ25lcnMucHVzaChtc2cuc2VuZGVyKTsKICAgICAgICAgICAgYWRkU2lnbmF0dXJlc0V2ZW50KGV2aWRlbmNlLGV2aWRlbmNlSW5mbyxldmlkZW5jZUlkLHYscixzKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgICAgZXJyb3JBZGRTaWduYXR1cmVzRXZlbnQoZXZpZGVuY2UsZXZpZGVuY2VJbmZvLGV2aWRlbmNlSWQsdixyLHMsbXNnLnNlbmRlcik7CiAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgfQogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRTaWduZXJzKClwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzW10pCiAgICB7CiAgICAgICAgIHVpbnQgbGVuZ3RoID0gRXZpZGVuY2VTaWduZXJzRGF0YUFCSShzaWduZXJzQWRkcikuZ2V0U2lnbmVyc1NpemUoKTsKICAgICAgICAgYWRkcmVzc1tdIG1lbW9yeSBzaWduZXJMaXN0ID0gbmV3IGFkZHJlc3NbXShsZW5ndGgpOwogICAgICAgICBmb3IodWludCBpPSAwIDtpPGxlbmd0aCA7aSsrKQogICAgICAgICB7CiAgICAgICAgICAgICBzaWduZXJMaXN0W2ldID0gKEV2aWRlbmNlU2lnbmVyc0RhdGFBQkkoc2lnbmVyc0FkZHIpLmdldFNpZ25lcihpKSk7CiAgICAgICAgIH0KICAgICAgICAgcmV0dXJuIHNpZ25lckxpc3Q7CiAgICB9Cn0=", + "contractDesc_en" : "" + }, + { + "contractId" : 7, + "contractFolderId" : 2, + "contractName" : "EvidenceSignersData", + "contractDesc" : "# Evidence 合约\n\n## 简介\nEvidence 示例合约,使用分层的智能合约结构: \n1)工厂合约(EvidenceSignersData.sol),由存证各方事前约定,存储存证生效条件,并管理存证的生成。 \n2)存证合约(Evidence.sol),由工厂合约生成,存储存证id,hash和各方签名(每张存证一个合约)。 ", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuNDsKaW1wb3J0ICJFdmlkZW5jZS5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VTaWduZXJzRGF0YXsKICAgICAgICBhZGRyZXNzW10gc2lnbmVyczsKCQlldmVudCBuZXdFdmlkZW5jZUV2ZW50KGFkZHJlc3MgYWRkcik7CiAgICAgICAgZnVuY3Rpb24gbmV3RXZpZGVuY2Uoc3RyaW5nIGV2aSwgc3RyaW5nIGluZm8sc3RyaW5nIGlkLHVpbnQ4IHYsIGJ5dGVzMzIgcixieXRlczMyIHMpcHVibGljIHJldHVybnMoYWRkcmVzcykKICAgICAgICB7CiAgICAgICAgICAgIEV2aWRlbmNlIGV2aWRlbmNlID0gbmV3IEV2aWRlbmNlKGV2aSwgaW5mbywgaWQsIHYsIHIsIHMsIHRoaXMsIG1zZy5zZW5kZXIpOwogICAgICAgICAgICBuZXdFdmlkZW5jZUV2ZW50KGV2aWRlbmNlKTsKICAgICAgICAgICAgcmV0dXJuIGV2aWRlbmNlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gRXZpZGVuY2VTaWduZXJzRGF0YShhZGRyZXNzW10gZXZpZGVuY2VTaWduZXJzKXB1YmxpY3sKICAgICAgICAgICAgZm9yKHVpbnQgaT0wOyBpPGV2aWRlbmNlU2lnbmVycy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICBzaWduZXJzLnB1c2goZXZpZGVuY2VTaWduZXJzW2ldKTsKCQkJfQoJCX0KCiAgICBmdW5jdGlvbiB2ZXJpZnkoYWRkcmVzcyBhZGRyKXB1YmxpYyBjb25zdGFudCByZXR1cm5zKGJvb2wpewogICAgZm9yKHVpbnQgaT0wOyBpPHNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZiAoYWRkciA9PSBzaWduZXJzW2ldKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyKHVpbnQgaW5kZXgpcHVibGljIGNvbnN0YW50IHJldHVybnMoYWRkcmVzcyl7CiAgICAgICAgdWludCBsaXN0U2l6ZSA9IHNpZ25lcnMubGVuZ3RoOwogICAgICAgIGlmKGluZGV4IDwgbGlzdFNpemUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc2lnbmVyc1tpbmRleF07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVyc1NpemUoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyh1aW50KXsKICAgICAgICByZXR1cm4gc2lnbmVycy5sZW5ndGg7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2lnbmVycygpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKGFkZHJlc3NbXSl7CiAgICAgICAgcmV0dXJuIHNpZ25lcnM7CiAgICB9Cgp9", + "contractDesc_en" : "" + }, + { + "contractId" : 8, + "contractFolderId" : 3, + "contractName" : "BAC001", + "contractDesc" : "# 积分合约\n\n## 简介\n BAC001 是一套区块链积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能。\n\n## 四个基本元素\n\n- description \n\n 此积分的具体描述\n\n- shortName \n\n 积分简称\n\n- minUnit \n\n 积分最小单位\n\n- totalAmount \n\n 积分总数量\n\n## 五个基本行为: \n\n- 发行\n\n 调用合约的 deploy 方法,传入你初始化的四个元素即可,即在区块链上发行了你指定总量和名称的积分。\n\n - 其中 minUnit 和 totalAmount 不能为负数或小数\n\n- 转账\n\n 调用 send 方法即可实现转账,之后调用 balance 方法可以查看自己的积分余额\n\n- 增发\n\n 调用 issue 方法特定地址增发积分, 并可以通过 addIssuer 增加有权限增发积分的人,也可以通过renounceIssuer 方法移除增发权限\n\n- 销毁\n\n 调用 destroy 以及 destroyFrom 销毁自己地址下积分和特定地址下的积分\n\n- 暂停\n\n 遇到紧急状况,你可以调用 suspend 方法,暂停合约,这样任何人都不能调用 send 函数。故障修复后,可以调用 unSuspend 方法解除暂停。也可以通过 addSuspender 和 renounceSuspender 相应增加和移除暂停者权限\n\n\n## 接口说明\n\n- totalAmount()\n\n 返回积分总量\n\n - 这里的积分总量需要计算最小转账单位,所以实际返回值为 totalAmount * 10minUnit \n\n- balance(address owner)\n\n 返回owner的帐户的积分余额\n\n- send(address to, uint256 value , string data)\n\n 将数量为value的积分转入地址 to 并触发 transfer 事件, data 是转账备注\n\n - suspend 状态下无法进行此操作\n - 请避免 to 为自身进行操作\n\n- sendFrom(address from,address to,uint256 value,string data))\n\n 将地址 from 中的 value 数量的积分转入地址 to ,并触发 transfer 事件,data 是转账备注。\n\n - 方法的调用者可以不为 from, 此时需要预先进行 approve 授权\n\n - from 不能为调用者自身地址,否则会报错\n - suspend 状态下无法执行此操作\n\n- safeSendFrom(address from, address to, uint256 value, string data)\n\n 安全的将地址 from 中的 value 数量的积分转入地址 to ( to如果是合约地址,必须实现接收接口 BAC001Holder 才可以接收转账) ,并触发 transfer 事件,data 是转账备注\n\n - suspend 状态下无法执行此操作\n\n- safeBatchSend( address[] to, uint256[] values, string data)\n\n 批量将自己账户下的积分转给 to 数组的地址, to 和 values 的个数要一致\n\n - suspend 状态下无法执行此操作\n\n- approve(address spender,uint256 value)\n\n 允许 spender 从自己账户提取限额 value 的积分\n\n - 此方法配合 sendfrom / safesendfrom 一起使用\n - 重复授权时,最终授权额度为最后一次授权的值\n\n- allowance(address owner,address spender)\n\n 返回 spender 可从 owner 提取的积分数量上限\n\n - 此方法配合 approve 一起使用\n\n- increaseAllowance(address spender, uint256 addedValue)\n\n 允许 spender 提取的积分上限在原有基础上增加 addedValue\n\n - 此方法配合 approve 使用\n\n- decreaseAllowance(address spender, uint256 subtractedValue)\n\n 允许 spender 提取的积分上限在原有基础上减少 subtractedValue\n\n - 此方法配合 approve 使用\n\n- minUnit()\n\n 积分最小单位\n\n- shortName()\n\n 积分简称\n\n- description()\n\n 积分描述\n\n- destroy(uint256 value, string data)\n\n 减少自己的积分,data 是转账备注\n\n - 调用时,value 值需要小于等于目前自己的积分总量\n\n- destroyFrom(address from, uint256 value, string data)\n\n 减少地址 from 积分,data 是转账备注\n\n - 调用此方法时,需要配合 approve 进行使用\n\n- issue(address to, uint256 value,string data)\n\n 给地址 to 增加数量为 value 的积分,data 是转账备注\n\n- isIssuer(address account)\n\n 检查 account 是否有增加积分的权限\n\n- addIssuer(address account)\n\n 使地址 account 拥有增加积分的权限\n\n- renounceIssuer()\n\n 移除增加积分的权限\n\n- suspend()\n\n 暂停合约\n\n - suspend 后无法进行 send / safesendfrom / sendfrom / safeBatchSend / approves 操作\n\n- unSuspend()\n\n 重启合约\n \n- suspended\n\n 判断合约是否处于暂停状态\n\n- isSuspender(address account)\n\n 是否有暂停合约权限\n\n - 配合 suspend 方法一起使用\n\n- addSuspender(address account)\n\n 增加暂停权限者\n\n - 配合 suspend 方法一起使用\n\n- renounceSuspender()\n\n 移除暂停权限\n\n - 配合 suspend / addSuspender 方法使用\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==", + "contractDesc_en" : "" + }, + { + "contractId" : 9, + "contractFolderId" : 3, + "contractName" : "IBAC001", + "contractDesc" : "# 积分合约\n\n## 简介\n BAC001 是一套区块链积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能。\n\n## 四个基本元素\n\n- description \n\n 此积分的具体描述\n\n- shortName \n\n 积分简称\n\n- minUnit \n\n 积分最小单位\n\n- totalAmount \n\n 积分总数量\n\n## 五个基本行为: \n\n- 发行\n\n 调用合约的 deploy 方法,传入你初始化的四个元素即可,即在区块链上发行了你指定总量和名称的积分。\n\n - 其中 minUnit 和 totalAmount 不能为负数或小数\n\n- 转账\n\n 调用 send 方法即可实现转账,之后调用 balance 方法可以查看自己的积分余额\n\n- 增发\n\n 调用 issue 方法特定地址增发积分, 并可以通过 addIssuer 增加有权限增发积分的人,也可以通过renounceIssuer 方法移除增发权限\n\n- 销毁\n\n 调用 destroy 以及 destroyFrom 销毁自己地址下积分和特定地址下的积分\n\n- 暂停\n\n 遇到紧急状况,你可以调用 suspend 方法,暂停合约,这样任何人都不能调用 send 函数。故障修复后,可以调用 unSuspend 方法解除暂停。也可以通过 addSuspender 和 renounceSuspender 相应增加和移除暂停者权限\n\n\n## 接口说明\n\n- totalAmount()\n\n 返回积分总量\n\n - 这里的积分总量需要计算最小转账单位,所以实际返回值为 totalAmount * 10minUnit \n\n- balance(address owner)\n\n 返回owner的帐户的积分余额\n\n- send(address to, uint256 value , string data)\n\n 将数量为value的积分转入地址 to 并触发 transfer 事件, data 是转账备注\n\n - suspend 状态下无法进行此操作\n - 请避免 to 为自身进行操作\n\n- sendFrom(address from,address to,uint256 value,string data))\n\n 将地址 from 中的 value 数量的积分转入地址 to ,并触发 transfer 事件,data 是转账备注。\n\n - 方法的调用者可以不为 from, 此时需要预先进行 approve 授权\n\n - from 不能为调用者自身地址,否则会报错\n - suspend 状态下无法执行此操作\n\n- safeSendFrom(address from, address to, uint256 value, string data)\n\n 安全的将地址 from 中的 value 数量的积分转入地址 to ( to如果是合约地址,必须实现接收接口 BAC001Holder 才可以接收转账) ,并触发 transfer 事件,data 是转账备注\n\n - suspend 状态下无法执行此操作\n\n- safeBatchSend( address[] to, uint256[] values, string data)\n\n 批量将自己账户下的积分转给 to 数组的地址, to 和 values 的个数要一致\n\n - suspend 状态下无法执行此操作\n\n- approve(address spender,uint256 value)\n\n 允许 spender 从自己账户提取限额 value 的积分\n\n - 此方法配合 sendfrom / safesendfrom 一起使用\n - 重复授权时,最终授权额度为最后一次授权的值\n\n- allowance(address owner,address spender)\n\n 返回 spender 可从 owner 提取的积分数量上限\n\n - 此方法配合 approve 一起使用\n\n- increaseAllowance(address spender, uint256 addedValue)\n\n 允许 spender 提取的积分上限在原有基础上增加 addedValue\n\n - 此方法配合 approve 使用\n\n- decreaseAllowance(address spender, uint256 subtractedValue)\n\n 允许 spender 提取的积分上限在原有基础上减少 subtractedValue\n\n - 此方法配合 approve 使用\n\n- minUnit()\n\n 积分最小单位\n\n- shortName()\n\n 积分简称\n\n- description()\n\n 积分描述\n\n- destroy(uint256 value, string data)\n\n 减少自己的积分,data 是转账备注\n\n - 调用时,value 值需要小于等于目前自己的积分总量\n\n- destroyFrom(address from, uint256 value, string data)\n\n 减少地址 from 积分,data 是转账备注\n\n - 调用此方法时,需要配合 approve 进行使用\n\n- issue(address to, uint256 value,string data)\n\n 给地址 to 增加数量为 value 的积分,data 是转账备注\n\n- isIssuer(address account)\n\n 检查 account 是否有增加积分的权限\n\n- addIssuer(address account)\n\n 使地址 account 拥有增加积分的权限\n\n- renounceIssuer()\n\n 移除增加积分的权限\n\n- suspend()\n\n 暂停合约\n\n - suspend 后无法进行 send / safesendfrom / sendfrom / safeBatchSend / approves 操作\n\n- unSuspend()\n\n 重启合约\n \n- suspended\n\n 判断合约是否处于暂停状态\n\n- isSuspender(address account)\n\n 是否有暂停合约权限\n\n - 配合 suspend 方法一起使用\n\n- addSuspender(address account)\n\n 增加暂停权限者\n\n - 配合 suspend 方法一起使用\n\n- renounceSuspender()\n\n 移除暂停权限\n\n - 配合 suspend / addSuspender 方法使用\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==", + "contractDesc_en" : "" + }, + { + "contractId" : 10, + "contractFolderId" : 3, + "contractName" : "Roles", + "contractDesc" : "# Roles\n\nRole permissions control contracts\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=", + "contractDesc_en" : "" + }, + { + "contractId" : 11, + "contractFolderId" : 3, + "contractName" : "SafeMath", + "contractDesc" : "# SafeMath\n\nSafeMath library\n\nA secure mathematical library that provides a safe addition, subtract, and divide。The use of secure mathematical contracts can refer to the Points contract warehouse。", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=", + "contractDesc_en" : "" + }, + { + "contractId" : 12, + "contractFolderId" : 3, + "contractName" : "Address", + "contractDesc" : "# Address\n\nAddress library\n\nAddress contract usage methods can refer to the Points contract warehouse。\n\n1. Detect whether the address is a contract\n2. Detect if the address is 0x0", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=", + "contractDesc_en" : "" + }, + { + "contractId" : 13, + "contractFolderId" : 4, + "contractName" : "Crypto", + "contractDesc" : "# Crypto\n\nCrypto Interface Contract\nSupported in FISCO-BCOS above version of v2.8.0, [Crypto API](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/default/Crypto.html)\n", + "contractSrc" : "LyoqCiAqIG9ubHkgc3VwcG9ydGVkIGluIEZJU0NPLUJDT1MgdjIuOC4wKyAKICovCmNvbnRyYWN0IENyeXB0bwp7CiAgICBmdW5jdGlvbiBzbTMoYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMil7fQogICAgZnVuY3Rpb24ga2VjY2FrMjU2SGFzaChieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljIHZpZXcgcmV0dXJucyhieXRlczMyKXt9CiAgICBmdW5jdGlvbiBzbTJWZXJpZnkoYnl0ZXMzMiAgbWVzc2FnZSwgYnl0ZXMgbWVtb3J5IHB1YmxpY0tleSwgYnl0ZXMzMiByLCBieXRlczMyIHMpIHB1YmxpYyB2aWV3IHJldHVybnMoYm9vbCwgYWRkcmVzcyl7fQogICAgZnVuY3Rpb24gY3VydmUyNTUxOVZSRlZlcmlmeShzdHJpbmcgbWVtb3J5IGlucHV0LCBzdHJpbmcgbWVtb3J5IHZyZlB1YmxpY0tleSwgc3RyaW5nIG1lbW9yeSB2cmZQcm9vZikgcHVibGljIHZpZXcgcmV0dXJucyhib29sLHVpbnQyNTYpe30KfQ==", + "contractDesc_en" : "# Crypto\n\nCrypto Interface Contract\nSupported in FISCO-BCOS above version of v2.8.0, [Crypto API](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/default/Crypto.html)\n" + }, + { + "contractId" : 14, + "contractFolderId" : 4, + "contractName" : "ShaTest", + "contractDesc" : "# ShaTest\n\nCrypto Interface Contract\n\nCrypto Test Contract, Supported in FISCO-BCOS above version of v2.8.0, [Crypto API](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/default/Crypto.html)\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgpwcmFnbWEgZXhwZXJpbWVudGFsIEFCSUVuY29kZXJWMjsKCmltcG9ydCAiLi9DcnlwdG8uc29sIjsKCi8qKgogKiBvbmx5IHN1cHBvcnRlZCBpbiBGSVNDTy1CQ09TIHYyLjguMCsgCiAqLwpjb250cmFjdCBTaGFUZXN0ewogICAgYnl0ZXMgX2RhdGEgPSAiSGVsbG8sIFNoYVRlc3QiOwogICAgQ3J5cHRvIGNyeXB0bzsKCiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgY3J5cHRvID0gQ3J5cHRvKDB4NTAwNik7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0U2hhMjU2KGJ5dGVzIG1lbW9yeSBfbWVtb3J5KSBwdWJsaWMgcmV0dXJucyhieXRlczMyIHJlc3VsdCkKICAgIHsKICAgICAgICByZXR1cm4gc2hhMjU2KF9tZW1vcnkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldEtlY2NhazI1NihieXRlcyBtZW1vcnkgX21lbW9yeSkgcHVibGljIHJldHVybnMoYnl0ZXMzMiByZXN1bHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGtlY2NhazI1NihfbWVtb3J5KTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXREYXRhKCkgcHVibGljIHZpZXcgcmV0dXJucyhieXRlcyBtZW1vcnkpCiAgICB7CiAgICAgICAgcmV0dXJuIF9kYXRhOwogICAgfQp9Cg==", + "contractDesc_en" : "# ShaTest\n\nCrypto Interface Contract\n\nCrypto Test Contract, Supported in FISCO-BCOS above version of v2.8.0, [Crypto API](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/default/Crypto.html)\n" + }, + { + "contractId" : 15, + "contractFolderId" : 4, + "contractName" : "HelloWorld", + "contractDesc" : "# HelloWorld\n\nHelloWorld Contract\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBIZWxsb1dvcmxkIHsKICAgIHN0cmluZyBuYW1lOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljIHsKICAgICAgICBuYW1lID0gIkhlbGxvLCBXb3JsZCEiOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgIH0KCiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nIG1lbW9yeSBuKSBwdWJsaWMgewogICAgICAgIG5hbWUgPSBuOwogICAgfQp9", + "contractDesc_en" : "# HelloWorld\n\nHelloWorld Contract\n" + }, + { + "contractId" : 16, + "contractFolderId" : 4, + "contractName" : "KVTableTest", + "contractDesc" : "# KVTableTest\n\nKVTable contract for CRUD \n\nCRUD Test, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgppbXBvcnQgIi4vVGFibGUuc29sIjsKCmNvbnRyYWN0IEtWVGFibGVUZXN0IHsKICAgIGV2ZW50IFNldFJlc3VsdChpbnQyNTYgY291bnQpOwoKICAgIEtWVGFibGVGYWN0b3J5IHRhYmxlRmFjdG9yeTsKICAgIHN0cmluZyBjb25zdGFudCBUQUJMRV9OQU1FID0gInRfa3Z0ZXN0IjsKCiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgLy9UaGUgZml4ZWQgYWRkcmVzcyBpcyAweDEwMTAgZm9yIEtWVGFibGVGYWN0b3J5CiAgICAgICAgdGFibGVGYWN0b3J5ID0gS1ZUYWJsZUZhY3RvcnkoMHgxMDEwKTsKICAgICAgICAvLyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVUYWJsZSBhcmUgdGFibGVOYW1lLGtleUZpZWxkLCJ2bGF1ZUZpbGVkMSx2bGF1ZUZpbGVkMix2bGF1ZUZpbGVkMywuLi4iCiAgICAgICAgdGFibGVGYWN0b3J5LmNyZWF0ZVRhYmxlKFRBQkxFX05BTUUsICJpZCIsICJpdGVtX3ByaWNlLGl0ZW1fbmFtZSIpOwogICAgfQoKICAgIC8vZ2V0IHJlY29yZAogICAgZnVuY3Rpb24gZ2V0KHN0cmluZyBtZW1vcnkgaWQpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJvb2wsIGludDI1Niwgc3RyaW5nIG1lbW9yeSkgewogICAgICAgIEtWVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwogICAgICAgIGJvb2wgb2sgPSBmYWxzZTsKICAgICAgICBFbnRyeSBlbnRyeTsKICAgICAgICAob2ssIGVudHJ5KSA9IHRhYmxlLmdldChpZCk7CiAgICAgICAgaW50MjU2IGl0ZW1fcHJpY2U7CiAgICAgICAgc3RyaW5nIG1lbW9yeSBpdGVtX25hbWU7CiAgICAgICAgaWYgKG9rKSB7CiAgICAgICAgICAgIGl0ZW1fcHJpY2UgPSBlbnRyeS5nZXRJbnQoIml0ZW1fcHJpY2UiKTsKICAgICAgICAgICAgaXRlbV9uYW1lID0gZW50cnkuZ2V0U3RyaW5nKCJpdGVtX25hbWUiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChvaywgaXRlbV9wcmljZSwgaXRlbV9uYW1lKTsKICAgIH0KCiAgICAvL3NldCByZWNvcmQKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcgbWVtb3J5IGlkLCBpbnQyNTYgaXRlbV9wcmljZSwgc3RyaW5nIG1lbW9yeSBpdGVtX25hbWUpCiAgICBwdWJsaWMKICAgIHJldHVybnMgKGludDI1NikKICAgIHsKICAgICAgICBLVlRhYmxlIHRhYmxlID0gdGFibGVGYWN0b3J5Lm9wZW5UYWJsZShUQUJMRV9OQU1FKTsKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgLy8gdGhlIGxlbmd0aCBvZiBlbnRyeSdzIGZpZWxkIHZhbHVlIHNob3VsZCA8IDE2TUIKICAgICAgICBlbnRyeS5zZXQoImlkIiwgaWQpOwogICAgICAgIGVudHJ5LnNldCgiaXRlbV9wcmljZSIsIGl0ZW1fcHJpY2UpOwogICAgICAgIGVudHJ5LnNldCgiaXRlbV9uYW1lIiwgaXRlbV9uYW1lKTsKICAgICAgICAvLyB0aGUgZmlyc3QgcGFyYW1ldGVyIGxlbmd0aCBvZiBzZXQgc2hvdWxkIDw9IDI1NUIKICAgICAgICBpbnQyNTYgY291bnQgPSB0YWJsZS5zZXQoaWQsIGVudHJ5KTsKICAgICAgICBlbWl0IFNldFJlc3VsdChjb3VudCk7CiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQp9", + "contractDesc_en" : "# KVTableTest\n\nKVTable contract for CRUD \n\nCRUD Test, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n" + }, + { + "contractId" : 17, + "contractFolderId" : 4, + "contractName" : "Table", + "contractDesc" : "# Table\n\nTable contract for CRUD, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7Cgpjb250cmFjdCBUYWJsZUZhY3RvcnkgewogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoVGFibGUpOyAvL29wZW4gdGFibGUKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOyAvL2NyZWF0ZSB0YWJsZQp9CgovL3NlbGVjdCBjb25kaXRpb24KY29udHJhY3QgQ29uZGl0aW9uIHsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgc3RyaW5nKSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgYWRkcmVzcykgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQyNTYpIHB1YmxpYyB2aWV3OwogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyB2aWV3OwoKICAgIGZ1bmN0aW9uIEdUKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50MjU2KSBwdWJsaWMgdmlldzsKCiAgICBmdW5jdGlvbiBMVChzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludDI1NikgcHVibGljIHZpZXc7CgogICAgZnVuY3Rpb24gbGltaXQoaW50MjU2KSBwdWJsaWMgdmlldzsKICAgIGZ1bmN0aW9uIGxpbWl0KGludDI1NiwgaW50MjU2KSBwdWJsaWMgdmlldzsKfQoKLy9vbmUgcmVjb3JkCmNvbnRyYWN0IEVudHJ5IHsKICAgIGZ1bmN0aW9uIGdldEludChzdHJpbmcpIHB1YmxpYyB2aWV3IHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRVSW50KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CiAgICBmdW5jdGlvbiBnZXRBZGRyZXNzKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcyk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMxWzY0XSk7CiAgICBmdW5jdGlvbiBnZXRCeXRlczMyKHN0cmluZykgcHVibGljIHZpZXcgcmV0dXJucyAoYnl0ZXMzMik7CiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcpOwoKICAgIGZ1bmN0aW9uIHNldChzdHJpbmcsIGludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgdWludDI1NikgcHVibGljOwogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBhZGRyZXNzKSBwdWJsaWM7Cn0KCi8vcmVjb3JkIHNldHMKY29udHJhY3QgRW50cmllcyB7CiAgICBmdW5jdGlvbiBnZXQoaW50MjU2KSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIHZpZXcgcmV0dXJucyAoaW50MjU2KTsKfQoKLy9UYWJsZSBtYWluIGNvbnRyYWN0CmNvbnRyYWN0IFRhYmxlIHsKICAgIGZ1bmN0aW9uIHNlbGVjdChzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHZpZXcgcmV0dXJucyAoRW50cmllcyk7CiAgICBmdW5jdGlvbiBpbnNlcnQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiB1cGRhdGUoc3RyaW5nLCBFbnRyeSwgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KTsKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcsIENvbmRpdGlvbikgcHVibGljIHJldHVybnMgKGludDI1Nik7CgogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgdmlldyByZXR1cm5zIChFbnRyeSk7CiAgICBmdW5jdGlvbiBuZXdDb25kaXRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChDb25kaXRpb24pOwp9Cgpjb250cmFjdCBLVlRhYmxlRmFjdG9yeSB7CiAgICBmdW5jdGlvbiBvcGVuVGFibGUoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChLVlRhYmxlKTsKICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHB1YmxpYyByZXR1cm5zIChpbnQyNTYpOwp9CgovL0tWVGFibGUgcGVyIHBlcm1pYXJ5IGtleSBoYXMgb25seSBvbmUgRW50cnkKY29udHJhY3QgS1ZUYWJsZSB7CiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sLCBFbnRyeSk7CiAgICBmdW5jdGlvbiBzZXQoc3RyaW5nLCBFbnRyeSkgcHVibGljIHJldHVybnMgKGludDI1Nik7CiAgICBmdW5jdGlvbiBuZXdFbnRyeSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKEVudHJ5KTsKfQo=", + "contractDesc_en" : "# Table\n\nTable contract for CRUD, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n" + }, + { + "contractId" : 18, + "contractFolderId" : 4, + "contractName" : "TableTest", + "contractDesc" : "# TableTest\n\nTable contract for CRUD \n\nCRUD Test, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CnByYWdtYSBleHBlcmltZW50YWwgQUJJRW5jb2RlclYyOwoKaW1wb3J0ICIuL1RhYmxlLnNvbCI7Cgpjb250cmFjdCBUYWJsZVRlc3QgewogICAgZXZlbnQgQ3JlYXRlUmVzdWx0KGludDI1NiBjb3VudCk7CiAgICBldmVudCBJbnNlcnRSZXN1bHQoaW50MjU2IGNvdW50KTsKICAgIGV2ZW50IFVwZGF0ZVJlc3VsdChpbnQyNTYgY291bnQpOwogICAgZXZlbnQgUmVtb3ZlUmVzdWx0KGludDI1NiBjb3VudCk7CgogICAgVGFibGVGYWN0b3J5IHRhYmxlRmFjdG9yeTsKICAgIHN0cmluZyBjb25zdGFudCBUQUJMRV9OQU1FID0gInRfdGVzdCI7CiAgICBjb25zdHJ1Y3RvcigpIHB1YmxpYyB7CiAgICAgICAgdGFibGVGYWN0b3J5ID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7IC8vVGhlIGZpeGVkIGFkZHJlc3MgaXMgMHgxMDAxIGZvciBUYWJsZUZhY3RvcnkKICAgICAgICAvLyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVUYWJsZSBhcmUgdGFibGVOYW1lLGtleUZpZWxkLCJ2bGF1ZUZpbGVkMSx2bGF1ZUZpbGVkMix2bGF1ZUZpbGVkMywuLi4iCiAgICAgICAgdGFibGVGYWN0b3J5LmNyZWF0ZVRhYmxlKFRBQkxFX05BTUUsICJuYW1lIiwgIml0ZW1faWQsaXRlbV9uYW1lIik7CiAgICB9CgogICAgLy9zZWxlY3QgcmVjb3JkcwogICAgZnVuY3Rpb24gc2VsZWN0KHN0cmluZyBtZW1vcnkgbmFtZSkKICAgIHB1YmxpYwogICAgdmlldwogICAgcmV0dXJucyAoc3RyaW5nW10gbWVtb3J5LCBpbnQyNTZbXSBtZW1vcnksIHN0cmluZ1tdIG1lbW9yeSkKICAgIHsKICAgICAgICBUYWJsZSB0YWJsZSA9IHRhYmxlRmFjdG9yeS5vcGVuVGFibGUoVEFCTEVfTkFNRSk7CgogICAgICAgIENvbmRpdGlvbiBjb25kaXRpb24gPSB0YWJsZS5uZXdDb25kaXRpb24oKTsKCiAgICAgICAgRW50cmllcyBlbnRyaWVzID0gdGFibGUuc2VsZWN0KG5hbWUsIGNvbmRpdGlvbik7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IHVzZXJfbmFtZV9ieXRlc19saXN0ID0gbmV3IHN0cmluZ1tdKAogICAgICAgICAgICB1aW50MjU2KGVudHJpZXMuc2l6ZSgpKQogICAgICAgICk7CiAgICAgICAgaW50MjU2W10gbWVtb3J5IGl0ZW1faWRfbGlzdCA9IG5ldyBpbnQyNTZbXSh1aW50MjU2KGVudHJpZXMuc2l6ZSgpKSk7CiAgICAgICAgc3RyaW5nW10gbWVtb3J5IGl0ZW1fbmFtZV9ieXRlc19saXN0ID0gbmV3IHN0cmluZ1tdKAogICAgICAgICAgICB1aW50MjU2KGVudHJpZXMuc2l6ZSgpKQogICAgICAgICk7CgogICAgICAgIGZvciAoaW50MjU2IGkgPSAwOyBpIDwgZW50cmllcy5zaXplKCk7ICsraSkgewogICAgICAgICAgICBFbnRyeSBlbnRyeSA9IGVudHJpZXMuZ2V0KGkpOwoKICAgICAgICAgICAgdXNlcl9uYW1lX2J5dGVzX2xpc3RbdWludDI1NihpKV0gPSBlbnRyeS5nZXRTdHJpbmcoIm5hbWUiKTsKICAgICAgICAgICAgaXRlbV9pZF9saXN0W3VpbnQyNTYoaSldID0gZW50cnkuZ2V0SW50KCJpdGVtX2lkIik7CiAgICAgICAgICAgIGl0ZW1fbmFtZV9ieXRlc19saXN0W3VpbnQyNTYoaSldID0gZW50cnkuZ2V0U3RyaW5nKCJpdGVtX25hbWUiKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAodXNlcl9uYW1lX2J5dGVzX2xpc3QsIGl0ZW1faWRfbGlzdCwgaXRlbV9uYW1lX2J5dGVzX2xpc3QpOwogICAgfQogICAgLy9pbnNlcnQgcmVjb3JkcwogICAgZnVuY3Rpb24gaW5zZXJ0KHN0cmluZyBtZW1vcnkgbmFtZSwgaW50MjU2IGl0ZW1faWQsIHN0cmluZyBtZW1vcnkgaXRlbV9uYW1lKQogICAgcHVibGljCiAgICByZXR1cm5zIChpbnQyNTYpCiAgICB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgZW50cnkuc2V0KCJuYW1lIiwgbmFtZSk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX2lkIiwgaXRlbV9pZCk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX25hbWUiLCBpdGVtX25hbWUpOwoKICAgICAgICBpbnQyNTYgY291bnQgPSB0YWJsZS5pbnNlcnQobmFtZSwgZW50cnkpOwogICAgICAgIGVtaXQgSW5zZXJ0UmVzdWx0KGNvdW50KTsKCiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQogICAgLy91cGRhdGUgcmVjb3JkcwogICAgZnVuY3Rpb24gdXBkYXRlKHN0cmluZyBtZW1vcnkgbmFtZSwgaW50MjU2IGl0ZW1faWQsIHN0cmluZyBtZW1vcnkgaXRlbV9uYW1lKQogICAgcHVibGljCiAgICByZXR1cm5zIChpbnQyNTYpCiAgICB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7CiAgICAgICAgZW50cnkuc2V0KCJpdGVtX25hbWUiLCBpdGVtX25hbWUpOwoKICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJpdGVtX2lkIiwgaXRlbV9pZCk7CgogICAgICAgIGludDI1NiBjb3VudCA9IHRhYmxlLnVwZGF0ZShuYW1lLCBlbnRyeSwgY29uZGl0aW9uKTsKICAgICAgICBlbWl0IFVwZGF0ZVJlc3VsdChjb3VudCk7CgogICAgICAgIHJldHVybiBjb3VudDsKICAgIH0KICAgIC8vcmVtb3ZlIHJlY29yZHMKICAgIGZ1bmN0aW9uIHJlbW92ZShzdHJpbmcgbWVtb3J5IG5hbWUsIGludDI1NiBpdGVtX2lkKSBwdWJsaWMgcmV0dXJucyAoaW50MjU2KSB7CiAgICAgICAgVGFibGUgdGFibGUgPSB0YWJsZUZhY3Rvcnkub3BlblRhYmxlKFRBQkxFX05BTUUpOwoKICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgY29uZGl0aW9uLkVRKCJpdGVtX2lkIiwgaXRlbV9pZCk7CgogICAgICAgIGludDI1NiBjb3VudCA9IHRhYmxlLnJlbW92ZShuYW1lLCBjb25kaXRpb24pOwogICAgICAgIGVtaXQgUmVtb3ZlUmVzdWx0KGNvdW50KTsKCiAgICAgICAgcmV0dXJuIGNvdW50OwogICAgfQp9Cg==", + "contractDesc_en" : "# TableTest\n\nTable contract for CRUD \n\nCRUD Test, [CRUD API](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/articles/3_features/33_storage/crud_guidance.html)\n" + }, + { + "contractId" : 19, + "contractFolderId" : 5, + "contractName" : "EvidenceController", + "contractDesc" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离", + "contractSrc" : "Ci8qCiAqIENvcHlyaWdodCAyMDE0LTIwMTkgdGhlIG9yaWdpbmFsIGF1dGhvciBvciBhdXRob3JzLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICogKi8KCnByYWdtYSBzb2xpZGl0eSA+PTAuNC4yNCA8MC42LjExOyAKCmltcG9ydCAiLi9SZXF1ZXN0UmVwb3NpdG9yeS5zb2wiOwppbXBvcnQgIi4vRXZpZGVuY2VSZXBvc2l0b3J5LnNvbCI7Cgpjb250cmFjdCBFdmlkZW5jZUNvbnRyb2xsZXJ7CiAgICBSZXF1ZXN0UmVwb3NpdG9yeSBwdWJsaWMgX3JlcXVlc3RSZXBvOwogICAgRXZpZGVuY2VSZXBvc2l0b3J5IHB1YmxpYyBfZXZpZGVuY2VSZXBvOwoKICAgIGV2ZW50IENyZWF0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaW5kZXhlZCBoYXNoLCBhZGRyZXNzIGNyZWF0b3IpOyAgIAogICAgZXZlbnQgVm90ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaW5kZXhlZCBoYXNoLCBhZGRyZXNzIHZvdGVyLCBib29sIGNvbXBsZXRlKTsKICAgIGV2ZW50IEV2aWRlbmNlU2F2ZWQoYnl0ZXMzMiBpbmRleGVkIGhhc2gpOwoKICAgIGNvbnN0cnVjdG9yKHVpbnQ4IHRocmVzaG9sZCwgYWRkcmVzc1tdIG1lbW9yeSB2b3RlckFycmF5KSBwdWJsaWN7CiAgICAgICAgX3JlcXVlc3RSZXBvID0gbmV3IFJlcXVlc3RSZXBvc2l0b3J5KHRocmVzaG9sZCwgdm90ZXJBcnJheSk7CiAgICAgICAgX2V2aWRlbmNlUmVwbyA9IG5ldyBFdmlkZW5jZVJlcG9zaXRvcnkoKTsKICAgIH0KCiAgICBtb2RpZmllciB2YWxpZGF0ZUhhc2goYnl0ZXMzMiBoYXNoKXsKICAgICAgcmVxdWlyZShoYXNoICE9IDAsICJOb3QgdmFsaWQgaGFzaCIpOwogICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaGFzaCwgYnl0ZXMgbWVtb3J5IGV4dCkgcHVibGljIHZhbGlkYXRlSGFzaChoYXNoKXsKICAgICAgICBfcmVxdWVzdFJlcG8uY3JlYXRlU2F2ZVJlcXVlc3QoaGFzaCwgbXNnLnNlbmRlciwgZXh0KTsKICAgICAgICBlbWl0IENyZWF0ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIHZvdGVTYXZlUmVxdWVzdChieXRlczMyIGhhc2gpIHB1YmxpYyB2YWxpZGF0ZUhhc2goaGFzaCkgcmV0dXJucyhib29sKXsKICAgICAgICBib29sIGIgPSBfcmVxdWVzdFJlcG8udm90ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIpOwogICAgICAgIGlmKCFiKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgKGJ5dGVzMzIgaCwgYWRkcmVzcyBjcmVhdG9yLCBieXRlcyBtZW1vcnkgZXh0LCAgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCkgPSAgX3JlcXVlc3RSZXBvLmdldFJlcXVlc3REYXRhKGhhc2gpOwogICAgICAgIGJvb2wgcGFzc2VkID0gdm90ZWQgPj0gdGhyZXNob2xkOwogICAgICAgIGVtaXQgVm90ZVNhdmVSZXF1ZXN0KGhhc2gsIG1zZy5zZW5kZXIsIHBhc3NlZCk7CiAgICAgICAgaWYocGFzc2VkKXsKICAgICAgICAgICAgX2V2aWRlbmNlUmVwby5zZXREYXRhKGhhc2gsIGNyZWF0b3IsIG5vdyk7CiAgICAgICAgICAgIF9yZXF1ZXN0UmVwby5kZWxldGVTYXZlUmVxdWVzdChoYXNoKTsKICAgICAgICAgICAgZW1pdCBFdmlkZW5jZVNhdmVkKGhhc2gpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRSZXF1ZXN0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IAogICAgICByZXR1cm5zKGJ5dGVzMzIsIGFkZHJlc3MgY3JlYXRvciwgYnl0ZXMgbWVtb3J5IGV4dCwgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCl7CiAgICAgICAgcmV0dXJuIF9yZXF1ZXN0UmVwby5nZXRSZXF1ZXN0RGF0YShoYXNoKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRFdmlkZW5jZShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMiAsIGFkZHJlc3MsIHVpbnQpewogICAgICAgIHJldHVybiBfZXZpZGVuY2VSZXBvLmdldERhdGEoaGFzaCk7CiAgICB9Cn0K", + "contractDesc_en" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离" + }, + { + "contractId" : 20, + "contractFolderId" : 5, + "contractName" : "EvidenceRepository", + "contractDesc" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离", + "contractSrc" : "LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CmltcG9ydCAiLi9BdXRoZW50aWNhdGlvbi5zb2wiOwoKY29udHJhY3QgRXZpZGVuY2VSZXBvc2l0b3J5IGlzIEF1dGhlbnRpY2F0aW9uIHsgICAgCiAgICBzdHJ1Y3QgRXZpZGVuY2VEYXRhewogICAgICAgIGJ5dGVzMzIgaGFzaDsKICAgICAgICBhZGRyZXNzIG93bmVyOwogICAgICAgIHVpbnQgdGltZXN0YW1wOwogICAgfQogICAgbWFwcGluZyhieXRlczMyPT5FdmlkZW5jZURhdGEpIHByaXZhdGUgX2V2aWRlbmNlczsgIAogICAgCiAgICBmdW5jdGlvbiBzZXREYXRhKGJ5dGVzMzIgaGFzaCwgYWRkcmVzcyBvd25lciwgdWludCB0aW1lc3RhbXApIHB1YmxpYyBhdXRoIHsKICAgICAgICBfZXZpZGVuY2VzW2hhc2hdLmhhc2ggPSBoYXNoOwogICAgICAgIF9ldmlkZW5jZXNbaGFzaF0ub3duZXIgPSBvd25lcjsKICAgICAgICBfZXZpZGVuY2VzW2hhc2hdLnRpbWVzdGFtcCA9IHRpbWVzdGFtcDsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gZ2V0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IHJldHVybnMoYnl0ZXMzMiAsIGFkZHJlc3MsIHVpbnQpewogICAgICAgIEV2aWRlbmNlRGF0YSBzdG9yYWdlIGV2aWRlbmNlID0gX2V2aWRlbmNlc1toYXNoXTsKICAgICAgICByZXF1aXJlKGV2aWRlbmNlLmhhc2ggPT0gaGFzaCwgIkV2aWRlbmNlIG5vdCBleGlzdCIpOwogICAgICAgIHJldHVybiAoZXZpZGVuY2UuaGFzaCwgZXZpZGVuY2Uub3duZXIsIGV2aWRlbmNlLnRpbWVzdGFtcCk7CiAgICB9Cn0K", + "contractDesc_en" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离" + }, + { + "contractId" : 21, + "contractFolderId" : 5, + "contractName" : "RequestRepository", + "contractDesc" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离", + "contractSrc" : "LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7CgppbXBvcnQgIi4vQXV0aGVudGljYXRpb24uc29sIjsKCmNvbnRyYWN0IFJlcXVlc3RSZXBvc2l0b3J5IGlzIEF1dGhlbnRpY2F0aW9ueyAgICAKICAgIHN0cnVjdCBTYXZlUmVxdWVzdHsKICAgICAgICBieXRlczMyIGhhc2g7CiAgICAgICAgYWRkcmVzcyBjcmVhdG9yOwogICAgICAgIHVpbnQ4IHZvdGVkOwogICAgICAgIGJ5dGVzIGV4dDsKICAgICAgICBtYXBwaW5nKGFkZHJlc3M9PmJvb2wpIHN0YXR1czsKICAgIH0KICAgIHVpbnQ4IHB1YmxpYyBfdGhyZXNob2xkOwogICAgbWFwcGluZyhieXRlczMyPT5TYXZlUmVxdWVzdCkgcHJpdmF0ZSBfc2F2ZVJlcXVlc3RzOwogICAgbWFwcGluZyhhZGRyZXNzPT5ib29sKSBwcml2YXRlIF92b3RlcnM7CiAgICAKICAgIGNvbnN0cnVjdG9yKHVpbnQ4IHRocmVzaG9sZCwgYWRkcmVzc1tdIG1lbW9yeSB2b3RlckFycmF5KSBwdWJsaWN7CiAgICAgICAgX3RocmVzaG9sZCA9IHRocmVzaG9sZDsKICAgICAgICBmb3IodWludCBpPTA7aTx2b3RlckFycmF5Lmxlbmd0aDtpKyspewogICAgICAgICAgICBfdm90ZXJzW3ZvdGVyQXJyYXlbaV1dID0gdHJ1ZTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY3JlYXRlU2F2ZVJlcXVlc3QoYnl0ZXMzMiBoYXNoLCBhZGRyZXNzIG93bmVyLCBieXRlcyBtZW1vcnkgZXh0KSBwdWJsaWMgYXV0aHsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSAwLCAicmVxdWVzdCBhbHJlYWR5IGV4aXN0ZWQiKTsKICAgICAgICBfc2F2ZVJlcXVlc3RzW2hhc2hdLmhhc2ggPSBoYXNoOwogICAgICAgIF9zYXZlUmVxdWVzdHNbaGFzaF0uY3JlYXRvciA9IG93bmVyOwogICAgICAgIF9zYXZlUmVxdWVzdHNbaGFzaF0uZXh0ID0gZXh0OwogICAgfQoKICAgIGZ1bmN0aW9uIHZvdGVTYXZlUmVxdWVzdChieXRlczMyIGhhc2gsIGFkZHJlc3Mgdm90ZXIpIHB1YmxpYyBhdXRoIHJldHVybnMgKGJvb2wpewogICAgICAgIHJlcXVpcmUoX3ZvdGVyc1t2b3Rlcl0gPT0gdHJ1ZSwgIk5vdCBhbGxvd2VkIHRvIHZvdGUiKTsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSBoYXNoLCAicmVxdWVzdCBub3QgZm91bmQiKTsKICAgICAgICBTYXZlUmVxdWVzdCBzdG9yYWdlIHJlcXVlc3QgPSBfc2F2ZVJlcXVlc3RzW2hhc2hdOwogICAgICAgIHJlcXVpcmUocmVxdWVzdC5zdGF0dXNbdm90ZXJdID09IGZhbHNlLCAiVm90ZXIgYWxyZWFkeSB2b3RlZCIpOwogICAgICAgIHJlcXVlc3Quc3RhdHVzW3ZvdGVyXSA9IHRydWU7CiAgICAgICAgcmVxdWVzdC52b3RlZCsrOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgCiAgICBmdW5jdGlvbiBnZXRSZXF1ZXN0RGF0YShieXRlczMyIGhhc2gpIHB1YmxpYyB2aWV3IAogICAgICByZXR1cm5zKGJ5dGVzMzIsIGFkZHJlc3MgY3JlYXRvciwgYnl0ZXMgbWVtb3J5IGV4dCwgdWludDggdm90ZWQsIHVpbnQ4IHRocmVzaG9sZCl7CiAgICAgICAgU2F2ZVJlcXVlc3Qgc3RvcmFnZSByZXF1ZXN0ID0gX3NhdmVSZXF1ZXN0c1toYXNoXTsKICAgICAgICByZXF1aXJlKF9zYXZlUmVxdWVzdHNbaGFzaF0uaGFzaCA9PSBoYXNoLCAicmVxdWVzdCBub3QgZm91bmQiKTsKICAgICAgICByZXR1cm4gKGhhc2gsIHJlcXVlc3QuY3JlYXRvciwgcmVxdWVzdC5leHQsIHJlcXVlc3Qudm90ZWQsIF90aHJlc2hvbGQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlbGV0ZVNhdmVSZXF1ZXN0KGJ5dGVzMzIgaGFzaCkgcHVibGljIGF1dGggewogICAgICAgIHJlcXVpcmUoX3NhdmVSZXF1ZXN0c1toYXNoXS5oYXNoID09IGhhc2gsICJyZXF1ZXN0IG5vdCBmb3VuZCIpOwogICAgICAgIGRlbGV0ZSBfc2F2ZVJlcXVlc3RzW2hhc2hdOwogICAgfQp9Cg==", + "contractDesc_en" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离" + }, + { + "contractId" : 22, + "contractFolderId" : 5, + "contractName" : "Authentication", + "contractDesc" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离", + "contractSrc" : "LyoKICogQ29weXJpZ2h0IDIwMTQtMjAxOSB0aGUgb3JpZ2luYWwgYXV0aG9yIG9yIGF1dGhvcnMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgogKiAqLwoKcHJhZ21hIHNvbGlkaXR5ID49MC40LjI0IDwwLjYuMTE7Cgpjb250cmFjdCBBdXRoZW50aWNhdGlvbnsKICAgIGFkZHJlc3MgcHVibGljIF9vd25lcjsKICAgIG1hcHBpbmcoYWRkcmVzcz0+Ym9vbCkgcHJpdmF0ZSBfYWNsOwoKICAgIGNvbnN0cnVjdG9yKCkgcHVibGljewogICAgICBfb3duZXIgPSBtc2cuc2VuZGVyOwogICAgfSAKCiAgICBtb2RpZmllciBvbmx5T3duZXIoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciwgIk5vdCBhZG1pbiIpOwogICAgICBfOwogICAgfQoKICAgIG1vZGlmaWVyIGF1dGgoKXsKICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IF9vd25lciB8fCBfYWNsW21zZy5zZW5kZXJdPT10cnVlLCAiTm90IGF1dGhlbnRpY2F0ZWQiKTsKICAgICAgXzsKICAgIH0KCiAgICBmdW5jdGlvbiBhbGxvdyhhZGRyZXNzIGFkZHIpIHB1YmxpYyBvbmx5T3duZXJ7CiAgICAgIF9hY2xbYWRkcl0gPSB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlbnkoYWRkcmVzcyBhZGRyKSBwdWJsaWMgb25seU93bmVyewogICAgICBfYWNsW2FkZHJdID0gZmFsc2U7CiAgICB9Cn0K", + "contractDesc_en" : "# Evidence存证\n\n## 简介\n\n存证操作,上传、审批、修改、删除等,详情查看[Smart-Dev Evidence Doc](https://toolkit-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/api/business_template/Evidence.html)\n\n合约:\n1) EvidenceController 对外服务的唯一接口\n2) EvidenceRepository 辅助合约,用于数据和逻辑分离\n3) RequestRepository 辅助合约,用于数据和逻辑分离\n4) Authentication 辅助合约,用于数据和逻辑分离" + }, + { + "contractId" : 23, + "contractFolderId" : 6, + "contractName" : "BAC002", + "contractDesc" : "# BAC002 合约规范\n\n## 简介\n BAC002 是区块链上定义非同质化资产的一种标准,可以用于唯一性资产类型,如房产、汽车、道具、版权等。,并可以做相应增发,销毁,暂停合约,黑白名单等权限控制。\n## 三个基本元素\n- description\n\n 资产的具体描述\n\n- shortName\n\n 资产简称\n\n- assetId\n\n 资产编号\n\n ## 五个基本行为\n- 发行\n\n 调用合约的 deploy 方法,传入 description 和 shortName,即在区块链上发行指定名称的资产\n\n- 转账\n\n 调用 safeSendFrom 方法实现转账,调用 balance 方法可以查看自己的资产数量\n\n- 增发\n\n 调用 issueWithAssetURI 方法向资产地址增发指定资产编号和资产描述链接信息的资产。另外,可以通过 addIssuer 增加 有权限增发资产的人,也可以通过 renounceIssuer 方法移除增发权限\n\n- 销毁\n\n 调用 destroy 以及 destroyFrom 销毁自己地址下资产和特定地址下的资产\n\n- 暂停\n\n 遇到紧急状况,你可以调用 suspend 方法,暂停合约,这样任何人都不能调用 send 函数。故障修复后,可以调用 unSuspend 方法解除暂停。也可以通过 addSuspender 和 renounceSuspender 相应增加和移除暂停者权限\n\n\n## 接口说明\n\n- shortName()\n\n 资产简称\n\n- description()\n\n 资产描述\n\n- balance(address owner)\n\n 返回 owner 的资产总数\n\n- totalSupply()\n\n 获得当前合约总的资产数目\n\n- ownerOf(uint256 assetId)\n\n 返回资产持有者的地址\n\n- approve(address to, uint256 assetId)\n\n 授予地址to具有指定资产的控制权\n\n - 此方法配合 getapproved 使用\n\n- getApproved(uint256 assetId)\n\n 获得资产授权的地址用户\n\n - 此方法配合 approve 使用,注意不要配合 setapprovealforall 方法使用\n\n- setApprovalForAll(address operator, bool approved)\n\n 授予地址operator具有自己所有资产的控制权\n\n- isApprovedForAll(address owner, address operator)\n\n 查询授权\n\n- sendFrom(address from, address to, uint256 assetId, bytes memory data)\n\n 安全转账,防止你转到错误的合约地址 ( to如果是合约地址,必须实现接收接口 BAC002Holder 才可以接收转账 ),并可以带转账备注\n\n - suspend 状态下无法执行此操作\n\n- batchSendFrom(address from, address[] to, uint256[] assetId, bytes memory data)\n\n 批量安全转账\n\n - suspend 状态下无法执行此操作\n - to 数组元素个数需要和 assetid 数组元素个数一致\n\n- issueWithAssetURI(address to, uint256 assetId, string memory assetURI, bytes data)\n\n 给地址 to 创建资产 assetId,data 是转账备注, assetURI 资产描述\n\n- isIssuer(address account)\n\n 检查account是否有增加资产的权限\n\n- addIssuer(address account)\n\n 使地址 account 拥有增加资产的权限\n\n- renounceIssuer()\n\n 移除增加资产的权限\n\n- suspend()\n\n 暂停合约\n\n - suspend 后无法进行 safesendfrom / sendfrom / safeBatchSendFrom 操作\n\n- unSuspend()\n\n 重启合约\n\n - 此方法配合 suspend 使用\n\n- isSuspender(address account)\n\n 是否有暂停合约权限\n\n - 此方法配合 addsuspender 使用\n\n- addSuspender(address account)\n\n 增加暂停权限者\n\n - 此方法配合 renouncesuspender / issuspender 放啊发使用\n\n- renounceSuspender()\n\n 移除暂停权限\n\n- destroy(uint256 assetId, bytes data)\n\n 减少自己的资产,data 是转账备注\n\n - 调用时,value 值需要小于等于目前自己的资产总量\n\n- assetOfOwnerByIndex(address owner, uint256 index)\n\n 根据索引 index 获取 owner 的资产 ID\n\n- assetByIndex(uint256 index)\n\n 根据索引 index 获取当前合约的资产 ID\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CgppbXBvcnQgIi4vUmVnaXN0ZXIuc29sIjsKaW1wb3J0ICIuL0NvdW50ZXJzLnNvbCI7CmltcG9ydCAiLi9Sb2xlcy5zb2wiOwoKCmNvbnRyYWN0IElCQUMwMDJSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAyIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMlJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiBhc3NldElkLCBieXRlcyBtZW1vcnkgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDJIb2xkZXIgaXMgSUJBQzAwMlJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAyUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMgbWVtb3J5KSBwdWJsaWMgcmV0dXJucyAoYnl0ZXM0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMub25CQUMwMDJSZWNlaXZlZC5zZWxlY3RvcjsKICAgIH0KfQoKY29udHJhY3QgSXNzdWVyUm9sZSB7CiAgICB1c2luZyBSb2xlcyBmb3IgUm9sZXMuUm9sZTsKCiAgICBldmVudCBJc3N1ZXJBZGRlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CiAgICBldmVudCBJc3N1ZXJSZW1vdmVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKCiAgICBSb2xlcy5Sb2xlIHByaXZhdGUgX2lzc3VlcnM7CgogICAgY29uc3RydWN0b3IgKCkgaW50ZXJuYWwgewogICAgICAgIF9hZGRJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgbW9kaWZpZXIgb25seUlzc3VlcigpIHsKICAgICAgICByZXF1aXJlKGlzSXNzdWVyKG1zZy5zZW5kZXIpLCAiSXNzdWVyUm9sZTogY2FsbGVyIGRvZXMgbm90IGhhdmUgdGhlIElzc3VlciByb2xlIik7CiAgICAgICAgXzsKICAgIH0KCiAgICBmdW5jdGlvbiBpc0lzc3VlcihhZGRyZXNzIGFjY291bnQpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX2lzc3VlcnMuaGFzKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIHB1YmxpYyBvbmx5SXNzdWVyIHsKICAgICAgICBfYWRkSXNzdWVyKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbm91bmNlSXNzdWVyKCkgcHVibGljIHsKICAgICAgICBfcmVtb3ZlSXNzdWVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9hZGRJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX2lzc3VlcnMuYWRkKGFjY291bnQpOwogICAgICAgIGVtaXQgSXNzdWVyQWRkZWQoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gX3JlbW92ZUlzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5yZW1vdmUoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJSZW1vdmVkKGFjY291bnQpOwogICAgfQp9Cgpjb250cmFjdCBTdXNwZW5kZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IFN1c3BlbmRlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IFN1c3BlbmRlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfc3VzcGVuZGVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5U3VzcGVuZGVyKCkgewogICAgICAgIHJlcXVpcmUoaXNTdXNwZW5kZXIobXNnLnNlbmRlciksICJTdXNwZW5kZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgU3VzcGVuZGVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfc3VzcGVuZGVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlTdXNwZW5kZXIgewogICAgICAgIF9hZGRTdXNwZW5kZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VTdXNwZW5kZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVTdXNwZW5kZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBTdXNwZW5kZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRhYmxlIGlzIFN1c3BlbmRlclJvbGUgewoKICAgIGV2ZW50IFN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwogICAgZXZlbnQgVW5TdXNwZW5kZWQoYWRkcmVzcyBhY2NvdW50KTsKCiAgICBib29sIHByaXZhdGUgX3N1c3BlbmRlZDsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQsIGZhbHNlIG90aGVyd2lzZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZGVkKCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfc3VzcGVuZGVkOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBub3Qgc3VzcGVuZGVkLgogICAgICovCiAgICBtb2RpZmllciB3aGVuTm90U3VzcGVuZGVkKCkgewogICAgICAgIHJlcXVpcmUoIV9zdXNwZW5kZWQsICJTdXNwZW5kYWJsZTogc3VzcGVuZGVkIik7CiAgICAgICAgXzsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgTW9kaWZpZXIgdG8gbWFrZSBhIGZ1bmN0aW9uIGNhbGxhYmxlIG9ubHkgd2hlbiB0aGUgY29udHJhY3QgaXMgc3VzcGVuZGVkLgogICAgICovCiAgICBtb2RpZmllciB3aGVuU3VzcGVuZGVkKCkgewogICAgICAgIHJlcXVpcmUoX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBub3Qgc3VzcGVuZGVkIik7CiAgICAgICAgXzsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQ2FsbGVkIGJ5IGEgU3VzcGVuZGVyIHRvIHN1c3BlbmQsIHRyaWdnZXJzIHN0b3BwZWQgc3RhdGUuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHN1c3BlbmQoKSBwdWJsaWMgb25seVN1c3BlbmRlciB3aGVuTm90U3VzcGVuZGVkIHsKICAgICAgICBfc3VzcGVuZGVkID0gdHJ1ZTsKICAgICAgICBlbWl0IFN1c3BlbmRlZChtc2cuc2VuZGVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQ2FsbGVkIGJ5IGEgU3VzcGVuZGVyIHRvIHVuU3VzcGVuZCwgcmV0dXJucyB0byBub3JtYWwgc3RhdGUuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHVuU3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5TdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSBmYWxzZTsKICAgICAgICBlbWl0IFVuU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQp9CgovL2RlbGV0ZSByZWdpc3Rlcgpjb250cmFjdCBCQUMwMDIgaXMgIElzc3VlclJvbGUsIFN1c3BlbmRhYmxlIHsKICAgIHVzaW5nIFNhZmVNYXRoIGZvciB1aW50MjU2OwogICAgdXNpbmcgQWRkcmVzcyBmb3IgYWRkcmVzczsKICAgIHVzaW5nIENvdW50ZXJzIGZvciBDb3VudGVycy5Db3VudGVyOwoKICAgIC8vIEVxdWFscyB0byBgYnl0ZXM0KGtlY2NhazI1Nigib25CQUMwMDJSZWNlaXZlZChhZGRyZXNzLGFkZHJlc3MsdWludDI1NixieXRlcykiKSlgCiAgICBieXRlczQgcHJpdmF0ZSBjb25zdGFudCBfQkFDMDAyX1JFQ0VJVkVEID0gMHgzMWY2ZjUwZTsKCiAgICAvLyBNYXBwaW5nIGZyb20gYXNzZXQgSUQgdG8gb3duZXIKICAgIG1hcHBpbmcodWludDI1NiA9PiBhZGRyZXNzKSBwcml2YXRlIF9hc3NldE93bmVyOwoKICAgIC8vIE1hcHBpbmcgZnJvbSBhc3NldCBJRCB0byBhcHByb3ZlZCBhZGRyZXNzCiAgICBtYXBwaW5nKHVpbnQyNTYgPT4gYWRkcmVzcykgcHJpdmF0ZSBfYXNzZXRBcHByb3ZhbHM7CgogICAgLy8gTWFwcGluZyBmcm9tIG93bmVyIHRvIG51bWJlciBvZiBvd25lZCBhc3NldAogICAgbWFwcGluZyhhZGRyZXNzID0+IENvdW50ZXJzLkNvdW50ZXIpIHByaXZhdGUgX293bmVkQXNzZXRzQ291bnQ7CgogICAgLy8gTWFwcGluZyBmcm9tIG93bmVyIHRvIG9wZXJhdG9yIGFwcHJvdmFscwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiBib29sKSkgcHJpdmF0ZSBfb3BlcmF0b3JBcHByb3ZhbHM7CgogICAgc3RyaW5nIHByaXZhdGUgX2Rlc2NyaXB0aW9uOwoKICAgIHN0cmluZyBwcml2YXRlIF9zaG9ydE5hbWU7CgogICAgLy8gT3B0aW9uYWwgbWFwcGluZyBmb3IgYXNzZXQgVVJJcwogICAgbWFwcGluZyh1aW50MjU2ID0+IHN0cmluZykgcHJpdmF0ZSBfYXNzZXRVUklzOwoKICAgIC8vIE1hcHBpbmcgZnJvbSBvd25lciB0byBsaXN0IG9mIG93bmVkIGFzc2V0IElEcwogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTZbXSkgcHJpdmF0ZSBfb3duZWRBc3NldHM7CgogICAgLy8gTWFwcGluZyBmcm9tIGFzc2V0IElEIHRvIGluZGV4IG9mIHRoZSBvd25lciBhc3NldHMgbGlzdAogICAgbWFwcGluZyh1aW50MjU2ID0+IHVpbnQyNTYpIHByaXZhdGUgX293bmVkQXNzZXRzSW5kZXg7CgogICAgLy8gQXJyYXkgd2l0aCBhbGwgYXNzZXQgaWRzLCB1c2VkIGZvciBlbnVtZXJhdGlvbgogICAgdWludDI1NltdIHByaXZhdGUgX2FsbEFzc2V0czsKCiAgICAvLyBNYXBwaW5nIGZyb20gYXNzZXQgaWQgdG8gcG9zaXRpb24gaW4gdGhlIGFsbEFzc2V0cyBhcnJheQogICAgbWFwcGluZyh1aW50MjU2ID0+IHVpbnQyNTYpIHByaXZhdGUgX2FsbEFzc2V0c0luZGV4OwoKICAgIGV2ZW50IFNlbmQoYWRkcmVzcyBpbmRleGVkIG9wZXJhdG9yLCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIGRhdGEpOwogICAgZXZlbnQgQXBwcm92YWwoIGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBhcHByb3ZlZCwgdWludDI1NiBhc3NldElkKTsKICAgIGV2ZW50IEFwcHJvdmFsRm9yQWxsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBvcGVyYXRvciwgYm9vbCBhcHByb3ZlZCk7CgogICAgLy8gY29uc3RydWN0b3IKICAgIGNvbnN0cnVjdG9yKHN0cmluZyBkZXNjcmlwdGlvbiwgc3RyaW5nIHNob3J0TmFtZSkgcHVibGljCiAgICB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgR2V0cyB0aGUgYmFsYW5jZSBvZiB0aGUgc3BlY2lmaWVkIGFkZHJlc3MuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGJhbGFuY2UoYWRkcmVzcyBvd25lcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMjogYmFsYW5jZSBxdWVyeSBmb3IgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiBfb3duZWRBc3NldHNDb3VudFtvd25lcl0uY3VycmVudCgpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBHZXRzIHRoZSBvd25lciBvZiB0aGUgc3BlY2lmaWVkIGFzc2V0IElELgogICAgICovCiAgICBmdW5jdGlvbiBvd25lck9mKHVpbnQyNTYgYXNzZXRJZCkgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcykgewogICAgICAgIGFkZHJlc3Mgb3duZXIgPSBfYXNzZXRPd25lclthc3NldElkXTsKICAgICAgICByZXF1aXJlKG93bmVyICE9IGFkZHJlc3MoMCksICJCQUMwMDI6IG93bmVyIHF1ZXJ5IGZvciBub25leGlzdGVudCBhc3NldCIpOwogICAgICAgIHJldHVybiBvd25lcjsKICAgIH0KCgogICAgZnVuY3Rpb24gYXNzZXRPZk93bmVyQnlJbmRleChhZGRyZXNzIG93bmVyLCB1aW50MjU2IGluZGV4KSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShpbmRleCA8IGJhbGFuY2Uob3duZXIpLCAiQkFDMDAyRW51bWVyYWJsZTogb3duZXIgaW5kZXggb3V0IG9mIGJvdW5kcyIpOwogICAgICAgIHJldHVybiBfb3duZWRBc3NldHNbb3duZXJdW2luZGV4XTsKICAgIH0KCiAgICBmdW5jdGlvbiBhc3NldE9mT3duZXIoYWRkcmVzcyBvd25lcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NltdKSB7CiAgICAgICAgcmV0dXJuIF9vd25lZEFzc2V0c1tvd25lcl07CiAgICB9CgoKICAgIGZ1bmN0aW9uIGFzc2V0QnlJbmRleCh1aW50MjU2IGluZGV4KSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShpbmRleCA8IHRvdGFsU3VwcGx5KCksICJCQUMwMDJFbnVtZXJhYmxlOiBnbG9iYWwgaW5kZXggb3V0IG9mIGJvdW5kcyIpOwogICAgICAgIHJldHVybiBfYWxsQXNzZXRzW2luZGV4XTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZXMgYW5vdGhlciBhZGRyZXNzIHRvIHNlbmQgdGhlIGdpdmVuIGFzc2V0IElECiAgICAgKi8KICAgIGZ1bmN0aW9uIGFwcHJvdmUoYWRkcmVzcyB0bywgdWludDI1NiBhc3NldElkKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgYWRkcmVzcyBvd25lciA9IG93bmVyT2YoYXNzZXRJZCk7CiAgICAgICAgcmVxdWlyZSh0byAhPSBvd25lciwgIkJBQzAwMjogYXBwcm92YWwgdG8gY3VycmVudCBvd25lciIpOwoKICAgICAgICByZXF1aXJlKG1zZy5zZW5kZXIgPT0gb3duZXIgfHwgaXNBcHByb3ZlZEZvckFsbChvd25lciwgbXNnLnNlbmRlciksCiAgICAgICAgICAgICJCQUMwMDI6IGFwcHJvdmUgY2FsbGVyIGlzIG5vdCBvd25lciBub3IgYXBwcm92ZWQgZm9yIGFsbCIKICAgICAgICApOwogICAgICAgIF9hc3NldEFwcHJvdmFsc1thc3NldElkXSA9IHRvOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCB0bywgYXNzZXRJZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEdldHMgdGhlIGFwcHJvdmVkIGFkZHJlc3MgZm9yIGEgYXNzZXQgSUQsIG9yIHplcm8gaWYgbm8gYWRkcmVzcyBzZXQKICAgICAqLwogICAgZnVuY3Rpb24gZ2V0QXBwcm92ZWQodWludDI1NiBhc3NldElkKSBwdWJsaWMgdmlldyByZXR1cm5zIChhZGRyZXNzKSB7CiAgICAgICAgcmVxdWlyZShfZXhpc3RzKGFzc2V0SWQpLCAiQkFDMDAyOiBhcHByb3ZlZCBxdWVyeSBmb3Igbm9uZXhpc3RlbnQgYXNzZXQiKTsKICAgICAgICByZXR1cm4gX2Fzc2V0QXBwcm92YWxzW2Fzc2V0SWRdOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZXRzIG9yIHVuc2V0cyB0aGUgYXBwcm92YWwgb2YgYSBnaXZlbiBvcGVyYXRvcgogICAgICovCiAgICBmdW5jdGlvbiBzZXRBcHByb3ZhbEZvckFsbChhZGRyZXNzIHRvLCBib29sIGFwcHJvdmVkKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgcmVxdWlyZSh0byAhPSBtc2cuc2VuZGVyLCAiQkFDMDAyOiBhcHByb3ZlIHRvIGNhbGxlciIpOwogICAgICAgIF9vcGVyYXRvckFwcHJvdmFsc1ttc2cuc2VuZGVyXVt0b10gPSBhcHByb3ZlZDsKICAgICAgICBlbWl0IEFwcHJvdmFsRm9yQWxsKCBtc2cuc2VuZGVyLCB0bywgYXBwcm92ZWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBUZWxscyB3aGV0aGVyIGFuIG9wZXJhdG9yIGlzIGFwcHJvdmVkIGJ5IGEgZ2l2ZW4gb3duZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGlzQXBwcm92ZWRGb3JBbGwoYWRkcmVzcyBvd25lciwgYWRkcmVzcyBvcGVyYXRvcikgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfb3BlcmF0b3JBcHByb3ZhbHNbb3duZXJdW29wZXJhdG9yXTsKICAgIH0KCi8vICAgIC8qKgovLyAgICAgKiBAZGV2IFNlbmRzIHRoZSBvd25lcnNoaXAgb2YgYSBnaXZlbiBhc3NldCBJRCB0byBhbm90aGVyIGFkZHJlc3MuCi8vICAgICAqLwovLyAgICBmdW5jdGlvbiBzZW5kRnJvbShhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHsKLy8gICAgICAgIC8vc29saGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGluZS1sZW5ndGgKLy8gICAgICAgIHJlcXVpcmUoX2lzQXBwcm92ZWRPck93bmVyKG1zZy5zZW5kZXIsIGFzc2V0SWQpLCAiQkFDMDAyOiBzZW5kIGNhbGxlciBpcyBub3Qgb3duZXIgbm9yIGFwcHJvdmVkIik7Ci8vICAgICAgICBfc2VuZEZyb20oZnJvbSwgdG8sIGFzc2V0SWQsIGRhdGEpOwovLyAgICB9CgogICAgLy8gLyoqCiAgICAvLyAgKiBAZGV2IFNhZmVseSBzZW5kcyB0aGUgb3duZXJzaGlwIG9mIGEgZ2l2ZW4gYXNzZXQgSUQgdG8gYW5vdGhlciBhZGRyZXNzCiAgICAvLyAgKi8KICAgIC8vIGZ1bmN0aW9uIHNhZmVTZW5kRnJvbShhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgLy8gICAgIHNhZmVTZW5kRnJvbShmcm9tLCB0bywgYXNzZXRJZCwgIiIpOwogICAgLy8gfQoKICAgIC8qKgogICAgICogQGRldiBTYWZlbHkgc2VuZHMgdGhlIG93bmVyc2hpcCBvZiBhIGdpdmVuIGFzc2V0IElEIHRvIGFub3RoZXIgYWRkcmVzcwogICAgICovCiAgICBmdW5jdGlvbiBzZW5kRnJvbShhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHsKCgogICAgICAgIHJlcXVpcmUoX2lzQXBwcm92ZWRPck93bmVyKG1zZy5zZW5kZXIsIGFzc2V0SWQpLCAiQkFDMDAyOiBzZW5kIGNhbGxlciBpcyBub3Qgb3duZXIgbm9yIGFwcHJvdmVkIik7CiAgICAgICAgX3NlbmRGcm9tKGZyb20sIHRvLCBhc3NldElkLCBkYXRhKTsKICAgICAgICByZXF1aXJlKF9jaGVja09uQkFDMDAyUmVjZWl2ZWQoZnJvbSwgdG8sIGFzc2V0SWQsIGRhdGEpLCAiQkFDMDAyOiBzZW5kIHRvIG5vbiBCQUMwMDJSZWNlaXZlciBpbXBsZW1lbnRlciIpOwogICAgfQoKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gYXNzZXRJZCwgYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHsKCiAgICAgICAgcmVxdWlyZSh0by5sZW5ndGggPT0gYXNzZXRJZC5sZW5ndGgsICJ0byBhbmQgYXNzZXRJZCBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CiAgICAgICAgICAgIHNlbmRGcm9tKGZyb20sIHRvW2ldLCBhc3NldElkW2ldLCBkYXRhKTsKCiAgICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgZGF0YSkgcHVibGljIHsKICAgICAgICAvL3NvbGhpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxpbmUtbGVuZ3RoCiAgICAgICAgcmVxdWlyZShfaXNBcHByb3ZlZE9yT3duZXIobXNnLnNlbmRlciwgYXNzZXRJZCksICJCQUMwMDJCdXJuYWJsZTogY2FsbGVyIGlzIG5vdCBvd25lciBub3IgYXBwcm92ZWQiKTsKICAgICAgICBfZGVzdHJveShhc3NldElkLCBkYXRhKTsKICAgIH0KCiAgICAvL2FkZCBpc3N1ZXJBZGRyZXNzCiAgICBmdW5jdGlvbiBpc3N1ZVdpdGhBc3NldFVSSShhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQsIHN0cmluZyBtZW1vcnkgYXNzZXRVUkksIGJ5dGVzIGRhdGEpIHB1YmxpYyBvbmx5SXNzdWVyIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfaXNzdWUoIHRvLCBhc3NldElkLCBkYXRhKTsKICAgICAgICBfc2V0QXNzZXRVUkkoYXNzZXRJZCwgYXNzZXRVUkkpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlc2NyaXB0aW9uKCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICBmdW5jdGlvbiBzaG9ydE5hbWUoKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyBhbiBVUkkgZm9yIGEgZ2l2ZW4gYXNzZXQgSUQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFzc2V0VVJJKHVpbnQyNTYgYXNzZXRJZCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmVxdWlyZShfZXhpc3RzKGFzc2V0SWQpLCAiQkFDMDAyTWV0YWRhdGE6IFVSSSBxdWVyeSBmb3Igbm9uZXhpc3RlbnQgYXNzZXQiKTsKICAgICAgICByZXR1cm4gX2Fzc2V0VVJJc1thc3NldElkXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdG8gc2V0IHRoZSBhc3NldCBVUkkgZm9yIGEgZ2l2ZW4gYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9zZXRBc3NldFVSSSh1aW50MjU2IGFzc2V0SWQsIHN0cmluZyBtZW1vcnkgdXJpKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShfZXhpc3RzKGFzc2V0SWQpLCAiQkFDMDAyTWV0YWRhdGE6IFVSSSBzZXQgb2Ygbm9uZXhpc3RlbnQgYXNzZXQiKTsKICAgICAgICBfYXNzZXRVUklzW2Fzc2V0SWRdID0gdXJpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBhc3NldCBleGlzdHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9leGlzdHModWludDI1NiBhc3NldElkKSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICBhZGRyZXNzIG93bmVyID0gX2Fzc2V0T3duZXJbYXNzZXRJZF07CiAgICAgICAgcmV0dXJuIG93bmVyICE9IGFkZHJlc3MoMCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gc3BlbmRlciBjYW4gc2VuZCBhIGdpdmVuIGFzc2V0IElELgogICAgICovCiAgICBmdW5jdGlvbiBfaXNBcHByb3ZlZE9yT3duZXIoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFzc2V0SWQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoX2V4aXN0cyhhc3NldElkKSwgIkJBQzAwMjogb3BlcmF0b3IgcXVlcnkgZm9yIG5vbmV4aXN0ZW50IGFzc2V0Iik7CiAgICAgICAgYWRkcmVzcyBvd25lciA9IG93bmVyT2YoYXNzZXRJZCk7CiAgICAgICAgcmV0dXJuIChzcGVuZGVyID09IG93bmVyIHx8IGdldEFwcHJvdmVkKGFzc2V0SWQpID09IHNwZW5kZXIgfHwgaXNBcHByb3ZlZEZvckFsbChvd25lciwgc3BlbmRlcikpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbnRlcm5hbCBmdW5jdGlvbiB0byBtaW50IGEgbmV3IGFzc2V0LgogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUodG8gIT0gYWRkcmVzcygwKSwgIkJBQzAwMjogbWludCB0byB0aGUgemVybyBhZGRyZXNzIik7CiAgICAgICAgcmVxdWlyZSghX2V4aXN0cyhhc3NldElkKSwgIkJBQzAwMjogYXNzZXQgYWxyZWFkeSBtaW50ZWQiKTsKCiAgICAgICAgX2Fzc2V0T3duZXJbYXNzZXRJZF0gPSB0bzsKICAgICAgICBfb3duZWRBc3NldHNDb3VudFt0b10uaW5jcmVtZW50KCk7CgogICAgICAgIGVtaXQgU2VuZChtc2cuc2VuZGVyLCBhZGRyZXNzKDApLCB0bywgYXNzZXRJZCwgZGF0YSk7CgogICAgICAgIF9hZGRBc3NldFRvT3duZXJFbnVtZXJhdGlvbih0bywgYXNzZXRJZCk7CgogICAgICAgIF9hZGRBc3NldFRvQWxsQXNzZXRzRW51bWVyYXRpb24oYXNzZXRJZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIGRlc3Ryb3kgYSBzcGVjaWZpYyBhc3NldC4KICAgICAqIFJldmVydHMgaWYgdGhlIGFzc2V0IGRvZXMgbm90IGV4aXN0LgogICAgICovCiAgICBmdW5jdGlvbiBfZGVzdHJveShhZGRyZXNzIG93bmVyLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKG93bmVyT2YoYXNzZXRJZCkgPT0gb3duZXIsICJCQUMwMDI6IGRlc3Ryb3kgb2YgYXNzZXQgdGhhdCBpcyBub3Qgb3duIik7CgogICAgICAgIF9jbGVhckFwcHJvdmFsKGFzc2V0SWQpOwoKICAgICAgICBfb3duZWRBc3NldHNDb3VudFtvd25lcl0uZGVjcmVtZW50KCk7CiAgICAgICAgX2Fzc2V0T3duZXJbYXNzZXRJZF0gPSBhZGRyZXNzKDApOwoKICAgICAgICBpZiAoYnl0ZXMoX2Fzc2V0VVJJc1thc3NldElkXSkubGVuZ3RoICE9IDApIHsKICAgICAgICAgICAgZGVsZXRlIF9hc3NldFVSSXNbYXNzZXRJZF07CiAgICAgICAgfQoKICAgICAgICBlbWl0IFNlbmQodGhpcywgb3duZXIsIGFkZHJlc3MoMCksIGFzc2V0SWQsIGRhdGEpOwoKICAgICAgICBfcmVtb3ZlQXNzZXRGcm9tT3duZXJFbnVtZXJhdGlvbihvd25lciwgYXNzZXRJZCk7CiAgICAgICAgLy8gU2luY2UgYXNzZXRJZCB3aWxsIGJlIGRlbGV0ZWQsIHdlIGNhbiBjbGVhciBpdHMgc2xvdCBpbiBfb3duZWRBc3NldHNJbmRleCB0byB0cmlnZ2VyIGEgZ2FzIHJlZnVuZAogICAgICAgIF9vd25lZEFzc2V0c0luZGV4W2Fzc2V0SWRdID0gMDsKCiAgICAgICAgX3JlbW92ZUFzc2V0RnJvbUFsbEFzc2V0c0VudW1lcmF0aW9uKGFzc2V0SWQpOwogICAgfQoKCiAgICAvKioKICAgICAqIEBkZXYgR2V0cyB0aGUgdG90YWwgYW1vdW50IG9mIGFzc2V0cyBzdG9yZWQgYnkgdGhlIGNvbnRyYWN0LgogICAgICogQHJldHVybiB1aW50MjU2IHJlcHJlc2VudGluZyB0aGUgdG90YWwgYW1vdW50IG9mIGFzc2V0cwogICAgICovCiAgICBmdW5jdGlvbiB0b3RhbFN1cHBseSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbEFzc2V0cy5sZW5ndGg7CiAgICB9CgoKICAgIGZ1bmN0aW9uIF9hc3NldHNPZk93bmVyKGFkZHJlc3Mgb3duZXIpIGludGVybmFsIHZpZXcgcmV0dXJucyAodWludDI1NltdIHN0b3JhZ2UpIHsKICAgICAgICByZXR1cm4gX293bmVkQXNzZXRzW293bmVyXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUHJpdmF0ZSBmdW5jdGlvbiB0byBhZGQgYSBhc3NldCB0byB0aGlzIGV4dGVuc2lvbidzIG93bmVyc2hpcC10cmFja2luZyBkYXRhIHN0cnVjdHVyZXMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hZGRBc3NldFRvT3duZXJFbnVtZXJhdGlvbihhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQpIHByaXZhdGUgewogICAgICAgIF9vd25lZEFzc2V0c0luZGV4W2Fzc2V0SWRdID0gX293bmVkQXNzZXRzW3RvXS5sZW5ndGg7CiAgICAgICAgX293bmVkQXNzZXRzW3RvXS5wdXNoKGFzc2V0SWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBQcml2YXRlIGZ1bmN0aW9uIHRvIGFkZCBhIGFzc2V0IHRvIHRoaXMgZXh0ZW5zaW9uJ3MgYXNzZXQgdHJhY2tpbmcgZGF0YSBzdHJ1Y3R1cmVzLgogICAgICovCiAgICBmdW5jdGlvbiBfYWRkQXNzZXRUb0FsbEFzc2V0c0VudW1lcmF0aW9uKHVpbnQyNTYgYXNzZXRJZCkgcHJpdmF0ZSB7CiAgICAgICAgX2FsbEFzc2V0c0luZGV4W2Fzc2V0SWRdID0gX2FsbEFzc2V0cy5sZW5ndGg7CiAgICAgICAgX2FsbEFzc2V0cy5wdXNoKGFzc2V0SWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBQcml2YXRlIGZ1bmN0aW9uIHRvIHJlbW92ZSBhIGFzc2V0IGZyb20gdGhpcyBleHRlbnNpb24ncyBvd25lcnNoaXAtdHJhY2tpbmcgZGF0YSBzdHJ1Y3R1cmVzLiBOb3RlIHRoYXQKICAgICAqLwogICAgZnVuY3Rpb24gX3JlbW92ZUFzc2V0RnJvbU93bmVyRW51bWVyYXRpb24oYWRkcmVzcyBmcm9tLCB1aW50MjU2IGFzc2V0SWQpIHByaXZhdGUgewogICAgICAgIC8vIFRvIHByZXZlbnQgYSBnYXAgaW4gZnJvbSdzIGFzc2V0cyBhcnJheSwgd2Ugc3RvcmUgdGhlIGxhc3QgYXNzZXQgaW4gdGhlIGluZGV4IG9mIHRoZSBhc3NldCB0byBkZWxldGUsIGFuZAogICAgICAgIC8vIHRoZW4gZGVsZXRlIHRoZSBsYXN0IHNsb3QgKHN3YXAgYW5kIHBvcCkuCgogICAgICAgIHVpbnQyNTYgbGFzdEFzc2V0SW5kZXggPSBfb3duZWRBc3NldHNbZnJvbV0ubGVuZ3RoLnN1YigxKTsKICAgICAgICB1aW50MjU2IGFzc2V0SW5kZXggPSBfb3duZWRBc3NldHNJbmRleFthc3NldElkXTsKCiAgICAgICAgLy8gV2hlbiB0aGUgYXNzZXQgdG8gZGVsZXRlIGlzIHRoZSBsYXN0IGFzc2V0LCB0aGUgc3dhcCBvcGVyYXRpb24gaXMgdW5uZWNlc3NhcnkKICAgICAgICBpZiAoYXNzZXRJbmRleCAhPSBsYXN0QXNzZXRJbmRleCkgewogICAgICAgICAgICB1aW50MjU2IGxhc3RBc3NldElkID0gX293bmVkQXNzZXRzW2Zyb21dW2xhc3RBc3NldEluZGV4XTsKCiAgICAgICAgICAgIF9vd25lZEFzc2V0c1tmcm9tXVthc3NldEluZGV4XSA9IGxhc3RBc3NldElkOwogICAgICAgICAgICAvLyBNb3ZlIHRoZSBsYXN0IGFzc2V0IHRvIHRoZSBzbG90IG9mIHRoZSB0by1kZWxldGUgYXNzZXQKICAgICAgICAgICAgX293bmVkQXNzZXRzSW5kZXhbbGFzdEFzc2V0SWRdID0gYXNzZXRJbmRleDsKICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBtb3ZlZCBhc3NldCdzIGluZGV4CiAgICAgICAgfQoKICAgICAgICAvLyBUaGlzIGFsc28gZGVsZXRlcyB0aGUgY29udGVudHMgYXQgdGhlIGxhc3QgcG9zaXRpb24gb2YgdGhlIGFycmF5CiAgICAgICAgX293bmVkQXNzZXRzW2Zyb21dLmxlbmd0aC0tOwoKICAgICAgICAvLyBOb3RlIHRoYXQgX293bmVkQXNzZXRzSW5kZXhbYXNzZXRJZF0gaGFzbid0IGJlZW4gY2xlYXJlZDogaXQgc3RpbGwgcG9pbnRzIHRvIHRoZSBvbGQgc2xvdCAobm93IG9jY3VwaWVkIGJ5CiAgICAgICAgLy8gbGFzdEFzc2V0SWQsIG9yIGp1c3Qgb3ZlciB0aGUgZW5kIG9mIHRoZSBhcnJheSBpZiB0aGUgYXNzZXQgd2FzIHRoZSBsYXN0IG9uZSkuCiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFByaXZhdGUgZnVuY3Rpb24gdG8gcmVtb3ZlIGEgYXNzZXQgZnJvbSB0aGlzIGV4dGVuc2lvbidzIGFzc2V0IHRyYWNraW5nIGRhdGEgc3RydWN0dXJlcy4KICAgICAqLwogICAgZnVuY3Rpb24gX3JlbW92ZUFzc2V0RnJvbUFsbEFzc2V0c0VudW1lcmF0aW9uKHVpbnQyNTYgYXNzZXRJZCkgcHJpdmF0ZSB7CiAgICAgICAgLy8gVG8gcHJldmVudCBhIGdhcCBpbiB0aGUgYXNzZXRzIGFycmF5LCB3ZSBzdG9yZSB0aGUgbGFzdCBhc3NldCBpbiB0aGUgaW5kZXggb2YgdGhlIGFzc2V0IHRvIGRlbGV0ZSwgYW5kCiAgICAgICAgLy8gdGhlbiBkZWxldGUgdGhlIGxhc3Qgc2xvdCAoc3dhcCBhbmQgcG9wKS4KCiAgICAgICAgdWludDI1NiBsYXN0QXNzZXRJbmRleCA9IF9hbGxBc3NldHMubGVuZ3RoLnN1YigxKTsKICAgICAgICB1aW50MjU2IGFzc2V0SW5kZXggPSBfYWxsQXNzZXRzSW5kZXhbYXNzZXRJZF07CgogICAgICAgIC8vIFdoZW4gdGhlIGFzc2V0IHRvIGRlbGV0ZSBpcyB0aGUgbGFzdCBhc3NldCwgdGhlIHN3YXAgb3BlcmF0aW9uIGlzIHVubmVjZXNzYXJ5LiBIb3dldmVyLCBzaW5jZSB0aGlzIG9jY3VycyBzbwogICAgICAgIC8vIHJhcmVseSAod2hlbiB0aGUgbGFzdCBtaW50ZWQgYXNzZXQgaXMgZGVzdHJveXQpIHRoYXQgd2Ugc3RpbGwgZG8gdGhlIHN3YXAgaGVyZSB0byBhdm9pZCB0aGUgZ2FzIGNvc3Qgb2YgYWRkaW5nCiAgICAgICAgLy8gYW4gJ2lmJyBzdGF0ZW1lbnQgKGxpa2UgaW4gX3JlbW92ZUFzc2V0RnJvbU93bmVyRW51bWVyYXRpb24pCiAgICAgICAgdWludDI1NiBsYXN0QXNzZXRJZCA9IF9hbGxBc3NldHNbbGFzdEFzc2V0SW5kZXhdOwoKICAgICAgICBfYWxsQXNzZXRzW2Fzc2V0SW5kZXhdID0gbGFzdEFzc2V0SWQ7CiAgICAgICAgLy8gTW92ZSB0aGUgbGFzdCBhc3NldCB0byB0aGUgc2xvdCBvZiB0aGUgdG8tZGVsZXRlIGFzc2V0CiAgICAgICAgX2FsbEFzc2V0c0luZGV4W2xhc3RBc3NldElkXSA9IGFzc2V0SW5kZXg7CiAgICAgICAgLy8gVXBkYXRlIHRoZSBtb3ZlZCBhc3NldCdzIGluZGV4CgogICAgICAgIC8vIFRoaXMgYWxzbyBkZWxldGVzIHRoZSBjb250ZW50cyBhdCB0aGUgbGFzdCBwb3NpdGlvbiBvZiB0aGUgYXJyYXkKICAgICAgICBfYWxsQXNzZXRzLmxlbmd0aC0tOwogICAgICAgIF9hbGxBc3NldHNJbmRleFthc3NldElkXSA9IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIGRlc3Ryb3kgYSBzcGVjaWZpYyBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gX2Rlc3Ryb3kodWludDI1NiBhc3NldElkLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgX2Rlc3Ryb3kob3duZXJPZihhc3NldElkKSwgYXNzZXRJZCwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIHNlbmQgb3duZXJzaGlwIG9mIGEgZ2l2ZW4gYXNzZXQgSUQgdG8gYW5vdGhlciBhZGRyZXNzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKG93bmVyT2YoYXNzZXRJZCkgPT0gZnJvbSwgIkJBQzAwMjogc2VuZCBvZiBhc3NldCB0aGF0IGlzIG5vdCBvd24iKTsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDI6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfY2xlYXJBcHByb3ZhbChhc3NldElkKTsKICAgICAgICBfb3duZWRBc3NldHNDb3VudFtmcm9tXS5kZWNyZW1lbnQoKTsKICAgICAgICBfb3duZWRBc3NldHNDb3VudFt0b10uaW5jcmVtZW50KCk7CgogICAgICAgIF9hc3NldE93bmVyW2Fzc2V0SWRdID0gdG87CgogICAgICAgIGVtaXQgU2VuZChtc2cuc2VuZGVyLCBmcm9tLCB0bywgYXNzZXRJZCwgZGF0YSk7CgogICAgICAgIF9yZW1vdmVBc3NldEZyb21Pd25lckVudW1lcmF0aW9uKGZyb20sIGFzc2V0SWQpOwoKICAgICAgICBfYWRkQXNzZXRUb093bmVyRW51bWVyYXRpb24odG8sIGFzc2V0SWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbnRlcm5hbCBmdW5jdGlvbiB0byBpbnZva2UgYG9uQkFDMDAyUmVjZWl2ZWRgIG9uIGEgdGFyZ2V0IGFkZHJlc3MuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9jaGVja09uQkFDMDAyUmVjZWl2ZWQoYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIG1lbW9yeSBfZGF0YSkKICAgIGludGVybmFsIHJldHVybnMgKGJvb2wpCiAgICB7CiAgICAgICAgaWYgKCF0by5pc0NvbnRyYWN0KCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBieXRlczQgcmV0dmFsID0gSUJBQzAwMlJlY2VpdmVyKHRvKS5vbkJBQzAwMlJlY2VpdmVkKG1zZy5zZW5kZXIsIGZyb20sIGFzc2V0SWQsIF9kYXRhKTsKICAgICAgICByZXR1cm4gKHJldHZhbCA9PSBfQkFDMDAyX1JFQ0VJVkVEKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUHJpdmF0ZSBmdW5jdGlvbiB0byBjbGVhciBjdXJyZW50IGFwcHJvdmFsIG9mIGEgZ2l2ZW4gYXNzZXQgSUQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9jbGVhckFwcHJvdmFsKHVpbnQyNTYgYXNzZXRJZCkgcHJpdmF0ZSB7CiAgICAgICAgaWYgKF9hc3NldEFwcHJvdmFsc1thc3NldElkXSAhPSBhZGRyZXNzKDApKSB7CiAgICAgICAgICAgIF9hc3NldEFwcHJvdmFsc1thc3NldElkXSA9IGFkZHJlc3MoMCk7CiAgICAgICAgfQogICAgfQp9", + "contractDesc_en" : "" + }, + { + "contractId" : 24, + "contractFolderId" : 6, + "contractName" : "IBAC002", + "contractDesc" : "# BAC002 合约规范\n\n## 简介\n BAC002 是区块链上定义非同质化资产的一种标准,可以用于唯一性资产类型,如房产、汽车、道具、版权等。,并可以做相应增发,销毁,暂停合约,黑白名单等权限控制。\n## 三个基本元素\n- description\n\n 资产的具体描述\n\n- shortName\n\n 资产简称\n\n- assetId\n\n 资产编号\n\n ## 五个基本行为\n- 发行\n\n 调用合约的 deploy 方法,传入 description 和 shortName,即在区块链上发行指定名称的资产\n\n- 转账\n\n 调用 safeSendFrom 方法实现转账,调用 balance 方法可以查看自己的资产数量\n\n- 增发\n\n 调用 issueWithAssetURI 方法向资产地址增发指定资产编号和资产描述链接信息的资产。另外,可以通过 addIssuer 增加 有权限增发资产的人,也可以通过 renounceIssuer 方法移除增发权限\n\n- 销毁\n\n 调用 destroy 以及 destroyFrom 销毁自己地址下资产和特定地址下的资产\n\n- 暂停\n\n 遇到紧急状况,你可以调用 suspend 方法,暂停合约,这样任何人都不能调用 send 函数。故障修复后,可以调用 unSuspend 方法解除暂停。也可以通过 addSuspender 和 renounceSuspender 相应增加和移除暂停者权限\n\n\n## 接口说明\n\n- shortName()\n\n 资产简称\n\n- description()\n\n 资产描述\n\n- balance(address owner)\n\n 返回 owner 的资产总数\n\n- totalSupply()\n\n 获得当前合约总的资产数目\n\n- ownerOf(uint256 assetId)\n\n 返回资产持有者的地址\n\n- approve(address to, uint256 assetId)\n\n 授予地址to具有指定资产的控制权\n\n - 此方法配合 getapproved 使用\n\n- getApproved(uint256 assetId)\n\n 获得资产授权的地址用户\n\n - 此方法配合 approve 使用,注意不要配合 setapprovealforall 方法使用\n\n- setApprovalForAll(address operator, bool approved)\n\n 授予地址operator具有自己所有资产的控制权\n\n- isApprovedForAll(address owner, address operator)\n\n 查询授权\n\n- sendFrom(address from, address to, uint256 assetId, bytes memory data)\n\n 安全转账,防止你转到错误的合约地址 ( to如果是合约地址,必须实现接收接口 BAC002Holder 才可以接收转账 ),并可以带转账备注\n\n - suspend 状态下无法执行此操作\n\n- batchSendFrom(address from, address[] to, uint256[] assetId, bytes memory data)\n\n 批量安全转账\n\n - suspend 状态下无法执行此操作\n - to 数组元素个数需要和 assetid 数组元素个数一致\n\n- issueWithAssetURI(address to, uint256 assetId, string memory assetURI, bytes data)\n\n 给地址 to 创建资产 assetId,data 是转账备注, assetURI 资产描述\n\n- isIssuer(address account)\n\n 检查account是否有增加资产的权限\n\n- addIssuer(address account)\n\n 使地址 account 拥有增加资产的权限\n\n- renounceIssuer()\n\n 移除增加资产的权限\n\n- suspend()\n\n 暂停合约\n\n - suspend 后无法进行 safesendfrom / sendfrom / safeBatchSendFrom 操作\n\n- unSuspend()\n\n 重启合约\n\n - 此方法配合 suspend 使用\n\n- isSuspender(address account)\n\n 是否有暂停合约权限\n\n - 此方法配合 addsuspender 使用\n\n- addSuspender(address account)\n\n 增加暂停权限者\n\n - 此方法配合 renouncesuspender / issuspender 放啊发使用\n\n- renounceSuspender()\n\n 移除暂停权限\n\n- destroy(uint256 assetId, bytes data)\n\n 减少自己的资产,data 是转账备注\n\n - 调用时,value 值需要小于等于目前自己的资产总量\n\n- assetOfOwnerByIndex(address owner, uint256 index)\n\n 根据索引 index 获取 owner 的资产 ID\n\n- assetByIndex(uint256 index)\n\n 根据索引 index 获取当前合约的资产 ID\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7Cgpjb250cmFjdCBJQkFDMDAyICB7CiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgZGF0YSk7CiAgICBldmVudCBBcHByb3ZhbCggYWRkcmVzcyBpbmRleGVkIG93bmVyLCBhZGRyZXNzIGFwcHJvdmVkLCB1aW50MjU2IGFzc2V0SWQpOwogICAgZXZlbnQgQXBwcm92YWxGb3JBbGwoIGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIG9wZXJhdG9yLCBib29sIGFwcHJvdmVkKTsKCiAgICBmdW5jdGlvbiBiYWxhbmNlKGFkZHJlc3Mgb3duZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYgYmFsYW5jZSk7CgogICAgZnVuY3Rpb24gb3duZXJPZih1aW50MjU2IGFzc2V0SWQpIHB1YmxpYyB2aWV3IHJldHVybnMgKGFkZHJlc3Mgb3duZXIpOwoKICAgIGZ1bmN0aW9uIHNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiBhc3NldElkLCBieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljOwoKICAgIGZ1bmN0aW9uIGJhdGNoU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzW10gdG8sIHVpbnQyNTZbXSBhc3NldElkLCBieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljOwoKICAgIGZ1bmN0aW9uIGRlc3Ryb3kodWludDI1NiBhc3NldElkLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWVXaXRoQXNzZXRVUkkoYWRkcmVzcyB0bywgdWludDI1NiBhc3NldElkLCBzdHJpbmcgbWVtb3J5IGFzc2V0VVJJLCBieXRlcyBkYXRhKSBwdWJsaWMgIHJldHVybnMgKGJvb2wpOwoKICAgIGZ1bmN0aW9uIGFzc2V0VVJJKHVpbnQyNTYgYXNzZXRJZCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KTsKCiAgICBmdW5jdGlvbiBhcHByb3ZlKGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCkgcHVibGljOwogICAgZnVuY3Rpb24gZ2V0QXBwcm92ZWQodWludDI1NiBhc3NldElkKSBwdWJsaWMgdmlldyByZXR1cm5zIChhZGRyZXNzIG9wZXJhdG9yKTsKCiAgICBmdW5jdGlvbiBzZXRBcHByb3ZhbEZvckFsbChhZGRyZXNzIHRvLCBib29sIF9hcHByb3ZlZCkgcHVibGljOwogICAgZnVuY3Rpb24gaXNBcHByb3ZlZEZvckFsbChhZGRyZXNzIG93bmVyLCBhZGRyZXNzIG9wZXJhdG9yKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBhc3NldE9mT3duZXJCeUluZGV4KGFkZHJlc3Mgb3duZXIsIHVpbnQyNTYgaW5kZXgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIDsKCiAgICBmdW5jdGlvbiBzYWZlVHJhbnNmZXJGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB0b2tlbklkLCBieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljOwp9Cg==", + "contractDesc_en" : "" + }, + { + "contractId" : 25, + "contractFolderId" : 6, + "contractName" : "Counters", + "contractDesc" : "# Roles\n\nRole permissions control contracts\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CmltcG9ydCAiLi9TYWZlTWF0aC5zb2wiOwoKCmxpYnJhcnkgQ291bnRlcnMgewogICAgdXNpbmcgU2FmZU1hdGggZm9yIHVpbnQyNTY7CgogICAgc3RydWN0IENvdW50ZXIgewogICAgICAgIC8vIFRoaXMgdmFyaWFibGUgc2hvdWxkIG5ldmVyIGJlIGRpcmVjdGx5IGFjY2Vzc2VkIGJ5IHVzZXJzIG9mIHRoZSBsaWJyYXJ5OiBpbnRlcmFjdGlvbnMgbXVzdCBiZSByZXN0cmljdGVkIHRvCiAgICAgICAgLy8gdGhlIGxpYnJhcnkncyBmdW5jdGlvbi4gQXMgb2YgU29saWRpdHkgdjAuNS4yLCB0aGlzIGNhbm5vdCBiZSBlbmZvcmNlZCwgdGhvdWdoIHRoZXJlIGlzIGEgcHJvcG9zYWwgdG8gYWRkCiAgICAgICAgdWludDI1NiBfdmFsdWU7IC8vIGRlZmF1bHQ6IDAKICAgIH0KCiAgICBmdW5jdGlvbiBjdXJyZW50KENvdW50ZXIgc3RvcmFnZSBjb3VudGVyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gY291bnRlci5fdmFsdWU7CiAgICB9CgogICAgZnVuY3Rpb24gaW5jcmVtZW50KENvdW50ZXIgc3RvcmFnZSBjb3VudGVyKSBpbnRlcm5hbCB7CiAgICAgICAgY291bnRlci5fdmFsdWUgKz0gMTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZWNyZW1lbnQoQ291bnRlciBzdG9yYWdlIGNvdW50ZXIpIGludGVybmFsIHsKICAgICAgICBjb3VudGVyLl92YWx1ZSA9IGNvdW50ZXIuX3ZhbHVlLnN1YigxKTsKICAgIH0KfQoKCi8qKgogKiBVdGlsaXR5IGxpYnJhcnkgb2YgaW5saW5lIGZ1bmN0aW9ucyBvbiBhZGRyZXNzZXMKICovCmxpYnJhcnkgQWRkcmVzcyB7CiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgdGFyZ2V0IGFkZHJlc3MgaXMgYSBjb250cmFjdAogICAgICogQGRldiBUaGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGZhbHNlIGlmIGludm9rZWQgZHVyaW5nIHRoZSBjb25zdHJ1Y3RvciBvZiBhIGNvbnRyYWN0LAogICAgICogYXMgdGhlIGNvZGUgaXMgbm90IGFjdHVhbGx5IGNyZWF0ZWQgdW50aWwgYWZ0ZXIgdGhlIGNvbnN0cnVjdG9yIGZpbmlzaGVzLgogICAgICogQHBhcmFtIGFjY291bnQgYWRkcmVzcyBvZiB0aGUgYWNjb3VudCB0byBjaGVjawogICAgICogQHJldHVybiB3aGV0aGVyIHRoZSB0YXJnZXQgYWRkcmVzcyBpcyBhIGNvbnRyYWN0CiAgICAgKi8KICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICB1aW50MjU2IHNpemU7CiAgICAgICAgLy8gWFhYIEN1cnJlbnRseSB0aGVyZSBpcyBubyBiZXR0ZXIgd2F5IHRvIGNoZWNrIGlmIHRoZXJlIGlzIGEgY29udHJhY3QgaW4gYW4gYWRkcmVzcwogICAgICAgIC8vIHRoYW4gdG8gY2hlY2sgdGhlIHNpemUgb2YgdGhlIGNvZGUgYXQgdGhhdCBhZGRyZXNzLgogICAgICAgIC8vIFNlZSBodHRwczovL2V0aGVyZXVtLnN0YWNrZXhjaGFuZ2UuY29tL2EvMTQwMTYvMzY2MDMKICAgICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzIGFib3V0IGhvdyB0aGlzIHdvcmtzLgogICAgICAgIC8vIFRPRE8gQ2hlY2sgdGhpcyBhZ2FpbiBiZWZvcmUgdGhlIFNlcmVuaXR5IHJlbGVhc2UsIGJlY2F1c2UgYWxsIGFkZHJlc3NlcyB3aWxsIGJlCiAgICAgICAgLy8gY29udHJhY3RzIHRoZW4uCiAgICAgICAgLy8gc29saGludC1kaXNhYmxlLW5leHQtbGluZSBuby1pbmxpbmUtYXNzZW1ibHkKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWNjb3VudCkgfQogICAgICAgIHJldHVybiBzaXplID4gMDsKICAgIH0KfQ==", + "contractDesc_en" : "# Counters\n\nCounters tool contract\n" + }, + { + "contractId" : 26, + "contractFolderId" : 6, + "contractName" : "Register", + "contractDesc" : "# Roles\n\nRole permissions control contracts\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CgoKY29udHJhY3QgUmVnaXN0ZXIgIHsKICAgIC8qCiAgICAgKiBieXRlczQoa2VjY2FrMjU2KCdzdXBwb3J0c0ludGVyZmFjZShieXRlczQpJykpID09IDB4MDFmZmM5YTcKICAgICAqLwogICAgYnl0ZXM0IHByaXZhdGUgY29uc3RhbnQgX0lOVEVSRkFDRV9JRF9CQUMgPSAweDAxZmZjOWE3OwoKICAgIC8qKgogICAgICogQGRldiBNYXBwaW5nIG9mIGludGVyZmFjZSBpZHMgdG8gd2hldGhlciBvciBub3QgaXQncyBzdXBwb3J0ZWQuCiAgICAgKi8KICAgIG1hcHBpbmcoYnl0ZXM0ID0+IGJvb2wpIHByaXZhdGUgX3N1cHBvcnRlZEludGVyZmFjZXM7CgogICAgLyoqCiAgICAgKiBAZGV2IEEgY29udHJhY3QgaW1wbGVtZW50aW5nIFN1cHBvcnRzSW50ZXJmYWNlV2l0aExvb2t1cAogICAgICoKICAgICAqCiAgICAgKi8KICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfcmVnaXN0ZXJJbnRlcmZhY2UoX0lOVEVSRkFDRV9JRF9CQUMpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbXBsZW1lbnQgc3VwcG9ydHNJbnRlcmZhY2UoYnl0ZXM0KSB1c2luZyBhIGxvb2t1cCB0YWJsZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VwcG9ydHNJbnRlcmZhY2UoYnl0ZXM0IGludGVyZmFjZUlkKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX3N1cHBvcnRlZEludGVyZmFjZXNbaW50ZXJmYWNlSWRdOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbnRlcm5hbCBtZXRob2QgZm9yIHJlZ2lzdGVyaW5nIGFuIGludGVyZmFjZS4KICAgICAqLwogICAgZnVuY3Rpb24gX3JlZ2lzdGVySW50ZXJmYWNlKGJ5dGVzNCBpbnRlcmZhY2VJZCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoaW50ZXJmYWNlSWQgIT0gMHhmZmZmZmZmZiwgIkJBQzogaW52YWxpZCBpbnRlcmZhY2UgaWQiKTsKICAgICAgICBfc3VwcG9ydGVkSW50ZXJmYWNlc1tpbnRlcmZhY2VJZF0gPSB0cnVlOwogICAgfQp9Cg==", + "contractDesc_en" : "# Register\n\nRegister control contract\n" + }, + { + "contractId" : 27, + "contractFolderId" : 6, + "contractName" : "Roles", + "contractDesc" : "# Roles\n\nRole permissions control contracts\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IFJvbGVzIHsKICAgIHN0cnVjdCBSb2xlIHsKICAgICAgICBtYXBwaW5nIChhZGRyZXNzID0+IGJvb2wpIGJlYXJlcjsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGQoUm9sZSBzdG9yYWdlIHJvbGUsIGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoIWhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGFscmVhZHkgaGFzIHJvbGUiKTsKICAgICAgICByb2xlLmJlYXJlclthY2NvdW50XSA9IHRydWU7CiAgICB9CgogICAgZnVuY3Rpb24gcmVtb3ZlKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKGhhcyhyb2xlLCBhY2NvdW50KSwgIlJvbGVzOiBhY2NvdW50IGRvZXMgbm90IGhhdmUgcm9sZSIpOwogICAgICAgIHJvbGUuYmVhcmVyW2FjY291bnRdID0gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gaGFzKFJvbGUgc3RvcmFnZSByb2xlLCBhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiUm9sZXM6IGFjY291bnQgaXMgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiByb2xlLmJlYXJlclthY2NvdW50XTsKICAgIH0KfQo=", + "contractDesc_en" : "# Roles\n\nRole permissions control contracts\n" + }, + { + "contractId" : 28, + "contractFolderId" : 6, + "contractName" : "SafeMath", + "contractDesc" : "# SafeMath\n\nSafeMath library\n\nA secure mathematical library that provides a safe addition, subtract, and divide。The use of secure mathematical contracts can refer to the Points contract warehouse。", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKbGlicmFyeSBTYWZlTWF0aCB7CiAgICBmdW5jdGlvbiBtdWwodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIC8vIEdhcyBvcHRpbWl6YXRpb246IHRoaXMgaXMgY2hlYXBlciB0aGFuIHJlcXVpcmluZyAnYScgbm90IGJlaW5nIHplcm8sIGJ1dCB0aGUKICAgICAgICAvLyBiZW5lZml0IGlzIGxvc3QgaWYgJ2InIGlzIGFsc28gdGVzdGVkLgogICAgICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL09wZW5aZXBwZWxpbi9vcGVuemVwcGVsaW4tc29saWRpdHkvcHVsbC81MjIKICAgICAgICBpZiAoYSA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgdWludDI1NiBjID0gYSAqIGI7CiAgICAgICAgcmVxdWlyZShjIC8gYSA9PSBiLCAiU2FmZU1hdGg6IG11bHRpcGxpY2F0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gZGl2KHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICAvLyBTb2xpZGl0eSBvbmx5IGF1dG9tYXRpY2FsbHkgYXNzZXJ0cyB3aGVuIGRpdmlkaW5nIGJ5IDAKICAgICAgICByZXF1aXJlKGIgPiAwLCAiU2FmZU1hdGg6IGRpdmlzaW9uIGJ5IHplcm8iKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC8gYjsKICAgICAgICAvLyBhc3NlcnQoYSA9PSBiICogYyArIGEgJSBiKTsgLy8gVGhlcmUgaXMgbm8gY2FzZSBpbiB3aGljaCB0aGlzIGRvZXNuJ3QgaG9sZAoKICAgICAgICByZXR1cm4gYzsKICAgIH0KICAgIGZ1bmN0aW9uIHN1Yih1aW50MjU2IGEsIHVpbnQyNTYgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShiIDw9IGEsICJTYWZlTWF0aDogc3VidHJhY3Rpb24gb3ZlcmZsb3ciKTsKICAgICAgICB1aW50MjU2IGMgPSBhIC0gYjsKCiAgICAgICAgcmV0dXJuIGM7CiAgICB9CiAgICBmdW5jdGlvbiBhZGQodWludDI1NiBhLCB1aW50MjU2IGIpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHVpbnQyNTYgYyA9IGEgKyBiOwogICAgICAgIHJlcXVpcmUoYyA+PSBhLCAiU2FmZU1hdGg6IGFkZGl0aW9uIG92ZXJmbG93Iik7CgogICAgICAgIHJldHVybiBjOwogICAgfQogICAgZnVuY3Rpb24gbW9kKHVpbnQyNTYgYSwgdWludDI1NiBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXF1aXJlKGIgIT0gMCwgIlNhZmVNYXRoOiBtb2R1bG8gYnkgemVybyIpOwogICAgICAgIHJldHVybiBhICUgYjsKICAgIH0KfQo=", + "contractDesc_en" : "# Roles\n\nRole permissions control contracts\n" + }, + { + "contractId" : 29, + "contractFolderId" : 1, + "contractName" : "Counters", + "contractDesc" : "# Roles\n\nRole permissions control contracts\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CmltcG9ydCAiLi9TYWZlTWF0aC5zb2wiOwoKCmxpYnJhcnkgQ291bnRlcnMgewogICAgdXNpbmcgU2FmZU1hdGggZm9yIHVpbnQyNTY7CgogICAgc3RydWN0IENvdW50ZXIgewogICAgICAgIC8vIFRoaXMgdmFyaWFibGUgc2hvdWxkIG5ldmVyIGJlIGRpcmVjdGx5IGFjY2Vzc2VkIGJ5IHVzZXJzIG9mIHRoZSBsaWJyYXJ5OiBpbnRlcmFjdGlvbnMgbXVzdCBiZSByZXN0cmljdGVkIHRvCiAgICAgICAgLy8gdGhlIGxpYnJhcnkncyBmdW5jdGlvbi4gQXMgb2YgU29saWRpdHkgdjAuNS4yLCB0aGlzIGNhbm5vdCBiZSBlbmZvcmNlZCwgdGhvdWdoIHRoZXJlIGlzIGEgcHJvcG9zYWwgdG8gYWRkCiAgICAgICAgdWludDI1NiBfdmFsdWU7IC8vIGRlZmF1bHQ6IDAKICAgIH0KCiAgICBmdW5jdGlvbiBjdXJyZW50KENvdW50ZXIgc3RvcmFnZSBjb3VudGVyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gY291bnRlci5fdmFsdWU7CiAgICB9CgogICAgZnVuY3Rpb24gaW5jcmVtZW50KENvdW50ZXIgc3RvcmFnZSBjb3VudGVyKSBpbnRlcm5hbCB7CiAgICAgICAgY291bnRlci5fdmFsdWUgKz0gMTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZWNyZW1lbnQoQ291bnRlciBzdG9yYWdlIGNvdW50ZXIpIGludGVybmFsIHsKICAgICAgICBjb3VudGVyLl92YWx1ZSA9IGNvdW50ZXIuX3ZhbHVlLnN1YigxKTsKICAgIH0KfQoKCi8qKgogKiBVdGlsaXR5IGxpYnJhcnkgb2YgaW5saW5lIGZ1bmN0aW9ucyBvbiBhZGRyZXNzZXMKICovCmxpYnJhcnkgQWRkcmVzcyB7CiAgICAvKioKICAgICAqIFJldHVybnMgd2hldGhlciB0aGUgdGFyZ2V0IGFkZHJlc3MgaXMgYSBjb250cmFjdAogICAgICogQGRldiBUaGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGZhbHNlIGlmIGludm9rZWQgZHVyaW5nIHRoZSBjb25zdHJ1Y3RvciBvZiBhIGNvbnRyYWN0LAogICAgICogYXMgdGhlIGNvZGUgaXMgbm90IGFjdHVhbGx5IGNyZWF0ZWQgdW50aWwgYWZ0ZXIgdGhlIGNvbnN0cnVjdG9yIGZpbmlzaGVzLgogICAgICogQHBhcmFtIGFjY291bnQgYWRkcmVzcyBvZiB0aGUgYWNjb3VudCB0byBjaGVjawogICAgICogQHJldHVybiB3aGV0aGVyIHRoZSB0YXJnZXQgYWRkcmVzcyBpcyBhIGNvbnRyYWN0CiAgICAgKi8KICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICB1aW50MjU2IHNpemU7CiAgICAgICAgLy8gWFhYIEN1cnJlbnRseSB0aGVyZSBpcyBubyBiZXR0ZXIgd2F5IHRvIGNoZWNrIGlmIHRoZXJlIGlzIGEgY29udHJhY3QgaW4gYW4gYWRkcmVzcwogICAgICAgIC8vIHRoYW4gdG8gY2hlY2sgdGhlIHNpemUgb2YgdGhlIGNvZGUgYXQgdGhhdCBhZGRyZXNzLgogICAgICAgIC8vIFNlZSBodHRwczovL2V0aGVyZXVtLnN0YWNrZXhjaGFuZ2UuY29tL2EvMTQwMTYvMzY2MDMKICAgICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzIGFib3V0IGhvdyB0aGlzIHdvcmtzLgogICAgICAgIC8vIFRPRE8gQ2hlY2sgdGhpcyBhZ2FpbiBiZWZvcmUgdGhlIFNlcmVuaXR5IHJlbGVhc2UsIGJlY2F1c2UgYWxsIGFkZHJlc3NlcyB3aWxsIGJlCiAgICAgICAgLy8gY29udHJhY3RzIHRoZW4uCiAgICAgICAgLy8gc29saGludC1kaXNhYmxlLW5leHQtbGluZSBuby1pbmxpbmUtYXNzZW1ibHkKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWNjb3VudCkgfQogICAgICAgIHJldHVybiBzaXplID4gMDsKICAgIH0KfQ==", + "contractDesc_en" : "# Counters\n\nCounters tool contract\n" + }, + { + "contractId" : 30, + "contractFolderId" : 1, + "contractName" : "Register", + "contractDesc" : "# Roles\n\nRole permissions control contracts\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CgoKY29udHJhY3QgUmVnaXN0ZXIgIHsKICAgIC8qCiAgICAgKiBieXRlczQoa2VjY2FrMjU2KCdzdXBwb3J0c0ludGVyZmFjZShieXRlczQpJykpID09IDB4MDFmZmM5YTcKICAgICAqLwogICAgYnl0ZXM0IHByaXZhdGUgY29uc3RhbnQgX0lOVEVSRkFDRV9JRF9CQUMgPSAweDAxZmZjOWE3OwoKICAgIC8qKgogICAgICogQGRldiBNYXBwaW5nIG9mIGludGVyZmFjZSBpZHMgdG8gd2hldGhlciBvciBub3QgaXQncyBzdXBwb3J0ZWQuCiAgICAgKi8KICAgIG1hcHBpbmcoYnl0ZXM0ID0+IGJvb2wpIHByaXZhdGUgX3N1cHBvcnRlZEludGVyZmFjZXM7CgogICAgLyoqCiAgICAgKiBAZGV2IEEgY29udHJhY3QgaW1wbGVtZW50aW5nIFN1cHBvcnRzSW50ZXJmYWNlV2l0aExvb2t1cAogICAgICoKICAgICAqCiAgICAgKi8KICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfcmVnaXN0ZXJJbnRlcmZhY2UoX0lOVEVSRkFDRV9JRF9CQUMpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbXBsZW1lbnQgc3VwcG9ydHNJbnRlcmZhY2UoYnl0ZXM0KSB1c2luZyBhIGxvb2t1cCB0YWJsZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VwcG9ydHNJbnRlcmZhY2UoYnl0ZXM0IGludGVyZmFjZUlkKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX3N1cHBvcnRlZEludGVyZmFjZXNbaW50ZXJmYWNlSWRdOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbnRlcm5hbCBtZXRob2QgZm9yIHJlZ2lzdGVyaW5nIGFuIGludGVyZmFjZS4KICAgICAqLwogICAgZnVuY3Rpb24gX3JlZ2lzdGVySW50ZXJmYWNlKGJ5dGVzNCBpbnRlcmZhY2VJZCkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoaW50ZXJmYWNlSWQgIT0gMHhmZmZmZmZmZiwgIkJBQzogaW52YWxpZCBpbnRlcmZhY2UgaWQiKTsKICAgICAgICBfc3VwcG9ydGVkSW50ZXJmYWNlc1tpbnRlcmZhY2VJZF0gPSB0cnVlOwogICAgfQp9Cg==", + "contractDesc_en" : "# Register\n\nRegister control contract\n" + }, + { + "contractId" : 31, + "contractFolderId" : 7, + "contractName" : "Goods", + "contractDesc" : "# 溯源\n\n## 简介\n\n包含创建Traceability溯源类目、创建Goods溯源商品、更新溯源/商品状态、获取溯源/商品信息等\n\n合约:\n1) Goods 溯源商品\n2) Traceability 商品溯源类目\n3) TraceabilityFactory 溯源工厂类\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CnByYWdtYSBleHBlcmltZW50YWwgQUJJRW5jb2RlclYyOwoKY29udHJhY3QgR29vZHMgewogICAgc3RydWN0IFRyYWNlRGF0YSB7CiAgICAgICAgYWRkcmVzcyBhZGRyOyAgICAgLy9PcGVyYXRvciBhZGRyZXNzCiAgICAgICAgaW50MTYgc3RhdHVzOyAgICAgLy9nb29kcyBzdGF0dXMKICAgICAgICB1aW50IHRpbWVzdGFtcDsgICAvL09wZXJhdG9yIHRpbWUKICAgICAgICBzdHJpbmcgcmVtYXJrOyAgICAvL0RpZ2VzdGVkIERhdGEKICAgIH0KICAgIHVpbnQ2NCBfZ29vZHNJZDsgCiAgICBpbnQxNiBfc3RhdHVzOyAgIC8vY3VycmVudCBzdGF0dXMKICAgIFRyYWNlRGF0YVtdIF90cmFjZURhdGE7CiAgICAKICAgIGV2ZW50IG5ld1N0YXR1cyggYWRkcmVzcyBhZGRyLCBpbnQxNiBzdGF0dXMsIHVpbnQgdGltZXN0YW1wLCBzdHJpbmcgcmVtYXJrKTsKICAgIAogICAgY29uc3RydWN0b3IodWludDY0IGdvb2RzSWQpIHB1YmxpYyB7CiAgICAgICAgX2dvb2RzSWQgPSBnb29kc0lkOwogICAgICAgIF90cmFjZURhdGEucHVzaChUcmFjZURhdGEoe2FkZHI6bXNnLnNlbmRlciwgc3RhdHVzOjAsIHRpbWVzdGFtcDpub3csIHJlbWFyazoiY3JlYXRlIn0pKTsKICAgICAgICBlbWl0IG5ld1N0YXR1cyhtc2cuc2VuZGVyLCAwLCBub3csICJjcmVhdGUiKTsKICAgIH0KICAgIAogICAgZnVuY3Rpb24gY2hhbmdlU3RhdHVzKGludDE2IGdvb2RzU3RhdHVzLCBzdHJpbmcgbWVtb3J5IHJlbWFyaykgcHVibGljIHsKICAgICAgICBfc3RhdHVzID0gZ29vZHNTdGF0dXM7CiAgICAgICAgX3RyYWNlRGF0YS5wdXNoKFRyYWNlRGF0YSh7YWRkcjptc2cuc2VuZGVyLCBzdGF0dXM6Z29vZHNTdGF0dXMsIHRpbWVzdGFtcDpub3csIHJlbWFyazpyZW1hcmt9KSk7CiAgICAgICAgZW1pdCBuZXdTdGF0dXMobXNnLnNlbmRlciwgZ29vZHNTdGF0dXMsIG5vdywgcmVtYXJrKTsKICAgIH0KICAgICAgCiAgICBmdW5jdGlvbiBnZXRTdGF0dXMoKSBwdWJsaWMgdmlldyByZXR1cm5zKGludDE2KSB7CiAgICAgICAgcmV0dXJuIF9zdGF0dXM7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGdldFRyYWNlSW5mbygpIHB1YmxpYyB2aWV3IHJldHVybnMoVHJhY2VEYXRhW10gbWVtb3J5IF9kYXRhKSB7CiAgICAgICAgcmV0dXJuIF90cmFjZURhdGE7CiAgICB9Cn0=", + "contractDesc_en" : "# 溯源\n\n## 简介\n\n包含创建Traceability溯源类目、创建Goods溯源商品、更新溯源/商品状态、获取溯源/商品信息等\n\n合约:\n1) Goods 溯源商品\n2) Traceability 商品溯源类目\n3) TraceabilityFactory 溯源工厂类\n" + }, + { + "contractId" : 32, + "contractFolderId" : 7, + "contractName" : "Traceability", + "contractDesc" : "# 溯源\n\n## 简介\n\n包含创建Traceability溯源类目、创建Goods溯源商品、更新溯源/商品状态、获取溯源/商品信息等\n\n合约:\n1) Goods 溯源商品\n2) Traceability 商品溯源类目\n3) TraceabilityFactory 溯源工厂类\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CgppbXBvcnQgIi4vR29vZHMuc29sIjsKCmNvbnRyYWN0IFRyYWNlYWJpbGl0eSB7CiAgICBzdHJ1Y3QgR29vZHNEYXRhIHsKICAgICAgICBHb29kcyB0cmFjZUdvb2RzOwogICAgICAgIGJvb2wgdmFsaWQ7CiAgICB9CiAgICBieXRlczMyIF9jYXRlZ29yeTsKICAgIG1hcHBpbmcodWludDY0ID0+IEdvb2RzRGF0YSkgcHJpdmF0ZSBfZ29vZHM7CiAgICBjb25zdHJ1Y3RvcihieXRlczMyICBnb29kc1RwKSBwdWJsaWMgewogICAgICAgIF9jYXRlZ29yeSA9IGdvb2RzVHA7CiAgICB9CiAgICAKICAgIGV2ZW50IG5ld0dvb2RzRXZlbnQodWludDY0IGdvb2RzSWQpOwogICAgCiAgICBmdW5jdGlvbiBjcmVhdGVHb29kcyh1aW50NjQgZ29vZHNJZCkgcHVibGljIHJldHVybnMoR29vZHMpIHsKICAgICAgICByZXF1aXJlKCFfZ29vZHNbZ29vZHNJZF0udmFsaWQsICJpZCByZWFsbHkgZXhpc3RzIik7CiAgICAgICAgCiAgICAgICAgX2dvb2RzW2dvb2RzSWRdLnZhbGlkID0gdHJ1ZTsKICAgICAgICBHb29kcyB0cmFjZUdvb2RzID0gbmV3IEdvb2RzKGdvb2RzSWQpOwogICAgICAgIGVtaXQgbmV3R29vZHNFdmVudChnb29kc0lkKTsKICAgICAgICBfZ29vZHNbZ29vZHNJZF0udHJhY2VHb29kcyA9IHRyYWNlR29vZHM7CiAgICAgICAgcmV0dXJuIHRyYWNlR29vZHM7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIGNoYW5nZUdvb2RzU3RhdHVzKHVpbnQ2NCBnb29kc0lkLCBpbnQxNiBnb29kc1N0YXR1cywgc3RyaW5nIG1lbW9yeSByZW1hcmspIHB1YmxpYyB7CiAgICAgICAgcmVxdWlyZShfZ29vZHNbZ29vZHNJZF0udmFsaWQsICJub3QgZXhpc3RzIik7CiAgICAgICAgIF9nb29kc1tnb29kc0lkXS50cmFjZUdvb2RzLmNoYW5nZVN0YXR1cyhnb29kc1N0YXR1cywgcmVtYXJrKTsKICAgIH0KICAgICAgCiAgICAgZnVuY3Rpb24gZ2V0U3RhdHVzKHVpbnQ2NCBnb29kc0lkKSBwdWJsaWMgdmlldyByZXR1cm5zKGludDE2KSB7CiAgICAgICAgIHJlcXVpcmUoX2dvb2RzW2dvb2RzSWRdLnZhbGlkLCAibm90IGV4aXN0cyIpOwogICAgICAgICByZXR1cm4gX2dvb2RzW2dvb2RzSWRdLnRyYWNlR29vZHMuZ2V0U3RhdHVzKCk7CiAgICB9CgogICAgIGZ1bmN0aW9uIGdldEdvb2RzKHVpbnQ2NCBnb29kc0lkKSBwdWJsaWMgdmlldyByZXR1cm5zKEdvb2RzKSB7CiAgICAgICAgIHJlcXVpcmUoX2dvb2RzW2dvb2RzSWRdLnZhbGlkLCAibm90IGV4aXN0cyIpOwogICAgICAgICByZXR1cm4gX2dvb2RzW2dvb2RzSWRdLnRyYWNlR29vZHM7CiAgICB9Cn0K", + "contractDesc_en" : "# 溯源\n\n## 简介\n\n包含创建Traceability溯源类目、创建Goods溯源商品、更新溯源/商品状态、获取溯源/商品信息等\n\n合约:\n1) Goods 溯源商品\n2) Traceability 商品溯源类目\n3) TraceabilityFactory 溯源工厂类\n" + }, + { + "contractId" : 33, + "contractFolderId" : 7, + "contractName" : "TraceabilityFactory", + "contractDesc" : "# 溯源\n\n## 简介\n\n包含创建Traceability溯源类目、创建Goods溯源商品、更新溯源/商品状态、获取溯源/商品信息等\n\n合约:\n1) Goods 溯源商品\n2) Traceability 商品溯源类目\n3) TraceabilityFactory 溯源工厂类\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CgppbXBvcnQgIi4vVHJhY2VhYmlsaXR5LnNvbCI7Cgpjb250cmFjdCBUcmFjZWFiaWxpdHlGYWN0b3J5IHsKICAgIHN0cnVjdCBHb29kc1RyYWNlIHsKICAgICAgICBUcmFjZWFiaWxpdHkgdHJhY2U7CiAgICAgICAgYm9vbCB2YWxpZDsKICAgIH0KICAgIG1hcHBpbmcoYnl0ZXMzMiA9PiBHb29kc1RyYWNlKSBwcml2YXRlIF9nb29kc0NhdGVnb3J5OwoKCWV2ZW50IG5ld1RyYWNlRXZlbnQoYnl0ZXMzMiBnb29kc0dyb3VwKTsKCQoJLy9DcmVhdGUgdHJhY2VhYmlsaXR5IGNvbW1vZGl0eSBjYXRlZ29yeQogICAgZnVuY3Rpb24gY3JlYXRlVHJhY2VhYmlsaXR5KGJ5dGVzMzIgZ29vZHNHcm91cCkgcHVibGljIHJldHVybnMoVHJhY2VhYmlsaXR5KSB7CiAgICAgICAgcmVxdWlyZSghX2dvb2RzQ2F0ZWdvcnlbZ29vZHNHcm91cF0udmFsaWQsICJUaGUgdHJhZGVtYXJrIGFscmVhZHkgZXhpc3RzIik7CiAgICAgICAgVHJhY2VhYmlsaXR5IGNhdGVnb3J5ID0gbmV3IFRyYWNlYWJpbGl0eShnb29kc0dyb3VwKTsKICAgICAgICBfZ29vZHNDYXRlZ29yeVtnb29kc0dyb3VwXS52YWxpZCA9IHRydWU7CiAgICAgICAgX2dvb2RzQ2F0ZWdvcnlbZ29vZHNHcm91cF0udHJhY2UgPSBjYXRlZ29yeTsKICAgICAgICBlbWl0IG5ld1RyYWNlRXZlbnQoZ29vZHNHcm91cCk7CiAgICAgICAgcmV0dXJuIGNhdGVnb3J5OwogICAgfQogICAgCiAgICAgZnVuY3Rpb24gZ2V0VHJhY2VhYmlsaXR5KGJ5dGVzMzIgZ29vZHNHcm91cCkgcHJpdmF0ZSB2aWV3IHJldHVybnMoVHJhY2VhYmlsaXR5KSB7CiAgICAgICAgcmVxdWlyZShfZ29vZHNDYXRlZ29yeVtnb29kc0dyb3VwXS52YWxpZCwgIlRoZSB0cmFkZW1hcmsgaGFzIG5vdCBleGlzdHMiKTsKICAgICAgICByZXR1cm4gX2dvb2RzQ2F0ZWdvcnlbZ29vZHNHcm91cF0udHJhY2U7CiAgICB9CiAgICAvL0NyZWF0ZSB0cmFjZWFiaWxpdHkgcHJvZHVjdHMgICAgCiAgICBmdW5jdGlvbiBjcmVhdGVUcmFjZUdvb2RzKGJ5dGVzMzIgZ29vZHNHcm91cCwgdWludDY0IGdvb2RzSWQpIHB1YmxpYyByZXR1cm5zKEdvb2RzKSB7CiAgICAgICAgVHJhY2VhYmlsaXR5IGNhdGVnb3J5ID0gZ2V0VHJhY2VhYmlsaXR5KGdvb2RzR3JvdXApOwogICAgICAgICByZXR1cm4gY2F0ZWdvcnkuY3JlYXRlR29vZHMoZ29vZHNJZCk7CiAgICB9CiAgICAKICAgIC8vQ2hhbmdlIHByb2R1Y3Qgc3RhdHVzCiAgICBmdW5jdGlvbiBjaGFuZ2VUcmFjZUdvb2RzKGJ5dGVzMzIgZ29vZHNHcm91cCwgdWludDY0IGdvb2RzSWQsIGludDE2IGdvb2RzU3RhdHVzLCBzdHJpbmcgbWVtb3J5IHJlbWFyaykgcHVibGljIHsKICAgICAgICAgVHJhY2VhYmlsaXR5IGNhdGVnb3J5ID0gZ2V0VHJhY2VhYmlsaXR5KGdvb2RzR3JvdXApOwogICAgICAgICBjYXRlZ29yeS5jaGFuZ2VHb29kc1N0YXR1cyhnb29kc0lkLCBnb29kc1N0YXR1cywgcmVtYXJrKTsKICAgIH0KICAgIAogICAgLy9RdWVyeSB0aGUgY3VycmVudCBzdGF0dXMgb2YgZ29vZHMKICAgICBmdW5jdGlvbiBnZXRTdGF0dXMoYnl0ZXMzMiBnb29kc0dyb3VwLCB1aW50NjQgZ29vZHNJZCkgcHVibGljIHZpZXcgcmV0dXJucyhpbnQxNikgewogICAgICAgICBUcmFjZWFiaWxpdHkgY2F0ZWdvcnkgPSBnZXRUcmFjZWFiaWxpdHkoZ29vZHNHcm91cCk7CiAgICAgICAgIHJldHVybiBjYXRlZ29yeS5nZXRTdGF0dXMoZ29vZHNJZCk7CiAgICB9CiAgICAKICAgIC8vVGhlIHdob2xlIHByb2Nlc3Mgb2YgcXVlcnlpbmcgZ29vZHMKICAgICBmdW5jdGlvbiBnZXRUcmFjZUluZm8oYnl0ZXMzMiBnb29kc0dyb3VwLCB1aW50NjQgZ29vZHNJZCkgcHVibGljIHZpZXcgcmV0dXJucyhHb29kcykgewogICAgICAgICBUcmFjZWFiaWxpdHkgY2F0ZWdvcnkgPSBnZXRUcmFjZWFiaWxpdHkoZ29vZHNHcm91cCk7CiAgICAgICAgIHJldHVybiBjYXRlZ29yeS5nZXRHb29kcyhnb29kc0lkKTsKICAgIH0KfQ==", + "contractDesc_en" : "# 溯源\n\n## 简介\n\n包含创建Traceability溯源类目、创建Goods溯源商品、更新溯源/商品状态、获取溯源/商品信息等\n\n合约:\n1) Goods 溯源商品\n2) Traceability 商品溯源类目\n3) TraceabilityFactory 溯源工厂类\n" + }, + { + "contractId" : 34, + "contractFolderId" : 8, + "contractName" : "EnrollProxy", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQoNCmltcG9ydCAiLi9Qcm94eS5zb2wiOw0KaW1wb3J0ICIuL0Vucm9sbFN0b3JhZ2VTdGF0ZWZ1bC5zb2wiOw0KDQovKioNCiAqIOeZu+iusOWFpeWPo+WQiOe6pg0KICovDQpjb250cmFjdCBFbnJvbGxQcm94eSBpcyBFbnJvbGxTdG9yYWdlU3RhdGVmdWwsIFByb3h5IHsNCg0KDQogICAgLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLyBFdmVudA0KICAgIC8vLy8vLy8vLy8vLy8vLw0KICAgIGV2ZW50IFNldFN0b3JhZ2UoYWRkcmVzcyBvcGVyYXRvciwgYWRkcmVzcyBlbnJvbGxTdG9yYWdlKTsNCg0KICAgIC8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8gRnVuY3Rpb25zDQogICAgLy8vLy8vLy8vLy8vLy8vDQoNCiAgICAvKioNCiAgICAqIEBub3RpY2Ug6K6+572u5a2Y5YKoDQogICAgKiBAZGV2IOmZkOWQiOe6pueuoeeQhuWRmOiwg+eUqA0KICAgICogQHBhcmFtIF9zdG9yYWdlQWRkciDnmbvorrDlrZjlgqjlkIjnuqYNCiAgICAqLw0KICAgIGZ1bmN0aW9uIHNldFN0b3JhZ2UoYWRkcmVzcyBfc3RvcmFnZUFkZHIpIGV4dGVybmFsIG9ubHlPd25lciB7DQoNCiAgICAgICAgcmVxdWlyZShfc3RvcmFnZUFkZHIgIT0gYWRkcmVzcygwKSwgIlByb3h5OiBzdG9yYWdlIGFkZHJlc3Mgc2hvdWxkIG5vdCBiZSAweCIpOw0KICAgICAgICByZXF1aXJlKEFkZHJlc3MuaXNDb250cmFjdChfc3RvcmFnZUFkZHIpLCAiUHJveHk6IENhbm5vdCBzZXQgYSBwcm94eSBzdG9yYWdlIHRvIGEgbm9uLWNvbnRyYWN0IGFkZHJlc3MiKTsNCg0KICAgICAgICBlbnJvbGxTdG9yYWdlID0gRW5yb2xsU3RvcmFnZShfc3RvcmFnZUFkZHIpOw0KICAgICAgICBzdG9yYWdlQWRkckxpc3QucHVzaChfc3RvcmFnZUFkZHIpOw0KICAgICAgICBlbWl0IFNldFN0b3JhZ2UobXNnLnNlbmRlciwgX3N0b3JhZ2VBZGRyKTsNCiAgICB9DQoNCiAgICAvKioNCiAgICAqIEBub3RpY2Ug6L+U5Zue5omA5pyJ55qE5a2Y5YKo5ZCI57qm5Zyw5Z2A5YiX6KGoDQogICAgKi8NCiAgICBmdW5jdGlvbiBnZXRTdG9yYWdlVmVyc2lvbnMoKSB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkgcmVzdWx0KXsNCiAgICAgICAgcmVzdWx0PSJ7IjsNCiAgICAgICAgZm9yKHVpbnQgaSA9IDA7IGkgPCBzdG9yYWdlQWRkckxpc3QubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC50b1NsaWNlKCkuY29uY2F0KGFkZHJlc3NUb1N0cmluZyhzdG9yYWdlQWRkckxpc3RbaV0pLnRvU2xpY2UoKSk7DQogICAgICAgICAgICBpZihpICE9IChzdG9yYWdlQWRkckxpc3QubGVuZ3RoLTEpKSB7DQogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnRvU2xpY2UoKS5jb25jYXQoIiwiLnRvU2xpY2UoKSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnRvU2xpY2UoKS5jb25jYXQoIn0iLnRvU2xpY2UoKSk7DQogICAgfQ0KfQ0K", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 35, + "contractFolderId" : 8, + "contractName" : "EnrollController", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQpwcmFnbWEgZXhwZXJpbWVudGFsIEFCSUVuY29kZXJWMjsNCg0KaW1wb3J0ICIuL093bmFibGUuc29sIjsNCmltcG9ydCAiLi9FbnJvbGxTdG9yYWdlU3RhdGVmdWwuc29sIjsNCmltcG9ydCAiLi9UYWJsZS5zb2wiOw0KaW1wb3J0ICIuL1N0cmluZ3Muc29sIjsNCg0KDQoNCi8qKg0KICog55m76K6w6YC76L6R5ZCI57qmDQogKi8NCmNvbnRyYWN0IEVucm9sbENvbnRyb2xsZXIgaXMgRW5yb2xsU3RvcmFnZVN0YXRlZnVsLCBPd25hYmxlIHsNCiAgICANCiAgICB1c2luZyBTdHJpbmdzIGZvciAqOw0KDQogICAgLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLyBFdmVudA0KICAgIC8vLy8vLy8vLy8vLy8vLw0KDQogICAgZXZlbnQgQ3JlYXRlKHN0cmluZyB0YWJsZU5hbWUpOw0KICAgIGV2ZW50IFB1dChzdHJpbmcgdGFibGVOYW1lLCBzdHJpbmcga2V5LCBzdHJpbmcgdmFsdWUpOw0KICAgIGV2ZW50IFJlbW92ZShzdHJpbmcgdGFibGVOYW1lLCBzdHJpbmcga2V5KTsNCiAgICBldmVudCBNdWx0aVB1dEpzb24oc3RyaW5nIHRhYmxlTmFtZSwgc3RyaW5nIGtleXMsIHN0cmluZyB2YWx1ZXMsIHN0cmluZyByZXN1bHQpOw0KDQogICAgLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLyBGdW5jdGlvbnMNCiAgICAvLy8vLy8vLy8vLy8vLy8NCg0KICAgIC8qKg0KICAgICogQG5vdGljZSDliqjmgIHlu7rooagNCiAgICAqIEBwYXJhbSB0YWJsZU5hbWUg6KGo5ZCNDQogICAgKi8NCiAgICBmdW5jdGlvbiBjcmVhdGUoc3RyaW5nIHRhYmxlTmFtZSkgZXh0ZXJuYWwgew0KDQogICAgICAgIHJlcXVpcmUoZW5yb2xsU3RvcmFnZS5TdG9yYWdlQ3JlYXRlKHRhYmxlTmFtZSkgPT0gaW50KDApLCAiRW5yb2xsQ29udHJvbGxlcjogY3JlYXRlVGFibGUgZXJyb3IiKTsNCg0KICAgICAgICBlbWl0IENyZWF0ZSh0YWJsZU5hbWUpOw0KICAgIH0NCg0KICAgIC8qKg0KICAgICogQG5vdGljZSDmt7vliqDkv6Hmga/vvIzoh6rliqjljLrliIbmmK/ms6jlhozkv6Hmga/ov5jmmK/mm7TmlrDkv6Hmga8NCiAgICAqIEBwYXJhbSB0YWJsZU5hbWUg6KGo5ZCNDQogICAgKiBAcGFyYW0ga2V5IOS4u+mUrg0KICAgICogQHBhcmFtIHZhbHVlIOWAvA0KICAgICovDQogICAgZnVuY3Rpb24gcHV0KHN0cmluZyB0YWJsZU5hbWUsIHN0cmluZyBrZXksIHN0cmluZyB2YWx1ZSkgZXh0ZXJuYWwgew0KDQogICAgICAgIGludCBfcmVzdWx0IDsNCiAgICAgICAgc3RyaW5nIG1lbW9yeSAgX2tleTsNCiAgICAgICAgc3RyaW5nIG1lbW9yeSAgX3ZhbHVlIDsNCiAgICAgICAgDQogICAgICAgIChfcmVzdWx0LCBfa2V5LCBfdmFsdWUpID0gZW5yb2xsU3RvcmFnZS5TdG9yYWdlU2VsZWN0KHRhYmxlTmFtZSwga2V5KTsNCg0KICAgICAgICByZXF1aXJlKGtlY2NhazI1NihfdmFsdWUpICE9IGtlY2NhazI1Nih2YWx1ZSksIkVucm9sbENvbnRyb2xsZXI6IHNhbWUgdmFsdWUsIG5vdCBuZWVkIHB1dCIpOw0KDQogICAgICAgIHJlcXVpcmUoZW5yb2xsU3RvcmFnZS5TdG9yYWdlUHV0KHRhYmxlTmFtZSwga2V5LCB2YWx1ZSkgPT0gaW50KDEpLCAiRW5yb2xsQ29udHJvbGxlcjogcHV0IGluZm8gZXJyb3IiKTsNCg0KICAgICAgICBlbWl0IFB1dCh0YWJsZU5hbWUsIGtleSwgdmFsdWUpOw0KICAgIH0NCg0KICAgIC8qDQogICAgKiBAbm90aWNlIOWcqOihqOS4reWIoOmZpGtleeWvueW6lOeahOiusOW9lQ0KICAgICogICAgICAgICDliKDpmaTmiYDmnInniYjmnKzkuK1rZXnlr7nlupTnmoTorrDlvZUNCiAgICAqDQogICAgKiBAcGFyYW0gdGFibGVOYW1lIOihqOWQjQ0KICAgICogQHBhcmFtIGtleVZhbHVlIOS4u+mUrg0KICAgICovDQogICAgZnVuY3Rpb24gcmVtb3ZlKHN0cmluZyB0YWJsZU5hbWUsIHN0cmluZyBrZXkpIGV4dGVybmFsIHsNCg0KICAgICAgICByZXF1aXJlKGVucm9sbFN0b3JhZ2UuU3RvcmFnZVJlbW92ZSh0YWJsZU5hbWUsIGtleSkgPT0gaW50KDEpLCAiRW5yb2xsQ29udHJvbGxlcjogcmVtb3ZlIGluZm8gZXJyb3IiKTsNCg0KICAgICAgICBlbWl0IFJlbW92ZSh0YWJsZU5hbWUsIGtleSk7DQogICAgfQ0KDQogICAgLyoqDQogICAgKiBAbm90aWNlIOiOt+WPlumTvuS4iuS/oeaBrw0KICAgICogQHBhcmFtIHRhYmxlTmFtZSDooajlkI0NCiAgICAqIEBwYXJhbSBrZXkg5Li76ZSuDQogICAgKi8NCiAgICBmdW5jdGlvbiBnZXQoc3RyaW5nICB0YWJsZU5hbWUsIHN0cmluZyAga2V5KSB2aWV3IHJldHVybnMoDQogICAgICAgIGludCBfcmVzdWx0ICxzdHJpbmcgIF9rZXksc3RyaW5nICBfdmFsdWUpew0KDQogICAgICAgIHJldHVybiBlbnJvbGxTdG9yYWdlLlN0b3JhZ2VTZWxlY3QodGFibGVOYW1lLCBrZXkpOw0KICAgIH0NCg0KfQ==", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 36, + "contractFolderId" : 8, + "contractName" : "EnrollStorage", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQpwcmFnbWEgZXhwZXJpbWVudGFsIEFCSUVuY29kZXJWMjsNCg0KaW1wb3J0ICIuL1RhYmxlLnNvbCI7DQppbXBvcnQgIi4vQmFzZVN0b3JhZ2Uuc29sIjsNCmltcG9ydCAiLi9TdHJpbmdzLnNvbCI7DQoNCi8qKg0KICog55m76K6w5a2Y5YKo5ZCI57qmDQogKi8NCmNvbnRyYWN0IEVucm9sbFN0b3JhZ2UgaXMgQmFzZVN0b3JhZ2Ugew0KICAgIHVzaW5nIFN0cmluZ3MgZm9yICo7DQoJDQogICAgLy8gdGFibGXliJfooagNCiAgICBzdHJpbmdbXSBpbnRlcm5hbCB0YWJsZUxpc3Q7DQogICAgLy8gdGFibGXorrDlvZXnmoTmnaHnm67mlbANCiAgICBtYXBwaW5nKHN0cmluZyA9PiB1aW50KSBpbnRlcm5hbCB0YWJsZVJlY29yZHM7DQogICAgLyoqDQogICAgKiBAcmV0dXJuIHRhYmxl5YiX6KGoDQogICAgKi8NCiAgICBmdW5jdGlvbiBnZXRUYWJsZUxpc3QoKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmdbXSkgew0KICAgICAgICByZXR1cm4gdGFibGVMaXN0Ow0KICAgIH0NCg0KICAgIC8qKg0KICAgICogQHJldHVybiB0YWJsZeS4reaTjeS9nOeahOadoeebruaVsA0KICAgICovDQogICAgZnVuY3Rpb24gZ2V0VGFibGVSZWNvcmRzKHN0cmluZyBrZXkpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQpIHsNCiAgICAgICAgcmV0dXJuIHRhYmxlUmVjb3Jkc1trZXldOw0KICAgIH0NCg0KICAgIC8qKg0KICAgICogQG5vdGljZSDliqjmgIHliJvlu7rooagNCiAgICAqIEBwYXJhbSB0YWJsZU5hbWUg6KGo55qE5ZCN56ewDQogICAgKiDooajnu5PmnoTvvJoNCiAgICAqICstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsNCiAgICAqIHwgRmllbGQgICAgICAgIHwgVHlwZSAgICAgICAgICAgICAgICB8IERlc2MgICAgICAgICAgICAgICAgICAgIHwNCiAgICAqICstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsNCiAgICAqIHwga2V5ICAgICAgICAgIHwgc3RyaW5nICAgICAgICAgICAgICB8IOS4u+mUriAgICAgICAgICAgICAgICAgICAgIHwNCiAgICAqIHwgdmFsdWUgICAgICAgIHwgc3RyaW5nICAgICAgICAgICAgICB8IOWvueW6lHZhbHVlICAgICAgICAgICAgICAgIHwNCiAgICAqICstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsNCiAgICAqICBjb3VudCA9IDAg6KGo56S65oiQ5Yqf5Yib5bu6DQogICAgKiAg5YW25LuW5YC86KGo56S65Yib5bu65aSx6LSlDQogICAgKi8NCiAgICBmdW5jdGlvbiBTdG9yYWdlQ3JlYXRlKHN0cmluZyBtZW1vcnkgdGFibGVOYW1lKXB1YmxpYyBvbmx5UHJveHkgcmV0dXJucyhpbnQpIHsNCiAgICAgICAgVGFibGVGYWN0b3J5IHRmID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7DQogICAgICAgIGludCBjb3VudCA9IHRmLmNyZWF0ZVRhYmxlKHRhYmxlTmFtZSwgImtleSIsICJ2YWx1ZSIpOw0KDQogICAgICAgIHRhYmxlTGlzdC5wdXNoKHRhYmxlTmFtZSk7DQogICAgICAgIGVtaXQgQ3JlYXRlUmVzdWx0KGNvdW50KTsNCiAgICAgICAgDQogICAgICAgIHJldHVybiBjb3VudDsNCiAgICB9DQoNCiAgICAvKioNCiAgICAqIEBub3RpY2Ug5o+S5YWl5pWw5o2uDQogICAgKiBAZGV2IOmZkOWFpeWPo+WQiOe6puiwg+eUqA0KICAgICogQHBhcmFtIHRhYmxlTmFtZSDooajnmoTlkI3np7ANCiAgICAqIEBwYXJhbSBrZXkgICAgICAg5Li76ZSuDQogICAgKiBAcGFyYW0gdmFsdWUgICAgIOWvueW6lHZhbHVlDQogICAgKiBjb3VudCA9IDEgIOihqOekuuaPkuWFpeaIkOWKnw0KICAgICogY291bnQgPSAtMSDooajnpLprZXnlt7LlrZjlnKgNCiAgICAqIOWFtuS7luWAvCDooajnpLrmj5LlhaXlpLHotKUNCiAgICAqLw0KICAgIGZ1bmN0aW9uIFN0b3JhZ2VJbnNlcnQoc3RyaW5nIG1lbW9yeSB0YWJsZU5hbWUsIHN0cmluZyBtZW1vcnkga2V5LCBzdHJpbmcgbWVtb3J5IHZhbHVlKXB1YmxpYyBvbmx5UHJveHkgcmV0dXJucyhpbnQpIHsNCiAgICAgICAgVGFibGVGYWN0b3J5IHRmID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7DQogICAgICAgIFRhYmxlIHRhYmxlID0gdGYub3BlblRhYmxlKHRhYmxlTmFtZSk7DQoNCiAgICAgICAgaW50IGNvdW50ID0gMCA7DQogICAgICAgIGlmKF9pc0tleUV4aXN0KHRhYmxlLCBrZXkpKXsNCiAgICAgICAgICAgIGNvdW50ID0gLTEgOw0KICAgICAgICAgICAgdGFibGVSZWNvcmRzW3RhYmxlTmFtZS50b1NsaWNlKCkuY29uY2F0KCJfSW5zZXJ0X0JBRCIudG9TbGljZSgpKV0gKz0gMTsgDQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgRW50cnkgZW50cnkgPSB0YWJsZS5uZXdFbnRyeSgpOw0KICAgICAgICAgICAgZW50cnkuc2V0KCJrZXkiLCBrZXkpOw0KICAgICAgICAgICAgZW50cnkuc2V0KCJ2YWx1ZSIsIHZhbHVlKTsNCiAgICAgICAgICAgIGNvdW50ID0gdGFibGUuaW5zZXJ0KGtleSwgZW50cnkpOw0KICAgICAgICAgICAgdGFibGVSZWNvcmRzW3RhYmxlTmFtZS50b1NsaWNlKCkuY29uY2F0KCJfSW5zZXJ0X09LIi50b1NsaWNlKCkpXSArPSAxOyANCiAgICAgICAgfQ0KICAgICAgICBlbWl0IEluc2VydFJlc3VsdChjb3VudCk7DQogICAgICAgIHJldHVybiBjb3VudDsNCiAgICB9DQoNCiAgICAvKioNCiAgICAqIEBub3RpY2Ug6YCa6L+Ha2V55p+l6K+i5pWw5o2uDQogICAgKiBAcGFyYW0gdGFibGVOYW1lIOihqOeahOWQjeensA0KICAgICogQHBhcmFtIGtleSAgICAgICDkuLvplK4NCiAgICAqDQogICAgKiByZXN1bHQgPSAgMCDooajnpLrmn6Xor6LmiJDlip8NCiAgICAqIHJlc3VsdCA9IC0xIOihqOekuuafpeivouWksei0pQ0KICAgICovDQogICAgZnVuY3Rpb24gU3RvcmFnZVNlbGVjdChzdHJpbmcgbWVtb3J5IHRhYmxlTmFtZSwgIHN0cmluZyBtZW1vcnkga2V5KSBwdWJsaWMgdmlldyByZXR1cm5zKA0KICAgICAgICBpbnQgX3Jlc3VsdCAsc3RyaW5nIG1lbW9yeSBfa2V5LHN0cmluZyBtZW1vcnkgX3ZhbHVlDQogICAgKXsNCiAgICAgICAgVGFibGVGYWN0b3J5IHRmID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7DQogICAgICAgIFRhYmxlIHRhYmxlID0gdGYub3BlblRhYmxlKHRhYmxlTmFtZSk7DQoNCiAgICAgICAgaWYoX2lzS2V5RXhpc3QodGFibGUsIGtleSkpew0KICAgICAgICAgICAgQ29uZGl0aW9uIGNvbmRpdGlvbiA9IHRhYmxlLm5ld0NvbmRpdGlvbigpOw0KICAgICAgICAgICAgRW50cnkgZW50cnkgPSB0YWJsZS5zZWxlY3Qoa2V5LCBjb25kaXRpb24pLmdldChpbnQoMCkpOw0KICAgICAgICAgICAgX3Jlc3VsdCA9IDAgOw0KICAgICAgICAgICAgKF9rZXksIF92YWx1ZSkgPSBfcmV0dXJuRGF0YShlbnRyeSk7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgX3Jlc3VsdD0gLTEgOw0KICAgICAgICAgICAgX2tleT0ga2V5IDsNCiAgICAgICAgICAgIF92YWx1ZT0gIiIgOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLyoqDQogICAgKiBAbm90aWNlIOmAmui/h2tleea3u+WKoOaVsOaNru+8jOiHquWKqOWMuuWIhuaYr+azqOWGjOi/mOaYr+abtOaWsA0KICAgICogQHBhcmFtIHRhYmxlTmFtZSDooajnmoTlkI3np7ANCiAgICAqIEBwYXJhbSBrZXkgICAgICAg5Li76ZSuDQogICAgKiBAcGFyYW0gdmFsdWUgICAgIOWvueW6lHZhbHVlDQogICAgKg0KICAgICogY291bnQgPSAgMSDooajnpLrmt7vliqDmiJDlip8NCiAgICAqIOWFtuS7luWAvOihqOekuuabtOaWsOWksei0pQ0KICAgICovDQogICAgZnVuY3Rpb24gU3RvcmFnZVB1dChzdHJpbmcgbWVtb3J5IHRhYmxlTmFtZSwgc3RyaW5nIG1lbW9yeSBrZXksIHN0cmluZyBtZW1vcnkgdmFsdWUpIHB1YmxpYyBvbmx5UHJveHkgcmV0dXJucyhpbnQpIHsNCiAgICAgICAgVGFibGVGYWN0b3J5IHRmID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7DQogICAgICAgIFRhYmxlIHRhYmxlID0gdGYub3BlblRhYmxlKHRhYmxlTmFtZSk7DQogICAgICAgIGludCBjb3VudCA9IDAgOw0KDQogICAgICAgICggaW50IF9yZXN1bHQsICwgc3RyaW5nIG1lbW9yeSBfdmFsdWUgKSA9IFN0b3JhZ2VTZWxlY3QodGFibGVOYW1lLCBrZXkpOw0KICAgICAgICBFbnRyeSBlbnRyeSA9IHRhYmxlLm5ld0VudHJ5KCk7DQogICAgICAgIGlmKF9yZXN1bHQgPT0gMCApew0KICAgICAgICAgICAgZW50cnkuc2V0KCJ2YWx1ZSIsIHZhbHVlKTsNCiAgICAgICAgICAgIENvbmRpdGlvbiBjb25kaXRpb24gPSB0YWJsZS5uZXdDb25kaXRpb24oKTsNCiAgICAgICAgICAgIGNvdW50ID0gdGFibGUudXBkYXRlKGtleSwgZW50cnksIGNvbmRpdGlvbik7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgZW50cnkuc2V0KCJrZXkiLCBrZXkpOw0KICAgICAgICAgICAgZW50cnkuc2V0KCJ2YWx1ZSIsIHZhbHVlKTsNCiAgICAgICAgICAgIGNvdW50ID0gdGFibGUuaW5zZXJ0KGtleSwgZW50cnkpOw0KICAgICAgICB9DQoNCiAgICAgICAgdGFibGVSZWNvcmRzW3RhYmxlTmFtZS50b1NsaWNlKCkuY29uY2F0KCJfUHV0Ii50b1NsaWNlKCkpXSArPSAxOw0KICAgICAgICBlbWl0IFB1dFJlc3VsdChfcmVzdWx0LCBjb3VudCk7DQogICAgICAgIHJldHVybiBjb3VudDsNCiAgICB9DQoNCiAgICAvKioNCiAgICAqIEBub3RpY2Ug6YCa6L+Ha2V55pu05paw5pWw5o2uDQogICAgKiBAcGFyYW0gdGFibGVOYW1lIOihqOeahOWQjeensA0KICAgICogQHBhcmFtIGtleSAgICAgICDkuLvplK4NCiAgICAqIEBwYXJhbSB2YWx1ZSAgICAg5a+55bqUdmFsdWUNCiAgICAqDQogICAgKiBjb3VudCA9ICAxIOihqOekuuabtOaWsOaIkOWKnw0KICAgICogY291bnQgPSAtMSDooajnpLprZXnkuI3lrZjlnKgNCiAgICAqIOWFtuS7luWAvOihqOekuuabtOaWsOWksei0pQ0KICAgICovDQogICAgZnVuY3Rpb24gU3RvcmFnZVVwZGF0ZShzdHJpbmcgbWVtb3J5IHRhYmxlTmFtZSwgc3RyaW5nIG1lbW9yeSBrZXksIHN0cmluZyBtZW1vcnkgdmFsdWUpIHB1YmxpYyBvbmx5UHJveHkgcmV0dXJucyhpbnQpIHsNCiAgICAgICAgVGFibGVGYWN0b3J5IHRmID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7DQogICAgICAgIFRhYmxlIHRhYmxlID0gdGYub3BlblRhYmxlKHRhYmxlTmFtZSk7DQogICAgICAgIGludCBjb3VudCA9IDAgOw0KDQogICAgICAgICggaW50IF9yZXN1bHQsICwgc3RyaW5nIG1lbW9yeSBfdmFsdWUgKSA9IFN0b3JhZ2VTZWxlY3QodGFibGVOYW1lLCBrZXkpOw0KICAgICAgICBpZihfcmVzdWx0ID09IDAgKXsNCiAgICAgICAgICAgIEVudHJ5IGVudHJ5ID0gdGFibGUubmV3RW50cnkoKTsNCiAgICAgICAgICAgIGVudHJ5LnNldCgidmFsdWUiLCB2YWx1ZSk7DQogICAgICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7DQogICAgICAgICAgICBjb3VudCA9IHRhYmxlLnVwZGF0ZShrZXksIGVudHJ5LCBjb25kaXRpb24pOw0KICAgICAgICAgICAgdGFibGVSZWNvcmRzW3RhYmxlTmFtZS50b1NsaWNlKCkuY29uY2F0KCJfVXBkYXRlX09LIi50b1NsaWNlKCkpXSArPSAxOyAgICANCiAgICAgICAgfWVsc2V7DQogICAgICAgICAgICBjb3VudCA9IC0xOw0KICAgICAgICAgICAgdGFibGVSZWNvcmRzW3RhYmxlTmFtZS50b1NsaWNlKCkuY29uY2F0KCJfVXBkYXRlX0JBRCIudG9TbGljZSgpKV0gKz0gMTsgICAgCSAgICANCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgZW1pdCBVcGRhdGVSZXN1bHQoY291bnQpOw0KICAgICAgICByZXR1cm4gY291bnQ7DQogICAgfQ0KDQogICAgLyoqDQogICAgKiBAbm90aWNlIOmAmui/h2tleeWIoOmZpOaVsOaNrg0KICAgICogQHBhcmFtIHRhYmxlTmFtZSDooajnmoTlkI3np7ANCiAgICAqIEBwYXJhbSBrZXkgICAgICAg5Li76ZSuDQogICAgKg0KICAgICogY291bnQgPSAgMSDmoIfor4bliKDpmaTmiJDlip8NCiAgICAqIGNvdW50ID0gLTEg6KGo56S6a2V55LiN5a2Y5ZyoDQogICAgKiDlhbbku5blgLzooajnpLrliKDpmaTlpLHotKUNCiAgICAqLw0KICAgIGZ1bmN0aW9uIFN0b3JhZ2VSZW1vdmUoc3RyaW5nIG1lbW9yeSB0YWJsZU5hbWUsIHN0cmluZyBtZW1vcnkga2V5KSBwdWJsaWMgb25seVByb3h5IHJldHVybnMoaW50KXsNCiAgICAgICAgVGFibGVGYWN0b3J5IHRmID0gVGFibGVGYWN0b3J5KDB4MTAwMSk7DQogICAgICAgIFRhYmxlIHRhYmxlID0gdGYub3BlblRhYmxlKHRhYmxlTmFtZSk7DQogICAgICAgIGludCBjb3VudCA9IDAgOw0KICAgICAgICBpZihfaXNLZXlFeGlzdCh0YWJsZSwga2V5KSl7DQogICAgICAgICAgICBDb25kaXRpb24gY29uZGl0aW9uID0gdGFibGUubmV3Q29uZGl0aW9uKCk7DQogICAgICAgICAgICBjb3VudCA9IHRhYmxlLnJlbW92ZShrZXksIGNvbmRpdGlvbik7DQogICAgICAgICAgICB0YWJsZVJlY29yZHNbdGFibGVOYW1lLnRvU2xpY2UoKS5jb25jYXQoIl9SZW1vdmVfT0siLnRvU2xpY2UoKSldICs9IDE7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgY291bnQgPSAtMTsNCiAgICAgICAgICAgIHRhYmxlUmVjb3Jkc1t0YWJsZU5hbWUudG9TbGljZSgpLmNvbmNhdCgiX1JlbW92ZV9CQUQiLnRvU2xpY2UoKSldICs9IDE7CSAgICANCiAgICAgICAgfQ0KCQ0KICAgICAgICBlbWl0IFJlbW92ZVJlc3VsdChjb3VudCk7DQogICAgICAgIHJldHVybiBjb3VudDsNCiAgICB9DQoNCg0KICAgIC8qKg0KICAgICogQG5vdGljZSDliKTor7trZXnlgLzmmK/lkKblrZjlnKgNCiAgICAqIEBwYXJhbSB0YWJsZU5hbWUg6KGo55qE5ZCN56ewDQogICAgKiBAcGFyYW0ga2V5ICAgICAgIOS4u+mUrg0KICAgICovDQogICAgZnVuY3Rpb24gaXNLZXlFeGlzdChzdHJpbmcgdGFibGVOYW1lLCBzdHJpbmcga2V5KSBleHRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgew0KICAgICAgICBUYWJsZUZhY3RvcnkgdGYgPSBUYWJsZUZhY3RvcnkoMHgxMDAxKTsNCiAgICAgICAgVGFibGUgdGFibGUgPSB0Zi5vcGVuVGFibGUodGFibGVOYW1lKTsNCg0KICAgICAgICByZXR1cm4gX2lzS2V5RXhpc3QodGFibGUsIGtleSk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX2lzS2V5RXhpc3QoVGFibGUgX3RhYmxlLCBzdHJpbmcgbWVtb3J5IF9pZCkgaW50ZXJuYWwgdmlldyByZXR1cm5zKGJvb2wpIHsNCiAgICAgICAgQ29uZGl0aW9uIGNvbmRpdGlvbiA9IF90YWJsZS5uZXdDb25kaXRpb24oKTsNCiAgICAgICAgcmV0dXJuIF90YWJsZS5zZWxlY3QoX2lkLCBjb25kaXRpb24pLnNpemUoKSAhPSBpbnQoMCk7DQogICAgfQ0KDQoNCiAgICBmdW5jdGlvbiBfcmV0dXJuRGF0YShFbnRyeSBfZW50cnkpIGludGVybmFsIHZpZXcgcmV0dXJucygNCiAgICAgICAgc3RyaW5nIG1lbW9yeSBfa2V5LA0KICAgICAgICBzdHJpbmcgbWVtb3J5IF92YWx1ZQ0KICAgICl7DQogICAgICAgIF9rZXkgPSBfZW50cnkuZ2V0U3RyaW5nKCJrZXkiKTsNCiAgICAgICAgX3ZhbHVlID0gX2VudHJ5LmdldFN0cmluZygidmFsdWUiKTsNCiAgICB9DQp9DQo=", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 37, + "contractFolderId" : 8, + "contractName" : "EnrollStorageStateful", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQoNCmltcG9ydCAiLi9FbnJvbGxTdG9yYWdlLnNvbCI7DQoNCi8qKg0KICog55m76K6w5ZCI57qm6ZyA6KaB5byV5YWl55qE5a2Y5YKo5ZCI57qmDQogKi8NCmNvbnRyYWN0IEVucm9sbFN0b3JhZ2VTdGF0ZWZ1bCB7DQoNCiAgICAvLyDlrZjlgqjlkIjnuqbniYjmnKzliJfooagNCiAgICBhZGRyZXNzW10gcHVibGljIHN0b3JhZ2VBZGRyTGlzdDsNCg0KICAgIEVucm9sbFN0b3JhZ2UgcHVibGljIGVucm9sbFN0b3JhZ2U7DQp9", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 38, + "contractFolderId" : 8, + "contractName" : "Proxy", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQoNCmltcG9ydCAiLi9Pd25hYmxlLnNvbCI7DQppbXBvcnQgIi4vQWRkcmVzcy5zb2wiOw0KaW1wb3J0ICIuL1N0cmluZ3Muc29sIjsNCi8qKg0KICog5YWl5Y+j5ZCI57qm77yM55So5LqO6L2s5Y+R5Lqk5piT6Iez6YC76L6R5ZCI57qmDQogKi8NCmNvbnRyYWN0IFByb3h5IGlzIE93bmFibGUgew0KCXVzaW5nIFN0cmluZ3MgZm9yICo7DQoNCgkvLyDniYjmnKzlr7nlupTnmoTmjqfliLblkIjnuqblnLDlnYAg54mI5pys5Y+3ID0+IOaOp+WItuWQiOe6puWcsOWdgA0KCW1hcHBpbmcoc3RyaW5nID0+IGFkZHJlc3MpIGludGVybmFsIF92ZXJzaW9uczsNCg0KCS8vIOeJiOacrOWIl+ihqA0KCXN0cmluZ1tdIHB1YmxpYyB2ZXJzaW9uTGlzdDsNCg0KCS8vIOW9k+WJjeeJiOacrA0KCXN0cmluZyBwdWJsaWMgdmVyc2lvbjsNCg0KCS8vLy8vLy8vLy8vLy8vLw0KCS8vLy8gRXZlbnQNCgkvLy8vLy8vLy8vLy8vLy8NCg0KCS8vIOS6i+S7tu+8jOabtOaWsOWQjuinpuWPkQ0KCWV2ZW50IFVwZ3JhZGVkKHN0cmluZyBuZXdWZXJzaW9uLCBhZGRyZXNzIG5ld0ltcGxlbWVudGF0aW9uKTsNCgkvLy8vLy8vLy8vLy8vLy8NCgkvLy8vIEZ1bmN0aW9ucw0KCS8vLy8vLy8vLy8vLy8vLw0KDQoJLy9hZGRyZXNz57G75Z6L6L2sc3RyaW5nDQoJZnVuY3Rpb24gYWRkcmVzc1RvU3RyaW5nKGFkZHJlc3MgX2FkZHIpIHB1YmxpYyBwdXJlIHJldHVybnMoc3RyaW5nKSB7DQoJCWJ5dGVzMzIgdmFsdWUgPSBieXRlczMyKHVpbnQyNTYoX2FkZHIpKTsNCgkJYnl0ZXMgbWVtb3J5IGFscGhhYmV0ID0gIjAxMjM0NTY3ODlhYmNkZWYiOw0KDQoJCWJ5dGVzIG1lbW9yeSBzdHIgPSBuZXcgYnl0ZXMoNTEpOw0KCQlzdHJbMF0gPSAiMCI7DQoJCXN0clsxXSA9ICJ4IjsNCgkJZm9yICh1aW50IGkgPSAwOyBpIDwgMjA7IGkrKykgew0KCQkJc3RyWzIraSoyXSA9IGFscGhhYmV0W3VpbnQodWludDgodmFsdWVbaSArIDEyXSA+PiA0KSldOw0KCQkJc3RyWzMraSoyXSA9IGFscGhhYmV0W3VpbnQodWludDgodmFsdWVbaSArIDEyXSAmIDB4MGYpKV07DQoJCX0NCgkJcmV0dXJuIHN0cmluZyhzdHIpOw0KCX0NCg0KCS8v6L+U5Zue5omA5pyJ55qE54mI5pys5YiX6KGoDQoJZnVuY3Rpb24gZ2V0VmVyc2lvbnMoKSB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkgcmVzdWx0KXsNCgkJcmVzdWx0PSJ7IjsNCgkJZm9yKHVpbnQgaSA9IDA7IGkgPCB2ZXJzaW9uTGlzdC5sZW5ndGg7IGkrKykgew0KCQkJcmVzdWx0ID0gcmVzdWx0LnRvU2xpY2UoKS5jb25jYXQodmVyc2lvbkxpc3RbaV0udG9TbGljZSgpKTsNCgkJCXJlc3VsdCA9IHJlc3VsdC50b1NsaWNlKCkuY29uY2F0KCI6Ii50b1NsaWNlKCkpOw0KCQkJcmVzdWx0ID0gcmVzdWx0LnRvU2xpY2UoKS5jb25jYXQoYWRkcmVzc1RvU3RyaW5nKF92ZXJzaW9uc1t2ZXJzaW9uTGlzdFtpXV0pLnRvU2xpY2UoKSk7DQoJCQlpZihpICE9ICh2ZXJzaW9uTGlzdC5sZW5ndGgtMSkpIHsNCgkJCQlyZXN1bHQgPSByZXN1bHQudG9TbGljZSgpLmNvbmNhdCgiLCIudG9TbGljZSgpKTsNCgkJCX0NCgkJfQ0KCQlyZXN1bHQgPSByZXN1bHQudG9TbGljZSgpLmNvbmNhdCgifSIudG9TbGljZSgpKTsNCgl9DQoNCgkvLyDov5Tlm57lrp7njrDlnLDlnYANCglmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbigpIHB1YmxpYyB2aWV3IHJldHVybnMgKGFkZHJlc3MpIHsNCgkJcmV0dXJuIF92ZXJzaW9uc1t2ZXJzaW9uXTsNCgl9DQoNCgkvLyDmm7TmlrDlrp7njrDlnLDlnYANCglmdW5jdGlvbiB1cGdyYWRlVG8oc3RyaW5nIG1lbW9yeSBfbmV3VmVyc2lvbiwgYWRkcmVzcyBfbmV3SW1wbGVtZW50YXRpb24pIHB1YmxpYyBvbmx5T3duZXIgew0KCQlyZXF1aXJlKGltcGxlbWVudGF0aW9uKCkgIT0gX25ld0ltcGxlbWVudGF0aW9uICYmIF9uZXdJbXBsZW1lbnRhdGlvbiAhPSBhZGRyZXNzKDApLCAiUHJveHk6IE9sZCBhZGRyZXNzIGlzIG5vdCBhbGxvd2VkIGFuZCBpbXBsZW1lbnRhdGlvbiBhZGRyZXNzIHNob3VsZCBub3QgYmUgMHgiKTsNCgkJcmVxdWlyZShBZGRyZXNzLmlzQ29udHJhY3QoX25ld0ltcGxlbWVudGF0aW9uKSwgIlByb3h5OiBDYW5ub3Qgc2V0IGEgcHJveHkgaW1wbGVtZW50YXRpb24gdG8gYSBub24tY29udHJhY3QgYWRkcmVzcyIpOw0KCQlyZXF1aXJlKGJ5dGVzKF9uZXdWZXJzaW9uKS5sZW5ndGggPiAwLCAiUHJveHk6IFZlcnNpb24gc2hvdWxkIG5vdCBiZSBlbXB0eSBzdHJpbmciKTsNCgkJdmVyc2lvbiA9IF9uZXdWZXJzaW9uOw0KCQlfdmVyc2lvbnNbdmVyc2lvbl0gPSBfbmV3SW1wbGVtZW50YXRpb247DQoJCXZlcnNpb25MaXN0LnB1c2goX25ld1ZlcnNpb24pOw0KCQllbWl0IFVwZ3JhZGVkKF9uZXdWZXJzaW9uLCBfbmV3SW1wbGVtZW50YXRpb24pOw0KCX0NCg0KCS8vIOiOt+WPlueJiOacrOWvueW6lOeahOmAu+i+keWQiOe6puWcsOWdgA0KCWZ1bmN0aW9uIGdldEltcGxGcm9tVmVyc2lvbihzdHJpbmcgIF92ZXJzaW9uKSBleHRlcm5hbCAgdmlldyBvbmx5T3duZXIgcmV0dXJucyhhZGRyZXNzKSB7DQoJCXJlcXVpcmUoYnl0ZXMoX3ZlcnNpb24pLmxlbmd0aCA+IDAsICJWZXJzaW9uIHNob3VsZCBub3QgYmUgZW1wdHkgc3RyaW5nIik7DQoJCXJldHVybiBfdmVyc2lvbnNbX3ZlcnNpb25dOw0KCX0NCg0KCS8vIGZhbGxiYWNrDQoJZnVuY3Rpb24gKCkgcGF5YWJsZSBleHRlcm5hbCB7DQoJCWFkZHJlc3MgX2ltcGwgPSBpbXBsZW1lbnRhdGlvbigpOw0KCQlyZXF1aXJlKF9pbXBsICE9IGFkZHJlc3MoMCksICJpbXBsZW1lbnRhdGlvbiBub3Qgc2V0Iik7DQoNCgkJLy8g5aeU5omY6LCD55So6L+U5Zue57uT5p6cDQoJCWFzc2VtYmx5IHsNCgkJCWxldCBwdHIgOj0gbWxvYWQoMHg0MCkNCgkJCWNhbGxkYXRhY29weShwdHIsIDAsIGNhbGxkYXRhc2l6ZSkNCgkJCWxldCByZXN1bHQgOj0gZGVsZWdhdGVjYWxsKGdhcywgX2ltcGwsIHB0ciwgY2FsbGRhdGFzaXplLCAwLCAwKQ0KCQkJbGV0IHNpemUgOj0gcmV0dXJuZGF0YXNpemUNCgkJCXJldHVybmRhdGFjb3B5KHB0ciwgMCwgc2l6ZSkNCg0KCQkJc3dpdGNoIHJlc3VsdA0KCQkJY2FzZSAwIHsgcmV2ZXJ0KHB0ciwgc2l6ZSkgfQ0KCQkJZGVmYXVsdCB7IHJldHVybihwdHIsIHNpemUpIH0NCgkJfQ0KCX0NCn0NCg==", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 39, + "contractFolderId" : 8, + "contractName" : "BaseStorage", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQoNCmltcG9ydCAiLi9Pd25hYmxlLnNvbCI7DQoNCi8qKg0KICog54i25a2Y5YKo5ZCI57qmDQogKi8NCmNvbnRyYWN0IEJhc2VTdG9yYWdlIGlzIE93bmFibGUgew0KDQogICAgLy8g5YWl5Y+j5Zyw5Z2ADQogICAgYWRkcmVzcyBwdWJsaWMgcHJveHlBZGRyZXNzOw0KDQogICAgLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLyBFdmVudA0KICAgIC8vLy8vLy8vLy8vLy8vLw0KDQogICAgZXZlbnQgQ3JlYXRlUmVzdWx0KGludCBjb3VudCk7DQogICAgZXZlbnQgSW5zZXJ0UmVzdWx0KGludCBjb3VudCk7DQogICAgZXZlbnQgVXBkYXRlUmVzdWx0KGludCBjb3VudCk7DQogICAgZXZlbnQgUHV0UmVzdWx0KGludCBhY3Rpb24saW50IGNvdW50KTsNCiAgICBldmVudCBSZW1vdmVSZXN1bHQoaW50IGNvdW50KTsNCiAgICBldmVudCBTZXRQcm94eShhZGRyZXNzIG9wZXJhdG9yLCBhZGRyZXNzIHByb3h5KTsNCg0KICAgIC8vLy8vLy8vLy8vLy8vLw0KICAgIC8vLy8gTW9kaWZpZXINCiAgICAvLy8vLy8vLy8vLy8vLy8NCg0KICAgIC8vIOS7hemZkOWFpeWPo+WQiOe6puiwg+eUqA0KICAgIG1vZGlmaWVyIG9ubHlQcm94eSgpIHsNCiAgICAgICAgcmVxdWlyZShtc2cuc2VuZGVyID09IHByb3h5QWRkcmVzcywgIkJhc2VTdG9yYWdlOiBvbmx5IHByb3h5IGNhbiBjYWxsIik7DQogICAgICAgIF87DQogICAgfQ0KDQogICAgLy8vLy8vLy8vLy8vLy8vDQogICAgLy8vLyBGdW5jdGlvbnMNCiAgICAvLy8vLy8vLy8vLy8vLy8NCg0KICAgIC8vIOiuvue9ruWFpeWPow0KICAgIGZ1bmN0aW9uIHNldFByb3h5KGFkZHJlc3MgX3Byb3h5KSBleHRlcm5hbCBvbmx5T3duZXIgew0KICAgICAgICBwcm94eUFkZHJlc3MgPSBfcHJveHk7DQogICAgICAgIGVtaXQgU2V0UHJveHkobXNnLnNlbmRlciwgX3Byb3h5KTsNCiAgICB9DQoNCn0NCg==", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 40, + "contractFolderId" : 8, + "contractName" : "Ownable", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQoNCmNvbnRyYWN0IE93bmFibGUgew0KICAgIGFkZHJlc3MgcHJpdmF0ZSBfb3duZXI7DQoNCiAgICBldmVudCBPd25lcnNoaXBUcmFuc2ZlcnJlZChhZGRyZXNzICBwcmV2aW91c093bmVyLCBhZGRyZXNzICBuZXdPd25lcik7DQoNCiAgICAvKioNCiAgICAgKiBAZGV2IFRoZSBPd25hYmxlIGNvbnN0cnVjdG9yIHNldHMgdGhlIG9yaWdpbmFsIGBvd25lcmAgb2YgdGhlIGNvbnRyYWN0IHRvIHRoZSBzZW5kZXINCiAgICAgKiBhY2NvdW50Lg0KICAgICAqLw0KICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsNCiAgICAgICAgX293bmVyID0gbXNnLnNlbmRlcjsNCiAgICAgICAgZW1pdCBPd25lcnNoaXBUcmFuc2ZlcnJlZChhZGRyZXNzKDApLCBfb3duZXIpOw0KICAgIH0NCg0KICAgIC8qKg0KICAgICAqIEByZXR1cm4gdGhlIGFkZHJlc3Mgb2YgdGhlIG93bmVyLg0KICAgICAqLw0KICAgIGZ1bmN0aW9uIG93bmVyKCkgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcykgew0KICAgICAgICByZXR1cm4gX293bmVyOw0KICAgIH0NCg0KICAgIC8qKg0KICAgICAqIEBkZXYgVGhyb3dzIGlmIGNhbGxlZCBieSBhbnkgYWNjb3VudCBvdGhlciB0aGFuIHRoZSBvd25lci4NCiAgICAgKi8NCiAgICBtb2RpZmllciBvbmx5T3duZXIoKSB7DQogICAgICAgIHJlcXVpcmUoaXNPd25lcigpLCAiT3duYWJsZTogbm90IGF1dGhvcml6ZWQiKTsNCiAgICAgICAgXzsNCiAgICB9DQoNCiAgICAvKioNCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgYG1zZy5zZW5kZXJgIGlzIHRoZSBvd25lciBvZiB0aGUgY29udHJhY3QuDQogICAgICovDQogICAgZnVuY3Rpb24gaXNPd25lcigpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJvb2wpIHsNCiAgICAgICAgcmV0dXJuIG1zZy5zZW5kZXIgPT0gX293bmVyOw0KICAgIH0NCg0KICAgIC8qKg0KICAgICAqIEBkZXYgQWxsb3dzIHRoZSBjdXJyZW50IG93bmVyIHRvIHRyYW5zZmVyIGNvbnRyb2wgb2YgdGhlIGNvbnRyYWN0IHRvIGEgbmV3T3duZXIuDQogICAgICogQHBhcmFtIG5ld093bmVyIFRoZSBhZGRyZXNzIHRvIHRyYW5zZmVyIG93bmVyc2hpcCB0by4NCiAgICAgKi8NCiAgICBmdW5jdGlvbiB0cmFuc2Zlck93bmVyc2hpcChhZGRyZXNzIG5ld093bmVyKSBwdWJsaWMgb25seU93bmVyIHsNCiAgICAgICAgX3RyYW5zZmVyT3duZXJzaGlwKG5ld093bmVyKTsNCiAgICB9DQoNCiAgICAvKioNCiAgICAgKiBAZGV2IFRyYW5zZmVycyBjb250cm9sIG9mIHRoZSBjb250cmFjdCB0byBhIG5ld093bmVyLg0KICAgICAqIEBwYXJhbSBuZXdPd25lciBUaGUgYWRkcmVzcyB0byB0cmFuc2ZlciBvd25lcnNoaXAgdG8uDQogICAgICovDQogICAgZnVuY3Rpb24gX3RyYW5zZmVyT3duZXJzaGlwKGFkZHJlc3MgbmV3T3duZXIpIGludGVybmFsIHsNCiAgICAgICAgcmVxdWlyZShuZXdPd25lciAhPSBhZGRyZXNzKDApLCAiT3duYWJsZTogbmV3T3duZXIgbm90IGJlIHplcm8iKTsNCiAgICAgICAgZW1pdCBPd25lcnNoaXBUcmFuc2ZlcnJlZChfb3duZXIsIG5ld093bmVyKTsNCiAgICAgICAgX293bmVyID0gbmV3T3duZXI7DQogICAgfQ0KfQ0K", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 41, + "contractFolderId" : 8, + "contractName" : "Strings", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "LyoKICogQHRpdGxlIFN0cmluZyAmIHNsaWNlIHV0aWxpdHkgbGlicmFyeSBmb3IgU29saWRpdHkgY29udHJhY3RzLgogKiBAYXV0aG9yIE5pY2sgSm9obnNvbiA8YXJhY2huaWRAbm90ZG90Lm5ldD4KICoKICogQGRldiBGdW5jdGlvbmFsaXR5IGluIHRoaXMgbGlicmFyeSBpcyBsYXJnZWx5IGltcGxlbWVudGVkIHVzaW5nIGFuCiAqICAgICAgYWJzdHJhY3Rpb24gY2FsbGVkIGEgJ3NsaWNlJy4gQSBzbGljZSByZXByZXNlbnRzIGEgcGFydCBvZiBhIHN0cmluZyAtCiAqICAgICAgYW55dGhpbmcgZnJvbSB0aGUgZW50aXJlIHN0cmluZyB0byBhIHNpbmdsZSBjaGFyYWN0ZXIsIG9yIGV2ZW4gbm8KICogICAgICBjaGFyYWN0ZXJzIGF0IGFsbCAoYSAwLWxlbmd0aCBzbGljZSkuIFNpbmNlIGEgc2xpY2Ugb25seSBoYXMgdG8gc3BlY2lmeQogKiAgICAgIGFuIG9mZnNldCBhbmQgYSBsZW5ndGgsIGNvcHlpbmcgYW5kIG1hbmlwdWxhdGluZyBzbGljZXMgaXMgYSBsb3QgbGVzcwogKiAgICAgIGV4cGVuc2l2ZSB0aGFuIGNvcHlpbmcgYW5kIG1hbmlwdWxhdGluZyB0aGUgc3RyaW5ncyB0aGV5IHJlZmVyZW5jZS4KICoKICogICAgICBUbyBmdXJ0aGVyIHJlZHVjZSBnYXMgY29zdHMsIG1vc3QgZnVuY3Rpb25zIG9uIHNsaWNlIHRoYXQgbmVlZCB0byByZXR1cm4KICogICAgICBhIHNsaWNlIG1vZGlmeSB0aGUgb3JpZ2luYWwgb25lIGluc3RlYWQgb2YgYWxsb2NhdGluZyBhIG5ldyBvbmU7IGZvcgogKiAgICAgIGluc3RhbmNlLCBgcy5zcGxpdCgiLiIpYCB3aWxsIHJldHVybiB0aGUgdGV4dCB1cCB0byB0aGUgZmlyc3QgJy4nLAogKiAgICAgIG1vZGlmeWluZyBzIHRvIG9ubHkgY29udGFpbiB0aGUgcmVtYWluZGVyIG9mIHRoZSBzdHJpbmcgYWZ0ZXIgdGhlICcuJy4KICogICAgICBJbiBzaXR1YXRpb25zIHdoZXJlIHlvdSBkbyBub3Qgd2FudCB0byBtb2RpZnkgdGhlIG9yaWdpbmFsIHNsaWNlLCB5b3UKICogICAgICBjYW4gbWFrZSBhIGNvcHkgZmlyc3Qgd2l0aCBgLmNvcHkoKWAsIGZvciBleGFtcGxlOgogKiAgICAgIGBzLmNvcHkoKS5zcGxpdCgiLiIpYC4gVHJ5IGFuZCBhdm9pZCB1c2luZyB0aGlzIGlkaW9tIGluIGxvb3BzOyBzaW5jZQogKiAgICAgIFNvbGlkaXR5IGhhcyBubyBtZW1vcnkgbWFuYWdlbWVudCwgaXQgd2lsbCByZXN1bHQgaW4gYWxsb2NhdGluZyBtYW55CiAqICAgICAgc2hvcnQtbGl2ZWQgc2xpY2VzIHRoYXQgYXJlIGxhdGVyIGRpc2NhcmRlZC4KICoKICogICAgICBGdW5jdGlvbnMgdGhhdCByZXR1cm4gdHdvIHNsaWNlcyBjb21lIGluIHR3byB2ZXJzaW9uczogYSBub24tYWxsb2NhdGluZwogKiAgICAgIHZlcnNpb24gdGhhdCB0YWtlcyB0aGUgc2Vjb25kIHNsaWNlIGFzIGFuIGFyZ3VtZW50LCBtb2RpZnlpbmcgaXQgaW4KICogICAgICBwbGFjZSwgYW5kIGFuIGFsbG9jYXRpbmcgdmVyc2lvbiB0aGF0IGFsbG9jYXRlcyBhbmQgcmV0dXJucyB0aGUgc2Vjb25kCiAqICAgICAgc2xpY2U7IHNlZSBgbmV4dFJ1bmVgIGZvciBleGFtcGxlLgogKgogKiAgICAgIEZ1bmN0aW9ucyB0aGF0IGhhdmUgdG8gY29weSBzdHJpbmcgZGF0YSB3aWxsIHJldHVybiBzdHJpbmdzIHJhdGhlciB0aGFuCiAqICAgICAgc2xpY2VzOyB0aGVzZSBjYW4gYmUgY2FzdCBiYWNrIHRvIHNsaWNlcyBmb3IgZnVydGhlciBwcm9jZXNzaW5nIGlmCiAqICAgICAgcmVxdWlyZWQuCiAqCiAqICAgICAgRm9yIGNvbnZlbmllbmNlLCBzb21lIGZ1bmN0aW9ucyBhcmUgcHJvdmlkZWQgd2l0aCBub24tbW9kaWZ5aW5nCiAqICAgICAgdmFyaWFudHMgdGhhdCBjcmVhdGUgYSBuZXcgc2xpY2UgYW5kIHJldHVybiBib3RoOyBmb3IgaW5zdGFuY2UsCiAqICAgICAgYHMuc3BsaXROZXcoJy4nKWAgbGVhdmVzIHMgdW5tb2RpZmllZCwgYW5kIHJldHVybnMgdHdvIHZhbHVlcwogKiAgICAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGxlZnQgYW5kIHJpZ2h0IHBhcnRzIG9mIHRoZSBzdHJpbmcuCiAqLwoKcHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CgpsaWJyYXJ5IFN0cmluZ3MgewogICAgc3RydWN0IHNsaWNlIHsKICAgICAgICB1aW50IF9sZW47CiAgICAgICAgdWludCBfcHRyOwogICAgfQoKICAgIGZ1bmN0aW9uIG1lbWNweSh1aW50IGRlc3QsIHVpbnQgc3JjLCB1aW50IGxlbikgcHJpdmF0ZSBwdXJlIHsKICAgICAgICAvLyBDb3B5IHdvcmQtbGVuZ3RoIGNodW5rcyB3aGlsZSBwb3NzaWJsZQogICAgICAgIGZvcig7IGxlbiA+PSAzMjsgbGVuIC09IDMyKSB7CiAgICAgICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgICAgIG1zdG9yZShkZXN0LCBtbG9hZChzcmMpKQogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlc3QgKz0gMzI7CiAgICAgICAgICAgIHNyYyArPSAzMjsKICAgICAgICB9CgogICAgICAgIC8vIENvcHkgcmVtYWluaW5nIGJ5dGVzCiAgICAgICAgdWludCBtYXNrID0gMjU2ICoqICgzMiAtIGxlbikgLSAxOwogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgbGV0IHNyY3BhcnQgOj0gYW5kKG1sb2FkKHNyYyksIG5vdChtYXNrKSkKICAgICAgICAgICAgbGV0IGRlc3RwYXJ0IDo9IGFuZChtbG9hZChkZXN0KSwgbWFzaykKICAgICAgICAgICAgbXN0b3JlKGRlc3QsIG9yKGRlc3RwYXJ0LCBzcmNwYXJ0KSkKICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgUmV0dXJucyBhIHNsaWNlIGNvbnRhaW5pbmcgdGhlIGVudGlyZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc3RyaW5nIHRvIG1ha2UgYSBzbGljZSBmcm9tLgogICAgICogQHJldHVybiBBIG5ld2x5IGFsbG9jYXRlZCBzbGljZSBjb250YWluaW5nIHRoZSBlbnRpcmUgc3RyaW5nLgogICAgICovCiAgICBmdW5jdGlvbiB0b1NsaWNlKHN0cmluZyBtZW1vcnkgc2VsZikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChzbGljZSBtZW1vcnkpIHsKICAgICAgICB1aW50IHB0cjsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIHB0ciA6PSBhZGQoc2VsZiwgMHgyMCkKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNsaWNlKGJ5dGVzKHNlbGYpLmxlbmd0aCwgcHRyKTsKICAgIH0KCiAgICAvKgogICAgICogQGRldiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgYSBudWxsLXRlcm1pbmF0ZWQgYnl0ZXMzMiBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgdmFsdWUgdG8gZmluZCB0aGUgbGVuZ3RoIG9mLgogICAgICogQHJldHVybiBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcsIGZyb20gMCB0byAzMi4KICAgICAqLwogICAgZnVuY3Rpb24gbGVuKGJ5dGVzMzIgc2VsZikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCByZXQ7CiAgICAgICAgaWYgKHNlbGYgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgaWYgKHNlbGYgJiAweGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmID09IDApIHsKICAgICAgICAgICAgcmV0ICs9IDE2OwogICAgICAgICAgICBzZWxmID0gYnl0ZXMzMih1aW50KHNlbGYpIC8gMHgxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDApOwogICAgICAgIH0KICAgICAgICBpZiAoc2VsZiAmIDB4ZmZmZmZmZmZmZmZmZmZmZiA9PSAwKSB7CiAgICAgICAgICAgIHJldCArPSA4OwogICAgICAgICAgICBzZWxmID0gYnl0ZXMzMih1aW50KHNlbGYpIC8gMHgxMDAwMDAwMDAwMDAwMDAwMCk7CiAgICAgICAgfQogICAgICAgIGlmIChzZWxmICYgMHhmZmZmZmZmZiA9PSAwKSB7CiAgICAgICAgICAgIHJldCArPSA0OwogICAgICAgICAgICBzZWxmID0gYnl0ZXMzMih1aW50KHNlbGYpIC8gMHgxMDAwMDAwMDApOwogICAgICAgIH0KICAgICAgICBpZiAoc2VsZiAmIDB4ZmZmZiA9PSAwKSB7CiAgICAgICAgICAgIHJldCArPSAyOwogICAgICAgICAgICBzZWxmID0gYnl0ZXMzMih1aW50KHNlbGYpIC8gMHgxMDAwMCk7CiAgICAgICAgfQogICAgICAgIGlmIChzZWxmICYgMHhmZiA9PSAwKSB7CiAgICAgICAgICAgIHJldCArPSAxOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMzIgLSByZXQ7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgUmV0dXJucyBhIHNsaWNlIGNvbnRhaW5pbmcgdGhlIGVudGlyZSBieXRlczMyLCBpbnRlcnByZXRlZCBhcyBhCiAgICAgKiAgICAgIG51bGwtdGVybWluYXRlZCB1dGYtOCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgYnl0ZXMzMiB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgc2xpY2UuCiAgICAgKiBAcmV0dXJuIEEgbmV3IHNsaWNlIGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSBpbnB1dCBhcmd1bWVudCB1cCB0byB0aGUKICAgICAqICAgICAgICAgZmlyc3QgbnVsbC4KICAgICAqLwogICAgZnVuY3Rpb24gdG9TbGljZUIzMihieXRlczMyIHNlbGYpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc2xpY2UgbWVtb3J5IHJldCkgewogICAgICAgIC8vIEFsbG9jYXRlIHNwYWNlIGZvciBgc2VsZmAgaW4gbWVtb3J5LCBjb3B5IGl0IHRoZXJlLCBhbmQgcG9pbnQgcmV0IGF0IGl0CiAgICAgICAgYXNzZW1ibHkgewogICAgICAgICAgICBsZXQgcHRyIDo9IG1sb2FkKDB4NDApCiAgICAgICAgICAgIG1zdG9yZSgweDQwLCBhZGQocHRyLCAweDIwKSkKICAgICAgICAgICAgbXN0b3JlKHB0ciwgc2VsZikKICAgICAgICAgICAgbXN0b3JlKGFkZChyZXQsIDB4MjApLCBwdHIpCiAgICAgICAgfQogICAgICAgIHJldC5fbGVuID0gbGVuKHNlbGYpOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgYSBuZXcgc2xpY2UgY29udGFpbmluZyB0aGUgc2FtZSBkYXRhIGFzIHRoZSBjdXJyZW50IHNsaWNlLgogICAgICogQHBhcmFtIHNlbGYgVGhlIHNsaWNlIHRvIGNvcHkuCiAgICAgKiBAcmV0dXJuIEEgbmV3IHNsaWNlIGNvbnRhaW5pbmcgdGhlIHNhbWUgZGF0YSBhcyBgc2VsZmAuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGNvcHkoc2xpY2UgbWVtb3J5IHNlbGYpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc2xpY2UgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIHNsaWNlKHNlbGYuX2xlbiwgc2VsZi5fcHRyKTsKICAgIH0KCiAgICAvKgogICAgICogQGRldiBDb3BpZXMgYSBzbGljZSB0byBhIG5ldyBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gY29weS4KICAgICAqIEByZXR1cm4gQSBuZXdseSBhbGxvY2F0ZWQgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHNsaWNlJ3MgdGV4dC4KICAgICAqLwogICAgZnVuY3Rpb24gdG9TdHJpbmcoc2xpY2UgbWVtb3J5IHNlbGYpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSkgewogICAgICAgIHN0cmluZyBtZW1vcnkgcmV0ID0gbmV3IHN0cmluZyhzZWxmLl9sZW4pOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsgcmV0cHRyIDo9IGFkZChyZXQsIDMyKSB9CgogICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGYuX3B0ciwgc2VsZi5fbGVuKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIGxlbmd0aCBpbiBydW5lcyBvZiB0aGUgc2xpY2UuIE5vdGUgdGhhdCB0aGlzIG9wZXJhdGlvbgogICAgICogICAgICB0YWtlcyB0aW1lIHByb3BvcnRpb25hbCB0byB0aGUgbGVuZ3RoIG9mIHRoZSBzbGljZTsgYXZvaWQgdXNpbmcgaXQKICAgICAqICAgICAgaW4gbG9vcHMsIGFuZCBjYWxsIGBzbGljZS5lbXB0eSgpYCBpZiB5b3Ugb25seSBuZWVkIHRvIGtub3cgd2hldGhlcgogICAgICogICAgICB0aGUgc2xpY2UgaXMgZW1wdHkgb3Igbm90LgogICAgICogQHBhcmFtIHNlbGYgVGhlIHNsaWNlIHRvIG9wZXJhdGUgb24uCiAgICAgKiBAcmV0dXJuIFRoZSBsZW5ndGggb2YgdGhlIHNsaWNlIGluIHJ1bmVzLgogICAgICovCiAgICBmdW5jdGlvbiBsZW4oc2xpY2UgbWVtb3J5IHNlbGYpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludCBsKSB7CiAgICAgICAgLy8gU3RhcnRpbmcgYXQgcHRyLTMxIG1lYW5zIHRoZSBMU0Igd2lsbCBiZSB0aGUgYnl0ZSB3ZSBjYXJlIGFib3V0CiAgICAgICAgdWludCBwdHIgPSBzZWxmLl9wdHIgLSAzMTsKICAgICAgICB1aW50IGVuZCA9IHB0ciArIHNlbGYuX2xlbjsKICAgICAgICBmb3IgKGwgPSAwOyBwdHIgPCBlbmQ7IGwrKykgewogICAgICAgICAgICB1aW50OCBiOwogICAgICAgICAgICBhc3NlbWJseSB7IGIgOj0gYW5kKG1sb2FkKHB0ciksIDB4RkYpIH0KICAgICAgICAgICAgaWYgKGIgPCAweDgwKSB7CiAgICAgICAgICAgICAgICBwdHIgKz0gMTsKICAgICAgICAgICAgfSBlbHNlIGlmKGIgPCAweEUwKSB7CiAgICAgICAgICAgICAgICBwdHIgKz0gMjsKICAgICAgICAgICAgfSBlbHNlIGlmKGIgPCAweEYwKSB7CiAgICAgICAgICAgICAgICBwdHIgKz0gMzsKICAgICAgICAgICAgfSBlbHNlIGlmKGIgPCAweEY4KSB7CiAgICAgICAgICAgICAgICBwdHIgKz0gNDsKICAgICAgICAgICAgfSBlbHNlIGlmKGIgPCAweEZDKSB7CiAgICAgICAgICAgICAgICBwdHIgKz0gNTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHB0ciArPSA2OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgdHJ1ZSBpZiB0aGUgc2xpY2UgaXMgZW1wdHkgKGhhcyBhIGxlbmd0aCBvZiAwKS4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBzbGljZSB0byBvcGVyYXRlIG9uLgogICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBzbGljZSBpcyBlbXB0eSwgRmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBlbXB0eShzbGljZSBtZW1vcnkgc2VsZikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuX2xlbiA9PSAwOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgYSBwb3NpdGl2ZSBudW1iZXIgaWYgYG90aGVyYCBjb21lcyBsZXhpY29ncmFwaGljYWxseSBhZnRlcgogICAgICogICAgICBgc2VsZmAsIGEgbmVnYXRpdmUgbnVtYmVyIGlmIGl0IGNvbWVzIGJlZm9yZSwgb3IgemVybyBpZiB0aGUKICAgICAqICAgICAgY29udGVudHMgb2YgdGhlIHR3byBzbGljZXMgYXJlIGVxdWFsLiBDb21wYXJpc29uIGlzIGRvbmUgcGVyLXJ1bmUsCiAgICAgKiAgICAgIG9uIHVuaWNvZGUgY29kZXBvaW50cy4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBmaXJzdCBzbGljZSB0byBjb21wYXJlLgogICAgICogQHBhcmFtIG90aGVyIFRoZSBzZWNvbmQgc2xpY2UgdG8gY29tcGFyZS4KICAgICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgY29tcGFyaXNvbi4KICAgICAqLwogICAgZnVuY3Rpb24gY29tcGFyZShzbGljZSBtZW1vcnkgc2VsZiwgc2xpY2UgbWVtb3J5IG90aGVyKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGludCkgewogICAgICAgIHVpbnQgc2hvcnRlc3QgPSBzZWxmLl9sZW47CiAgICAgICAgaWYgKG90aGVyLl9sZW4gPCBzZWxmLl9sZW4pCiAgICAgICAgICAgIHNob3J0ZXN0ID0gb3RoZXIuX2xlbjsKCiAgICAgICAgdWludCBzZWxmcHRyID0gc2VsZi5fcHRyOwogICAgICAgIHVpbnQgb3RoZXJwdHIgPSBvdGhlci5fcHRyOwogICAgICAgIGZvciAodWludCBpZHggPSAwOyBpZHggPCBzaG9ydGVzdDsgaWR4ICs9IDMyKSB7CiAgICAgICAgICAgIHVpbnQgYTsKICAgICAgICAgICAgdWludCBiOwogICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICBhIDo9IG1sb2FkKHNlbGZwdHIpCiAgICAgICAgICAgICAgICBiIDo9IG1sb2FkKG90aGVycHRyKQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhICE9IGIpIHsKICAgICAgICAgICAgICAgIC8vIE1hc2sgb3V0IGlycmVsZXZhbnQgYnl0ZXMgYW5kIGNoZWNrIGFnYWluCiAgICAgICAgICAgICAgICB1aW50MjU2IG1hc2sgPSB1aW50MjU2KC0xKTsgLy8gMHhmZmZmLi4uCiAgICAgICAgICAgICAgICBpZihzaG9ydGVzdCA8IDMyKSB7CiAgICAgICAgICAgICAgICAgIG1hc2sgPSB+KDIgKiogKDggKiAoMzIgLSBzaG9ydGVzdCArIGlkeCkpIC0gMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB1aW50MjU2IGRpZmYgPSAoYSAmIG1hc2spIC0gKGIgJiBtYXNrKTsKICAgICAgICAgICAgICAgIGlmIChkaWZmICE9IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGludChkaWZmKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZWxmcHRyICs9IDMyOwogICAgICAgICAgICBvdGhlcnB0ciArPSAzMjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGludChzZWxmLl9sZW4pIC0gaW50KG90aGVyLl9sZW4pOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgdHJ1ZSBpZiB0aGUgdHdvIHNsaWNlcyBjb250YWluIHRoZSBzYW1lIHRleHQuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgZmlyc3Qgc2xpY2UgdG8gY29tcGFyZS4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBzZWNvbmQgc2xpY2UgdG8gY29tcGFyZS4KICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgc2xpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBlcXVhbHMoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBvdGhlcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmUoc2VsZiwgb3RoZXIpID09IDA7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgRXh0cmFjdHMgdGhlIGZpcnN0IHJ1bmUgaW4gdGhlIHNsaWNlIGludG8gYHJ1bmVgLCBhZHZhbmNpbmcgdGhlCiAgICAgKiAgICAgIHNsaWNlIHRvIHBvaW50IHRvIHRoZSBuZXh0IHJ1bmUgYW5kIHJldHVybmluZyBgc2VsZmAuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gb3BlcmF0ZSBvbi4KICAgICAqIEBwYXJhbSBydW5lIFRoZSBzbGljZSB0aGF0IHdpbGwgY29udGFpbiB0aGUgZmlyc3QgcnVuZS4KICAgICAqIEByZXR1cm4gYHJ1bmVgLgogICAgICovCiAgICBmdW5jdGlvbiBuZXh0UnVuZShzbGljZSBtZW1vcnkgc2VsZiwgc2xpY2UgbWVtb3J5IHJ1bmUpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc2xpY2UgbWVtb3J5KSB7CiAgICAgICAgcnVuZS5fcHRyID0gc2VsZi5fcHRyOwoKICAgICAgICBpZiAoc2VsZi5fbGVuID09IDApIHsKICAgICAgICAgICAgcnVuZS5fbGVuID0gMDsKICAgICAgICAgICAgcmV0dXJuIHJ1bmU7CiAgICAgICAgfQoKICAgICAgICB1aW50IGw7CiAgICAgICAgdWludCBiOwogICAgICAgIC8vIExvYWQgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIHJ1bmUgaW50byB0aGUgTFNCcyBvZiBiCiAgICAgICAgYXNzZW1ibHkgeyBiIDo9IGFuZChtbG9hZChzdWIobWxvYWQoYWRkKHNlbGYsIDMyKSksIDMxKSksIDB4RkYpIH0KICAgICAgICBpZiAoYiA8IDB4ODApIHsKICAgICAgICAgICAgbCA9IDE7CiAgICAgICAgfSBlbHNlIGlmKGIgPCAweEUwKSB7CiAgICAgICAgICAgIGwgPSAyOwogICAgICAgIH0gZWxzZSBpZihiIDwgMHhGMCkgewogICAgICAgICAgICBsID0gMzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsID0gNDsKICAgICAgICB9CgogICAgICAgIC8vIENoZWNrIGZvciB0cnVuY2F0ZWQgY29kZXBvaW50cwogICAgICAgIGlmIChsID4gc2VsZi5fbGVuKSB7CiAgICAgICAgICAgIHJ1bmUuX2xlbiA9IHNlbGYuX2xlbjsKICAgICAgICAgICAgc2VsZi5fcHRyICs9IHNlbGYuX2xlbjsKICAgICAgICAgICAgc2VsZi5fbGVuID0gMDsKICAgICAgICAgICAgcmV0dXJuIHJ1bmU7CiAgICAgICAgfQoKICAgICAgICBzZWxmLl9wdHIgKz0gbDsKICAgICAgICBzZWxmLl9sZW4gLT0gbDsKICAgICAgICBydW5lLl9sZW4gPSBsOwogICAgICAgIHJldHVybiBydW5lOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIGZpcnN0IHJ1bmUgaW4gdGhlIHNsaWNlLCBhZHZhbmNpbmcgdGhlIHNsaWNlIHRvIHBvaW50CiAgICAgKiAgICAgIHRvIHRoZSBuZXh0IHJ1bmUuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gb3BlcmF0ZSBvbi4KICAgICAqIEByZXR1cm4gQSBzbGljZSBjb250YWluaW5nIG9ubHkgdGhlIGZpcnN0IHJ1bmUgZnJvbSBgc2VsZmAuCiAgICAgKi8KICAgIGZ1bmN0aW9uIG5leHRSdW5lKHNsaWNlIG1lbW9yeSBzZWxmKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHNsaWNlIG1lbW9yeSByZXQpIHsKICAgICAgICBuZXh0UnVuZShzZWxmLCByZXQpOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgdGhlIG51bWJlciBvZiB0aGUgZmlyc3QgY29kZXBvaW50IGluIHRoZSBzbGljZS4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBzbGljZSB0byBvcGVyYXRlIG9uLgogICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHRoZSBmaXJzdCBjb2RlcG9pbnQgaW4gdGhlIHNsaWNlLgogICAgICovCiAgICBmdW5jdGlvbiBvcmQoc2xpY2UgbWVtb3J5IHNlbGYpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludCByZXQpIHsKICAgICAgICBpZiAoc2VsZi5fbGVuID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICB1aW50IHdvcmQ7CiAgICAgICAgdWludCBsZW5ndGg7CiAgICAgICAgdWludCBkaXZpc29yID0gMiAqKiAyNDg7CgogICAgICAgIC8vIExvYWQgdGhlIHJ1bmUgaW50byB0aGUgTVNCcyBvZiBiCiAgICAgICAgYXNzZW1ibHkgeyB3b3JkOj0gbWxvYWQobWxvYWQoYWRkKHNlbGYsIDMyKSkpIH0KICAgICAgICB1aW50IGIgPSB3b3JkIC8gZGl2aXNvcjsKICAgICAgICBpZiAoYiA8IDB4ODApIHsKICAgICAgICAgICAgcmV0ID0gYjsKICAgICAgICAgICAgbGVuZ3RoID0gMTsKICAgICAgICB9IGVsc2UgaWYoYiA8IDB4RTApIHsKICAgICAgICAgICAgcmV0ID0gYiAmIDB4MUY7CiAgICAgICAgICAgIGxlbmd0aCA9IDI7CiAgICAgICAgfSBlbHNlIGlmKGIgPCAweEYwKSB7CiAgICAgICAgICAgIHJldCA9IGIgJiAweDBGOwogICAgICAgICAgICBsZW5ndGggPSAzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldCA9IGIgJiAweDA3OwogICAgICAgICAgICBsZW5ndGggPSA0OwogICAgICAgIH0KCiAgICAgICAgLy8gQ2hlY2sgZm9yIHRydW5jYXRlZCBjb2RlcG9pbnRzCiAgICAgICAgaWYgKGxlbmd0aCA+IHNlbGYuX2xlbikgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIGZvciAodWludCBpID0gMTsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGRpdmlzb3IgPSBkaXZpc29yIC8gMjU2OwogICAgICAgICAgICBiID0gKHdvcmQgLyBkaXZpc29yKSAmIDB4RkY7CiAgICAgICAgICAgIGlmIChiICYgMHhDMCAhPSAweDgwKSB7CiAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIFVURi04IHNlcXVlbmNlCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXQgPSAocmV0ICogNjQpIHwgKGIgJiAweDNGKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXQ7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgUmV0dXJucyB0aGUga2VjY2FrLTI1NiBoYXNoIG9mIHRoZSBzbGljZS4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBzbGljZSB0byBoYXNoLgogICAgICogQHJldHVybiBUaGUgaGFzaCBvZiB0aGUgc2xpY2UuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGtlY2NhayhzbGljZSBtZW1vcnkgc2VsZikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChieXRlczMyIHJldCkgewogICAgICAgIGFzc2VtYmx5IHsKICAgICAgICAgICAgcmV0IDo9IGtlY2NhazI1NihtbG9hZChhZGQoc2VsZiwgMzIpKSwgbWxvYWQoc2VsZikpCiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgdHJ1ZSBpZiBgc2VsZmAgc3RhcnRzIHdpdGggYG5lZWRsZWAuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gb3BlcmF0ZSBvbi4KICAgICAqIEBwYXJhbSBuZWVkbGUgVGhlIHNsaWNlIHRvIHNlYXJjaCBmb3IuCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHNsaWNlIHN0YXJ0cyB3aXRoIHRoZSBwcm92aWRlZCB0ZXh0LCBmYWxzZSBvdGhlcndpc2UuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHN0YXJ0c1dpdGgoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBuZWVkbGUpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCkgewogICAgICAgIGlmIChzZWxmLl9sZW4gPCBuZWVkbGUuX2xlbikgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2VsZi5fcHRyID09IG5lZWRsZS5fcHRyKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYm9vbCBlcXVhbDsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIGxldCBsZW5ndGggOj0gbWxvYWQobmVlZGxlKQogICAgICAgICAgICBsZXQgc2VsZnB0ciA6PSBtbG9hZChhZGQoc2VsZiwgMHgyMCkpCiAgICAgICAgICAgIGxldCBuZWVkbGVwdHIgOj0gbWxvYWQoYWRkKG5lZWRsZSwgMHgyMCkpCiAgICAgICAgICAgIGVxdWFsIDo9IGVxKGtlY2NhazI1NihzZWxmcHRyLCBsZW5ndGgpLCBrZWNjYWsyNTYobmVlZGxlcHRyLCBsZW5ndGgpKQogICAgICAgIH0KICAgICAgICByZXR1cm4gZXF1YWw7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgSWYgYHNlbGZgIHN0YXJ0cyB3aXRoIGBuZWVkbGVgLCBgbmVlZGxlYCBpcyByZW1vdmVkIGZyb20gdGhlCiAgICAgKiAgICAgIGJlZ2lubmluZyBvZiBgc2VsZmAuIE90aGVyd2lzZSwgYHNlbGZgIGlzIHVubW9kaWZpZWQuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gb3BlcmF0ZSBvbi4KICAgICAqIEBwYXJhbSBuZWVkbGUgVGhlIHNsaWNlIHRvIHNlYXJjaCBmb3IuCiAgICAgKiBAcmV0dXJuIGBzZWxmYAogICAgICovCiAgICBmdW5jdGlvbiBiZXlvbmQoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBuZWVkbGUpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc2xpY2UgbWVtb3J5KSB7CiAgICAgICAgaWYgKHNlbGYuX2xlbiA8IG5lZWRsZS5fbGVuKSB7CiAgICAgICAgICAgIHJldHVybiBzZWxmOwogICAgICAgIH0KCiAgICAgICAgYm9vbCBlcXVhbCA9IHRydWU7CiAgICAgICAgaWYgKHNlbGYuX3B0ciAhPSBuZWVkbGUuX3B0cikgewogICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICBsZXQgbGVuZ3RoIDo9IG1sb2FkKG5lZWRsZSkKICAgICAgICAgICAgICAgIGxldCBzZWxmcHRyIDo9IG1sb2FkKGFkZChzZWxmLCAweDIwKSkKICAgICAgICAgICAgICAgIGxldCBuZWVkbGVwdHIgOj0gbWxvYWQoYWRkKG5lZWRsZSwgMHgyMCkpCiAgICAgICAgICAgICAgICBlcXVhbCA6PSBlcShrZWNjYWsyNTYoc2VsZnB0ciwgbGVuZ3RoKSwga2VjY2FrMjU2KG5lZWRsZXB0ciwgbGVuZ3RoKSkKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGVxdWFsKSB7CiAgICAgICAgICAgIHNlbGYuX2xlbiAtPSBuZWVkbGUuX2xlbjsKICAgICAgICAgICAgc2VsZi5fcHRyICs9IG5lZWRsZS5fbGVuOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNlbGY7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgUmV0dXJucyB0cnVlIGlmIHRoZSBzbGljZSBlbmRzIHdpdGggYG5lZWRsZWAuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gb3BlcmF0ZSBvbi4KICAgICAqIEBwYXJhbSBuZWVkbGUgVGhlIHNsaWNlIHRvIHNlYXJjaCBmb3IuCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHNsaWNlIHN0YXJ0cyB3aXRoIHRoZSBwcm92aWRlZCB0ZXh0LCBmYWxzZSBvdGhlcndpc2UuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGVuZHNXaXRoKHNsaWNlIG1lbW9yeSBzZWxmLCBzbGljZSBtZW1vcnkgbmVlZGxlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBpZiAoc2VsZi5fbGVuIDwgbmVlZGxlLl9sZW4pIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgdWludCBzZWxmcHRyID0gc2VsZi5fcHRyICsgc2VsZi5fbGVuIC0gbmVlZGxlLl9sZW47CgogICAgICAgIGlmIChzZWxmcHRyID09IG5lZWRsZS5fcHRyKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYm9vbCBlcXVhbDsKICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgIGxldCBsZW5ndGggOj0gbWxvYWQobmVlZGxlKQogICAgICAgICAgICBsZXQgbmVlZGxlcHRyIDo9IG1sb2FkKGFkZChuZWVkbGUsIDB4MjApKQogICAgICAgICAgICBlcXVhbCA6PSBlcShrZWNjYWsyNTYoc2VsZnB0ciwgbGVuZ3RoKSwga2VjY2FrMjU2KG5lZWRsZXB0ciwgbGVuZ3RoKSkKICAgICAgICB9CgogICAgICAgIHJldHVybiBlcXVhbDsKICAgIH0KCiAgICAvKgogICAgICogQGRldiBJZiBgc2VsZmAgZW5kcyB3aXRoIGBuZWVkbGVgLCBgbmVlZGxlYCBpcyByZW1vdmVkIGZyb20gdGhlCiAgICAgKiAgICAgIGVuZCBvZiBgc2VsZmAuIE90aGVyd2lzZSwgYHNlbGZgIGlzIHVubW9kaWZpZWQuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gb3BlcmF0ZSBvbi4KICAgICAqIEBwYXJhbSBuZWVkbGUgVGhlIHNsaWNlIHRvIHNlYXJjaCBmb3IuCiAgICAgKiBAcmV0dXJuIGBzZWxmYAogICAgICovCiAgICBmdW5jdGlvbiB1bnRpbChzbGljZSBtZW1vcnkgc2VsZiwgc2xpY2UgbWVtb3J5IG5lZWRsZSkgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChzbGljZSBtZW1vcnkpIHsKICAgICAgICBpZiAoc2VsZi5fbGVuIDwgbmVlZGxlLl9sZW4pIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGY7CiAgICAgICAgfQoKICAgICAgICB1aW50IHNlbGZwdHIgPSBzZWxmLl9wdHIgKyBzZWxmLl9sZW4gLSBuZWVkbGUuX2xlbjsKICAgICAgICBib29sIGVxdWFsID0gdHJ1ZTsKICAgICAgICBpZiAoc2VsZnB0ciAhPSBuZWVkbGUuX3B0cikgewogICAgICAgICAgICBhc3NlbWJseSB7CiAgICAgICAgICAgICAgICBsZXQgbGVuZ3RoIDo9IG1sb2FkKG5lZWRsZSkKICAgICAgICAgICAgICAgIGxldCBuZWVkbGVwdHIgOj0gbWxvYWQoYWRkKG5lZWRsZSwgMHgyMCkpCiAgICAgICAgICAgICAgICBlcXVhbCA6PSBlcShrZWNjYWsyNTYoc2VsZnB0ciwgbGVuZ3RoKSwga2VjY2FrMjU2KG5lZWRsZXB0ciwgbGVuZ3RoKSkKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGVxdWFsKSB7CiAgICAgICAgICAgIHNlbGYuX2xlbiAtPSBuZWVkbGUuX2xlbjsKICAgICAgICB9CgogICAgICAgIHJldHVybiBzZWxmOwogICAgfQoKICAgIC8vIFJldHVybnMgdGhlIG1lbW9yeSBhZGRyZXNzIG9mIHRoZSBmaXJzdCBieXRlIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mCiAgICAvLyBgbmVlZGxlYCBpbiBgc2VsZmAsIG9yIHRoZSBmaXJzdCBieXRlIGFmdGVyIGBzZWxmYCBpZiBub3QgZm91bmQuCiAgICBmdW5jdGlvbiBmaW5kUHRyKHVpbnQgc2VsZmxlbiwgdWludCBzZWxmcHRyLCB1aW50IG5lZWRsZWxlbiwgdWludCBuZWVkbGVwdHIpIHByaXZhdGUgcHVyZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgdWludCBwdHIgPSBzZWxmcHRyOwogICAgICAgIHVpbnQgaWR4OwoKICAgICAgICBpZiAobmVlZGxlbGVuIDw9IHNlbGZsZW4pIHsKICAgICAgICAgICAgaWYgKG5lZWRsZWxlbiA8PSAzMikgewogICAgICAgICAgICAgICAgYnl0ZXMzMiBtYXNrID0gYnl0ZXMzMih+KDIgKiogKDggKiAoMzIgLSBuZWVkbGVsZW4pKSAtIDEpKTsKCiAgICAgICAgICAgICAgICBieXRlczMyIG5lZWRsZWRhdGE7CiAgICAgICAgICAgICAgICBhc3NlbWJseSB7IG5lZWRsZWRhdGEgOj0gYW5kKG1sb2FkKG5lZWRsZXB0ciksIG1hc2spIH0KCiAgICAgICAgICAgICAgICB1aW50IGVuZCA9IHNlbGZwdHIgKyBzZWxmbGVuIC0gbmVlZGxlbGVuOwogICAgICAgICAgICAgICAgYnl0ZXMzMiBwdHJkYXRhOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBwdHJkYXRhIDo9IGFuZChtbG9hZChwdHIpLCBtYXNrKSB9CgogICAgICAgICAgICAgICAgd2hpbGUgKHB0cmRhdGEgIT0gbmVlZGxlZGF0YSkgewogICAgICAgICAgICAgICAgICAgIGlmIChwdHIgPj0gZW5kKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZnB0ciArIHNlbGZsZW47CiAgICAgICAgICAgICAgICAgICAgcHRyKys7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBwdHJkYXRhIDo9IGFuZChtbG9hZChwdHIpLCBtYXNrKSB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcHRyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gRm9yIGxvbmcgbmVlZGxlcywgdXNlIGhhc2hpbmcKICAgICAgICAgICAgICAgIGJ5dGVzMzIgaGFzaDsKICAgICAgICAgICAgICAgIGFzc2VtYmx5IHsgaGFzaCA6PSBrZWNjYWsyNTYobmVlZGxlcHRyLCBuZWVkbGVsZW4pIH0KCiAgICAgICAgICAgICAgICBmb3IgKGlkeCA9IDA7IGlkeCA8PSBzZWxmbGVuIC0gbmVlZGxlbGVuOyBpZHgrKykgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBrZWNjYWsyNTYocHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaGFzaCA9PSB0ZXN0SGFzaCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHB0cjsKICAgICAgICAgICAgICAgICAgICBwdHIgKz0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZnB0ciArIHNlbGZsZW47CiAgICB9CgogICAgLy8gUmV0dXJucyB0aGUgbWVtb3J5IGFkZHJlc3Mgb2YgdGhlIGZpcnN0IGJ5dGUgYWZ0ZXIgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZgogICAgLy8gYG5lZWRsZWAgaW4gYHNlbGZgLCBvciB0aGUgYWRkcmVzcyBvZiBgc2VsZmAgaWYgbm90IGZvdW5kLgogICAgZnVuY3Rpb24gcmZpbmRQdHIodWludCBzZWxmbGVuLCB1aW50IHNlbGZwdHIsIHVpbnQgbmVlZGxlbGVuLCB1aW50IG5lZWRsZXB0cikgcHJpdmF0ZSBwdXJlIHJldHVybnMgKHVpbnQpIHsKICAgICAgICB1aW50IHB0cjsKCiAgICAgICAgaWYgKG5lZWRsZWxlbiA8PSBzZWxmbGVuKSB7CiAgICAgICAgICAgIGlmIChuZWVkbGVsZW4gPD0gMzIpIHsKICAgICAgICAgICAgICAgIGJ5dGVzMzIgbWFzayA9IGJ5dGVzMzIofigyICoqICg4ICogKDMyIC0gbmVlZGxlbGVuKSkgLSAxKSk7CgogICAgICAgICAgICAgICAgYnl0ZXMzMiBuZWVkbGVkYXRhOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBuZWVkbGVkYXRhIDo9IGFuZChtbG9hZChuZWVkbGVwdHIpLCBtYXNrKSB9CgogICAgICAgICAgICAgICAgcHRyID0gc2VsZnB0ciArIHNlbGZsZW4gLSBuZWVkbGVsZW47CiAgICAgICAgICAgICAgICBieXRlczMyIHB0cmRhdGE7CiAgICAgICAgICAgICAgICBhc3NlbWJseSB7IHB0cmRhdGEgOj0gYW5kKG1sb2FkKHB0ciksIG1hc2spIH0KCiAgICAgICAgICAgICAgICB3aGlsZSAocHRyZGF0YSAhPSBuZWVkbGVkYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHB0ciA8PSBzZWxmcHRyKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZnB0cjsKICAgICAgICAgICAgICAgICAgICBwdHItLTsKICAgICAgICAgICAgICAgICAgICBhc3NlbWJseSB7IHB0cmRhdGEgOj0gYW5kKG1sb2FkKHB0ciksIG1hc2spIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBwdHIgKyBuZWVkbGVsZW47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBGb3IgbG9uZyBuZWVkbGVzLCB1c2UgaGFzaGluZwogICAgICAgICAgICAgICAgYnl0ZXMzMiBoYXNoOwogICAgICAgICAgICAgICAgYXNzZW1ibHkgeyBoYXNoIDo9IGtlY2NhazI1NihuZWVkbGVwdHIsIG5lZWRsZWxlbikgfQogICAgICAgICAgICAgICAgcHRyID0gc2VsZnB0ciArIChzZWxmbGVuIC0gbmVlZGxlbGVuKTsKICAgICAgICAgICAgICAgIHdoaWxlIChwdHIgPj0gc2VsZnB0cikgewogICAgICAgICAgICAgICAgICAgIGJ5dGVzMzIgdGVzdEhhc2g7CiAgICAgICAgICAgICAgICAgICAgYXNzZW1ibHkgeyB0ZXN0SGFzaCA6PSBrZWNjYWsyNTYocHRyLCBuZWVkbGVsZW4pIH0KICAgICAgICAgICAgICAgICAgICBpZiAoaGFzaCA9PSB0ZXN0SGFzaCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHB0ciArIG5lZWRsZWxlbjsKICAgICAgICAgICAgICAgICAgICBwdHIgLT0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZnB0cjsKICAgIH0KCiAgICAvKgogICAgICogQGRldiBNb2RpZmllcyBgc2VsZmAgdG8gY29udGFpbiBldmVyeXRoaW5nIGZyb20gdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YKICAgICAqICAgICAgYG5lZWRsZWAgdG8gdGhlIGVuZCBvZiB0aGUgc2xpY2UuIGBzZWxmYCBpcyBzZXQgdG8gdGhlIGVtcHR5IHNsaWNlCiAgICAgKiAgICAgIGlmIGBuZWVkbGVgIGlzIG5vdCBmb3VuZC4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBzbGljZSB0byBzZWFyY2ggYW5kIG1vZGlmeS4KICAgICAqIEBwYXJhbSBuZWVkbGUgVGhlIHRleHQgdG8gc2VhcmNoIGZvci4KICAgICAqIEByZXR1cm4gYHNlbGZgLgogICAgICovCiAgICBmdW5jdGlvbiBmaW5kKHNsaWNlIG1lbW9yeSBzZWxmLCBzbGljZSBtZW1vcnkgbmVlZGxlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHNsaWNlIG1lbW9yeSkgewogICAgICAgIHVpbnQgcHRyID0gZmluZFB0cihzZWxmLl9sZW4sIHNlbGYuX3B0ciwgbmVlZGxlLl9sZW4sIG5lZWRsZS5fcHRyKTsKICAgICAgICBzZWxmLl9sZW4gLT0gcHRyIC0gc2VsZi5fcHRyOwogICAgICAgIHNlbGYuX3B0ciA9IHB0cjsKICAgICAgICByZXR1cm4gc2VsZjsKICAgIH0KCiAgICAvKgogICAgICogQGRldiBNb2RpZmllcyBgc2VsZmAgdG8gY29udGFpbiB0aGUgcGFydCBvZiB0aGUgc3RyaW5nIGZyb20gdGhlIHN0YXJ0IG9mCiAgICAgKiAgICAgIGBzZWxmYCB0byB0aGUgZW5kIG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGBuZWVkbGVgLiBJZiBgbmVlZGxlYAogICAgICogICAgICBpcyBub3QgZm91bmQsIGBzZWxmYCBpcyBzZXQgdG8gdGhlIGVtcHR5IHNsaWNlLgogICAgICogQHBhcmFtIHNlbGYgVGhlIHNsaWNlIHRvIHNlYXJjaCBhbmQgbW9kaWZ5LgogICAgICogQHBhcmFtIG5lZWRsZSBUaGUgdGV4dCB0byBzZWFyY2ggZm9yLgogICAgICogQHJldHVybiBgc2VsZmAuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHJmaW5kKHNsaWNlIG1lbW9yeSBzZWxmLCBzbGljZSBtZW1vcnkgbmVlZGxlKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHNsaWNlIG1lbW9yeSkgewogICAgICAgIHVpbnQgcHRyID0gcmZpbmRQdHIoc2VsZi5fbGVuLCBzZWxmLl9wdHIsIG5lZWRsZS5fbGVuLCBuZWVkbGUuX3B0cik7CiAgICAgICAgc2VsZi5fbGVuID0gcHRyIC0gc2VsZi5fcHRyOwogICAgICAgIHJldHVybiBzZWxmOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFNwbGl0cyB0aGUgc2xpY2UsIHNldHRpbmcgYHNlbGZgIHRvIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0CiAgICAgKiAgICAgIG9jY3VycmVuY2Ugb2YgYG5lZWRsZWAsIGFuZCBgdG9rZW5gIHRvIGV2ZXJ5dGhpbmcgYmVmb3JlIGl0LiBJZgogICAgICogICAgICBgbmVlZGxlYCBkb2VzIG5vdCBvY2N1ciBpbiBgc2VsZmAsIGBzZWxmYCBpcyBzZXQgdG8gdGhlIGVtcHR5IHNsaWNlLAogICAgICogICAgICBhbmQgYHRva2VuYCBpcyBzZXQgdG8gdGhlIGVudGlyZXR5IG9mIGBzZWxmYC4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBzbGljZSB0byBzcGxpdC4KICAgICAqIEBwYXJhbSBuZWVkbGUgVGhlIHRleHQgdG8gc2VhcmNoIGZvciBpbiBgc2VsZmAuCiAgICAgKiBAcGFyYW0gdG9rZW4gQW4gb3V0cHV0IHBhcmFtZXRlciB0byB3aGljaCB0aGUgZmlyc3QgdG9rZW4gaXMgd3JpdHRlbi4KICAgICAqIEByZXR1cm4gYHRva2VuYC4KICAgICAqLwogICAgZnVuY3Rpb24gc3BsaXQoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBuZWVkbGUsIHNsaWNlIG1lbW9yeSB0b2tlbikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChzbGljZSBtZW1vcnkpIHsKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoc2VsZi5fbGVuLCBzZWxmLl9wdHIsIG5lZWRsZS5fbGVuLCBuZWVkbGUuX3B0cik7CiAgICAgICAgdG9rZW4uX3B0ciA9IHNlbGYuX3B0cjsKICAgICAgICB0b2tlbi5fbGVuID0gcHRyIC0gc2VsZi5fcHRyOwogICAgICAgIGlmIChwdHIgPT0gc2VsZi5fcHRyICsgc2VsZi5fbGVuKSB7CiAgICAgICAgICAgIC8vIE5vdCBmb3VuZAogICAgICAgICAgICBzZWxmLl9sZW4gPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNlbGYuX2xlbiAtPSB0b2tlbi5fbGVuICsgbmVlZGxlLl9sZW47CiAgICAgICAgICAgIHNlbGYuX3B0ciA9IHB0ciArIG5lZWRsZS5fbGVuOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdG9rZW47CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgU3BsaXRzIHRoZSBzbGljZSwgc2V0dGluZyBgc2VsZmAgdG8gZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QKICAgICAqICAgICAgb2NjdXJyZW5jZSBvZiBgbmVlZGxlYCwgYW5kIHJldHVybmluZyBldmVyeXRoaW5nIGJlZm9yZSBpdC4gSWYKICAgICAqICAgICAgYG5lZWRsZWAgZG9lcyBub3Qgb2NjdXIgaW4gYHNlbGZgLCBgc2VsZmAgaXMgc2V0IHRvIHRoZSBlbXB0eSBzbGljZSwKICAgICAqICAgICAgYW5kIHRoZSBlbnRpcmV0eSBvZiBgc2VsZmAgaXMgcmV0dXJuZWQuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gc3BsaXQuCiAgICAgKiBAcGFyYW0gbmVlZGxlIFRoZSB0ZXh0IHRvIHNlYXJjaCBmb3IgaW4gYHNlbGZgLgogICAgICogQHJldHVybiBUaGUgcGFydCBvZiBgc2VsZmAgdXAgdG8gdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYGRlbGltYC4KICAgICAqLwogICAgZnVuY3Rpb24gc3BsaXQoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBuZWVkbGUpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc2xpY2UgbWVtb3J5IHRva2VuKSB7CiAgICAgICAgc3BsaXQoc2VsZiwgbmVlZGxlLCB0b2tlbik7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgU3BsaXRzIHRoZSBzbGljZSwgc2V0dGluZyBgc2VsZmAgdG8gZXZlcnl0aGluZyBiZWZvcmUgdGhlIGxhc3QKICAgICAqICAgICAgb2NjdXJyZW5jZSBvZiBgbmVlZGxlYCwgYW5kIGB0b2tlbmAgdG8gZXZlcnl0aGluZyBhZnRlciBpdC4gSWYKICAgICAqICAgICAgYG5lZWRsZWAgZG9lcyBub3Qgb2NjdXIgaW4gYHNlbGZgLCBgc2VsZmAgaXMgc2V0IHRvIHRoZSBlbXB0eSBzbGljZSwKICAgICAqICAgICAgYW5kIGB0b2tlbmAgaXMgc2V0IHRvIHRoZSBlbnRpcmV0eSBvZiBgc2VsZmAuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gc3BsaXQuCiAgICAgKiBAcGFyYW0gbmVlZGxlIFRoZSB0ZXh0IHRvIHNlYXJjaCBmb3IgaW4gYHNlbGZgLgogICAgICogQHBhcmFtIHRva2VuIEFuIG91dHB1dCBwYXJhbWV0ZXIgdG8gd2hpY2ggdGhlIGZpcnN0IHRva2VuIGlzIHdyaXR0ZW4uCiAgICAgKiBAcmV0dXJuIGB0b2tlbmAuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHJzcGxpdChzbGljZSBtZW1vcnkgc2VsZiwgc2xpY2UgbWVtb3J5IG5lZWRsZSwgc2xpY2UgbWVtb3J5IHRva2VuKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKHNsaWNlIG1lbW9yeSkgewogICAgICAgIHVpbnQgcHRyID0gcmZpbmRQdHIoc2VsZi5fbGVuLCBzZWxmLl9wdHIsIG5lZWRsZS5fbGVuLCBuZWVkbGUuX3B0cik7CiAgICAgICAgdG9rZW4uX3B0ciA9IHB0cjsKICAgICAgICB0b2tlbi5fbGVuID0gc2VsZi5fbGVuIC0gKHB0ciAtIHNlbGYuX3B0cik7CiAgICAgICAgaWYgKHB0ciA9PSBzZWxmLl9wdHIpIHsKICAgICAgICAgICAgLy8gTm90IGZvdW5kCiAgICAgICAgICAgIHNlbGYuX2xlbiA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsZi5fbGVuIC09IHRva2VuLl9sZW4gKyBuZWVkbGUuX2xlbjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRva2VuOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFNwbGl0cyB0aGUgc2xpY2UsIHNldHRpbmcgYHNlbGZgIHRvIGV2ZXJ5dGhpbmcgYmVmb3JlIHRoZSBsYXN0CiAgICAgKiAgICAgIG9jY3VycmVuY2Ugb2YgYG5lZWRsZWAsIGFuZCByZXR1cm5pbmcgZXZlcnl0aGluZyBhZnRlciBpdC4gSWYKICAgICAqICAgICAgYG5lZWRsZWAgZG9lcyBub3Qgb2NjdXIgaW4gYHNlbGZgLCBgc2VsZmAgaXMgc2V0IHRvIHRoZSBlbXB0eSBzbGljZSwKICAgICAqICAgICAgYW5kIHRoZSBlbnRpcmV0eSBvZiBgc2VsZmAgaXMgcmV0dXJuZWQuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gc3BsaXQuCiAgICAgKiBAcGFyYW0gbmVlZGxlIFRoZSB0ZXh0IHRvIHNlYXJjaCBmb3IgaW4gYHNlbGZgLgogICAgICogQHJldHVybiBUaGUgcGFydCBvZiBgc2VsZmAgYWZ0ZXIgdGhlIGxhc3Qgb2NjdXJyZW5jZSBvZiBgZGVsaW1gLgogICAgICovCiAgICBmdW5jdGlvbiByc3BsaXQoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBuZWVkbGUpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc2xpY2UgbWVtb3J5IHRva2VuKSB7CiAgICAgICAgcnNwbGl0KHNlbGYsIG5lZWRsZSwgdG9rZW4pOwogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IENvdW50cyB0aGUgbnVtYmVyIG9mIG5vbm92ZXJsYXBwaW5nIG9jY3VycmVuY2VzIG9mIGBuZWVkbGVgIGluIGBzZWxmYC4KICAgICAqIEBwYXJhbSBzZWxmIFRoZSBzbGljZSB0byBzZWFyY2guCiAgICAgKiBAcGFyYW0gbmVlZGxlIFRoZSB0ZXh0IHRvIHNlYXJjaCBmb3IgaW4gYHNlbGZgLgogICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIG9mIGBuZWVkbGVgIGZvdW5kIGluIGBzZWxmYC4KICAgICAqLwogICAgZnVuY3Rpb24gY291bnQoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBuZWVkbGUpIGludGVybmFsIHB1cmUgcmV0dXJucyAodWludCBjbnQpIHsKICAgICAgICB1aW50IHB0ciA9IGZpbmRQdHIoc2VsZi5fbGVuLCBzZWxmLl9wdHIsIG5lZWRsZS5fbGVuLCBuZWVkbGUuX3B0cikgKyBuZWVkbGUuX2xlbjsKICAgICAgICB3aGlsZSAocHRyIDw9IHNlbGYuX3B0ciArIHNlbGYuX2xlbikgewogICAgICAgICAgICBjbnQrKzsKICAgICAgICAgICAgcHRyID0gZmluZFB0cihzZWxmLl9sZW4gLSAocHRyIC0gc2VsZi5fcHRyKSwgcHRyLCBuZWVkbGUuX2xlbiwgbmVlZGxlLl9wdHIpICsgbmVlZGxlLl9sZW47CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBAZGV2IFJldHVybnMgVHJ1ZSBpZiBgc2VsZmAgY29udGFpbnMgYG5lZWRsZWAuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgc2xpY2UgdG8gc2VhcmNoLgogICAgICogQHBhcmFtIG5lZWRsZSBUaGUgdGV4dCB0byBzZWFyY2ggZm9yIGluIGBzZWxmYC4KICAgICAqIEByZXR1cm4gVHJ1ZSBpZiBgbmVlZGxlYCBpcyBmb3VuZCBpbiBgc2VsZmAsIGZhbHNlIG90aGVyd2lzZS4KICAgICAqLwogICAgZnVuY3Rpb24gY29udGFpbnMoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBuZWVkbGUpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiByZmluZFB0cihzZWxmLl9sZW4sIHNlbGYuX3B0ciwgbmVlZGxlLl9sZW4sIG5lZWRsZS5fcHRyKSAhPSBzZWxmLl9wdHI7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgUmV0dXJucyBhIG5ld2x5IGFsbG9jYXRlZCBzdHJpbmcgY29udGFpbmluZyB0aGUgY29uY2F0ZW5hdGlvbiBvZgogICAgICogICAgICBgc2VsZmAgYW5kIGBvdGhlcmAuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgZmlyc3Qgc2xpY2UgdG8gY29uY2F0ZW5hdGUuCiAgICAgKiBAcGFyYW0gb3RoZXIgVGhlIHNlY29uZCBzbGljZSB0byBjb25jYXRlbmF0ZS4KICAgICAqIEByZXR1cm4gVGhlIGNvbmNhdGVuYXRpb24gb2YgdGhlIHR3byBzdHJpbmdzLgogICAgICovCiAgICBmdW5jdGlvbiBjb25jYXQoc2xpY2UgbWVtb3J5IHNlbGYsIHNsaWNlIG1lbW9yeSBvdGhlcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgc3RyaW5nIG1lbW9yeSByZXQgPSBuZXcgc3RyaW5nKHNlbGYuX2xlbiArIG90aGVyLl9sZW4pOwogICAgICAgIHVpbnQgcmV0cHRyOwogICAgICAgIGFzc2VtYmx5IHsgcmV0cHRyIDo9IGFkZChyZXQsIDMyKSB9CiAgICAgICAgbWVtY3B5KHJldHB0ciwgc2VsZi5fcHRyLCBzZWxmLl9sZW4pOwogICAgICAgIG1lbWNweShyZXRwdHIgKyBzZWxmLl9sZW4sIG90aGVyLl9wdHIsIG90aGVyLl9sZW4pOwogICAgICAgIHJldHVybiByZXQ7CiAgICB9CgogICAgLyoKICAgICAqIEBkZXYgSm9pbnMgYW4gYXJyYXkgb2Ygc2xpY2VzLCB1c2luZyBgc2VsZmAgYXMgYSBkZWxpbWl0ZXIsIHJldHVybmluZyBhCiAgICAgKiAgICAgIG5ld2x5IGFsbG9jYXRlZCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc2VsZiBUaGUgZGVsaW1pdGVyIHRvIHVzZS4KICAgICAqIEBwYXJhbSBwYXJ0cyBBIGxpc3Qgb2Ygc2xpY2VzIHRvIGpvaW4uCiAgICAgKiBAcmV0dXJuIEEgbmV3bHkgYWxsb2NhdGVkIHN0cmluZyBjb250YWluaW5nIGFsbCB0aGUgc2xpY2VzIGluIGBwYXJ0c2AsCiAgICAgKiAgICAgICAgIGpvaW5lZCB3aXRoIGBzZWxmYC4KICAgICAqLwogICAgZnVuY3Rpb24gam9pbihzbGljZSBtZW1vcnkgc2VsZiwgc2xpY2VbXSBtZW1vcnkgcGFydHMpIGludGVybmFsIHB1cmUgcmV0dXJucyAoc3RyaW5nIG1lbW9yeSkgewogICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPT0gMCkKICAgICAgICAgICAgcmV0dXJuICIiOwoKICAgICAgICB1aW50IGxlbmd0aCA9IHNlbGYuX2xlbiAqIChwYXJ0cy5sZW5ndGggLSAxKTsKICAgICAgICBmb3IodWludCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKQogICAgICAgICAgICBsZW5ndGggKz0gcGFydHNbaV0uX2xlbjsKCiAgICAgICAgc3RyaW5nIG1lbW9yeSByZXQgPSBuZXcgc3RyaW5nKGxlbmd0aCk7CiAgICAgICAgdWludCByZXRwdHI7CiAgICAgICAgYXNzZW1ibHkgeyByZXRwdHIgOj0gYWRkKHJldCwgMzIpIH0KCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgbWVtY3B5KHJldHB0ciwgcGFydHNbaV0uX3B0ciwgcGFydHNbaV0uX2xlbik7CiAgICAgICAgICAgIHJldHB0ciArPSBwYXJ0c1tpXS5fbGVuOwogICAgICAgICAgICBpZiAoaSA8IHBhcnRzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgICAgIG1lbWNweShyZXRwdHIsIHNlbGYuX3B0ciwgc2VsZi5fbGVuKTsKICAgICAgICAgICAgICAgIHJldHB0ciArPSBzZWxmLl9sZW47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiByZXQ7CiAgICB9Cn0K", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 42, + "contractFolderId" : 8, + "contractName" : "Table", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7DQoNCmNvbnRyYWN0IFRhYmxlRmFjdG9yeSB7DQogICAgZnVuY3Rpb24gb3BlblRhYmxlKHN0cmluZykgcHVibGljIGNvbnN0YW50IHJldHVybnMgKFRhYmxlKTsgIC8vIOaJk+W8gOihqA0KICAgIGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKHN0cmluZyxzdHJpbmcsc3RyaW5nKSBwdWJsaWMgcmV0dXJucyhpbnQpOyAgLy8g5Yib5bu66KGoDQp9DQoNCi8vIOafpeivouadoeS7tg0KY29udHJhY3QgQ29uZGl0aW9uIHsNCiAgICAvL+etieS6jg0KICAgIGZ1bmN0aW9uIEVRKHN0cmluZywgaW50KSBwdWJsaWM7DQogICAgZnVuY3Rpb24gRVEoc3RyaW5nLCBzdHJpbmcpIHB1YmxpYzsNCg0KICAgIC8v5LiN562J5LqODQogICAgZnVuY3Rpb24gTkUoc3RyaW5nLCBpbnQpIHB1YmxpYzsNCiAgICBmdW5jdGlvbiBORShzdHJpbmcsIHN0cmluZykgIHB1YmxpYzsNCg0KICAgIC8v5aSn5LqODQogICAgZnVuY3Rpb24gR1Qoc3RyaW5nLCBpbnQpIHB1YmxpYzsNCiAgICAvL+Wkp+S6juaIluetieS6jg0KICAgIGZ1bmN0aW9uIEdFKHN0cmluZywgaW50KSBwdWJsaWM7DQoNCiAgICAvL+Wwj+S6jg0KICAgIGZ1bmN0aW9uIExUKHN0cmluZywgaW50KSBwdWJsaWM7DQogICAgLy/lsI/kuo7miJbnrYnkuo4NCiAgICBmdW5jdGlvbiBMRShzdHJpbmcsIGludCkgcHVibGljOw0KDQogICAgLy/pmZDliLbov5Tlm57orrDlvZXmnaHmlbANCiAgICBmdW5jdGlvbiBsaW1pdChpbnQpIHB1YmxpYzsNCiAgICBmdW5jdGlvbiBsaW1pdChpbnQsIGludCkgcHVibGljOw0KfQ0KDQovLyDljZXmnaHmlbDmja7orrDlvZUNCmNvbnRyYWN0IEVudHJ5IHsNCiAgICBmdW5jdGlvbiBnZXRJbnQoc3RyaW5nKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhpbnQpOw0KICAgIGZ1bmN0aW9uIGdldEFkZHJlc3Moc3RyaW5nKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhhZGRyZXNzKTsNCiAgICBmdW5jdGlvbiBnZXRCeXRlczY0KHN0cmluZykgcHVibGljIGNvbnN0YW50IHJldHVybnMoYnl0ZVs2NF0pOw0KICAgIGZ1bmN0aW9uIGdldEJ5dGVzMzIoc3RyaW5nKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhieXRlczMyKTsNCiAgICBmdW5jdGlvbiBnZXRTdHJpbmcoc3RyaW5nKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhzdHJpbmcpOw0KDQogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgaW50KSBwdWJsaWM7DQogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgc3RyaW5nKSBwdWJsaWM7DQogICAgZnVuY3Rpb24gc2V0KHN0cmluZywgYWRkcmVzcykgcHVibGljOw0KfQ0KDQovLyDmlbDmja7orrDlvZXpm4YNCmNvbnRyYWN0IEVudHJpZXMgew0KICAgIGZ1bmN0aW9uIGdldChpbnQpIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKEVudHJ5KTsNCiAgICBmdW5jdGlvbiBzaXplKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoaW50KTsNCn0NCg0KLy8gVGFibGXkuLvnsbsNCmNvbnRyYWN0IFRhYmxlIHsNCiAgICAvLyDmn6Xor6LmjqXlj6MNCiAgICBmdW5jdGlvbiBzZWxlY3Qoc3RyaW5nLCBDb25kaXRpb24pIHB1YmxpYyBjb25zdGFudCByZXR1cm5zKEVudHJpZXMpOw0KICAgIC8vIOaPkuWFpeaOpeWPow0KICAgIGZ1bmN0aW9uIGluc2VydChzdHJpbmcsIEVudHJ5KSBwdWJsaWMgcmV0dXJucyhpbnQpOw0KICAgIC8vIOabtOaWsOaOpeWPow0KICAgIGZ1bmN0aW9uIHVwZGF0ZShzdHJpbmcsIEVudHJ5LCBDb25kaXRpb24pIHB1YmxpYyByZXR1cm5zKGludCk7DQogICAgLy8g5Yig6Zmk5o6l5Y+jDQogICAgZnVuY3Rpb24gcmVtb3ZlKHN0cmluZywgQ29uZGl0aW9uKSBwdWJsaWMgcmV0dXJucyhpbnQpOw0KDQogICAgZnVuY3Rpb24gbmV3RW50cnkoKSBwdWJsaWMgY29uc3RhbnQgcmV0dXJucyhFbnRyeSk7DQogICAgZnVuY3Rpb24gbmV3Q29uZGl0aW9uKCkgcHVibGljIGNvbnN0YW50IHJldHVybnMoQ29uZGl0aW9uKTsNCn0=", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + }, + { + "contractId" : 43, + "contractFolderId" : 8, + "contractName" : "Address", + "contractDesc" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n", + "contractSrc" : "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgpsaWJyYXJ5IEFkZHJlc3MgewoKICAgIGZ1bmN0aW9uIGlzQ29udHJhY3QoYWRkcmVzcyBhZGRyKSBpbnRlcm5hbCB2aWV3IHJldHVybnMoYm9vbCkgewogICAgICAgIHVpbnQyNTYgc2l6ZTsKICAgICAgICBhc3NlbWJseSB7IHNpemUgOj0gZXh0Y29kZXNpemUoYWRkcikgfSAgCiAgICAgICAgcmV0dXJuIHNpemUgPiAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzRW1wdHlBZGRyZXNzKGFkZHJlc3MgYWRkcikgaW50ZXJuYWwgcHVyZSByZXR1cm5zKGJvb2wpewogICAgICAgIHJldHVybiBhZGRyID09IGFkZHJlc3MoMCk7CiAgICB9Cn0=", + "contractDesc_en" : "# 代理合约模板\n\n\n本合约模板由深圳前海股权交易中心贡献,针对数据上链编写的通用代理存储合约。\n\n## 简介\n代理合约利用solidity的fallback功能,包含EnrollProxy(代理合约),EnrollController(业务合约),EnrollStorage(存储合约)。\n\n- 代理合约对外交互接口\n- 业务合约实现业务逻辑\n- 存储合约完成数据存储\n\nEnrollProxy合约通过Fallback机制调用EnrollController合约的函数进行数据上链(通过EnrollProxy合约地址结合使用EnrollController合约的ABI,操作EnrollController合约的函数),其带来的优点包括:\n\n- 区块链应用的业务层只与EnrollProxy合约进行交互,EnrollProxy合约不会升级,地址不会变化。\n\n- 后续中业务或存储需求导致业务合约或存储合约需要升级,则升级EnrollController和EnrollStorage合约,达到数据、业务逻辑解耦的效果。\n\n*期待你一起完善合约模板中的权限控制逻辑*\n\n## 合约架构说明\n\n```java\nEnrollProxy\n\t继承EnrollStorageStateful\n\t继承Proxy(继承Ownable) \n \nEnrollController\n\t继承EnrollStorageStateful\n\t继承Ownable\n\nEnrollStorageStateful\n\t包含成员enrollStorage,EnrollStorage合约实例\n\n由于是继承的关系,EnrollProxy合约和EnrollController合约的存储空间排列是一样的,所以可通过EnrollProxy执行fallback操作。 \n\nenrollStorage是EnrollStorageStateful合约中的成员,所以enrollStorage合约与EnrollStorageStateful合约存储空间排布是不一样。\n```\n\n## 使用说明\n1. 编译部署EnrollProxy,EnrollController,EnrollStorage合约。\n2. 配置代理合约:\n 1. 存储合约合约:调用EnrollProxy合约setStorage函数,参数为EnrollStorage合约地址。\n 2. 配置业务合约:调用EnrollProxy合约upgradeTo函数,参数为:合约版本号,EnrollController合约地址。\n3. 设置存储合约的代理地址:调用EnrollStorage合约setProxy函数,参数为EnrollProxy合约地址。\n \n\n完成以上步骤后,就可以通过EnrollProxy合约地址,结合业务合约EnrollController合约的ABI,操作EnrollController合约的业务函数。\n\n\n" + } +] \ No newline at end of file diff --git a/src/main/resources/warehouse/folder.json b/src/main/resources/warehouse/folder.json new file mode 100644 index 0000000000000000000000000000000000000000..8bf336a77d442419968db0f2894e694c7be05dd4 --- /dev/null +++ b/src/main/resources/warehouse/folder.json @@ -0,0 +1,74 @@ +[ + { + "contractFolderId" : 1, + "storeId" : 1, + "contractFolderName" : "Tools", + "contractFolderDesc" : "工具箱中有常用的工具合约", + "contractFolderDetail" : "工具箱中有常用的工具合约", + "contractFolderDesc_en" : "Toolbox Contract Suite", + "contractFolderDetail_en" : "Toolbox Contract Suite" + }, + { + "contractFolderId" : 2, + "storeId" : 2, + "contractFolderName" : "Evidence", + "contractFolderDesc" : "一套区块链存证合约,实现区块链存证、取证", + "contractFolderDetail" : "一套区块链存证合约,实现区块链存证、取证", + "contractFolderDesc_en" : "Evidence Contract Suite", + "contractFolderDetail_en" : "Evidence Contract Suite" + }, + { + "contractFolderId" : 3, + "storeId" : 3, + "contractFolderName" : "Points", + "contractFolderDesc" : "一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能", + "contractFolderDetail" : "一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能", + "contractFolderDesc_en" : "Points Contract Suite", + "contractFolderDetail_en" : "Points Contract Suite" + }, + { + "contractFolderId" : 4, + "storeId" : 1, + "contractFolderName" : "Smart_Dev_Basic", + "contractFolderDesc" : "SmartDev基础合约,包含Table/KVTable/Sha/Crypto/HelloWorld等", + "contractFolderDetail" : "SmartDev基础合约,包含Table/KVTable/Sha/Crypto/HelloWorld等", + "contractFolderDesc_en" : "Smart-Dev-Contract basic contract suite, including Table/KVTable/Sha/Crypto/HelloWorld etc.", + "contractFolderDetail_en" : "Smart-Dev-Contract basic contract suite, including Table/KVTable/Sha/Crypto/HelloWorld etc." + }, + { + "contractFolderId" : 5, + "storeId" : 4, + "contractFolderName" : "Smart_Dev_Evidence", + "contractFolderDesc" : "SmartDev存证合约案例", + "contractFolderDetail" : "SmartDev存证合约案例", + "contractFolderDesc_en" : "Smart-Dev-Contract Evidence contract suite", + "contractFolderDetail_en" : "Smart-Dev-Contract Evidence contract suite" + }, + { + "contractFolderId" : 6, + "storeId" : 6, + "contractFolderName" : "Asset", + "contractFolderDesc" : "一套非同质化资产合约,具有于唯一性资产类型,如房产、汽车、道具、版权等,具有增发、销毁,暂停合约,黑白名单等权限控制等功能", + "contractFolderDetail" : "一套非同质化资产合约,具有于唯一性资产类型,如房产、汽车、道具、版权等,具有增发、销毁,暂停合约,黑白名单等权限控制等功能", + "contractFolderDesc_en" : "Asset Contract Suite", + "contractFolderDetail_en" : "Asset Contract Suite" + }, + { + "contractFolderId" : 7, + "storeId" : 7, + "contractFolderName" : "Traceability", + "contractFolderDesc" : "一套溯源应用合约模板(Smart-Dev-Contract)", + "contractFolderDetail" : "一套溯源应用合约模板(Smart-Dev-Contract)", + "contractFolderDesc_en" : "Traceability Contract Suite", + "contractFolderDetail_en" : "Traceability Contract Suite" + }, + { + "contractFolderId" : 8, + "storeId" : 8, + "contractFolderName" : "Proxy", + "contractFolderDesc" : "一套可升级的业务、数据分离的代理合约模板", + "contractFolderDetail" : "一套可升级的业务、数据分离的代理合约模板", + "contractFolderDesc_en" : "Proxy Contract Suite", + "contractFolderDetail_en" : "Proxy Contract Suite" + } +] \ No newline at end of file diff --git a/src/main/resources/warehouse/warehouse.json b/src/main/resources/warehouse/warehouse.json new file mode 100644 index 0000000000000000000000000000000000000000..4ac8445670b361081a949ec3809a5e6bf58a84c2 --- /dev/null +++ b/src/main/resources/warehouse/warehouse.json @@ -0,0 +1,74 @@ +[ + { + "storeId" : 1, + "storeName" : "工具箱", + "storeName_en" : "Toolbox", + "storeType" : "1", + "storeIcon" : "toolboxId", + "storeDesc" : "工具箱中有常用的工具合约", + "storeDetail" : "工具箱中有常用的工具合约", + "storeDesc_en" : "Toolbox Contract suite", + "storeDetail_en" : "Toolbox Contract suite" + }, { + "storeId" : 2, + "storeName" : "存证应用", + "storeName_en" : "Evidence", + "storeType" : "2", + "storeIcon" : "evidenceId", + "storeDesc" : "一套区块链存证合约,实现区块链存证、取证", + "storeDetail" : "一套区块链存证合约,实现区块链存证、取证", + "storeDesc_en" : "Evidence Contract suite", + "storeDetail_en" : "Evidence Contract suite" + }, { + "storeId" : 3, + "storeName" : "积分应用", + "storeName_en" : "Points", + "storeType" : "3", + "storeIcon" : "pointsId", + "storeDesc" : "一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能", + "storeDetail" : "一套积分合约,具有积分相关的增发,销毁,暂停合约,黑白名单等权限控制等功能", + "storeDesc_en" : "Points Contract suite", + "storeDetail_en" : "Points Contract suite" + }, { + "storeId" : 4, + "storeName" : "SmartDev存证应用", + "storeName_en" : "Smart_Dev_Evidence", + "storeType" : "4", + "storeIcon" : "evidenceId", + "storeDesc" : "Smart-Dev-Contract仓库中的存证应用模板", + "storeDetail" : "Smart-Dev-Contract's Evidence Contract suite of business_template", + "storeDesc_en" : "Smart-Dev-Contracts仓库中的存证应用模板", + "storeDetail_en" : "Smart-Dev-Contract's Evidence Contract suite of business_template" + + }, { + "storeId" : 6, + "storeName" : "资产应用", + "storeName_en" : "Asset", + "storeType" : "4", + "storeIcon" : "pointsId", + "storeDesc" : "一套非同质化资产合约,具有于唯一性资产类型,如房产、汽车、道具、版权等", + "storeDetail" : "Asset Contract Suite", + "storeDesc_en" : "一套非同质化资产合约,具有于唯一性资产类型,如房产、汽车、道具、版权等", + "storeDetail_en" : "Asset Contract Suite" + }, { + "storeId" : 7, + "storeName" : "溯源应用", + "storeName_en" : "Traceability", + "storeType" : "4", + "storeIcon" : "traceId", + "storeDesc" : "一套溯源应用合约模板(Smart-Dev-Contract)", + "storeDetail" : "Traceability Contract Suite", + "storeDesc_en" : "一套溯源应用合约模板(Smart-Dev-Contract)", + "storeDetail_en" : "Traceability Contract Suite" + }, { + "storeId" : 8, + "storeName" : "代理合约模板", + "storeName_en" : "Proxy", + "storeType" : "4", + "storeIcon" : "toolboxId", + "storeDesc" : "一套可升级的业务、数据分离的代理合约模板", + "storeDetail" : "Proxy Contract Suite", + "storeDesc_en" : "一套可升级的业务、数据分离的代理合约模板", + "storeDetail_en" : "Proxy Contract Suite" + } +] diff --git a/src/test/java/com/webank/webase/front/contract/ContractControllerTest.java b/src/test/java/com/webank/webase/front/contract/ContractControllerTest.java index 0cf4d8df290bb3b479ae375fd27ffbee771566dc..b66148787f0e1d7e9575b3720c90869cc86e8a93 100644 --- a/src/test/java/com/webank/webase/front/contract/ContractControllerTest.java +++ b/src/test/java/com/webank/webase/front/contract/ContractControllerTest.java @@ -95,7 +95,7 @@ public class ContractControllerTest extends SpringTestBase { @Test public void testDeploy() throws Exception { String abiInfo = "[{\"constant\":false,\"inputs\":[{\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"trans\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"type\":\"constructor\"}]"; - List list = JsonUtils.toJavaObjectList(abiInfo, ABIDefinition.class); + List list = JsonUtils.toJavaObjectList(abiInfo, Object.class); //param ReqDeploy deployInputParam = new ReqDeploy(); deployInputParam.setGroupId(groupId); diff --git a/src/test/java/com/webank/webase/front/contract/TransControllerTest.java b/src/test/java/com/webank/webase/front/contract/TransControllerTest.java index 7e06d94e4703f11f5d959743c046a725f3aeefdd..0d9a6abb745af59b292100ff1c9c75314a33f13d 100644 --- a/src/test/java/com/webank/webase/front/contract/TransControllerTest.java +++ b/src/test/java/com/webank/webase/front/contract/TransControllerTest.java @@ -74,7 +74,7 @@ public class TransControllerTest extends SpringTestBase { testNew.setEncodeStr("0x6d4ce63c"); testNew.setFuncName("get"); testNew.setContractAddress("0x5256755ee37aa003a4ed57b06e7a1008935b09a2"); - testNew.setContractAbi(JsonUtils.toJavaObjectList(abi, Object.class)); + testNew.setContractAbi(abi); ResultActions resultActions = mockMvc .perform(MockMvcRequestBuilders.post("/trans/query-transaction"). content(JsonUtils.toJSONString(testNew)). diff --git a/src/test/java/com/webank/webase/front/contractStore/ContractStoreServiceTest.java b/src/test/java/com/webank/webase/front/contractStore/ContractStoreServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..eee367a114d8e1abea0bec6c6d769c315f4dc48d --- /dev/null +++ b/src/test/java/com/webank/webase/front/contractStore/ContractStoreServiceTest.java @@ -0,0 +1,84 @@ +/** + * Copyright 2014-2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.webank.webase.front.contractStore; + +import com.webank.webase.front.base.SpringTestBase; +import com.webank.webase.front.base.exception.FrontException; +import com.webank.webase.front.contractStore.entity.ContractFolderItem; +import com.webank.webase.front.contractStore.entity.ContractItem; +import com.webank.webase.front.contractStore.entity.StoreItem; +import com.webank.webase.front.util.JsonUtils; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.List; +import org.apache.commons.io.IOUtils; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; + +public class ContractStoreServiceTest extends SpringTestBase { + + @Autowired + ContractStoreService contractStoreService; + @Autowired + ContractItemRepository contractItemRepository; + + @Test + public void testStoreList() { + List storeItems = contractStoreService.getStoreList(); + for (StoreItem storeItem : storeItems) { + storeItem.setCreateTime(null); + storeItem.setModifyTime(null); + System.out.println(JsonUtils.objToString(storeItem)); + } + + for (StoreItem item : storeItems) { + List folderList = contractStoreService.getFolderItemListByStoreId(item.getStoreId()); + for (ContractFolderItem folderItem : folderList) { + folderItem.setCreateTime(null); + folderItem.setModifyTime(null); + System.out.println(JsonUtils.objToString(folderItem)); + } + } + + for (StoreItem item : storeItems) { + List folderList = contractStoreService.getFolderItemListByStoreId(item.getStoreId()); + for (ContractFolderItem folderItem : folderList) { + List contractItemList = contractStoreService.getContractItemListByFolderId(folderItem.getContractFolderId()); + for (ContractItem contractItem : contractItemList) { + contractItem.setCreateTime(null); + contractItem.setModifyTime(null); + System.out.println(JsonUtils.objToString(contractItem)); + } + + } + } + } + + @Test + public void testPrintAll() { + + List contractItemList = contractItemRepository.findAll(); + for (ContractItem contractItem : contractItemList) { + contractItem.setCreateTime(null); + contractItem.setModifyTime(null); + System.out.println(JsonUtils.objToString(contractItem)); + } + } + + +}