修改test-network 默认的basic合约
- 通道创建好之后运行:
./network.sh deployCC
,默认调用的是basic合约(同命令./network.sh deployCC -ccn basic
) - basic对应的合约目录是:
/root/go/src/github.com/hyperledger/fabric/fabric-samples/asset-transfer-basic/chaincode-java
,将该目录整体拷贝到idea中进行修改 -
删除原java文件
QQ图片20210105233639.png - 仿照Asset文件新建以下两个文件Pic.java是存储结构,PicTransfer.java是交易函数
- 新建Pic.java
https://github.com/wilesanGH/chaincode-java-pic
/*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.fabric.samples.assettransfer;
import com.owlike.genson.annotation.JsonProperty;
import org.hyperledger.fabric.contract.annotation.DataType;
import org.hyperledger.fabric.contract.annotation.Property;
import java.util.Objects;
@DataType()
public final class Pic {
@Property()
private final String PicId;
@Property()
private final String eventId;
@Property()
private final String hashContext;
@Property()
private final String picPath;
@Property()
private final String createDate;
public String getPicId() {
return PicId;
}
public String getEventId() {
return eventId;
}
public String getHashContext() {
return hashContext;
}
public String getPicPath() {
return picPath;
}
public String getCreateDate() {
return createDate;
}
public Pic(
@JsonProperty("picId") final String picId,
@JsonProperty("eventId") final String eventId,
@JsonProperty("hashContext") final String hashContext,
@JsonProperty("picPath") final String picPath,
@JsonProperty("createDate") final String createDate
) {
PicId = picId;
this.eventId = eventId;
this.hashContext = hashContext;
this.picPath = picPath;
this.createDate = createDate;
}
@Override
public boolean equals(final Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
if (!super.equals(object)) {
return false;
}
Pic pic = (Pic) object;
return java.util.Objects.equals(PicId, pic.PicId) && java.util.Objects.equals(eventId, pic.eventId) && java.util.Objects.equals(hashContext, pic.hashContext) && java.util.Objects.equals(picPath, pic.picPath) && java.util.Objects.equals(createDate, pic.createDate);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), PicId, eventId, hashContext, picPath, createDate);
}
@Override
public String toString() {
return "Pic{"
+ "PicId='" + PicId + '\''
+ ", eventId='" + eventId + '\''
+ ", hashContext='" + hashContext + '\''
+ ", picPath='" + picPath + '\''
+ ", createDate='" + createDate + '\''
+ '}';
}
}
- 新建PicTransfer.java
/*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.fabric.samples.assettransfer;
import com.owlike.genson.Genson;
import org.hyperledger.fabric.contract.Context;
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.annotation.Contact;
import org.hyperledger.fabric.contract.annotation.Contract;
import org.hyperledger.fabric.contract.annotation.Default;
import org.hyperledger.fabric.contract.annotation.Info;
import org.hyperledger.fabric.contract.annotation.License;
import org.hyperledger.fabric.contract.annotation.Transaction;
import org.hyperledger.fabric.shim.ChaincodeException;
import org.hyperledger.fabric.shim.ChaincodeStub;
import org.hyperledger.fabric.shim.ledger.KeyValue;
import org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
import java.util.ArrayList;
import java.util.List;
@Contract(
name = "pic",
info = @Info(
title = "pic Transfer",
description = "The hyperlegendary pic transfer",
version = "0.0.1-SNAPSHOT",
license = @License(
name = "Apache 2.0 License",
url = "http://www.apache.org/licenses/LICENSE-2.0.html"),
contact = @Contact(
email = "[email protected]",
name = "Adrian Transfer",
url = "https://hyperledger.example.com")))
@Default
public final class PicTransfer implements ContractInterface {
private final Genson genson = new Genson();
/**
* Creates some initial Pics on the ledger.
*
* @param ctx the transaction context
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public void InitPicLedger(final Context ctx) {
ChaincodeStub stub = ctx.getStub();
CreatePic(ctx, "Pic1", "e1", "insdfd", "20", "2020-12-05 12:00:00");
CreatePic(ctx, "Pic2", "e2", "inasdd", "30", "2020-12-05 12:00:00");
CreatePic(ctx, "Pic3", "e3", "in1222", "40", "2020-12-05 12:00:00");
CreatePic(ctx, "Pic4", "e4", "out222", "60", "2020-11-05 12:00:00");
CreatePic(ctx, "Pic5", "e5", "in2222", "70", "2021-12-05 12:00:00");
CreatePic(ctx, "Pic6", "e6", "out222", "30", "2020-12-05 12:00:00");
}
/**
* Creates a new Pic on the ledger.
*
* @param ctx the transaction context
* @return the created Pic
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public Pic CreatePic(
final Context ctx,
final String picId,
final String eventId,
final String hashContext,
final String picPath,
final String createDate
) {
ChaincodeStub stub = ctx.getStub();
if (PicExists(ctx, picId)) {
String errorMessage = String.format("Pic %s already exists", picId);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, PicTransferErrors.ASSET_ALREADY_EXISTS.toString());
}
Pic pic = new Pic(picId, eventId, hashContext, picPath, createDate);
String picJSON = genson.serialize(pic);
stub.putStringState(picId, picJSON);
return pic;
}
/**
* Retrieves an Pic with the specified ID from the ledger.
*
* @param ctx the transaction context
* @param picId the ID of the Pic
* @return the Pic found on the ledger if there was one
*/
@Transaction(intent = Transaction.TYPE.EVALUATE)
public Pic ReadPic(final Context ctx, final String picId) {
ChaincodeStub stub = ctx.getStub();
String picJSON = stub.getStringState(picId);
if (picJSON == null || picJSON.isEmpty()) {
String errorMessage = String.format("PicPic %s does not exist", picId);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, PicTransferErrors.ASSET_NOT_FOUND.toString());
}
Pic pic = genson.deserialize(picJSON, Pic.class);
return pic;
}
/**
* Updates the properties of an Pic on the ledger.
*
* @param ctx the transaction context
* @return the transferred Pic
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public Pic UpdatePic(
final Context ctx,
final String picId,
final String eventId,
final String hashContext,
final String picPath,
final String createDate
) {
ChaincodeStub stub = ctx.getStub();
if (!PicExists(ctx, picId)) {
String errorMessage = String.format("Pic %s does not exist", picId);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, PicTransferErrors.ASSET_NOT_FOUND.toString());
}
Pic newPic = new Pic(
picId,
eventId,
hashContext,
picPath,
createDate
);
String newPicJSON = genson.serialize(newPic);
stub.putStringState(picId, newPicJSON);
return newPic;
}
/**
* Deletes Pic on the ledger.
*
* @param ctx the transaction context
* @param picId the ID of the Pic being deleted
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public void DeletePic(final Context ctx, final String picId) {
ChaincodeStub stub = ctx.getStub();
if (!PicExists(ctx, picId)) {
String errorMessage = String.format("Pic %s does not exist", picId);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, PicTransferErrors.ASSET_NOT_FOUND.toString());
}
stub.delState(picId);
}
/**
* Checks the existence of the Pic on the ledger
*
* @param ctx the transaction context
* @param pidId the ID of the Pic
* @return boolean indicating the existence of the Pic
*/
@Transaction(intent = Transaction.TYPE.EVALUATE)
public boolean PicExists(final Context ctx, final String pidId) {
ChaincodeStub stub = ctx.getStub();
String picJSON = stub.getStringState(pidId);
return (picJSON != null && !picJSON.isEmpty());
}
/**
* Changes the owner of a Pic on the ledger.
*
* @param ctx the transaction context
* @param picId the ID of the Pic being transferred
* @param newPicPath the new number
* @return the updated Pic
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public Pic TransferPic(final Context ctx, final String picId, final String newHashContext, final String newPicPath) {
ChaincodeStub stub = ctx.getStub();
String picJSON = stub.getStringState(picId);
if (picJSON == null || picJSON.isEmpty()) {
String errorMessage = String.format("Pic %s does not exist", picId);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, PicTransferErrors.ASSET_NOT_FOUND.toString());
}
Pic pic = genson.deserialize(picJSON, Pic.class);
Pic newPic = new Pic(
pic.getPicId(),
pic.getEventId(),
newHashContext,
newPicPath,
pic.getCreateDate()
);
String newPicJSON = genson.serialize(newPic);
stub.putStringState(picId, newPicJSON);
return newPic;
}
/**
* Retrieves all Pics from the ledger.
*
* @param ctx the transaction context
* @return array of Pics found on the ledger
*/
@Transaction(intent = Transaction.TYPE.EVALUATE)
public String GetAllPics(final Context ctx) {
ChaincodeStub stub = ctx.getStub();
List queryResults = new ArrayList();
// To retrieve all Pics from the ledger use getStateByRange with empty startKey & endKey.
// Giving empty startKey & endKey is interpreted as all the keys from beginning to end.
// As another example, if you use startKey = 'Pic0', endKey = 'Pic9' ,
// then getStateByRange will retrieve Pic with keys between Pic0 (inclusive) and Pic9 (exclusive) in lexical order.
QueryResultsIterator results = stub.getStateByRange("", "");
for (KeyValue result : results) {
Pic pic = genson.deserialize(result.getStringValue(), Pic.class);
queryResults.add(pic);
System.out.println(pic.toString());
}
final String response = genson.serialize(queryResults);
return response;
}
private enum PicTransferErrors {
ASSET_NOT_FOUND,
ASSET_ALREADY_EXISTS
}
}
- 修改settings.gradle
rootProject.name = 'pic'
- Ctrl+Alt+Shift+S
修改project name 为pic
- 删除build目录运行
gradle installDist
编译项目会重新生成build目录,确认build\install\lib\pic-1.0-SNAPSHOT.jar
已经生成,且编译没有错误 - 新建目录:
/root/go/src/github.com/hyperledger/fabric/fabric-samples/asset-transfer-pic/chaincode-java
将项目拷贝到该目录下。 -
完整项目目录如下:
QQ图片20210105234919.png
修改deployCC.sh
- 修改后的合约名为
pic
,这个名字deployCC.sh是不会识别的需要进行修改。 - 打开
/root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/scripts/deployCC.sh
,修改如下代码(主要是在最后添加了对pic合约的识别):
if [ "$CC_SRC_PATH" = "NA" ]; then
infoln "Determining the path to the chaincode"
# first see which chaincode we have. This will be based on the
# short name of the known chaincode sample
if [ "$CC_NAME" = "basic" ]; then
println $'\e[0;32m'asset-transfer-basic$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-basic"
elif [ "$CC_NAME" = "events" ]; then
println $'\e[0;32m'asset-transfer-events$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-events"
elif [ "$CC_NAME" = "secured" ]; then
println $'\e[0;32m'asset-transfer-secured-agreeement$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-secured-agreement"
elif [ "$CC_NAME" = "ledger" ]; then
println $'\e[0;32m'asset-transfer-ledger-agreeement$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-ledger-queries"
elif [ "$CC_NAME" = "private" ]; then
println $'\e[0;32m'asset-transfer-private-data$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-private-data"
elif [ "$CC_NAME" = "sbe" ]; then
println $'\e[0;32m'asset-transfer-sbe$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-sbe"
elif [ "$CC_NAME" = "pic" ]; then
println $'\e[0;32m'asset-transfer-pic$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-pic"
else
fatalln "The chaincode name ${CC_NAME} is not supported by this script. Supported chaincode names are: basic, events, ledger, private, sbe, secured"
fi
- 启动test-network:
./network.sh up createChannel -c mychannel -s couchdb
,
可以参考fabric2.2 test-network调用java合约(一) - 部署合约
./network.sh deployCC -ccn pic
,同时也可以部署basic合约./network.sh deployCC -ccn basic
这样两个都可以在一通道中部署。
合约调用
#使用Org1来调用合约
export PATH=/root/go/src/github.com/hyperledger/fabric/fabric-samples/bin:$PATH
export FABRIC_CFG_PATH=/root/go/src/github.com/hyperledger/fabric/fabric-samples/config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
#调用初asset初始化(这个地方原来是```InitLedger```我修改成```InitAssetLedger```了,以区别InitPicLedger,修改后要重新编译,在Centos中编译有可能有问题,我在idea中编译好放到chain-code-java目录下的)
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles /root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitAssetLedger","Args":[]}'
2021-01-05 15:19:30.473 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
#查询asset全部记录
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
[{"appraisedValue":300,"assetID":"asset1","color":"blue","owner":"Tomoko","size":5},{"appraisedValue":400,"assetID":"asset2","color":"red","owner":"Brad","size":5},{"appraisedValue":500,"assetID":"asset3","color":"green","owner":"Jin Soo","size":10},{"appraisedValue":600,"assetID":"asset4","color":"yellow","owner":"Max","size":10},{"appraisedValue":700,"assetID":"asset5","color":"black","owner":"Adrian","size":15},{"appraisedValue":700,"assetID":"asset6","color":"white","owner":"Michel","size":15}]
#调用初pic初始化 (注意basic要改成pic合约)
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n pic --peerAddresses localhost:7051 --tlsRootCertFiles /root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /root/go/src/github.com/hyperledger/fabric/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitPicLedger","Args":[]}'
2021-01-05 15:20:08.147 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
#查询pic全部记录
peer chaincode query -C mychannel -n pic -c '{"Args":["GetAllPics"]}'
[{"createDate":"2020-12-05 12:00:00","eventId":"e1","hashContext":"insdfd","picId":"Pic1","picPath":"20"},{"createDate":"2020-12-05 12:00:00","eventId":"e2","hashContext":"inasdd","picId":"Pic2","picPath":"30"},{"createDate":"2020-12-05 12:00:00","eventId":"e3","hashContext":"in1222","picId":"Pic3","picPath":"40"},{"createDate":"2020-11-05 12:00:00","eventId":"e4","hashContext":"out222","picId":"Pic4","picPath":"60"},{"createDate":"2021-12-05 12:00:00","eventId":"e5","hashContext":"in2222","picId":"Pic5","picPath":"70"},{"createDate":"2020-12-05 12:00:00","eventId":"e6","hashContext":"out222","picId":"Pic6","picPath":"30"}]
另一个合约
https://github.com/wilesanGH/chaincode-java-integral
integral.java
/*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.fabric.samples.assettransfer;
import com.owlike.genson.annotation.JsonProperty;
import org.hyperledger.fabric.contract.annotation.DataType;
import org.hyperledger.fabric.contract.annotation.Property;
import java.util.Objects;
@DataType()
public final class Integral {
@Property()
private final String integralId;
@Property()
private final String userId;
@Property()
private final String eventId;
@Property()
private final String type;
@Property()
private final int number;
@Property()
private final String createDate;
public String getIntegralId() {
return integralId;
}
public String getUserId() {
return userId;
}
public String getEventId() {
return eventId;
}
public String getType() {
return type;
}
public int getNumber() {
return number;
}
public String getCreateDate() {
return createDate;
}
public Integral(
@JsonProperty("integralId") final String integralId,
@JsonProperty("userId") final String userId,
@JsonProperty("eventId") final String eventId,
@JsonProperty("type") final String type,
@JsonProperty("number") final int number,
@JsonProperty("createDate") final String createDate
) {
this.integralId = integralId;
this.userId = userId;
this.eventId = eventId;
this.type = type;
this.number = number;
this.createDate = createDate;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Integral that = (Integral) o;
return eventId == that.eventId && number == that.number && Objects.equals(integralId, that.integralId) && Objects.equals(userId, that.userId) && Objects.equals(type, that.type) && Objects.equals(createDate, that.createDate);
}
@Override
public int hashCode() {
return Objects.hash(integralId, userId, eventId, type, number, createDate);
}
@Override
public String toString() {
return "AssetIntegral{"
+ "integralId='" + integralId + '\''
+ ", userId='" + userId + '\''
+ ", eventId=" + eventId
+ ", type='" + type + '\''
+ ", number=" + number
+ ", createDate='" + createDate + '\''
+ '}';
}
}
integralTransfer.java
/*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.fabric.samples.assettransfer;
import com.owlike.genson.Genson;
import org.hyperledger.fabric.contract.Context;
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.annotation.Contact;
import org.hyperledger.fabric.contract.annotation.Contract;
import org.hyperledger.fabric.contract.annotation.Default;
import org.hyperledger.fabric.contract.annotation.Info;
import org.hyperledger.fabric.contract.annotation.License;
import org.hyperledger.fabric.contract.annotation.Transaction;
import org.hyperledger.fabric.shim.ChaincodeException;
import org.hyperledger.fabric.shim.ChaincodeStub;
import org.hyperledger.fabric.shim.ledger.KeyValue;
import org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
import java.util.ArrayList;
import java.util.List;
@Contract(
name = "integral",
info = @Info(
title = "integral Transfer",
description = "The hyperlegendary integral transfer",
version = "0.0.1-SNAPSHOT",
license = @License(
name = "Apache 2.0 License",
url = "http://www.apache.org/licenses/LICENSE-2.0.html"),
contact = @Contact(
email = "[email protected]",
name = "Adrian Transfer",
url = "https://hyperledger.example.com")))
@Default
public final class IntegralTransfer implements ContractInterface {
private final Genson genson = new Genson();
/**
* Creates some initial integrals on the ledger.
*
* @param ctx the transaction context
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public void InitIntegralLedger(final Context ctx) {
ChaincodeStub stub = ctx.getStub();
CreateIntegral(ctx, "integral1", "user1", "e1", "in", 20, "2020-12-05 12:00:00");
CreateIntegral(ctx, "integral2", "user2", "e2", "in", 30, "2020-12-05 12:00:00");
CreateIntegral(ctx, "integral3", "user3", "e3", "in", 40, "2020-12-05 12:00:00");
CreateIntegral(ctx, "integral4", "user4", "e4", "out", 60, "2020-11-05 12:00:00");
CreateIntegral(ctx, "integral5", "user5", "e5", "in", 70, "2021-12-05 12:00:00");
CreateIntegral(ctx, "integral6", "user6", "e6", "out", 30, "2020-12-05 12:00:00");
}
/**
* Creates a new integral on the ledger.
*
* @param ctx the transaction context
* @param integralId the ID of the new integral
* @param userId the ID of the new integral
* @param eventId the color of the new integral
* @param type the size for the new integral
* @param number the owner of the new integral
* @return the created integral
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public Integral CreateIntegral(
final Context ctx,
final String integralId,
final String userId,
final String eventId,
final String type,
final int number,
final String createDate
) {
ChaincodeStub stub = ctx.getStub();
if (IntegralExists(ctx, integralId)) {
String errorMessage = String.format("Integral %s already exists", integralId);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, IntegralTransferErrors.ASSET_ALREADY_EXISTS.toString());
}
Integral integral = new Integral(integralId, userId, eventId, type, number, createDate);
String integralJSON = genson.serialize(integral);
stub.putStringState(integralId, integralJSON);
return integral;
}
/**
* Retrieves an integral with the specified ID from the ledger.
*
* @param ctx the transaction context
* @param integralID the ID of the integral
* @return the integral found on the ledger if there was one
*/
@Transaction(intent = Transaction.TYPE.EVALUATE)
public Integral ReadIntegral(final Context ctx, final String integralID) {
ChaincodeStub stub = ctx.getStub();
String integralJSON = stub.getStringState(integralID);
if (integralJSON == null || integralJSON.isEmpty()) {
String errorMessage = String.format("IntegralIntegral %s does not exist", integralID);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, IntegralTransferErrors.ASSET_NOT_FOUND.toString());
}
Integral integral = genson.deserialize(integralJSON, Integral.class);
return integral;
}
/**
* Updates the properties of an integral on the ledger.
*
* @param ctx the transaction context
* @param integralId the ID of the new integral
* @param userId the ID of the new integral
* @param eventId the color of the new integral
* @param type the size for the new integral
* @param number the owner of the new integral
* @return the transferred integral
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public Integral UpdateIntegral(
final Context ctx,
final String integralId,
final String userId,
final String eventId,
final String type,
final int number,
final String createDate
) {
ChaincodeStub stub = ctx.getStub();
if (!IntegralExists(ctx, integralId)) {
String errorMessage = String.format("Integral %s does not exist", integralId);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, IntegralTransferErrors.ASSET_NOT_FOUND.toString());
}
Integral newIntegral = new Integral(
integralId,
userId,
eventId,
type,
number,
createDate
);
String newIntegralJSON = genson.serialize(newIntegral);
stub.putStringState(integralId, newIntegralJSON);
return newIntegral;
}
/**
* Deletes integral on the ledger.
*
* @param ctx the transaction context
* @param integralID the ID of the integral being deleted
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public void DeleteIntegral(final Context ctx, final String integralID) {
ChaincodeStub stub = ctx.getStub();
if (!IntegralExists(ctx, integralID)) {
String errorMessage = String.format("Integral %s does not exist", integralID);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, IntegralTransferErrors.ASSET_NOT_FOUND.toString());
}
stub.delState(integralID);
}
/**
* Checks the existence of the integral on the ledger
*
* @param ctx the transaction context
* @param integralID the ID of the integral
* @return boolean indicating the existence of the integral
*/
@Transaction(intent = Transaction.TYPE.EVALUATE)
public boolean IntegralExists(final Context ctx, final String integralID) {
ChaincodeStub stub = ctx.getStub();
String integralJSON = stub.getStringState(integralID);
return (integralJSON != null && !integralJSON.isEmpty());
}
/**
* Changes the owner of a integral on the ledger.
*
* @param ctx the transaction context
* @param integralID the ID of the integral being transferred
* @param newNumber the new number
* @return the updated integral
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
public Integral TransferIntegral(final Context ctx, final String integralID, final int newNumber) {
ChaincodeStub stub = ctx.getStub();
String integralJSON = stub.getStringState(integralID);
if (integralJSON == null || integralJSON.isEmpty()) {
String errorMessage = String.format("Integral %s does not exist", integralID);
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, IntegralTransferErrors.ASSET_NOT_FOUND.toString());
}
Integral integral = genson.deserialize(integralJSON, Integral.class);
Integral newIntegral = new Integral(
integral.getIntegralId(),
integral.getUserId(),
integral.getEventId(),
integral.getType(),
newNumber,
integral.getCreateDate()
);
String newIntegralJSON = genson.serialize(newIntegral);
stub.putStringState(integralID, newIntegralJSON);
return newIntegral;
}
/**
* Retrieves all integrals from the ledger.
*
* @param ctx the transaction context
* @return array of integrals found on the ledger
*/
@Transaction(intent = Transaction.TYPE.EVALUATE)
public String GetAllIntegrals(final Context ctx) {
ChaincodeStub stub = ctx.getStub();
List queryResults = new ArrayList();
// To retrieve all integrals from the ledger use getStateByRange with empty startKey & endKey.
// Giving empty startKey & endKey is interpreted as all the keys from beginning to end.
// As another example, if you use startKey = 'integral0', endKey = 'integral9' ,
// then getStateByRange will retrieve integral with keys between integral0 (inclusive) and integral9 (exclusive) in lexical order.
QueryResultsIterator results = stub.getStateByRange("", "");
for (KeyValue result : results) {
Integral integral = genson.deserialize(result.getStringValue(), Integral.class);
queryResults.add(integral);
System.out.println(integral.toString());
}
final String response = genson.serialize(queryResults);
return response;
}
private enum IntegralTransferErrors {
ASSET_NOT_FOUND,
ASSET_ALREADY_EXISTS
}
}