From 606905eedecefdf0f3f48d42300784883a0c8c11 Mon Sep 17 00:00:00 2001 From: Krishnasuri Narayanam Date: Fri, 23 Jul 2021 21:30:09 +0530 Subject: [PATCH 1/7] changing asset exchange interop cc as package Signed-off-by: Krishnasuri Narayanam --- .../contracts/interop/Makefile | 6 +- .../contracts/interop/go.mod | 20 +- .../contracts/interop/go.sum | 124 ++- .../contracts/interop/manage_assets.go | 808 +---------------- .../contracts/interop/manage_assets_test.go | 397 ++++---- .../contracts/interop/setup_test.go | 2 +- .../libs/assetexchange/assetSwapContracts.go | 853 ++++++++++++++++++ .../libs/assetexchange/go.mod | 11 + .../libs/assetexchange/go.sum | 224 +++++ 9 files changed, 1409 insertions(+), 1036 deletions(-) create mode 100644 core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go create mode 100644 core/network/fabric-interop-cc/libs/assetexchange/go.mod create mode 100644 core/network/fabric-interop-cc/libs/assetexchange/go.sum diff --git a/core/network/fabric-interop-cc/contracts/interop/Makefile b/core/network/fabric-interop-cc/contracts/interop/Makefile index 00c5a2637..85c20716a 100644 --- a/core/network/fabric-interop-cc/contracts/interop/Makefile +++ b/core/network/fabric-interop-cc/contracts/interop/Makefile @@ -1,2 +1,6 @@ -test-manage-assets: +assetexchange: + cp -r ../../libs/assetexchange . +test-manage-assets: assetexchange go test manage_assets.go manage_assets_test.go main.go setup_test.go -v +clean: + rm -rf assetexchange diff --git a/core/network/fabric-interop-cc/contracts/interop/go.mod b/core/network/fabric-interop-cc/contracts/interop/go.mod index 5a614f143..aaa68ab59 100644 --- a/core/network/fabric-interop-cc/contracts/interop/go.mod +++ b/core/network/fabric-interop-cc/contracts/interop/go.mod @@ -2,15 +2,17 @@ module github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabr go 1.16 +replace github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange => ./assetexchange + require ( - github.com/golang/protobuf v1.5.0 - github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v0.0.0-20210712215013-866f5840a1a9 - github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664 - github.com/hyperledger/fabric-contract-api-go v1.1.0 - github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31 - github.com/sirupsen/logrus v1.4.2 - github.com/stretchr/testify v1.6.1 - golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 + github.com/golang/protobuf v1.5.2 + github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 + github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange v0.0.0-00010101000000-000000000000 + github.com/hyperledger/fabric-chaincode-go v0.0.0-20210718160520-38d29fabecb9 + github.com/hyperledger/fabric-contract-api-go v1.1.1 + github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 + github.com/sirupsen/logrus v1.8.1 + github.com/stretchr/testify v1.5.1 + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 google.golang.org/protobuf v1.27.1 - gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect ) diff --git a/core/network/fabric-interop-cc/contracts/interop/go.sum b/core/network/fabric-interop-cc/contracts/interop/go.sum index efe095cf7..507fc1d03 100644 --- a/core/network/fabric-interop-cc/contracts/interop/go.sum +++ b/core/network/fabric-interop-cc/contracts/interop/go.sum @@ -1,12 +1,18 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -15,7 +21,14 @@ github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2A github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -35,41 +48,55 @@ github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v0.0.0-20210712215013-866f5840a1a9 h1:4nvDlDhPUpompAiPBuGMKRPc+H6DjptO4A0euMoLpT0= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v0.0.0-20210712215013-866f5840a1a9/go.mod h1:U3ly7uEA+YqJF+WItb0sGfOW1XsZT6S0pndUtHjBTgw= +github.com/hyperledger-labs/weaver-dlt-interoperability v0.0.0-20210722105253-d001e6a4f7ca h1:LXOVVO1+Q34rHdUpmphtYMYQSNj5HUgBh1FE9d3tmvI= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 h1:c9VK82wttYXTe4/UfnDq2Gq1Zu4Yxcxx1PbhEQHKuvA= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1/go.mod h1:yJq9oxxBHPryM8hVFiqM5HgfV2XFj5Tzb9Unx9D+YuI= github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664 h1:Pu/9SNpo71SJj5DGehCXOKD9QGQ3MsuWjpsLM9Mkdwg= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-contract-api-go v1.1.0 h1:K9uucl/6eX3NF0/b+CGIiO1IPm1VYQxBkpnVGJur2S4= -github.com/hyperledger/fabric-contract-api-go v1.1.0/go.mod h1:nHWt0B45fK53owcFpLtAe8DH0Q5P068mnzkNXMPSL7E= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20210718160520-38d29fabecb9 h1:1cAZHHrBYFrX3bwQGhOZtOB4sCM9QWVppd81O8vsPXs= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20210718160520-38d29fabecb9/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= +github.com/hyperledger/fabric-contract-api-go v1.1.1 h1:gDhOC18gjgElNZ85kFWsbCQq95hyUP/21n++m0Sv6B0= +github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31 h1:T/uwoFIUioDDLffuJ/XgMLOWCUcx95/xXidv5igafl8= github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 h1:d7do07Q4LaOFAEWceRwUwVDdcfx3BdLeZYyUGtbHfRk= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -80,12 +107,15 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -98,9 +128,8 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -109,56 +138,99 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ= golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/core/network/fabric-interop-cc/contracts/interop/manage_assets.go b/core/network/fabric-interop-cc/contracts/interop/manage_assets.go index aecfab8ed..f75c522c9 100644 --- a/core/network/fabric-interop-cc/contracts/interop/manage_assets.go +++ b/core/network/fabric-interop-cc/contracts/interop/manage_assets.go @@ -9,845 +9,61 @@ package main import ( - "crypto/sha256" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "strconv" - "time" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange" "github.com/hyperledger/fabric-contract-api-go/contractapi" - mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" - log "github.com/sirupsen/logrus" ) -// Object used to capture the HashLock details used in Asset Locking -type HashLock struct { - HashBase64 string `json:"hashBase64"` -} - -// Object used in the map, --> (for non-fungible assets) -type AssetLockValue struct { - Locker string `json:"locker"` - Recipient string `json:"recipient"` - LockInfo interface{} `json:"lockInfo"` - ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` -} - -// Object used in the map, contractId --> (for fungible assets) -type FungibleAssetLockValue struct { - Type string `json:"type"` - NumUnits uint64 `json:"numUnits"` - Locker string `json:"locker"` - Recipient string `json:"recipient"` - LockInfo interface{} `json:"lockInfo"` - ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` -} - -const ( - assetKeyPrefix = "AssetKey_" // prefix for the map, asset-key --> asset-object - assetKeyDelimiter = "_" // delimiter for the asset-key - contractIdPrefix = "ContractId_" // prefix for the map, contractId --> asset-key -) - -// helper functions to log and return errors -func logThenErrorf(format string, args ...interface{}) error { - errorMsg := fmt.Sprintf(format, args...) - log.Error(errorMsg) - return errors.New(errorMsg) -} - -// function to generate a "SHA256" hash in base64 format for a given preimage -func generateSHA256HashInBase64Form(preimage string) string { - hasher := sha256.New() - hasher.Write([]byte(preimage)) - shaHash := hasher.Sum(nil) - shaHashBase64 := base64.StdEncoding.EncodeToString(shaHash) - return shaHashBase64 -} - -// function to return the key to fetch an element from the map using contractId -func generateContractIdMapKey(contractId string) string { - return contractIdPrefix + contractId -} - -/* - * Function to generate asset-lock key (which is combination of asset-type and asset-id) - * and contract-id (which is a hash on asset-lock key) for the non-fungible asset locking on the ledger - */ -func generateAssetLockKeyAndContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) (string, string, error) { - assetLockKey, err := ctx.GetStub().CreateCompositeKey("AssetExchangeContract", []string{assetAgreement.Type, assetAgreement.Id}) - if err != nil { - return "", "", logThenErrorf("error while creating composite key: %+v", err) - } - - contractId := generateSHA256HashInBase64Form(assetLockKey) - return assetLockKey, contractId, nil -} - -/* - * Function to generate contract-id for fungible asset-locking on the ledger (which is - * a hash on the attributes of the fungible asset exchange agreement) - */ -func generateFungibleAssetLockContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) string { - preimage := assetAgreement.Type + strconv.Itoa(int(assetAgreement.NumUnits)) + - assetAgreement.Locker + assetAgreement.Recipient + ctx.GetStub().GetTxID() - contractId := generateSHA256HashInBase64Form(preimage) - return contractId -} - -// function to get the caller identity from the transaction context -func getECertOfTxCreatorBase64(ctx contractapi.TransactionContextInterface) (string, error) { - - txCreatorBytes, err := ctx.GetStub().GetCreator() - if err != nil { - return "", logThenErrorf("unable to get the transaction creator information: %+v", err) - } - log.Infof("getECertOfTxCreatorBase64: TxCreator: %s", string(txCreatorBytes)) - - serializedIdentity := &mspProtobuf.SerializedIdentity{} - err = proto.Unmarshal(txCreatorBytes, serializedIdentity) - if err != nil { - return "", logThenErrorf("getECertOfTxCreatorBase64: unmarshal error: %+v", err) - } - log.Infof("getECertOfTxCreatorBase64: TxCreator ECert: %s", string(serializedIdentity.IdBytes)) - - eCertBytesBase64 := base64.StdEncoding.EncodeToString(serializedIdentity.IdBytes) - - return eCertBytesBase64, nil -} - -/* - * Function to validate the locker in asset agreement. - * If locker is not set, it will be set to the caller. - * If the locker is set already, it ensures that the locker is same as the creator of the transaction. - */ -func validateAndSetLockerOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Locker) == 0 { - assetAgreement.Locker = txCreatorECertBase64 - } else if assetAgreement.Locker != txCreatorECertBase64 { - return logThenErrorf("locker %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) - } - - return nil -} - -/* - * Function to validate the locker in fungible asset agreement. - * If locker is not set, it will be set to the caller. - * If the locker is set already, it ensures that the locker is same as the creator of the transaction. - */ -func validateAndSetLockerOfFungibleAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Locker) == 0 { - assetAgreement.Locker = txCreatorECertBase64 - } else if assetAgreement.Locker != txCreatorECertBase64 { - return logThenErrorf("locker %s in the fungible asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) - } - - return nil -} - -/* - * Function to validate the recipient in asset agreement. - * If recipient is not set, it will be set to the caller. - * If the recipeint is set already, it ensures that the recipient is same as the creator of the transaction. - */ -func validateAndSetRecipientOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Recipient) == 0 { - assetAgreement.Recipient = txCreatorECertBase64 - } else if assetAgreement.Recipient != txCreatorECertBase64 { - return logThenErrorf("recipient %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Recipient, txCreatorECertBase64) - } - - return nil -} - -func getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64 string) (interface{}, uint64, error) { - var lockInfoVal interface{} - var expiryTimeSecs uint64 - - lockInfoBytes, err := base64.StdEncoding.DecodeString(lockInfoBytesBase64) - if err != nil { - return lockInfoVal, 0, fmt.Errorf("error in base64 decode of lock information: %+v", err) - } - lockInfo := &common.AssetLock{} - err = proto.Unmarshal([]byte(lockInfoBytes), lockInfo) - if err != nil { - return lockInfoVal, 0, logThenErrorf(err.Error()) - } - - // process lock details here (lockInfo.LockInfo contains value based on the lock mechanism used) - if lockInfo.LockMechanism == common.LockMechanism_HTLC { - lockInfoHTLC := &common.AssetLockHTLC{} - err := proto.Unmarshal(lockInfo.LockInfo, lockInfoHTLC) - if err != nil { - return lockInfoVal, 0, logThenErrorf("unmarshal error: %s", err) - } - //display the passed hash lock information - log.Infof("lockInfoHTLC: %+v", lockInfoHTLC) - lockInfoVal = HashLock{HashBase64: string(lockInfoHTLC.HashBase64)} - // process time lock details here - if lockInfoHTLC.TimeSpec != common.AssetLockHTLC_EPOCH { - return lockInfoVal, 0, logThenErrorf("only EPOCH time is supported at present") - } - expiryTimeSecs = lockInfoHTLC.ExpiryTimeSecs - } else { - return lockInfoVal, 0, logThenErrorf("lock mechanism is not supported") - } - return lockInfoVal, expiryTimeSecs, nil -} - // LockAsset cc is used to record locking of an asset on the ledger func (s *SmartContract) LockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return "", logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf("error in locker validation: %+v", err) - } - - lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockVal := AssetLockValue{Locker: assetAgreement.Locker, Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - if assetLockValBytes != nil { - return "", logThenErrorf("asset of type %s and ID %s is already locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockValBytes, err = json.Marshal(assetLockVal) - if err != nil { - return "", logThenErrorf("marshal error: %+v", err) - } - - err = ctx.GetStub().PutState(assetLockKey, assetLockValBytes) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockKeyBytes, err := json.Marshal(assetLockKey) - if err != nil { - return "", logThenErrorf("marshal error: %+v", err) - } - - err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockKeyBytes) - if err != nil { - return "", logThenErrorf(err.Error()) - } - return contractId, nil + return assetexchange.LockAsset(ctx, assetAgreementBytesBase64, lockInfoBytesBase64) } // UnlockAsset cc is used to record unlocking of an asset on the ledger func (s *SmartContract) UnlockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) error { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return logThenErrorf("error in validation of asset agreement parties: %+v", err) - } - - assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return logThenErrorf("unmarshal error: %s", err) - } - - if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return logThenErrorf("cannot unlock asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock asset of type %s and ID %s as the expiry time is not yet elapsed", assetAgreement.Type, assetAgreement.Id) - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) - } - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) - } - - return nil + return assetexchange.UnlockAsset(ctx, assetAgreementBytesBase64) } // IsAssetLocked cc is used to query the ledger and findout if an asset is locked or not func (s *SmartContract) IsAssetLocked(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) (bool, error) { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return false, logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return false, logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - assetLockKey, _, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return false, logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return false, logThenErrorf("unmarshal error: %s", err) - } - log.Infof("assetLockVal: %+v", assetLockVal) - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for asset of type %s and ID %s is already elapsed", assetAgreement.Type, assetAgreement.Id) - } - - // '*' for recipient or locker in the query implies that the query seeks status for an arbitrary recipient or locker respectively - if (assetAgreement.Locker == "*" || assetLockVal.Locker == assetAgreement.Locker) && (assetAgreement.Recipient == "*" || assetLockVal.Recipient == assetAgreement.Recipient) { - return true, nil - } else if assetAgreement.Locker == "*" && assetLockVal.Recipient != assetAgreement.Recipient { - return false, logThenErrorf("asset of type %s and ID %s is not locked for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Recipient) - } else if assetAgreement.Recipient == "*" && assetLockVal.Locker != assetAgreement.Locker { - return false, logThenErrorf("asset of type %s and ID %s is not locked by %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker) - } else if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return false, logThenErrorf("asset of type %s and ID %s is not locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker, assetAgreement.Recipient) - } - - return true, nil -} - -/* - * Function to check if hashBase64 is the hash for the preimage preimageBase64. - * Both the preimage and hash are passed in base64 form. - */ -func checkIfCorrectPreimage(preimageBase64 string, hashBase64 string) (bool, error) { - funName := "checkIfCorrectPreimage" - preimage, err := base64.StdEncoding.DecodeString(preimageBase64) - if err != nil { - return false, logThenErrorf("base64 decode preimage error: %s", err) - } - - shaHashBase64 := generateSHA256HashInBase64Form(string(preimage)) - if shaHashBase64 == hashBase64 { - log.Infof("%s: preimage %s is passed correctly", funName, preimage) - } else { - log.Infof("%s: preimage %s is not passed correctly", funName, preimage) - return false, nil - } - return true, nil -} - -func validateHashPreimage(claimInfo *common.AssetClaim, lockInfo interface{}) (bool, error) { - claimInfoHTLC := &common.AssetClaimHTLC{} - err := proto.Unmarshal(claimInfo.ClaimInfo, claimInfoHTLC) - if err != nil { - return false, logThenErrorf("unmarshal claimInfo.ClaimInfo error: %s", err) - } - //display the claim information - log.Infof("claimInfoHTLC: %+v\n", claimInfoHTLC) - lockInfoVal := HashLock{} - lockInfoBytes, err := json.Marshal(lockInfo) - if err != nil { - return false, logThenErrorf("marshal lockInfo error: %s", err) - } - err = json.Unmarshal(lockInfoBytes, &lockInfoVal) - if err != nil { - return false, logThenErrorf("unmarshal lockInfoBytes error: %s", err) - } - log.Infof("HashLock: %+v\n", lockInfoVal) - - // match the hash passed during claim with the hash stored during asset locking - return checkIfCorrectPreimage(string(claimInfoHTLC.HashPreimageBase64), lockInfoVal.HashBase64) -} - -// fetches common.AssetClaim from the input parameter and checks if the lock mechanism is valid or not -func getClaimInfo(claimInfoBytesBase64 string) (*common.AssetClaim, error) { - claimInfo := &common.AssetClaim{} - - claimInfoBytes, err := base64.StdEncoding.DecodeString(claimInfoBytesBase64) - if err != nil { - return claimInfo, logThenErrorf("error in base64 decode of claim information: %+v", err) - } - - err = proto.Unmarshal([]byte(claimInfoBytes), claimInfo) - if err != nil { - return claimInfo, logThenErrorf("unmarshal error: %s", err) - } - // check if a valid lock mechanism is provided - if claimInfo.LockMechanism != common.LockMechanism_HTLC { - return claimInfo, logThenErrorf("lock mechanism is not supported") - } - - return claimInfo, nil + return assetexchange.IsAssetLocked(ctx, assetAgreementBytesBase64) } // ClaimAsset cc is used to record claim of an asset on the ledger func (s *SmartContract) ClaimAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, claimInfoBytesBase64 string) error { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - // display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v\n", assetAgreement) - - err = validateAndSetRecipientOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return logThenErrorf("error in recipient validation: %+v", err) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return logThenErrorf("unmarshal error: %s", err) - } - - if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return logThenErrorf("cannot claim asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim asset of type %s and ID %s as the expiry time is already elapsed", assetAgreement.Type, assetAgreement.Id) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim asset of type %s and ID %s error: %v", assetAgreement.Type, assetAgreement.Id, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim asset of type %s and ID %s as the hash preimage is not matching", assetAgreement.Type, assetAgreement.Id) - } - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) - } - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset claim: %v", contractId, err) - } - - return nil -} - -// function to fetch the asset-lock from the ledger using contractId -func fetchAssetLockedUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (string, AssetLockValue, error) { - var assetLockVal = AssetLockValue{} - var assetLockKey string = "" - assetLockKeyBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf(err.Error()) - } - - if assetLockKeyBytes == nil { - return assetLockKey, assetLockVal, logThenErrorf("no contractId %s exists on the ledger", contractId) - } - - err = json.Unmarshal(assetLockKeyBytes, &assetLockKey) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("assetLockKey unmarshal error: %s", err) - } - log.Infof("contractId: %s and assetLockKey: %s", contractId, assetLockKey) - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes == nil { - return assetLockKey, assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked asset", contractId) - } - - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("assetLockVal unmarshal error: %s", err) - } - return assetLockKey, assetLockVal, nil + return assetexchange.ClaimAsset(ctx, assetAgreementBytesBase64, claimInfoBytesBase64) } // UnlockAssetUsingContractId cc is used to record unlocking of an asset on the ledger (this uses the contractId) func (s *SmartContract) UnlockAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) error { - - assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the locker of the locked fungible asset - if assetLockVal.Locker != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %v", contractId, err) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) - } - - return nil + return assetexchange.UnlockAssetUsingContractId(ctx, contractId) } // ClaimAsset cc is used to record claim of an asset on the ledger (this uses the contractId) func (s *SmartContract) ClaimAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - - assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - if assetLockVal.Recipient != string(txCreatorECertBase64) { - return logThenErrorf("asset is not locked for %s to claim", string(txCreatorECertBase64)) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim asset associated with contractId %s as the expiry time is already elapsed", contractId) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim asset associated with contractId %s failed with error: %v", contractId, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim asset associated with contractId %s as the hash preimage is not matching", contractId) - } - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %+v", contractId, err) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset claim: %+v", contractId, err) - } - - return nil + return assetexchange.ClaimAssetUsingContractId(ctx, contractId, claimInfoBytesBase64) } // IsAssetLocked cc is used to query the ledger and find out if an asset is locked or not (this uses the contractId) func (s *SmartContract) IsAssetLockedQueryUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - - _, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for asset associated with contractId %s is already elapsed", contractId) - } - - return true, nil + return assetexchange.IsAssetLockedQueryUsingContractId(ctx, contractId) } // LockFungibleAsset cc is used to record locking of a group of fungible assets of an asset-type on the ledger func (s *SmartContract) LockFungibleAsset(ctx contractapi.TransactionContextInterface, fungibleAssetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - - fungibleAssetAgreementBytes, err := base64.StdEncoding.DecodeString(fungibleAssetAgreementBytesBase64) - if err != nil { - return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.FungibleAssetExchangeAgreement{} - err = proto.Unmarshal([]byte(fungibleAssetAgreementBytes), assetAgreement) - if err != nil { - return "", logThenErrorf("unmarshal error: %s", err) - } - - //display the requested fungible asset agreement - log.Infof("fungibleAssetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfFungibleAssetAgreement(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf("error in locker validation: %+v", err) - } - - lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - // generate the contractId for the fungible asset lock agreement - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) - - assetLockVal := FungibleAssetLockValue{Type: assetAgreement.Type, NumUnits: assetAgreement.NumUnits, Locker: assetAgreement.Locker, - Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} - - assetLockValBytes, err := ctx.GetStub().GetState(contractId) - if err != nil { - return "", logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes != nil { - return "", logThenErrorf("contractId %s already exists for the requested fungible asset agreement", contractId) - } - - assetLockValBytes, err = json.Marshal(assetLockVal) - if err != nil { - return "", logThenErrorf("marshal error: %s", err) - } - - err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockValBytes) - if err != nil { - return "", logThenErrorf("failed to write to the world state: %+v", err) - } - - return contractId, nil -} - -// function to fetch the fungible asset-lock value from the ledger using contractId -func fetchFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (FungibleAssetLockValue, error) { - var assetLockVal = FungibleAssetLockValue{} - - assetLockValBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) - if err != nil { - return assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes == nil { - return assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked fungible asset", contractId) - } - - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return assetLockVal, logThenErrorf("unmarshal error: %s", err) - } - log.Infof("contractId: %s and fungibleAssetLockVal: %+v", contractId, assetLockVal) - - return assetLockVal, nil + return assetexchange.LockFungibleAsset(ctx, fungibleAssetAgreementBytesBase64, lockInfoBytesBase64) } // IsFungibleAssetLocked cc is used to query the ledger and find out if a fungible asset is locked or not func (s *SmartContract) IsFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for fungible asset associated with contractId %s is already elapsed", contractId) - } - - return true, nil + return assetexchange.IsFungibleAssetLocked(ctx, contractId) } // ClaimFungibleAsset cc is used to record claim of a fungible asset on the ledger func (s *SmartContract) ClaimFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the recipient of the locked fungible asset - if assetLockVal.Recipient != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to claim", txCreatorECertBase64) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim fungible asset associated with contractId %s as the expiry time is already elapsed", contractId) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim fungible asset associated with contractId %s failed with error: %v", contractId, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim fungible asset associated with contractId %s as the hash preimage is not matching", contractId) - } - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of fungible asset claim: %+v", contractId, err) - } - - return nil + return assetexchange.ClaimFungibleAsset(ctx, contractId, claimInfoBytesBase64) } // UnlockFungibleAsset cc is used to record unlocking of a fungible asset on the ledger func (s *SmartContract) UnlockFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string) error { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the locker of the locked fungible asset - if assetLockVal.Locker != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock fungible asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of fungible asset unlock: %v", contractId, err) - } - - return nil + return assetexchange.UnlockFungibleAsset(ctx, contractId) } diff --git a/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go b/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go index 26acecdc8..d06d8fa8f 100644 --- a/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go +++ b/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go @@ -7,22 +7,23 @@ package main import ( + "encoding/base64" "encoding/json" "fmt" "testing" - "encoding/base64" - //"encoding/hex" + "time" - "github.com/stretchr/testify/require" "github.com/golang/protobuf/proto" + "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange" mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" log "github.com/sirupsen/logrus" - "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/stretchr/testify/require" ) -const( - defaultTimeLockSecs = 5 * 60 // 5 minutes +const ( + defaultTimeLockSecs = 5 * 60 // 5 minutes ) // function that supplies value that is to be returned by ctx.GetStub().GetCreator() @@ -51,28 +52,28 @@ func TestLockAsset(t *testing.T) { recipient := "Bob" locker := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - lockInfoHTLC := &common.AssetLockHTLC { + lockInfoHTLC := &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 minutes ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, - TimeSpec: common.AssetLockHTLC_EPOCH, + TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock { + lockInfo := &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) @@ -83,7 +84,7 @@ func TestLockAsset(t *testing.T) { require.NoError(t, err) fmt.Println("Test success as expected since the agreement and lock information are speccified properly") - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure by trying to lock an asset that is already locked @@ -92,7 +93,7 @@ func TestLockAsset(t *testing.T) { log.Info(fmt.Println("Test failed as expected with error:", err)) // no need to set chaincodeStub.GetStateReturns below since the error is hit before GetState() ledger access in LockAsset() - lockInfoHTLC = &common.AssetLockHTLC { + lockInfoHTLC = &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -100,9 +101,9 @@ func TestLockAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_DURATION, } lockInfoHTLCBytes, _ = proto.Marshal(lockInfoHTLC) - lockInfo = &common.AssetLock { + lockInfo = &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ = proto.Marshal(lockInfo) // Test failure with lock information not specified properly @@ -119,28 +120,28 @@ func TestUnlockAsset(t *testing.T) { recipient := "Bob" locker := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - lockInfoHTLC := &common.AssetLockHTLC { + lockInfoHTLC := &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for sometime in the past for testing UnlockAsset functionality ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs, - TimeSpec: common.AssetLockHTLC_EPOCH, + TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock { + lockInfo := &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) @@ -151,7 +152,7 @@ func TestUnlockAsset(t *testing.T) { require.NoError(t, err) log.Info(fmt.Println("Completed locking an asset. Proceed to test unlock asset.")) - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test success with asset agreement specified properly @@ -166,7 +167,7 @@ func TestUnlockAsset(t *testing.T) { log.Info(fmt.Println("Test failed as expected with error:", err)) // Assume that the asset is locked by Alice for Bob; then trying to unlock the asset by Alice for Charlie should fail since the locking is done for a different recipient - assetLockVal = AssetLockValue{Locker: locker, Recipient: "Charlie"} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: "Charlie"} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset id being locked for a different @@ -174,12 +175,11 @@ func TestUnlockAsset(t *testing.T) { require.Error(t, err) log.Info(fmt.Println("Test failed as expected with error:", err)) - - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock // lock for sometime in the future for testing UnlockAsset functionality - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure of unlock asset with expiry time not yet elapsed @@ -197,16 +197,15 @@ func TestIsAssetLocked(t *testing.T) { locker := "Alice" currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - - assetLockVal := AssetLockValue{Locker: locker, Recipient: "Charlie"} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: "Charlie"} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset agreement not specified properly @@ -215,8 +214,7 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test success with asset agreement specified properly @@ -225,8 +223,7 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified properly.")) - - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with expiry time elapsed already @@ -235,8 +232,7 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetLockVal = AssetLockValue{Locker: "Dave", Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: "Dave", Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset agreement not specified properly @@ -245,10 +241,9 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetAgreement = &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement = &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, // arbitrary locker specification Locker: "*", @@ -260,10 +255,9 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified to include arbitrary locker.")) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // wrong recipient specification Recipient: "Charlie", // arbitrary locker specification @@ -276,13 +270,12 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", - Locker: "Dave", + Locker: "Dave", } assetAgreementBytes, _ = proto.Marshal(assetAgreement) // Test success with asset agreement specified to include arbitrary recipient @@ -291,10 +284,9 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified to include arbitrary recipient.")) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", // wrong locker specification @@ -307,10 +299,9 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", // arbitrary locker specification @@ -332,33 +323,33 @@ func TestClaimAsset(t *testing.T) { recipient := getTxCreatorECertBase64() locker := "Alice" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC { + claimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim { + claimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) @@ -367,7 +358,7 @@ func TestClaimAsset(t *testing.T) { require.NoError(t, err) log.Info(fmt.Println("Test success as expected since the asset agreement and claim information are specified properly.")) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with expiry time elapsed to claim the asset @@ -377,17 +368,17 @@ func TestClaimAsset(t *testing.T) { wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfoHTLC := &common.AssetClaimHTLC { + wrongClaimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoHTLCBytes, _ := proto.Marshal(wrongClaimInfoHTLC) - wrongClaimInfo := &common.AssetClaim { + wrongClaimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: wrongClaimInfoHTLCBytes, + ClaimInfo: wrongClaimInfoHTLCBytes, } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with claim information (i.e., preimage) not specified properly @@ -423,30 +414,30 @@ func TestUnlockAssetUsingContractId(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId " + contractId) + require.EqualError(t, err, "unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with not a valid contractId being passed as the arguement chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") + require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with GetState(assetLockKey) fail to read from the world state @@ -455,7 +446,7 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is valid but there is no asset locked with the assetLockKey @@ -463,32 +454,32 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for asset unlock exercised with expiry time not yet elapsed chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "cannot unlock asset associated with the contractId " + contractId + " as the expiry time is not yet elapsed") + require.EqualError(t, err, "cannot unlock asset associated with the contractId "+contractId+" as the expiry time is not yet elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on assetLockKey chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete asset with key %s from world state", assetLockKey)) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId " + - contractId + ": unable to delete asset with key " + assetLockKey + " from world state") + require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId "+ + contractId+": unable to delete asset with key "+assetLockKey+" from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -498,8 +489,8 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(2, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of asset unlock: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of asset unlock: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being unlocked using contractId @@ -521,26 +512,26 @@ func TestClaimAssetUsingContractId(t *testing.T) { recipient := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC { + claimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim { + claimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) @@ -548,14 +539,14 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId " + contractId) + require.EqualError(t, err, "unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with not a valid contractId being passed as the arguement chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") + require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with GetState(assetLockKey) fail to read from the world state @@ -564,7 +555,7 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is valid but there is no asset locked with the assetLockKey @@ -572,42 +563,42 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for asset claim exercised with expiry time elapsed already chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim asset associated with contractId " + contractId + " as the expiry time is already elapsed") + require.EqualError(t, err, "cannot claim asset associated with contractId "+contractId+" as the expiry time is already elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with claim information (i.e., preimage) not specified properly chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfoHTLC := &common.AssetClaimHTLC { + wrongClaimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoHTLCBytes, _ := proto.Marshal(wrongClaimInfoHTLC) - wrongClaimInfo := &common.AssetClaim { + wrongClaimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: wrongClaimInfoHTLCBytes, + ClaimInfo: wrongClaimInfoHTLCBytes, } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(wrongClaimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim asset associated with contractId " + contractId + " as the hash preimage is not matching") + require.EqualError(t, err, "cannot claim asset associated with contractId "+contractId+" as the hash preimage is not matching") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on assetLockKey @@ -616,8 +607,8 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete asset with key %s from world state", assetLockKey)) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId " + - contractId + ": unable to delete asset with key " + assetLockKey + " from world state") + require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId "+ + contractId+": unable to delete asset with key "+assetLockKey+" from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -627,8 +618,8 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(2, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of asset claim: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of asset claim: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being claimed using contractId @@ -650,22 +641,22 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) isAssetLocked, err := interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId " + contractId) + require.EqualError(t, err, "unable to retrieve contractId "+contractId) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -673,7 +664,7 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(1, nil, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") + require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -683,7 +674,7 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -692,27 +683,27 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for query if asset is locked with lock expiry time elapsed already chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "expiry time for asset associated with contractId " + contractId + " is already elapsed") + require.EqualError(t, err, "expiry time for asset associated with contractId "+contractId+" is already elapsed") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being queried using contractId chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) @@ -730,22 +721,22 @@ func TestLockFungibleAsset(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) // Test failure with TimeSpec that is part of lock information not being currently supported // no need to set chaincodeStub.GetStateReturns below since the error is hit before GetState() ledger access - lockInfoHTLC := &common.AssetLockHTLC { + lockInfoHTLC := &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -753,9 +744,9 @@ func TestLockFungibleAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_DURATION, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock { + lockInfo := &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) _, err := interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) @@ -765,7 +756,7 @@ func TestLockFungibleAsset(t *testing.T) { // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) - lockInfoHTLC = &common.AssetLockHTLC { + lockInfoHTLC = &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -773,27 +764,27 @@ func TestLockFungibleAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ = proto.Marshal(lockInfoHTLC) - lockInfo = &common.AssetLock { + lockInfo = &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ = proto.Marshal(lockInfo) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with contractId already existing on the ledger - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfoVal, ExpiryTimeSecs: lockInfoHTLC.ExpiryTimeSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfoVal, ExpiryTimeSecs: lockInfoHTLC.ExpiryTimeSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " already exists for the requested fungible asset agreement") + require.EqualError(t, err, "contractId "+contractId+" already exists for the requested fungible asset agreement") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with PutState failing to write to the ledger @@ -801,7 +792,7 @@ func TestLockFungibleAsset(t *testing.T) { chaincodeStub.PutStateReturnsOnCall(0, fmt.Errorf("unable to write the fungible asset lock to the ledger for contractId %s", contractId)) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to write to the world state: unable to write the fungible asset lock to the ledger for contractId " + contractId) + require.EqualError(t, err, "failed to write to the world state: unable to write the fungible asset lock to the ledger for contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with fungible asset agreement specified properly @@ -820,22 +811,22 @@ func TestIsFungibleAssetLocked(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) isAssetLocked, err := interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -843,27 +834,27 @@ func TestIsFungibleAssetLocked(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(1, nil, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for query if fungible asset is locked with lock expiry time elapsed already - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "expiry time for fungible asset associated with contractId " + contractId + " is already elapsed") + require.EqualError(t, err, "expiry time for fungible asset associated with contractId "+contractId+" is already elapsed") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being queried using contractId - assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) @@ -881,26 +872,26 @@ func TestClaimFungibleAsset(t *testing.T) { recipient := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC { + claimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim { + claimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) @@ -908,43 +899,43 @@ func TestClaimFungibleAsset(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is not valid and there is no fungible asset locked with it chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for fungible asset claim exercised with expiry time elapsed already - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim fungible asset associated with contractId " + contractId + " as the expiry time is already elapsed") + require.EqualError(t, err, "cannot claim fungible asset associated with contractId "+contractId+" as the expiry time is already elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with claim information (i.e., preimage) not specified properly wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfo := &common.AssetClaimHTLC { + wrongClaimInfo := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(wrongClaimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim fungible asset associated with contractId " + contractId + " as the hash preimage is not matching") + require.EqualError(t, err, "cannot claim fungible asset associated with contractId "+contractId+" as the hash preimage is not matching") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -952,8 +943,8 @@ func TestClaimFungibleAsset(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of fungible asset claim: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of fungible asset claim: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being claimed using contractId @@ -978,55 +969,55 @@ func TestUnlockFungibleAsset(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is not valid and there is no fungible asset locked with it chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for fungible asset unlock exercised with expiry time not yet elapsed - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "cannot unlock fungible asset associated with the contractId " + contractId + " as the expiry time is not yet elapsed") + require.EqualError(t, err, "cannot unlock fungible asset associated with the contractId "+contractId+" as the expiry time is not yet elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId - assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of fungible asset unlock: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of fungible asset unlock: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with fungible asset being unlocked using contractId diff --git a/core/network/fabric-interop-cc/contracts/interop/setup_test.go b/core/network/fabric-interop-cc/contracts/interop/setup_test.go index ad17e2bbc..75e2dde06 100644 --- a/core/network/fabric-interop-cc/contracts/interop/setup_test.go +++ b/core/network/fabric-interop-cc/contracts/interop/setup_test.go @@ -13,11 +13,11 @@ import ( "os" "testing" + "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop/mocks" "github.com/hyperledger/fabric-chaincode-go/pkg/cid" "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-contract-api-go/contractapi" log "github.com/sirupsen/logrus" - "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop/mocks" ) const ( diff --git a/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go b/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go new file mode 100644 index 000000000..66b128faa --- /dev/null +++ b/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go @@ -0,0 +1,853 @@ +/* + * Copyright IBM Corp. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// manage_assets is a chaincode that contains all the code related to asset management operations (e.g., Lock, Unlock, Claim) +// and any related utility functions +package assetexchange + +import ( + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "strconv" + "time" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/hyperledger/fabric-contract-api-go/contractapi" + mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" + log "github.com/sirupsen/logrus" +) + +// Object used to capture the HashLock details used in Asset Locking +type HashLock struct { + HashBase64 string `json:"hashBase64"` +} + +// Object used in the map, --> (for non-fungible assets) +type AssetLockValue struct { + Locker string `json:"locker"` + Recipient string `json:"recipient"` + LockInfo interface{} `json:"lockInfo"` + ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` +} + +// Object used in the map, contractId --> (for fungible assets) +type FungibleAssetLockValue struct { + Type string `json:"type"` + NumUnits uint64 `json:"numUnits"` + Locker string `json:"locker"` + Recipient string `json:"recipient"` + LockInfo interface{} `json:"lockInfo"` + ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` +} + +const ( + assetKeyPrefix = "AssetKey_" // prefix for the map, asset-key --> asset-object + assetKeyDelimiter = "_" // delimiter for the asset-key + contractIdPrefix = "ContractId_" // prefix for the map, contractId --> asset-key +) + +// helper functions to log and return errors +func logThenErrorf(format string, args ...interface{}) error { + errorMsg := fmt.Sprintf(format, args...) + log.Error(errorMsg) + return errors.New(errorMsg) +} + +// function to generate a "SHA256" hash in base64 format for a given preimage +func GenerateSHA256HashInBase64Form(preimage string) string { + hasher := sha256.New() + hasher.Write([]byte(preimage)) + shaHash := hasher.Sum(nil) + shaHashBase64 := base64.StdEncoding.EncodeToString(shaHash) + return shaHashBase64 +} + +// function to return the key to fetch an element from the map using contractId +func generateContractIdMapKey(contractId string) string { + return contractIdPrefix + contractId +} + +/* + * Function to generate asset-lock key (which is combination of asset-type and asset-id) + * and contract-id (which is a hash on asset-lock key) for the non-fungible asset locking on the ledger + */ +func GenerateAssetLockKeyAndContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) (string, string, error) { + assetLockKey, err := ctx.GetStub().CreateCompositeKey("AssetExchangeContract", []string{assetAgreement.Type, assetAgreement.Id}) + if err != nil { + return "", "", logThenErrorf("error while creating composite key: %+v", err) + } + + contractId := GenerateSHA256HashInBase64Form(assetLockKey) + return assetLockKey, contractId, nil +} + +/* + * Function to generate contract-id for fungible asset-locking on the ledger (which is + * a hash on the attributes of the fungible asset exchange agreement) + */ +func GenerateFungibleAssetLockContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) string { + preimage := assetAgreement.Type + strconv.Itoa(int(assetAgreement.NumUnits)) + + assetAgreement.Locker + assetAgreement.Recipient + ctx.GetStub().GetTxID() + contractId := GenerateSHA256HashInBase64Form(preimage) + return contractId +} + +// function to get the caller identity from the transaction context +func getECertOfTxCreatorBase64(ctx contractapi.TransactionContextInterface) (string, error) { + + txCreatorBytes, err := ctx.GetStub().GetCreator() + if err != nil { + return "", logThenErrorf("unable to get the transaction creator information: %+v", err) + } + log.Infof("getECertOfTxCreatorBase64: TxCreator: %s", string(txCreatorBytes)) + + serializedIdentity := &mspProtobuf.SerializedIdentity{} + err = proto.Unmarshal(txCreatorBytes, serializedIdentity) + if err != nil { + return "", logThenErrorf("getECertOfTxCreatorBase64: unmarshal error: %+v", err) + } + log.Infof("getECertOfTxCreatorBase64: TxCreator ECert: %s", string(serializedIdentity.IdBytes)) + + eCertBytesBase64 := base64.StdEncoding.EncodeToString(serializedIdentity.IdBytes) + + return eCertBytesBase64, nil +} + +/* + * Function to validate the locker in asset agreement. + * If locker is not set, it will be set to the caller. + * If the locker is set already, it ensures that the locker is same as the creator of the transaction. + */ +func validateAndSetLockerOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Locker) == 0 { + assetAgreement.Locker = txCreatorECertBase64 + } else if assetAgreement.Locker != txCreatorECertBase64 { + return logThenErrorf("locker %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) + } + + return nil +} + +/* + * Function to validate the locker in fungible asset agreement. + * If locker is not set, it will be set to the caller. + * If the locker is set already, it ensures that the locker is same as the creator of the transaction. + */ +func validateAndSetLockerOfFungibleAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Locker) == 0 { + assetAgreement.Locker = txCreatorECertBase64 + } else if assetAgreement.Locker != txCreatorECertBase64 { + return logThenErrorf("locker %s in the fungible asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) + } + + return nil +} + +/* + * Function to validate the recipient in asset agreement. + * If recipient is not set, it will be set to the caller. + * If the recipeint is set already, it ensures that the recipient is same as the creator of the transaction. + */ +func validateAndSetRecipientOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Recipient) == 0 { + assetAgreement.Recipient = txCreatorECertBase64 + } else if assetAgreement.Recipient != txCreatorECertBase64 { + return logThenErrorf("recipient %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Recipient, txCreatorECertBase64) + } + + return nil +} + +func getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64 string) (interface{}, uint64, error) { + var lockInfoVal interface{} + var expiryTimeSecs uint64 + + lockInfoBytes, err := base64.StdEncoding.DecodeString(lockInfoBytesBase64) + if err != nil { + return lockInfoVal, 0, fmt.Errorf("error in base64 decode of lock information: %+v", err) + } + lockInfo := &common.AssetLock{} + err = proto.Unmarshal([]byte(lockInfoBytes), lockInfo) + if err != nil { + return lockInfoVal, 0, logThenErrorf(err.Error()) + } + + // process lock details here (lockInfo.LockInfo contains value based on the lock mechanism used) + if lockInfo.LockMechanism == common.LockMechanism_HTLC { + lockInfoHTLC := &common.AssetLockHTLC{} + err := proto.Unmarshal(lockInfo.LockInfo, lockInfoHTLC) + if err != nil { + return lockInfoVal, 0, logThenErrorf("unmarshal error: %s", err) + } + //display the passed hash lock information + log.Infof("lockInfoHTLC: %+v", lockInfoHTLC) + lockInfoVal = HashLock{HashBase64: string(lockInfoHTLC.HashBase64)} + // process time lock details here + if lockInfoHTLC.TimeSpec != common.AssetLockHTLC_EPOCH { + return lockInfoVal, 0, logThenErrorf("only EPOCH time is supported at present") + } + expiryTimeSecs = lockInfoHTLC.ExpiryTimeSecs + } else { + return lockInfoVal, 0, logThenErrorf("lock mechanism is not supported") + } + return lockInfoVal, expiryTimeSecs, nil +} + +// LockAsset cc is used to record locking of an asset on the ledger +func LockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return "", logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf("error in locker validation: %+v", err) + } + + lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockVal := AssetLockValue{Locker: assetAgreement.Locker, Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + if assetLockValBytes != nil { + return "", logThenErrorf("asset of type %s and ID %s is already locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockValBytes, err = json.Marshal(assetLockVal) + if err != nil { + return "", logThenErrorf("marshal error: %+v", err) + } + + err = ctx.GetStub().PutState(assetLockKey, assetLockValBytes) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockKeyBytes, err := json.Marshal(assetLockKey) + if err != nil { + return "", logThenErrorf("marshal error: %+v", err) + } + + err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockKeyBytes) + if err != nil { + return "", logThenErrorf(err.Error()) + } + return contractId, nil +} + +// UnlockAsset cc is used to record unlocking of an asset on the ledger +func UnlockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) error { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return logThenErrorf("error in validation of asset agreement parties: %+v", err) + } + + assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return logThenErrorf("unmarshal error: %s", err) + } + + if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return logThenErrorf("cannot unlock asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock asset of type %s and ID %s as the expiry time is not yet elapsed", assetAgreement.Type, assetAgreement.Id) + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) + } + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) + } + + return nil +} + +// IsAssetLocked cc is used to query the ledger and findout if an asset is locked or not +func IsAssetLocked(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) (bool, error) { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return false, logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return false, logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + assetLockKey, _, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return false, logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return false, logThenErrorf("unmarshal error: %s", err) + } + log.Infof("assetLockVal: %+v", assetLockVal) + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for asset of type %s and ID %s is already elapsed", assetAgreement.Type, assetAgreement.Id) + } + + // '*' for recipient or locker in the query implies that the query seeks status for an arbitrary recipient or locker respectively + if (assetAgreement.Locker == "*" || assetLockVal.Locker == assetAgreement.Locker) && (assetAgreement.Recipient == "*" || assetLockVal.Recipient == assetAgreement.Recipient) { + return true, nil + } else if assetAgreement.Locker == "*" && assetLockVal.Recipient != assetAgreement.Recipient { + return false, logThenErrorf("asset of type %s and ID %s is not locked for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Recipient) + } else if assetAgreement.Recipient == "*" && assetLockVal.Locker != assetAgreement.Locker { + return false, logThenErrorf("asset of type %s and ID %s is not locked by %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker) + } else if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return false, logThenErrorf("asset of type %s and ID %s is not locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker, assetAgreement.Recipient) + } + + return true, nil +} + +/* + * Function to check if hashBase64 is the hash for the preimage preimageBase64. + * Both the preimage and hash are passed in base64 form. + */ +func checkIfCorrectPreimage(preimageBase64 string, hashBase64 string) (bool, error) { + funName := "checkIfCorrectPreimage" + preimage, err := base64.StdEncoding.DecodeString(preimageBase64) + if err != nil { + return false, logThenErrorf("base64 decode preimage error: %s", err) + } + + shaHashBase64 := GenerateSHA256HashInBase64Form(string(preimage)) + if shaHashBase64 == hashBase64 { + log.Infof("%s: preimage %s is passed correctly", funName, preimage) + } else { + log.Infof("%s: preimage %s is not passed correctly", funName, preimage) + return false, nil + } + return true, nil +} + +func validateHashPreimage(claimInfo *common.AssetClaim, lockInfo interface{}) (bool, error) { + claimInfoHTLC := &common.AssetClaimHTLC{} + err := proto.Unmarshal(claimInfo.ClaimInfo, claimInfoHTLC) + if err != nil { + return false, logThenErrorf("unmarshal claimInfo.ClaimInfo error: %s", err) + } + //display the claim information + log.Infof("claimInfoHTLC: %+v\n", claimInfoHTLC) + lockInfoVal := HashLock{} + lockInfoBytes, err := json.Marshal(lockInfo) + if err != nil { + return false, logThenErrorf("marshal lockInfo error: %s", err) + } + err = json.Unmarshal(lockInfoBytes, &lockInfoVal) + if err != nil { + return false, logThenErrorf("unmarshal lockInfoBytes error: %s", err) + } + log.Infof("HashLock: %+v\n", lockInfoVal) + + // match the hash passed during claim with the hash stored during asset locking + return checkIfCorrectPreimage(string(claimInfoHTLC.HashPreimageBase64), lockInfoVal.HashBase64) +} + +// fetches common.AssetClaim from the input parameter and checks if the lock mechanism is valid or not +func getClaimInfo(claimInfoBytesBase64 string) (*common.AssetClaim, error) { + claimInfo := &common.AssetClaim{} + + claimInfoBytes, err := base64.StdEncoding.DecodeString(claimInfoBytesBase64) + if err != nil { + return claimInfo, logThenErrorf("error in base64 decode of claim information: %+v", err) + } + + err = proto.Unmarshal([]byte(claimInfoBytes), claimInfo) + if err != nil { + return claimInfo, logThenErrorf("unmarshal error: %s", err) + } + // check if a valid lock mechanism is provided + if claimInfo.LockMechanism != common.LockMechanism_HTLC { + return claimInfo, logThenErrorf("lock mechanism is not supported") + } + + return claimInfo, nil +} + +// ClaimAsset cc is used to record claim of an asset on the ledger +func ClaimAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, claimInfoBytesBase64 string) error { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + // display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v\n", assetAgreement) + + err = validateAndSetRecipientOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return logThenErrorf("error in recipient validation: %+v", err) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return logThenErrorf("unmarshal error: %s", err) + } + + if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return logThenErrorf("cannot claim asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim asset of type %s and ID %s as the expiry time is already elapsed", assetAgreement.Type, assetAgreement.Id) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim asset of type %s and ID %s error: %v", assetAgreement.Type, assetAgreement.Id, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim asset of type %s and ID %s as the hash preimage is not matching", assetAgreement.Type, assetAgreement.Id) + } + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) + } + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset claim: %v", contractId, err) + } + + return nil +} + +// function to fetch the asset-lock from the ledger using contractId +func fetchAssetLockedUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (string, AssetLockValue, error) { + var assetLockVal = AssetLockValue{} + var assetLockKey string = "" + assetLockKeyBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf(err.Error()) + } + + if assetLockKeyBytes == nil { + return assetLockKey, assetLockVal, logThenErrorf("no contractId %s exists on the ledger", contractId) + } + + err = json.Unmarshal(assetLockKeyBytes, &assetLockKey) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("assetLockKey unmarshal error: %s", err) + } + log.Infof("contractId: %s and assetLockKey: %s", contractId, assetLockKey) + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes == nil { + return assetLockKey, assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked asset", contractId) + } + + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("assetLockVal unmarshal error: %s", err) + } + return assetLockKey, assetLockVal, nil +} + +// UnlockAssetUsingContractId cc is used to record unlocking of an asset on the ledger (this uses the contractId) +func UnlockAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) error { + + assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the locker of the locked fungible asset + if assetLockVal.Locker != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %v", contractId, err) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) + } + + return nil +} + +// ClaimAsset cc is used to record claim of an asset on the ledger (this uses the contractId) +func ClaimAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { + + assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + if assetLockVal.Recipient != string(txCreatorECertBase64) { + return logThenErrorf("asset is not locked for %s to claim", string(txCreatorECertBase64)) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim asset associated with contractId %s as the expiry time is already elapsed", contractId) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim asset associated with contractId %s failed with error: %v", contractId, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim asset associated with contractId %s as the hash preimage is not matching", contractId) + } + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %+v", contractId, err) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset claim: %+v", contractId, err) + } + + return nil +} + +// IsAssetLocked cc is used to query the ledger and find out if an asset is locked or not (this uses the contractId) +func IsAssetLockedQueryUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { + + _, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for asset associated with contractId %s is already elapsed", contractId) + } + + return true, nil +} + +// LockFungibleAsset cc is used to record locking of a group of fungible assets of an asset-type on the ledger +func LockFungibleAsset(ctx contractapi.TransactionContextInterface, fungibleAssetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { + + fungibleAssetAgreementBytes, err := base64.StdEncoding.DecodeString(fungibleAssetAgreementBytesBase64) + if err != nil { + return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.FungibleAssetExchangeAgreement{} + err = proto.Unmarshal([]byte(fungibleAssetAgreementBytes), assetAgreement) + if err != nil { + return "", logThenErrorf("unmarshal error: %s", err) + } + + //display the requested fungible asset agreement + log.Infof("fungibleAssetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfFungibleAssetAgreement(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf("error in locker validation: %+v", err) + } + + lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + // generate the contractId for the fungible asset lock agreement + contractId := GenerateFungibleAssetLockContractId(ctx, assetAgreement) + + assetLockVal := FungibleAssetLockValue{Type: assetAgreement.Type, NumUnits: assetAgreement.NumUnits, Locker: assetAgreement.Locker, + Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} + + assetLockValBytes, err := ctx.GetStub().GetState(contractId) + if err != nil { + return "", logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes != nil { + return "", logThenErrorf("contractId %s already exists for the requested fungible asset agreement", contractId) + } + + assetLockValBytes, err = json.Marshal(assetLockVal) + if err != nil { + return "", logThenErrorf("marshal error: %s", err) + } + + err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockValBytes) + if err != nil { + return "", logThenErrorf("failed to write to the world state: %+v", err) + } + + return contractId, nil +} + +// function to fetch the fungible asset-lock value from the ledger using contractId +func fetchFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (FungibleAssetLockValue, error) { + var assetLockVal = FungibleAssetLockValue{} + + assetLockValBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) + if err != nil { + return assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes == nil { + return assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked fungible asset", contractId) + } + + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return assetLockVal, logThenErrorf("unmarshal error: %s", err) + } + log.Infof("contractId: %s and fungibleAssetLockVal: %+v", contractId, assetLockVal) + + return assetLockVal, nil +} + +// IsFungibleAssetLocked cc is used to query the ledger and find out if a fungible asset is locked or not +func IsFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for fungible asset associated with contractId %s is already elapsed", contractId) + } + + return true, nil +} + +// ClaimFungibleAsset cc is used to record claim of a fungible asset on the ledger +func ClaimFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the recipient of the locked fungible asset + if assetLockVal.Recipient != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to claim", txCreatorECertBase64) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim fungible asset associated with contractId %s as the expiry time is already elapsed", contractId) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim fungible asset associated with contractId %s failed with error: %v", contractId, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim fungible asset associated with contractId %s as the hash preimage is not matching", contractId) + } + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of fungible asset claim: %+v", contractId, err) + } + + return nil +} + +// UnlockFungibleAsset cc is used to record unlocking of a fungible asset on the ledger +func UnlockFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string) error { + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the locker of the locked fungible asset + if assetLockVal.Locker != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock fungible asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of fungible asset unlock: %v", contractId, err) + } + + return nil +} diff --git a/core/network/fabric-interop-cc/libs/assetexchange/go.mod b/core/network/fabric-interop-cc/libs/assetexchange/go.mod new file mode 100644 index 000000000..cddb0b62f --- /dev/null +++ b/core/network/fabric-interop-cc/libs/assetexchange/go.mod @@ -0,0 +1,11 @@ +module github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange + +go 1.16 + +require ( + github.com/golang/protobuf v1.5.2 + github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 + github.com/hyperledger/fabric-contract-api-go v1.1.1 + github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 + github.com/sirupsen/logrus v1.8.1 +) diff --git a/core/network/fabric-interop-cc/libs/assetexchange/go.sum b/core/network/fabric-interop-cc/libs/assetexchange/go.sum new file mode 100644 index 000000000..38b4d4d21 --- /dev/null +++ b/core/network/fabric-interop-cc/libs/assetexchange/go.sum @@ -0,0 +1,224 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2AZ5Ki+A= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= +github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= +github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= +github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= +github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= +github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hyperledger-labs/weaver-dlt-interoperability v0.0.0-20210722105253-d001e6a4f7ca h1:LXOVVO1+Q34rHdUpmphtYMYQSNj5HUgBh1FE9d3tmvI= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 h1:c9VK82wttYXTe4/UfnDq2Gq1Zu4Yxcxx1PbhEQHKuvA= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1/go.mod h1:yJq9oxxBHPryM8hVFiqM5HgfV2XFj5Tzb9Unx9D+YuI= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 h1:1i4lnpV8BDgKOLi1hgElfBqdHXjXieSuj8629mwBZ8o= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= +github.com/hyperledger/fabric-contract-api-go v1.1.1 h1:gDhOC18gjgElNZ85kFWsbCQq95hyUP/21n++m0Sv6B0= +github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= +github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 h1:d7do07Q4LaOFAEWceRwUwVDdcfx3BdLeZYyUGtbHfRk= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From e9e46063ab09a975e52487c0b39da35f7043b8a3 Mon Sep 17 00:00:00 2001 From: Krishnasuri Narayanam Date: Mon, 26 Jul 2021 14:48:23 +0530 Subject: [PATCH 2/7] Revert "changing asset exchange interop cc as package" This reverts commit 606905eedecefdf0f3f48d42300784883a0c8c11. --- .../contracts/interop/Makefile | 6 +- .../contracts/interop/go.mod | 20 +- .../contracts/interop/go.sum | 124 +-- .../contracts/interop/manage_assets.go | 808 ++++++++++++++++- .../contracts/interop/manage_assets_test.go | 397 ++++---- .../contracts/interop/setup_test.go | 2 +- .../libs/assetexchange/assetSwapContracts.go | 853 ------------------ .../libs/assetexchange/go.mod | 11 - .../libs/assetexchange/go.sum | 224 ----- 9 files changed, 1036 insertions(+), 1409 deletions(-) delete mode 100644 core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go delete mode 100644 core/network/fabric-interop-cc/libs/assetexchange/go.mod delete mode 100644 core/network/fabric-interop-cc/libs/assetexchange/go.sum diff --git a/core/network/fabric-interop-cc/contracts/interop/Makefile b/core/network/fabric-interop-cc/contracts/interop/Makefile index 85c20716a..00c5a2637 100644 --- a/core/network/fabric-interop-cc/contracts/interop/Makefile +++ b/core/network/fabric-interop-cc/contracts/interop/Makefile @@ -1,6 +1,2 @@ -assetexchange: - cp -r ../../libs/assetexchange . -test-manage-assets: assetexchange +test-manage-assets: go test manage_assets.go manage_assets_test.go main.go setup_test.go -v -clean: - rm -rf assetexchange diff --git a/core/network/fabric-interop-cc/contracts/interop/go.mod b/core/network/fabric-interop-cc/contracts/interop/go.mod index aaa68ab59..5a614f143 100644 --- a/core/network/fabric-interop-cc/contracts/interop/go.mod +++ b/core/network/fabric-interop-cc/contracts/interop/go.mod @@ -2,17 +2,15 @@ module github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabr go 1.16 -replace github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange => ./assetexchange - require ( - github.com/golang/protobuf v1.5.2 - github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 - github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange v0.0.0-00010101000000-000000000000 - github.com/hyperledger/fabric-chaincode-go v0.0.0-20210718160520-38d29fabecb9 - github.com/hyperledger/fabric-contract-api-go v1.1.1 - github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 - github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.5.1 - golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 + github.com/golang/protobuf v1.5.0 + github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v0.0.0-20210712215013-866f5840a1a9 + github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664 + github.com/hyperledger/fabric-contract-api-go v1.1.0 + github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31 + github.com/sirupsen/logrus v1.4.2 + github.com/stretchr/testify v1.6.1 + golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 google.golang.org/protobuf v1.27.1 + gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect ) diff --git a/core/network/fabric-interop-cc/contracts/interop/go.sum b/core/network/fabric-interop-cc/contracts/interop/go.sum index 507fc1d03..efe095cf7 100644 --- a/core/network/fabric-interop-cc/contracts/interop/go.sum +++ b/core/network/fabric-interop-cc/contracts/interop/go.sum @@ -1,18 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -21,14 +15,7 @@ github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2A github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -48,55 +35,41 @@ github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hyperledger-labs/weaver-dlt-interoperability v0.0.0-20210722105253-d001e6a4f7ca h1:LXOVVO1+Q34rHdUpmphtYMYQSNj5HUgBh1FE9d3tmvI= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 h1:c9VK82wttYXTe4/UfnDq2Gq1Zu4Yxcxx1PbhEQHKuvA= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1/go.mod h1:yJq9oxxBHPryM8hVFiqM5HgfV2XFj5Tzb9Unx9D+YuI= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v0.0.0-20210712215013-866f5840a1a9 h1:4nvDlDhPUpompAiPBuGMKRPc+H6DjptO4A0euMoLpT0= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v0.0.0-20210712215013-866f5840a1a9/go.mod h1:U3ly7uEA+YqJF+WItb0sGfOW1XsZT6S0pndUtHjBTgw= github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20210718160520-38d29fabecb9 h1:1cAZHHrBYFrX3bwQGhOZtOB4sCM9QWVppd81O8vsPXs= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20210718160520-38d29fabecb9/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-contract-api-go v1.1.1 h1:gDhOC18gjgElNZ85kFWsbCQq95hyUP/21n++m0Sv6B0= -github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664 h1:Pu/9SNpo71SJj5DGehCXOKD9QGQ3MsuWjpsLM9Mkdwg= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= +github.com/hyperledger/fabric-contract-api-go v1.1.0 h1:K9uucl/6eX3NF0/b+CGIiO1IPm1VYQxBkpnVGJur2S4= +github.com/hyperledger/fabric-contract-api-go v1.1.0/go.mod h1:nHWt0B45fK53owcFpLtAe8DH0Q5P068mnzkNXMPSL7E= github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31 h1:T/uwoFIUioDDLffuJ/XgMLOWCUcx95/xXidv5igafl8= github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 h1:d7do07Q4LaOFAEWceRwUwVDdcfx3BdLeZYyUGtbHfRk= -github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -107,15 +80,12 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -128,8 +98,9 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -138,99 +109,56 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A= golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ= golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/core/network/fabric-interop-cc/contracts/interop/manage_assets.go b/core/network/fabric-interop-cc/contracts/interop/manage_assets.go index f75c522c9..aecfab8ed 100644 --- a/core/network/fabric-interop-cc/contracts/interop/manage_assets.go +++ b/core/network/fabric-interop-cc/contracts/interop/manage_assets.go @@ -9,61 +9,845 @@ package main import ( - "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "strconv" + "time" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" "github.com/hyperledger/fabric-contract-api-go/contractapi" + mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" + log "github.com/sirupsen/logrus" ) +// Object used to capture the HashLock details used in Asset Locking +type HashLock struct { + HashBase64 string `json:"hashBase64"` +} + +// Object used in the map, --> (for non-fungible assets) +type AssetLockValue struct { + Locker string `json:"locker"` + Recipient string `json:"recipient"` + LockInfo interface{} `json:"lockInfo"` + ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` +} + +// Object used in the map, contractId --> (for fungible assets) +type FungibleAssetLockValue struct { + Type string `json:"type"` + NumUnits uint64 `json:"numUnits"` + Locker string `json:"locker"` + Recipient string `json:"recipient"` + LockInfo interface{} `json:"lockInfo"` + ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` +} + +const ( + assetKeyPrefix = "AssetKey_" // prefix for the map, asset-key --> asset-object + assetKeyDelimiter = "_" // delimiter for the asset-key + contractIdPrefix = "ContractId_" // prefix for the map, contractId --> asset-key +) + +// helper functions to log and return errors +func logThenErrorf(format string, args ...interface{}) error { + errorMsg := fmt.Sprintf(format, args...) + log.Error(errorMsg) + return errors.New(errorMsg) +} + +// function to generate a "SHA256" hash in base64 format for a given preimage +func generateSHA256HashInBase64Form(preimage string) string { + hasher := sha256.New() + hasher.Write([]byte(preimage)) + shaHash := hasher.Sum(nil) + shaHashBase64 := base64.StdEncoding.EncodeToString(shaHash) + return shaHashBase64 +} + +// function to return the key to fetch an element from the map using contractId +func generateContractIdMapKey(contractId string) string { + return contractIdPrefix + contractId +} + +/* + * Function to generate asset-lock key (which is combination of asset-type and asset-id) + * and contract-id (which is a hash on asset-lock key) for the non-fungible asset locking on the ledger + */ +func generateAssetLockKeyAndContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) (string, string, error) { + assetLockKey, err := ctx.GetStub().CreateCompositeKey("AssetExchangeContract", []string{assetAgreement.Type, assetAgreement.Id}) + if err != nil { + return "", "", logThenErrorf("error while creating composite key: %+v", err) + } + + contractId := generateSHA256HashInBase64Form(assetLockKey) + return assetLockKey, contractId, nil +} + +/* + * Function to generate contract-id for fungible asset-locking on the ledger (which is + * a hash on the attributes of the fungible asset exchange agreement) + */ +func generateFungibleAssetLockContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) string { + preimage := assetAgreement.Type + strconv.Itoa(int(assetAgreement.NumUnits)) + + assetAgreement.Locker + assetAgreement.Recipient + ctx.GetStub().GetTxID() + contractId := generateSHA256HashInBase64Form(preimage) + return contractId +} + +// function to get the caller identity from the transaction context +func getECertOfTxCreatorBase64(ctx contractapi.TransactionContextInterface) (string, error) { + + txCreatorBytes, err := ctx.GetStub().GetCreator() + if err != nil { + return "", logThenErrorf("unable to get the transaction creator information: %+v", err) + } + log.Infof("getECertOfTxCreatorBase64: TxCreator: %s", string(txCreatorBytes)) + + serializedIdentity := &mspProtobuf.SerializedIdentity{} + err = proto.Unmarshal(txCreatorBytes, serializedIdentity) + if err != nil { + return "", logThenErrorf("getECertOfTxCreatorBase64: unmarshal error: %+v", err) + } + log.Infof("getECertOfTxCreatorBase64: TxCreator ECert: %s", string(serializedIdentity.IdBytes)) + + eCertBytesBase64 := base64.StdEncoding.EncodeToString(serializedIdentity.IdBytes) + + return eCertBytesBase64, nil +} + +/* + * Function to validate the locker in asset agreement. + * If locker is not set, it will be set to the caller. + * If the locker is set already, it ensures that the locker is same as the creator of the transaction. + */ +func validateAndSetLockerOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Locker) == 0 { + assetAgreement.Locker = txCreatorECertBase64 + } else if assetAgreement.Locker != txCreatorECertBase64 { + return logThenErrorf("locker %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) + } + + return nil +} + +/* + * Function to validate the locker in fungible asset agreement. + * If locker is not set, it will be set to the caller. + * If the locker is set already, it ensures that the locker is same as the creator of the transaction. + */ +func validateAndSetLockerOfFungibleAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Locker) == 0 { + assetAgreement.Locker = txCreatorECertBase64 + } else if assetAgreement.Locker != txCreatorECertBase64 { + return logThenErrorf("locker %s in the fungible asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) + } + + return nil +} + +/* + * Function to validate the recipient in asset agreement. + * If recipient is not set, it will be set to the caller. + * If the recipeint is set already, it ensures that the recipient is same as the creator of the transaction. + */ +func validateAndSetRecipientOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Recipient) == 0 { + assetAgreement.Recipient = txCreatorECertBase64 + } else if assetAgreement.Recipient != txCreatorECertBase64 { + return logThenErrorf("recipient %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Recipient, txCreatorECertBase64) + } + + return nil +} + +func getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64 string) (interface{}, uint64, error) { + var lockInfoVal interface{} + var expiryTimeSecs uint64 + + lockInfoBytes, err := base64.StdEncoding.DecodeString(lockInfoBytesBase64) + if err != nil { + return lockInfoVal, 0, fmt.Errorf("error in base64 decode of lock information: %+v", err) + } + lockInfo := &common.AssetLock{} + err = proto.Unmarshal([]byte(lockInfoBytes), lockInfo) + if err != nil { + return lockInfoVal, 0, logThenErrorf(err.Error()) + } + + // process lock details here (lockInfo.LockInfo contains value based on the lock mechanism used) + if lockInfo.LockMechanism == common.LockMechanism_HTLC { + lockInfoHTLC := &common.AssetLockHTLC{} + err := proto.Unmarshal(lockInfo.LockInfo, lockInfoHTLC) + if err != nil { + return lockInfoVal, 0, logThenErrorf("unmarshal error: %s", err) + } + //display the passed hash lock information + log.Infof("lockInfoHTLC: %+v", lockInfoHTLC) + lockInfoVal = HashLock{HashBase64: string(lockInfoHTLC.HashBase64)} + // process time lock details here + if lockInfoHTLC.TimeSpec != common.AssetLockHTLC_EPOCH { + return lockInfoVal, 0, logThenErrorf("only EPOCH time is supported at present") + } + expiryTimeSecs = lockInfoHTLC.ExpiryTimeSecs + } else { + return lockInfoVal, 0, logThenErrorf("lock mechanism is not supported") + } + return lockInfoVal, expiryTimeSecs, nil +} + // LockAsset cc is used to record locking of an asset on the ledger func (s *SmartContract) LockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - return assetexchange.LockAsset(ctx, assetAgreementBytesBase64, lockInfoBytesBase64) + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return "", logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf("error in locker validation: %+v", err) + } + + lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockVal := AssetLockValue{Locker: assetAgreement.Locker, Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + if assetLockValBytes != nil { + return "", logThenErrorf("asset of type %s and ID %s is already locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockValBytes, err = json.Marshal(assetLockVal) + if err != nil { + return "", logThenErrorf("marshal error: %+v", err) + } + + err = ctx.GetStub().PutState(assetLockKey, assetLockValBytes) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockKeyBytes, err := json.Marshal(assetLockKey) + if err != nil { + return "", logThenErrorf("marshal error: %+v", err) + } + + err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockKeyBytes) + if err != nil { + return "", logThenErrorf(err.Error()) + } + return contractId, nil } // UnlockAsset cc is used to record unlocking of an asset on the ledger func (s *SmartContract) UnlockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) error { - return assetexchange.UnlockAsset(ctx, assetAgreementBytesBase64) + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return logThenErrorf("error in validation of asset agreement parties: %+v", err) + } + + assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return logThenErrorf("unmarshal error: %s", err) + } + + if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return logThenErrorf("cannot unlock asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock asset of type %s and ID %s as the expiry time is not yet elapsed", assetAgreement.Type, assetAgreement.Id) + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) + } + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) + } + + return nil } // IsAssetLocked cc is used to query the ledger and findout if an asset is locked or not func (s *SmartContract) IsAssetLocked(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) (bool, error) { - return assetexchange.IsAssetLocked(ctx, assetAgreementBytesBase64) + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return false, logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return false, logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + assetLockKey, _, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return false, logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return false, logThenErrorf("unmarshal error: %s", err) + } + log.Infof("assetLockVal: %+v", assetLockVal) + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for asset of type %s and ID %s is already elapsed", assetAgreement.Type, assetAgreement.Id) + } + + // '*' for recipient or locker in the query implies that the query seeks status for an arbitrary recipient or locker respectively + if (assetAgreement.Locker == "*" || assetLockVal.Locker == assetAgreement.Locker) && (assetAgreement.Recipient == "*" || assetLockVal.Recipient == assetAgreement.Recipient) { + return true, nil + } else if assetAgreement.Locker == "*" && assetLockVal.Recipient != assetAgreement.Recipient { + return false, logThenErrorf("asset of type %s and ID %s is not locked for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Recipient) + } else if assetAgreement.Recipient == "*" && assetLockVal.Locker != assetAgreement.Locker { + return false, logThenErrorf("asset of type %s and ID %s is not locked by %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker) + } else if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return false, logThenErrorf("asset of type %s and ID %s is not locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker, assetAgreement.Recipient) + } + + return true, nil +} + +/* + * Function to check if hashBase64 is the hash for the preimage preimageBase64. + * Both the preimage and hash are passed in base64 form. + */ +func checkIfCorrectPreimage(preimageBase64 string, hashBase64 string) (bool, error) { + funName := "checkIfCorrectPreimage" + preimage, err := base64.StdEncoding.DecodeString(preimageBase64) + if err != nil { + return false, logThenErrorf("base64 decode preimage error: %s", err) + } + + shaHashBase64 := generateSHA256HashInBase64Form(string(preimage)) + if shaHashBase64 == hashBase64 { + log.Infof("%s: preimage %s is passed correctly", funName, preimage) + } else { + log.Infof("%s: preimage %s is not passed correctly", funName, preimage) + return false, nil + } + return true, nil +} + +func validateHashPreimage(claimInfo *common.AssetClaim, lockInfo interface{}) (bool, error) { + claimInfoHTLC := &common.AssetClaimHTLC{} + err := proto.Unmarshal(claimInfo.ClaimInfo, claimInfoHTLC) + if err != nil { + return false, logThenErrorf("unmarshal claimInfo.ClaimInfo error: %s", err) + } + //display the claim information + log.Infof("claimInfoHTLC: %+v\n", claimInfoHTLC) + lockInfoVal := HashLock{} + lockInfoBytes, err := json.Marshal(lockInfo) + if err != nil { + return false, logThenErrorf("marshal lockInfo error: %s", err) + } + err = json.Unmarshal(lockInfoBytes, &lockInfoVal) + if err != nil { + return false, logThenErrorf("unmarshal lockInfoBytes error: %s", err) + } + log.Infof("HashLock: %+v\n", lockInfoVal) + + // match the hash passed during claim with the hash stored during asset locking + return checkIfCorrectPreimage(string(claimInfoHTLC.HashPreimageBase64), lockInfoVal.HashBase64) +} + +// fetches common.AssetClaim from the input parameter and checks if the lock mechanism is valid or not +func getClaimInfo(claimInfoBytesBase64 string) (*common.AssetClaim, error) { + claimInfo := &common.AssetClaim{} + + claimInfoBytes, err := base64.StdEncoding.DecodeString(claimInfoBytesBase64) + if err != nil { + return claimInfo, logThenErrorf("error in base64 decode of claim information: %+v", err) + } + + err = proto.Unmarshal([]byte(claimInfoBytes), claimInfo) + if err != nil { + return claimInfo, logThenErrorf("unmarshal error: %s", err) + } + // check if a valid lock mechanism is provided + if claimInfo.LockMechanism != common.LockMechanism_HTLC { + return claimInfo, logThenErrorf("lock mechanism is not supported") + } + + return claimInfo, nil } // ClaimAsset cc is used to record claim of an asset on the ledger func (s *SmartContract) ClaimAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, claimInfoBytesBase64 string) error { - return assetexchange.ClaimAsset(ctx, assetAgreementBytesBase64, claimInfoBytesBase64) + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + // display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v\n", assetAgreement) + + err = validateAndSetRecipientOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return logThenErrorf("error in recipient validation: %+v", err) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return logThenErrorf("unmarshal error: %s", err) + } + + if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return logThenErrorf("cannot claim asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim asset of type %s and ID %s as the expiry time is already elapsed", assetAgreement.Type, assetAgreement.Id) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim asset of type %s and ID %s error: %v", assetAgreement.Type, assetAgreement.Id, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim asset of type %s and ID %s as the hash preimage is not matching", assetAgreement.Type, assetAgreement.Id) + } + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) + } + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset claim: %v", contractId, err) + } + + return nil +} + +// function to fetch the asset-lock from the ledger using contractId +func fetchAssetLockedUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (string, AssetLockValue, error) { + var assetLockVal = AssetLockValue{} + var assetLockKey string = "" + assetLockKeyBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf(err.Error()) + } + + if assetLockKeyBytes == nil { + return assetLockKey, assetLockVal, logThenErrorf("no contractId %s exists on the ledger", contractId) + } + + err = json.Unmarshal(assetLockKeyBytes, &assetLockKey) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("assetLockKey unmarshal error: %s", err) + } + log.Infof("contractId: %s and assetLockKey: %s", contractId, assetLockKey) + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes == nil { + return assetLockKey, assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked asset", contractId) + } + + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("assetLockVal unmarshal error: %s", err) + } + return assetLockKey, assetLockVal, nil } // UnlockAssetUsingContractId cc is used to record unlocking of an asset on the ledger (this uses the contractId) func (s *SmartContract) UnlockAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) error { - return assetexchange.UnlockAssetUsingContractId(ctx, contractId) + + assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the locker of the locked fungible asset + if assetLockVal.Locker != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %v", contractId, err) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) + } + + return nil } // ClaimAsset cc is used to record claim of an asset on the ledger (this uses the contractId) func (s *SmartContract) ClaimAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - return assetexchange.ClaimAssetUsingContractId(ctx, contractId, claimInfoBytesBase64) + + assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + if assetLockVal.Recipient != string(txCreatorECertBase64) { + return logThenErrorf("asset is not locked for %s to claim", string(txCreatorECertBase64)) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim asset associated with contractId %s as the expiry time is already elapsed", contractId) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim asset associated with contractId %s failed with error: %v", contractId, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim asset associated with contractId %s as the hash preimage is not matching", contractId) + } + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %+v", contractId, err) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset claim: %+v", contractId, err) + } + + return nil } // IsAssetLocked cc is used to query the ledger and find out if an asset is locked or not (this uses the contractId) func (s *SmartContract) IsAssetLockedQueryUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - return assetexchange.IsAssetLockedQueryUsingContractId(ctx, contractId) + + _, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for asset associated with contractId %s is already elapsed", contractId) + } + + return true, nil } // LockFungibleAsset cc is used to record locking of a group of fungible assets of an asset-type on the ledger func (s *SmartContract) LockFungibleAsset(ctx contractapi.TransactionContextInterface, fungibleAssetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - return assetexchange.LockFungibleAsset(ctx, fungibleAssetAgreementBytesBase64, lockInfoBytesBase64) + + fungibleAssetAgreementBytes, err := base64.StdEncoding.DecodeString(fungibleAssetAgreementBytesBase64) + if err != nil { + return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.FungibleAssetExchangeAgreement{} + err = proto.Unmarshal([]byte(fungibleAssetAgreementBytes), assetAgreement) + if err != nil { + return "", logThenErrorf("unmarshal error: %s", err) + } + + //display the requested fungible asset agreement + log.Infof("fungibleAssetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfFungibleAssetAgreement(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf("error in locker validation: %+v", err) + } + + lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + // generate the contractId for the fungible asset lock agreement + contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + + assetLockVal := FungibleAssetLockValue{Type: assetAgreement.Type, NumUnits: assetAgreement.NumUnits, Locker: assetAgreement.Locker, + Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} + + assetLockValBytes, err := ctx.GetStub().GetState(contractId) + if err != nil { + return "", logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes != nil { + return "", logThenErrorf("contractId %s already exists for the requested fungible asset agreement", contractId) + } + + assetLockValBytes, err = json.Marshal(assetLockVal) + if err != nil { + return "", logThenErrorf("marshal error: %s", err) + } + + err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockValBytes) + if err != nil { + return "", logThenErrorf("failed to write to the world state: %+v", err) + } + + return contractId, nil +} + +// function to fetch the fungible asset-lock value from the ledger using contractId +func fetchFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (FungibleAssetLockValue, error) { + var assetLockVal = FungibleAssetLockValue{} + + assetLockValBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) + if err != nil { + return assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes == nil { + return assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked fungible asset", contractId) + } + + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return assetLockVal, logThenErrorf("unmarshal error: %s", err) + } + log.Infof("contractId: %s and fungibleAssetLockVal: %+v", contractId, assetLockVal) + + return assetLockVal, nil } // IsFungibleAssetLocked cc is used to query the ledger and find out if a fungible asset is locked or not func (s *SmartContract) IsFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - return assetexchange.IsFungibleAssetLocked(ctx, contractId) + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for fungible asset associated with contractId %s is already elapsed", contractId) + } + + return true, nil } // ClaimFungibleAsset cc is used to record claim of a fungible asset on the ledger func (s *SmartContract) ClaimFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - return assetexchange.ClaimFungibleAsset(ctx, contractId, claimInfoBytesBase64) + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the recipient of the locked fungible asset + if assetLockVal.Recipient != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to claim", txCreatorECertBase64) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim fungible asset associated with contractId %s as the expiry time is already elapsed", contractId) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim fungible asset associated with contractId %s failed with error: %v", contractId, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim fungible asset associated with contractId %s as the hash preimage is not matching", contractId) + } + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of fungible asset claim: %+v", contractId, err) + } + + return nil } // UnlockFungibleAsset cc is used to record unlocking of a fungible asset on the ledger func (s *SmartContract) UnlockFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string) error { - return assetexchange.UnlockFungibleAsset(ctx, contractId) + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the locker of the locked fungible asset + if assetLockVal.Locker != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock fungible asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of fungible asset unlock: %v", contractId, err) + } + + return nil } diff --git a/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go b/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go index d06d8fa8f..26acecdc8 100644 --- a/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go +++ b/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go @@ -7,23 +7,22 @@ package main import ( - "encoding/base64" "encoding/json" "fmt" "testing" - + "encoding/base64" + //"encoding/hex" "time" + "github.com/stretchr/testify/require" "github.com/golang/protobuf/proto" - "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" - "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange" mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" + "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" ) -const ( - defaultTimeLockSecs = 5 * 60 // 5 minutes +const( + defaultTimeLockSecs = 5 * 60 // 5 minutes ) // function that supplies value that is to be returned by ctx.GetStub().GetCreator() @@ -52,28 +51,28 @@ func TestLockAsset(t *testing.T) { recipient := "Bob" locker := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - lockInfoHTLC := &common.AssetLockHTLC{ + lockInfoHTLC := &common.AssetLockHTLC { HashBase64: []byte(hashBase64), // lock for next 5 minutes ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, - TimeSpec: common.AssetLockHTLC_EPOCH, + TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock{ + lockInfo := &common.AssetLock { LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) - assetAgreement := &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) @@ -84,7 +83,7 @@ func TestLockAsset(t *testing.T) { require.NoError(t, err) fmt.Println("Test success as expected since the agreement and lock information are speccified properly") - assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient} + assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure by trying to lock an asset that is already locked @@ -93,7 +92,7 @@ func TestLockAsset(t *testing.T) { log.Info(fmt.Println("Test failed as expected with error:", err)) // no need to set chaincodeStub.GetStateReturns below since the error is hit before GetState() ledger access in LockAsset() - lockInfoHTLC = &common.AssetLockHTLC{ + lockInfoHTLC = &common.AssetLockHTLC { HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -101,9 +100,9 @@ func TestLockAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_DURATION, } lockInfoHTLCBytes, _ = proto.Marshal(lockInfoHTLC) - lockInfo = &common.AssetLock{ + lockInfo = &common.AssetLock { LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ = proto.Marshal(lockInfo) // Test failure with lock information not specified properly @@ -120,28 +119,28 @@ func TestUnlockAsset(t *testing.T) { recipient := "Bob" locker := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - lockInfoHTLC := &common.AssetLockHTLC{ + lockInfoHTLC := &common.AssetLockHTLC { HashBase64: []byte(hashBase64), // lock for sometime in the past for testing UnlockAsset functionality ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs, - TimeSpec: common.AssetLockHTLC_EPOCH, + TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock{ + lockInfo := &common.AssetLock { LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) - assetAgreement := &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) @@ -152,7 +151,7 @@ func TestUnlockAsset(t *testing.T) { require.NoError(t, err) log.Info(fmt.Println("Completed locking an asset. Proceed to test unlock asset.")) - assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient} + assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test success with asset agreement specified properly @@ -167,7 +166,7 @@ func TestUnlockAsset(t *testing.T) { log.Info(fmt.Println("Test failed as expected with error:", err)) // Assume that the asset is locked by Alice for Bob; then trying to unlock the asset by Alice for Charlie should fail since the locking is done for a different recipient - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: "Charlie"} + assetLockVal = AssetLockValue{Locker: locker, Recipient: "Charlie"} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset id being locked for a different @@ -175,11 +174,12 @@ func TestUnlockAsset(t *testing.T) { require.Error(t, err) log.Info(fmt.Println("Test failed as expected with error:", err)) - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + + hashLock := HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock // lock for sometime in the future for testing UnlockAsset functionality - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure of unlock asset with expiry time not yet elapsed @@ -197,15 +197,16 @@ func TestIsAssetLocked(t *testing.T) { locker := "Alice" currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: "Charlie"} + + assetLockVal := AssetLockValue{Locker: locker, Recipient: "Charlie"} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset agreement not specified properly @@ -214,7 +215,8 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test success with asset agreement specified properly @@ -223,7 +225,8 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified properly.")) - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with expiry time elapsed already @@ -232,7 +235,8 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - assetLockVal = assetexchange.AssetLockValue{Locker: "Dave", Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + + assetLockVal = AssetLockValue{Locker: "Dave", Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset agreement not specified properly @@ -241,9 +245,10 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - assetAgreement = &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + + assetAgreement = &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, // arbitrary locker specification Locker: "*", @@ -255,9 +260,10 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified to include arbitrary locker.")) - assetAgreement = &common.AssetExchangeAgreement{ + + assetAgreement = &common.AssetExchangeAgreement { Type: assetType, - Id: assetId, + Id: assetId, // wrong recipient specification Recipient: "Charlie", // arbitrary locker specification @@ -270,12 +276,13 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - assetAgreement = &common.AssetExchangeAgreement{ + + assetAgreement = &common.AssetExchangeAgreement { Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", - Locker: "Dave", + Locker: "Dave", } assetAgreementBytes, _ = proto.Marshal(assetAgreement) // Test success with asset agreement specified to include arbitrary recipient @@ -284,9 +291,10 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified to include arbitrary recipient.")) - assetAgreement = &common.AssetExchangeAgreement{ + + assetAgreement = &common.AssetExchangeAgreement { Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", // wrong locker specification @@ -299,9 +307,10 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - assetAgreement = &common.AssetExchangeAgreement{ + + assetAgreement = &common.AssetExchangeAgreement { Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", // arbitrary locker specification @@ -323,33 +332,33 @@ func TestClaimAsset(t *testing.T) { recipient := getTxCreatorECertBase64() locker := "Alice" preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC{ + claimInfoHTLC := &common.AssetClaimHTLC { HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim{ + claimInfo := &common.AssetClaim { LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) @@ -358,7 +367,7 @@ func TestClaimAsset(t *testing.T) { require.NoError(t, err) log.Info(fmt.Println("Test success as expected since the asset agreement and claim information are specified properly.")) - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with expiry time elapsed to claim the asset @@ -368,17 +377,17 @@ func TestClaimAsset(t *testing.T) { wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfoHTLC := &common.AssetClaimHTLC{ + wrongClaimInfoHTLC := &common.AssetClaimHTLC { HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoHTLCBytes, _ := proto.Marshal(wrongClaimInfoHTLC) - wrongClaimInfo := &common.AssetClaim{ + wrongClaimInfo := &common.AssetClaim { LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: wrongClaimInfoHTLCBytes, + ClaimInfo: wrongClaimInfoHTLCBytes, } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with claim information (i.e., preimage) not specified properly @@ -414,30 +423,30 @@ func TestUnlockAssetUsingContractId(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId "+contractId) + require.EqualError(t, err, "unable to retrieve contractId " + contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with not a valid contractId being passed as the arguement chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") + require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with GetState(assetLockKey) fail to read from the world state @@ -446,7 +455,7 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is valid but there is no asset locked with the assetLockKey @@ -454,32 +463,32 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") + require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for asset unlock exercised with expiry time not yet elapsed chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "cannot unlock asset associated with the contractId "+contractId+" as the expiry time is not yet elapsed") + require.EqualError(t, err, "cannot unlock asset associated with the contractId " + contractId + " as the expiry time is not yet elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on assetLockKey chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete asset with key %s from world state", assetLockKey)) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId "+ - contractId+": unable to delete asset with key "+assetLockKey+" from world state") + require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId " + + contractId + ": unable to delete asset with key " + assetLockKey + " from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -489,8 +498,8 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(2, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId "+ - contractId+" as part of asset unlock: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId " + + contractId + " as part of asset unlock: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being unlocked using contractId @@ -512,26 +521,26 @@ func TestClaimAssetUsingContractId(t *testing.T) { recipient := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC{ + claimInfoHTLC := &common.AssetClaimHTLC { HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim{ + claimInfo := &common.AssetClaim { LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) @@ -539,14 +548,14 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId "+contractId) + require.EqualError(t, err, "unable to retrieve contractId " + contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with not a valid contractId being passed as the arguement chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") + require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with GetState(assetLockKey) fail to read from the world state @@ -555,7 +564,7 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is valid but there is no asset locked with the assetLockKey @@ -563,42 +572,42 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") + require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for asset claim exercised with expiry time elapsed already chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim asset associated with contractId "+contractId+" as the expiry time is already elapsed") + require.EqualError(t, err, "cannot claim asset associated with contractId " + contractId + " as the expiry time is already elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with claim information (i.e., preimage) not specified properly chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfoHTLC := &common.AssetClaimHTLC{ + wrongClaimInfoHTLC := &common.AssetClaimHTLC { HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoHTLCBytes, _ := proto.Marshal(wrongClaimInfoHTLC) - wrongClaimInfo := &common.AssetClaim{ + wrongClaimInfo := &common.AssetClaim { LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: wrongClaimInfoHTLCBytes, + ClaimInfo: wrongClaimInfoHTLCBytes, } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(wrongClaimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim asset associated with contractId "+contractId+" as the hash preimage is not matching") + require.EqualError(t, err, "cannot claim asset associated with contractId " + contractId + " as the hash preimage is not matching") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on assetLockKey @@ -607,8 +616,8 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete asset with key %s from world state", assetLockKey)) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId "+ - contractId+": unable to delete asset with key "+assetLockKey+" from world state") + require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId " + + contractId + ": unable to delete asset with key " + assetLockKey + " from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -618,8 +627,8 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(2, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId "+ - contractId+" as part of asset claim: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId " + + contractId + " as part of asset claim: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being claimed using contractId @@ -641,22 +650,22 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.AssetExchangeAgreement{ - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement { + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) isAssetLocked, err := interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId "+contractId) + require.EqualError(t, err, "unable to retrieve contractId " + contractId) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -664,7 +673,7 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(1, nil, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") + require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -674,7 +683,7 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -683,27 +692,27 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") + require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for query if asset is locked with lock expiry time elapsed already chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "expiry time for asset associated with contractId "+contractId+" is already elapsed") + require.EqualError(t, err, "expiry time for asset associated with contractId " + contractId + " is already elapsed") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being queried using contractId chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) - assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) @@ -721,22 +730,22 @@ func TestLockFungibleAsset(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.FungibleAssetExchangeAgreement{ - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement { + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) // Test failure with TimeSpec that is part of lock information not being currently supported // no need to set chaincodeStub.GetStateReturns below since the error is hit before GetState() ledger access - lockInfoHTLC := &common.AssetLockHTLC{ + lockInfoHTLC := &common.AssetLockHTLC { HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -744,9 +753,9 @@ func TestLockFungibleAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_DURATION, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock{ + lockInfo := &common.AssetLock { LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) _, err := interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) @@ -756,7 +765,7 @@ func TestLockFungibleAsset(t *testing.T) { // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) - lockInfoHTLC = &common.AssetLockHTLC{ + lockInfoHTLC = &common.AssetLockHTLC { HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -764,27 +773,27 @@ func TestLockFungibleAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ = proto.Marshal(lockInfoHTLC) - lockInfo = &common.AssetLock{ + lockInfo = &common.AssetLock { LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ = proto.Marshal(lockInfo) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with contractId already existing on the ledger - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfoVal, ExpiryTimeSecs: lockInfoHTLC.ExpiryTimeSecs} + assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfoVal, ExpiryTimeSecs: lockInfoHTLC.ExpiryTimeSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId "+contractId+" already exists for the requested fungible asset agreement") + require.EqualError(t, err, "contractId " + contractId + " already exists for the requested fungible asset agreement") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with PutState failing to write to the ledger @@ -792,7 +801,7 @@ func TestLockFungibleAsset(t *testing.T) { chaincodeStub.PutStateReturnsOnCall(0, fmt.Errorf("unable to write the fungible asset lock to the ledger for contractId %s", contractId)) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to write to the world state: unable to write the fungible asset lock to the ledger for contractId "+contractId) + require.EqualError(t, err, "failed to write to the world state: unable to write the fungible asset lock to the ledger for contractId " + contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with fungible asset agreement specified properly @@ -811,22 +820,22 @@ func TestIsFungibleAssetLocked(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.FungibleAssetExchangeAgreement{ - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement { + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) isAssetLocked, err := interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -834,27 +843,27 @@ func TestIsFungibleAssetLocked(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(1, nil, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for query if fungible asset is locked with lock expiry time elapsed already - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "expiry time for fungible asset associated with contractId "+contractId+" is already elapsed") + require.EqualError(t, err, "expiry time for fungible asset associated with contractId " + contractId + " is already elapsed") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being queried using contractId - assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) @@ -872,26 +881,26 @@ func TestClaimFungibleAsset(t *testing.T) { recipient := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.FungibleAssetExchangeAgreement{ - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement { + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC{ + claimInfoHTLC := &common.AssetClaimHTLC { HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim{ + claimInfo := &common.AssetClaim { LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) @@ -899,43 +908,43 @@ func TestClaimFungibleAsset(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is not valid and there is no fungible asset locked with it chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for fungible asset claim exercised with expiry time elapsed already - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim fungible asset associated with contractId "+contractId+" as the expiry time is already elapsed") + require.EqualError(t, err, "cannot claim fungible asset associated with contractId " + contractId + " as the expiry time is already elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with claim information (i.e., preimage) not specified properly wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfo := &common.AssetClaimHTLC{ + wrongClaimInfo := &common.AssetClaimHTLC { HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(wrongClaimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim fungible asset associated with contractId "+contractId+" as the hash preimage is not matching") + require.EqualError(t, err, "cannot claim fungible asset associated with contractId " + contractId + " as the hash preimage is not matching") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -943,8 +952,8 @@ func TestClaimFungibleAsset(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId "+ - contractId+" as part of fungible asset claim: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId " + + contractId + " as part of fungible asset claim: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being claimed using contractId @@ -969,55 +978,55 @@ func TestUnlockFungibleAsset(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) + hashBase64 := generateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.FungibleAssetExchangeAgreement{ - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement { + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is not valid and there is no fungible asset locked with it chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for fungible asset unlock exercised with expiry time not yet elapsed - hashLock := assetexchange.HashLock{HashBase64: hashBase64} + hashLock := HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "cannot unlock fungible asset associated with the contractId "+contractId+" as the expiry time is not yet elapsed") + require.EqualError(t, err, "cannot unlock fungible asset associated with the contractId " + contractId + " as the expiry time is not yet elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId - assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId "+ - contractId+" as part of fungible asset unlock: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId " + + contractId + " as part of fungible asset unlock: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with fungible asset being unlocked using contractId diff --git a/core/network/fabric-interop-cc/contracts/interop/setup_test.go b/core/network/fabric-interop-cc/contracts/interop/setup_test.go index 75e2dde06..ad17e2bbc 100644 --- a/core/network/fabric-interop-cc/contracts/interop/setup_test.go +++ b/core/network/fabric-interop-cc/contracts/interop/setup_test.go @@ -13,11 +13,11 @@ import ( "os" "testing" - "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop/mocks" "github.com/hyperledger/fabric-chaincode-go/pkg/cid" "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-contract-api-go/contractapi" log "github.com/sirupsen/logrus" + "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop/mocks" ) const ( diff --git a/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go b/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go deleted file mode 100644 index 66b128faa..000000000 --- a/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Copyright IBM Corp. All Rights Reserved. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -// manage_assets is a chaincode that contains all the code related to asset management operations (e.g., Lock, Unlock, Claim) -// and any related utility functions -package assetexchange - -import ( - "crypto/sha256" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "strconv" - "time" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" - "github.com/hyperledger/fabric-contract-api-go/contractapi" - mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" - log "github.com/sirupsen/logrus" -) - -// Object used to capture the HashLock details used in Asset Locking -type HashLock struct { - HashBase64 string `json:"hashBase64"` -} - -// Object used in the map, --> (for non-fungible assets) -type AssetLockValue struct { - Locker string `json:"locker"` - Recipient string `json:"recipient"` - LockInfo interface{} `json:"lockInfo"` - ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` -} - -// Object used in the map, contractId --> (for fungible assets) -type FungibleAssetLockValue struct { - Type string `json:"type"` - NumUnits uint64 `json:"numUnits"` - Locker string `json:"locker"` - Recipient string `json:"recipient"` - LockInfo interface{} `json:"lockInfo"` - ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` -} - -const ( - assetKeyPrefix = "AssetKey_" // prefix for the map, asset-key --> asset-object - assetKeyDelimiter = "_" // delimiter for the asset-key - contractIdPrefix = "ContractId_" // prefix for the map, contractId --> asset-key -) - -// helper functions to log and return errors -func logThenErrorf(format string, args ...interface{}) error { - errorMsg := fmt.Sprintf(format, args...) - log.Error(errorMsg) - return errors.New(errorMsg) -} - -// function to generate a "SHA256" hash in base64 format for a given preimage -func GenerateSHA256HashInBase64Form(preimage string) string { - hasher := sha256.New() - hasher.Write([]byte(preimage)) - shaHash := hasher.Sum(nil) - shaHashBase64 := base64.StdEncoding.EncodeToString(shaHash) - return shaHashBase64 -} - -// function to return the key to fetch an element from the map using contractId -func generateContractIdMapKey(contractId string) string { - return contractIdPrefix + contractId -} - -/* - * Function to generate asset-lock key (which is combination of asset-type and asset-id) - * and contract-id (which is a hash on asset-lock key) for the non-fungible asset locking on the ledger - */ -func GenerateAssetLockKeyAndContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) (string, string, error) { - assetLockKey, err := ctx.GetStub().CreateCompositeKey("AssetExchangeContract", []string{assetAgreement.Type, assetAgreement.Id}) - if err != nil { - return "", "", logThenErrorf("error while creating composite key: %+v", err) - } - - contractId := GenerateSHA256HashInBase64Form(assetLockKey) - return assetLockKey, contractId, nil -} - -/* - * Function to generate contract-id for fungible asset-locking on the ledger (which is - * a hash on the attributes of the fungible asset exchange agreement) - */ -func GenerateFungibleAssetLockContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) string { - preimage := assetAgreement.Type + strconv.Itoa(int(assetAgreement.NumUnits)) + - assetAgreement.Locker + assetAgreement.Recipient + ctx.GetStub().GetTxID() - contractId := GenerateSHA256HashInBase64Form(preimage) - return contractId -} - -// function to get the caller identity from the transaction context -func getECertOfTxCreatorBase64(ctx contractapi.TransactionContextInterface) (string, error) { - - txCreatorBytes, err := ctx.GetStub().GetCreator() - if err != nil { - return "", logThenErrorf("unable to get the transaction creator information: %+v", err) - } - log.Infof("getECertOfTxCreatorBase64: TxCreator: %s", string(txCreatorBytes)) - - serializedIdentity := &mspProtobuf.SerializedIdentity{} - err = proto.Unmarshal(txCreatorBytes, serializedIdentity) - if err != nil { - return "", logThenErrorf("getECertOfTxCreatorBase64: unmarshal error: %+v", err) - } - log.Infof("getECertOfTxCreatorBase64: TxCreator ECert: %s", string(serializedIdentity.IdBytes)) - - eCertBytesBase64 := base64.StdEncoding.EncodeToString(serializedIdentity.IdBytes) - - return eCertBytesBase64, nil -} - -/* - * Function to validate the locker in asset agreement. - * If locker is not set, it will be set to the caller. - * If the locker is set already, it ensures that the locker is same as the creator of the transaction. - */ -func validateAndSetLockerOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Locker) == 0 { - assetAgreement.Locker = txCreatorECertBase64 - } else if assetAgreement.Locker != txCreatorECertBase64 { - return logThenErrorf("locker %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) - } - - return nil -} - -/* - * Function to validate the locker in fungible asset agreement. - * If locker is not set, it will be set to the caller. - * If the locker is set already, it ensures that the locker is same as the creator of the transaction. - */ -func validateAndSetLockerOfFungibleAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Locker) == 0 { - assetAgreement.Locker = txCreatorECertBase64 - } else if assetAgreement.Locker != txCreatorECertBase64 { - return logThenErrorf("locker %s in the fungible asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) - } - - return nil -} - -/* - * Function to validate the recipient in asset agreement. - * If recipient is not set, it will be set to the caller. - * If the recipeint is set already, it ensures that the recipient is same as the creator of the transaction. - */ -func validateAndSetRecipientOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Recipient) == 0 { - assetAgreement.Recipient = txCreatorECertBase64 - } else if assetAgreement.Recipient != txCreatorECertBase64 { - return logThenErrorf("recipient %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Recipient, txCreatorECertBase64) - } - - return nil -} - -func getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64 string) (interface{}, uint64, error) { - var lockInfoVal interface{} - var expiryTimeSecs uint64 - - lockInfoBytes, err := base64.StdEncoding.DecodeString(lockInfoBytesBase64) - if err != nil { - return lockInfoVal, 0, fmt.Errorf("error in base64 decode of lock information: %+v", err) - } - lockInfo := &common.AssetLock{} - err = proto.Unmarshal([]byte(lockInfoBytes), lockInfo) - if err != nil { - return lockInfoVal, 0, logThenErrorf(err.Error()) - } - - // process lock details here (lockInfo.LockInfo contains value based on the lock mechanism used) - if lockInfo.LockMechanism == common.LockMechanism_HTLC { - lockInfoHTLC := &common.AssetLockHTLC{} - err := proto.Unmarshal(lockInfo.LockInfo, lockInfoHTLC) - if err != nil { - return lockInfoVal, 0, logThenErrorf("unmarshal error: %s", err) - } - //display the passed hash lock information - log.Infof("lockInfoHTLC: %+v", lockInfoHTLC) - lockInfoVal = HashLock{HashBase64: string(lockInfoHTLC.HashBase64)} - // process time lock details here - if lockInfoHTLC.TimeSpec != common.AssetLockHTLC_EPOCH { - return lockInfoVal, 0, logThenErrorf("only EPOCH time is supported at present") - } - expiryTimeSecs = lockInfoHTLC.ExpiryTimeSecs - } else { - return lockInfoVal, 0, logThenErrorf("lock mechanism is not supported") - } - return lockInfoVal, expiryTimeSecs, nil -} - -// LockAsset cc is used to record locking of an asset on the ledger -func LockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return "", logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf("error in locker validation: %+v", err) - } - - lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockVal := AssetLockValue{Locker: assetAgreement.Locker, Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - if assetLockValBytes != nil { - return "", logThenErrorf("asset of type %s and ID %s is already locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockValBytes, err = json.Marshal(assetLockVal) - if err != nil { - return "", logThenErrorf("marshal error: %+v", err) - } - - err = ctx.GetStub().PutState(assetLockKey, assetLockValBytes) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockKeyBytes, err := json.Marshal(assetLockKey) - if err != nil { - return "", logThenErrorf("marshal error: %+v", err) - } - - err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockKeyBytes) - if err != nil { - return "", logThenErrorf(err.Error()) - } - return contractId, nil -} - -// UnlockAsset cc is used to record unlocking of an asset on the ledger -func UnlockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) error { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return logThenErrorf("error in validation of asset agreement parties: %+v", err) - } - - assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return logThenErrorf("unmarshal error: %s", err) - } - - if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return logThenErrorf("cannot unlock asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock asset of type %s and ID %s as the expiry time is not yet elapsed", assetAgreement.Type, assetAgreement.Id) - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) - } - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) - } - - return nil -} - -// IsAssetLocked cc is used to query the ledger and findout if an asset is locked or not -func IsAssetLocked(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) (bool, error) { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return false, logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return false, logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - assetLockKey, _, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return false, logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return false, logThenErrorf("unmarshal error: %s", err) - } - log.Infof("assetLockVal: %+v", assetLockVal) - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for asset of type %s and ID %s is already elapsed", assetAgreement.Type, assetAgreement.Id) - } - - // '*' for recipient or locker in the query implies that the query seeks status for an arbitrary recipient or locker respectively - if (assetAgreement.Locker == "*" || assetLockVal.Locker == assetAgreement.Locker) && (assetAgreement.Recipient == "*" || assetLockVal.Recipient == assetAgreement.Recipient) { - return true, nil - } else if assetAgreement.Locker == "*" && assetLockVal.Recipient != assetAgreement.Recipient { - return false, logThenErrorf("asset of type %s and ID %s is not locked for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Recipient) - } else if assetAgreement.Recipient == "*" && assetLockVal.Locker != assetAgreement.Locker { - return false, logThenErrorf("asset of type %s and ID %s is not locked by %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker) - } else if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return false, logThenErrorf("asset of type %s and ID %s is not locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker, assetAgreement.Recipient) - } - - return true, nil -} - -/* - * Function to check if hashBase64 is the hash for the preimage preimageBase64. - * Both the preimage and hash are passed in base64 form. - */ -func checkIfCorrectPreimage(preimageBase64 string, hashBase64 string) (bool, error) { - funName := "checkIfCorrectPreimage" - preimage, err := base64.StdEncoding.DecodeString(preimageBase64) - if err != nil { - return false, logThenErrorf("base64 decode preimage error: %s", err) - } - - shaHashBase64 := GenerateSHA256HashInBase64Form(string(preimage)) - if shaHashBase64 == hashBase64 { - log.Infof("%s: preimage %s is passed correctly", funName, preimage) - } else { - log.Infof("%s: preimage %s is not passed correctly", funName, preimage) - return false, nil - } - return true, nil -} - -func validateHashPreimage(claimInfo *common.AssetClaim, lockInfo interface{}) (bool, error) { - claimInfoHTLC := &common.AssetClaimHTLC{} - err := proto.Unmarshal(claimInfo.ClaimInfo, claimInfoHTLC) - if err != nil { - return false, logThenErrorf("unmarshal claimInfo.ClaimInfo error: %s", err) - } - //display the claim information - log.Infof("claimInfoHTLC: %+v\n", claimInfoHTLC) - lockInfoVal := HashLock{} - lockInfoBytes, err := json.Marshal(lockInfo) - if err != nil { - return false, logThenErrorf("marshal lockInfo error: %s", err) - } - err = json.Unmarshal(lockInfoBytes, &lockInfoVal) - if err != nil { - return false, logThenErrorf("unmarshal lockInfoBytes error: %s", err) - } - log.Infof("HashLock: %+v\n", lockInfoVal) - - // match the hash passed during claim with the hash stored during asset locking - return checkIfCorrectPreimage(string(claimInfoHTLC.HashPreimageBase64), lockInfoVal.HashBase64) -} - -// fetches common.AssetClaim from the input parameter and checks if the lock mechanism is valid or not -func getClaimInfo(claimInfoBytesBase64 string) (*common.AssetClaim, error) { - claimInfo := &common.AssetClaim{} - - claimInfoBytes, err := base64.StdEncoding.DecodeString(claimInfoBytesBase64) - if err != nil { - return claimInfo, logThenErrorf("error in base64 decode of claim information: %+v", err) - } - - err = proto.Unmarshal([]byte(claimInfoBytes), claimInfo) - if err != nil { - return claimInfo, logThenErrorf("unmarshal error: %s", err) - } - // check if a valid lock mechanism is provided - if claimInfo.LockMechanism != common.LockMechanism_HTLC { - return claimInfo, logThenErrorf("lock mechanism is not supported") - } - - return claimInfo, nil -} - -// ClaimAsset cc is used to record claim of an asset on the ledger -func ClaimAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, claimInfoBytesBase64 string) error { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - // display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v\n", assetAgreement) - - err = validateAndSetRecipientOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return logThenErrorf("error in recipient validation: %+v", err) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return logThenErrorf("unmarshal error: %s", err) - } - - if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return logThenErrorf("cannot claim asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim asset of type %s and ID %s as the expiry time is already elapsed", assetAgreement.Type, assetAgreement.Id) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim asset of type %s and ID %s error: %v", assetAgreement.Type, assetAgreement.Id, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim asset of type %s and ID %s as the hash preimage is not matching", assetAgreement.Type, assetAgreement.Id) - } - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) - } - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset claim: %v", contractId, err) - } - - return nil -} - -// function to fetch the asset-lock from the ledger using contractId -func fetchAssetLockedUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (string, AssetLockValue, error) { - var assetLockVal = AssetLockValue{} - var assetLockKey string = "" - assetLockKeyBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf(err.Error()) - } - - if assetLockKeyBytes == nil { - return assetLockKey, assetLockVal, logThenErrorf("no contractId %s exists on the ledger", contractId) - } - - err = json.Unmarshal(assetLockKeyBytes, &assetLockKey) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("assetLockKey unmarshal error: %s", err) - } - log.Infof("contractId: %s and assetLockKey: %s", contractId, assetLockKey) - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes == nil { - return assetLockKey, assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked asset", contractId) - } - - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("assetLockVal unmarshal error: %s", err) - } - return assetLockKey, assetLockVal, nil -} - -// UnlockAssetUsingContractId cc is used to record unlocking of an asset on the ledger (this uses the contractId) -func UnlockAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) error { - - assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the locker of the locked fungible asset - if assetLockVal.Locker != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %v", contractId, err) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) - } - - return nil -} - -// ClaimAsset cc is used to record claim of an asset on the ledger (this uses the contractId) -func ClaimAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - - assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - if assetLockVal.Recipient != string(txCreatorECertBase64) { - return logThenErrorf("asset is not locked for %s to claim", string(txCreatorECertBase64)) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim asset associated with contractId %s as the expiry time is already elapsed", contractId) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim asset associated with contractId %s failed with error: %v", contractId, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim asset associated with contractId %s as the hash preimage is not matching", contractId) - } - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %+v", contractId, err) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset claim: %+v", contractId, err) - } - - return nil -} - -// IsAssetLocked cc is used to query the ledger and find out if an asset is locked or not (this uses the contractId) -func IsAssetLockedQueryUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - - _, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for asset associated with contractId %s is already elapsed", contractId) - } - - return true, nil -} - -// LockFungibleAsset cc is used to record locking of a group of fungible assets of an asset-type on the ledger -func LockFungibleAsset(ctx contractapi.TransactionContextInterface, fungibleAssetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - - fungibleAssetAgreementBytes, err := base64.StdEncoding.DecodeString(fungibleAssetAgreementBytesBase64) - if err != nil { - return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.FungibleAssetExchangeAgreement{} - err = proto.Unmarshal([]byte(fungibleAssetAgreementBytes), assetAgreement) - if err != nil { - return "", logThenErrorf("unmarshal error: %s", err) - } - - //display the requested fungible asset agreement - log.Infof("fungibleAssetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfFungibleAssetAgreement(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf("error in locker validation: %+v", err) - } - - lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - // generate the contractId for the fungible asset lock agreement - contractId := GenerateFungibleAssetLockContractId(ctx, assetAgreement) - - assetLockVal := FungibleAssetLockValue{Type: assetAgreement.Type, NumUnits: assetAgreement.NumUnits, Locker: assetAgreement.Locker, - Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} - - assetLockValBytes, err := ctx.GetStub().GetState(contractId) - if err != nil { - return "", logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes != nil { - return "", logThenErrorf("contractId %s already exists for the requested fungible asset agreement", contractId) - } - - assetLockValBytes, err = json.Marshal(assetLockVal) - if err != nil { - return "", logThenErrorf("marshal error: %s", err) - } - - err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockValBytes) - if err != nil { - return "", logThenErrorf("failed to write to the world state: %+v", err) - } - - return contractId, nil -} - -// function to fetch the fungible asset-lock value from the ledger using contractId -func fetchFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (FungibleAssetLockValue, error) { - var assetLockVal = FungibleAssetLockValue{} - - assetLockValBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) - if err != nil { - return assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes == nil { - return assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked fungible asset", contractId) - } - - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return assetLockVal, logThenErrorf("unmarshal error: %s", err) - } - log.Infof("contractId: %s and fungibleAssetLockVal: %+v", contractId, assetLockVal) - - return assetLockVal, nil -} - -// IsFungibleAssetLocked cc is used to query the ledger and find out if a fungible asset is locked or not -func IsFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for fungible asset associated with contractId %s is already elapsed", contractId) - } - - return true, nil -} - -// ClaimFungibleAsset cc is used to record claim of a fungible asset on the ledger -func ClaimFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the recipient of the locked fungible asset - if assetLockVal.Recipient != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to claim", txCreatorECertBase64) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim fungible asset associated with contractId %s as the expiry time is already elapsed", contractId) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim fungible asset associated with contractId %s failed with error: %v", contractId, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim fungible asset associated with contractId %s as the hash preimage is not matching", contractId) - } - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of fungible asset claim: %+v", contractId, err) - } - - return nil -} - -// UnlockFungibleAsset cc is used to record unlocking of a fungible asset on the ledger -func UnlockFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string) error { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the locker of the locked fungible asset - if assetLockVal.Locker != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock fungible asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of fungible asset unlock: %v", contractId, err) - } - - return nil -} diff --git a/core/network/fabric-interop-cc/libs/assetexchange/go.mod b/core/network/fabric-interop-cc/libs/assetexchange/go.mod deleted file mode 100644 index cddb0b62f..000000000 --- a/core/network/fabric-interop-cc/libs/assetexchange/go.mod +++ /dev/null @@ -1,11 +0,0 @@ -module github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange - -go 1.16 - -require ( - github.com/golang/protobuf v1.5.2 - github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 - github.com/hyperledger/fabric-contract-api-go v1.1.1 - github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 - github.com/sirupsen/logrus v1.8.1 -) diff --git a/core/network/fabric-interop-cc/libs/assetexchange/go.sum b/core/network/fabric-interop-cc/libs/assetexchange/go.sum deleted file mode 100644 index 38b4d4d21..000000000 --- a/core/network/fabric-interop-cc/libs/assetexchange/go.sum +++ /dev/null @@ -1,224 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2AZ5Ki+A= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= -github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= -github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= -github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= -github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= -github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= -github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hyperledger-labs/weaver-dlt-interoperability v0.0.0-20210722105253-d001e6a4f7ca h1:LXOVVO1+Q34rHdUpmphtYMYQSNj5HUgBh1FE9d3tmvI= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 h1:c9VK82wttYXTe4/UfnDq2Gq1Zu4Yxcxx1PbhEQHKuvA= -github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1/go.mod h1:yJq9oxxBHPryM8hVFiqM5HgfV2XFj5Tzb9Unx9D+YuI= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 h1:1i4lnpV8BDgKOLi1hgElfBqdHXjXieSuj8629mwBZ8o= -github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= -github.com/hyperledger/fabric-contract-api-go v1.1.1 h1:gDhOC18gjgElNZ85kFWsbCQq95hyUP/21n++m0Sv6B0= -github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= -github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 h1:d7do07Q4LaOFAEWceRwUwVDdcfx3BdLeZYyUGtbHfRk= -github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 76895e45588285f1c1af9f380d94dfc336e418d4 Mon Sep 17 00:00:00 2001 From: Krishnasuri Narayanam Date: Mon, 26 Jul 2021 15:59:56 +0530 Subject: [PATCH 3/7] changing asset exchange interop cc as a package Signed-off-by: Krishnasuri Narayanam --- .../contracts/interop/Makefile | 6 +- .../contracts/interop/go.mod | 11 +- .../contracts/interop/go.sum | 11 + .../contracts/interop/manage_assets.go | 808 +---------------- .../contracts/interop/manage_assets_test.go | 397 ++++---- .../contracts/interop/setup_test.go | 2 +- .../libs/assetexchange/assetSwapContracts.go | 853 ++++++++++++++++++ .../libs/assetexchange/go.mod | 11 + .../libs/assetexchange/go.sum | 224 +++++ .../fabric/dev/scripts/setupCC.sh | 4 +- .../fabric/dev/scripts/setupCCLocal.sh | 4 +- 11 files changed, 1324 insertions(+), 1007 deletions(-) create mode 100644 core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go create mode 100644 core/network/fabric-interop-cc/libs/assetexchange/go.mod create mode 100644 core/network/fabric-interop-cc/libs/assetexchange/go.sum diff --git a/core/network/fabric-interop-cc/contracts/interop/Makefile b/core/network/fabric-interop-cc/contracts/interop/Makefile index 00c5a2637..85c20716a 100644 --- a/core/network/fabric-interop-cc/contracts/interop/Makefile +++ b/core/network/fabric-interop-cc/contracts/interop/Makefile @@ -1,2 +1,6 @@ -test-manage-assets: +assetexchange: + cp -r ../../libs/assetexchange . +test-manage-assets: assetexchange go test manage_assets.go manage_assets_test.go main.go setup_test.go -v +clean: + rm -rf assetexchange diff --git a/core/network/fabric-interop-cc/contracts/interop/go.mod b/core/network/fabric-interop-cc/contracts/interop/go.mod index fadc367ca..bb5f9a19b 100644 --- a/core/network/fabric-interop-cc/contracts/interop/go.mod +++ b/core/network/fabric-interop-cc/contracts/interop/go.mod @@ -2,13 +2,16 @@ module github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabr go 1.16 +replace github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange => ./assetexchange + require ( - github.com/golang/protobuf v1.5.0 + github.com/golang/protobuf v1.5.2 github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 + github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange v0.0.0-00010101000000-000000000000 // indirect github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664 - github.com/hyperledger/fabric-contract-api-go v1.1.0 - github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31 - github.com/sirupsen/logrus v1.4.2 + github.com/hyperledger/fabric-contract-api-go v1.1.1 + github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 + github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.6.1 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 google.golang.org/protobuf v1.27.1 diff --git a/core/network/fabric-interop-cc/contracts/interop/go.sum b/core/network/fabric-interop-cc/contracts/interop/go.sum index 39eb810ce..ff7618d0a 100644 --- a/core/network/fabric-interop-cc/contracts/interop/go.sum +++ b/core/network/fabric-interop-cc/contracts/interop/go.sum @@ -63,6 +63,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -73,6 +75,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hyperledger-labs/weaver-dlt-interoperability v0.0.0-20210726084038-2210f22a1d24 h1:mDWoIWHe2zPqdMznLpWR4n35xkQrPQYP0uzcndBXIT8= github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 h1:c9VK82wttYXTe4/UfnDq2Gq1Zu4Yxcxx1PbhEQHKuvA= github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1/go.mod h1:yJq9oxxBHPryM8hVFiqM5HgfV2XFj5Tzb9Unx9D+YuI= github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= @@ -80,10 +83,14 @@ github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664 h1 github.com/hyperledger/fabric-chaincode-go v0.0.0-20200728190242-9b3ae92d8664/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= github.com/hyperledger/fabric-contract-api-go v1.1.0 h1:K9uucl/6eX3NF0/b+CGIiO1IPm1VYQxBkpnVGJur2S4= github.com/hyperledger/fabric-contract-api-go v1.1.0/go.mod h1:nHWt0B45fK53owcFpLtAe8DH0Q5P068mnzkNXMPSL7E= +github.com/hyperledger/fabric-contract-api-go v1.1.1 h1:gDhOC18gjgElNZ85kFWsbCQq95hyUP/21n++m0Sv6B0= +github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31 h1:T/uwoFIUioDDLffuJ/XgMLOWCUcx95/xXidv5igafl8= github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 h1:d7do07Q4LaOFAEWceRwUwVDdcfx3BdLeZYyUGtbHfRk= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= @@ -115,6 +122,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -174,6 +183,7 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -215,6 +225,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/core/network/fabric-interop-cc/contracts/interop/manage_assets.go b/core/network/fabric-interop-cc/contracts/interop/manage_assets.go index aecfab8ed..f75c522c9 100644 --- a/core/network/fabric-interop-cc/contracts/interop/manage_assets.go +++ b/core/network/fabric-interop-cc/contracts/interop/manage_assets.go @@ -9,845 +9,61 @@ package main import ( - "crypto/sha256" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "strconv" - "time" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange" "github.com/hyperledger/fabric-contract-api-go/contractapi" - mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" - log "github.com/sirupsen/logrus" ) -// Object used to capture the HashLock details used in Asset Locking -type HashLock struct { - HashBase64 string `json:"hashBase64"` -} - -// Object used in the map, --> (for non-fungible assets) -type AssetLockValue struct { - Locker string `json:"locker"` - Recipient string `json:"recipient"` - LockInfo interface{} `json:"lockInfo"` - ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` -} - -// Object used in the map, contractId --> (for fungible assets) -type FungibleAssetLockValue struct { - Type string `json:"type"` - NumUnits uint64 `json:"numUnits"` - Locker string `json:"locker"` - Recipient string `json:"recipient"` - LockInfo interface{} `json:"lockInfo"` - ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` -} - -const ( - assetKeyPrefix = "AssetKey_" // prefix for the map, asset-key --> asset-object - assetKeyDelimiter = "_" // delimiter for the asset-key - contractIdPrefix = "ContractId_" // prefix for the map, contractId --> asset-key -) - -// helper functions to log and return errors -func logThenErrorf(format string, args ...interface{}) error { - errorMsg := fmt.Sprintf(format, args...) - log.Error(errorMsg) - return errors.New(errorMsg) -} - -// function to generate a "SHA256" hash in base64 format for a given preimage -func generateSHA256HashInBase64Form(preimage string) string { - hasher := sha256.New() - hasher.Write([]byte(preimage)) - shaHash := hasher.Sum(nil) - shaHashBase64 := base64.StdEncoding.EncodeToString(shaHash) - return shaHashBase64 -} - -// function to return the key to fetch an element from the map using contractId -func generateContractIdMapKey(contractId string) string { - return contractIdPrefix + contractId -} - -/* - * Function to generate asset-lock key (which is combination of asset-type and asset-id) - * and contract-id (which is a hash on asset-lock key) for the non-fungible asset locking on the ledger - */ -func generateAssetLockKeyAndContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) (string, string, error) { - assetLockKey, err := ctx.GetStub().CreateCompositeKey("AssetExchangeContract", []string{assetAgreement.Type, assetAgreement.Id}) - if err != nil { - return "", "", logThenErrorf("error while creating composite key: %+v", err) - } - - contractId := generateSHA256HashInBase64Form(assetLockKey) - return assetLockKey, contractId, nil -} - -/* - * Function to generate contract-id for fungible asset-locking on the ledger (which is - * a hash on the attributes of the fungible asset exchange agreement) - */ -func generateFungibleAssetLockContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) string { - preimage := assetAgreement.Type + strconv.Itoa(int(assetAgreement.NumUnits)) + - assetAgreement.Locker + assetAgreement.Recipient + ctx.GetStub().GetTxID() - contractId := generateSHA256HashInBase64Form(preimage) - return contractId -} - -// function to get the caller identity from the transaction context -func getECertOfTxCreatorBase64(ctx contractapi.TransactionContextInterface) (string, error) { - - txCreatorBytes, err := ctx.GetStub().GetCreator() - if err != nil { - return "", logThenErrorf("unable to get the transaction creator information: %+v", err) - } - log.Infof("getECertOfTxCreatorBase64: TxCreator: %s", string(txCreatorBytes)) - - serializedIdentity := &mspProtobuf.SerializedIdentity{} - err = proto.Unmarshal(txCreatorBytes, serializedIdentity) - if err != nil { - return "", logThenErrorf("getECertOfTxCreatorBase64: unmarshal error: %+v", err) - } - log.Infof("getECertOfTxCreatorBase64: TxCreator ECert: %s", string(serializedIdentity.IdBytes)) - - eCertBytesBase64 := base64.StdEncoding.EncodeToString(serializedIdentity.IdBytes) - - return eCertBytesBase64, nil -} - -/* - * Function to validate the locker in asset agreement. - * If locker is not set, it will be set to the caller. - * If the locker is set already, it ensures that the locker is same as the creator of the transaction. - */ -func validateAndSetLockerOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Locker) == 0 { - assetAgreement.Locker = txCreatorECertBase64 - } else if assetAgreement.Locker != txCreatorECertBase64 { - return logThenErrorf("locker %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) - } - - return nil -} - -/* - * Function to validate the locker in fungible asset agreement. - * If locker is not set, it will be set to the caller. - * If the locker is set already, it ensures that the locker is same as the creator of the transaction. - */ -func validateAndSetLockerOfFungibleAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Locker) == 0 { - assetAgreement.Locker = txCreatorECertBase64 - } else if assetAgreement.Locker != txCreatorECertBase64 { - return logThenErrorf("locker %s in the fungible asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) - } - - return nil -} - -/* - * Function to validate the recipient in asset agreement. - * If recipient is not set, it will be set to the caller. - * If the recipeint is set already, it ensures that the recipient is same as the creator of the transaction. - */ -func validateAndSetRecipientOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf(err.Error()) - } - if len(assetAgreement.Recipient) == 0 { - assetAgreement.Recipient = txCreatorECertBase64 - } else if assetAgreement.Recipient != txCreatorECertBase64 { - return logThenErrorf("recipient %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Recipient, txCreatorECertBase64) - } - - return nil -} - -func getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64 string) (interface{}, uint64, error) { - var lockInfoVal interface{} - var expiryTimeSecs uint64 - - lockInfoBytes, err := base64.StdEncoding.DecodeString(lockInfoBytesBase64) - if err != nil { - return lockInfoVal, 0, fmt.Errorf("error in base64 decode of lock information: %+v", err) - } - lockInfo := &common.AssetLock{} - err = proto.Unmarshal([]byte(lockInfoBytes), lockInfo) - if err != nil { - return lockInfoVal, 0, logThenErrorf(err.Error()) - } - - // process lock details here (lockInfo.LockInfo contains value based on the lock mechanism used) - if lockInfo.LockMechanism == common.LockMechanism_HTLC { - lockInfoHTLC := &common.AssetLockHTLC{} - err := proto.Unmarshal(lockInfo.LockInfo, lockInfoHTLC) - if err != nil { - return lockInfoVal, 0, logThenErrorf("unmarshal error: %s", err) - } - //display the passed hash lock information - log.Infof("lockInfoHTLC: %+v", lockInfoHTLC) - lockInfoVal = HashLock{HashBase64: string(lockInfoHTLC.HashBase64)} - // process time lock details here - if lockInfoHTLC.TimeSpec != common.AssetLockHTLC_EPOCH { - return lockInfoVal, 0, logThenErrorf("only EPOCH time is supported at present") - } - expiryTimeSecs = lockInfoHTLC.ExpiryTimeSecs - } else { - return lockInfoVal, 0, logThenErrorf("lock mechanism is not supported") - } - return lockInfoVal, expiryTimeSecs, nil -} - // LockAsset cc is used to record locking of an asset on the ledger func (s *SmartContract) LockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return "", logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf("error in locker validation: %+v", err) - } - - lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockVal := AssetLockValue{Locker: assetAgreement.Locker, Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - if assetLockValBytes != nil { - return "", logThenErrorf("asset of type %s and ID %s is already locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockValBytes, err = json.Marshal(assetLockVal) - if err != nil { - return "", logThenErrorf("marshal error: %+v", err) - } - - err = ctx.GetStub().PutState(assetLockKey, assetLockValBytes) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - assetLockKeyBytes, err := json.Marshal(assetLockKey) - if err != nil { - return "", logThenErrorf("marshal error: %+v", err) - } - - err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockKeyBytes) - if err != nil { - return "", logThenErrorf(err.Error()) - } - return contractId, nil + return assetexchange.LockAsset(ctx, assetAgreementBytesBase64, lockInfoBytesBase64) } // UnlockAsset cc is used to record unlocking of an asset on the ledger func (s *SmartContract) UnlockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) error { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return logThenErrorf("error in validation of asset agreement parties: %+v", err) - } - - assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return logThenErrorf("unmarshal error: %s", err) - } - - if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return logThenErrorf("cannot unlock asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock asset of type %s and ID %s as the expiry time is not yet elapsed", assetAgreement.Type, assetAgreement.Id) - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) - } - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) - } - - return nil + return assetexchange.UnlockAsset(ctx, assetAgreementBytesBase64) } // IsAssetLocked cc is used to query the ledger and findout if an asset is locked or not func (s *SmartContract) IsAssetLocked(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) (bool, error) { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return false, logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return false, logThenErrorf(err.Error()) - } - //display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v", assetAgreement) - - assetLockKey, _, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return false, logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return false, logThenErrorf("unmarshal error: %s", err) - } - log.Infof("assetLockVal: %+v", assetLockVal) - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for asset of type %s and ID %s is already elapsed", assetAgreement.Type, assetAgreement.Id) - } - - // '*' for recipient or locker in the query implies that the query seeks status for an arbitrary recipient or locker respectively - if (assetAgreement.Locker == "*" || assetLockVal.Locker == assetAgreement.Locker) && (assetAgreement.Recipient == "*" || assetLockVal.Recipient == assetAgreement.Recipient) { - return true, nil - } else if assetAgreement.Locker == "*" && assetLockVal.Recipient != assetAgreement.Recipient { - return false, logThenErrorf("asset of type %s and ID %s is not locked for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Recipient) - } else if assetAgreement.Recipient == "*" && assetLockVal.Locker != assetAgreement.Locker { - return false, logThenErrorf("asset of type %s and ID %s is not locked by %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker) - } else if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return false, logThenErrorf("asset of type %s and ID %s is not locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker, assetAgreement.Recipient) - } - - return true, nil -} - -/* - * Function to check if hashBase64 is the hash for the preimage preimageBase64. - * Both the preimage and hash are passed in base64 form. - */ -func checkIfCorrectPreimage(preimageBase64 string, hashBase64 string) (bool, error) { - funName := "checkIfCorrectPreimage" - preimage, err := base64.StdEncoding.DecodeString(preimageBase64) - if err != nil { - return false, logThenErrorf("base64 decode preimage error: %s", err) - } - - shaHashBase64 := generateSHA256HashInBase64Form(string(preimage)) - if shaHashBase64 == hashBase64 { - log.Infof("%s: preimage %s is passed correctly", funName, preimage) - } else { - log.Infof("%s: preimage %s is not passed correctly", funName, preimage) - return false, nil - } - return true, nil -} - -func validateHashPreimage(claimInfo *common.AssetClaim, lockInfo interface{}) (bool, error) { - claimInfoHTLC := &common.AssetClaimHTLC{} - err := proto.Unmarshal(claimInfo.ClaimInfo, claimInfoHTLC) - if err != nil { - return false, logThenErrorf("unmarshal claimInfo.ClaimInfo error: %s", err) - } - //display the claim information - log.Infof("claimInfoHTLC: %+v\n", claimInfoHTLC) - lockInfoVal := HashLock{} - lockInfoBytes, err := json.Marshal(lockInfo) - if err != nil { - return false, logThenErrorf("marshal lockInfo error: %s", err) - } - err = json.Unmarshal(lockInfoBytes, &lockInfoVal) - if err != nil { - return false, logThenErrorf("unmarshal lockInfoBytes error: %s", err) - } - log.Infof("HashLock: %+v\n", lockInfoVal) - - // match the hash passed during claim with the hash stored during asset locking - return checkIfCorrectPreimage(string(claimInfoHTLC.HashPreimageBase64), lockInfoVal.HashBase64) -} - -// fetches common.AssetClaim from the input parameter and checks if the lock mechanism is valid or not -func getClaimInfo(claimInfoBytesBase64 string) (*common.AssetClaim, error) { - claimInfo := &common.AssetClaim{} - - claimInfoBytes, err := base64.StdEncoding.DecodeString(claimInfoBytesBase64) - if err != nil { - return claimInfo, logThenErrorf("error in base64 decode of claim information: %+v", err) - } - - err = proto.Unmarshal([]byte(claimInfoBytes), claimInfo) - if err != nil { - return claimInfo, logThenErrorf("unmarshal error: %s", err) - } - // check if a valid lock mechanism is provided - if claimInfo.LockMechanism != common.LockMechanism_HTLC { - return claimInfo, logThenErrorf("lock mechanism is not supported") - } - - return claimInfo, nil + return assetexchange.IsAssetLocked(ctx, assetAgreementBytesBase64) } // ClaimAsset cc is used to record claim of an asset on the ledger func (s *SmartContract) ClaimAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, claimInfoBytesBase64 string) error { - - assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) - if err != nil { - return logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.AssetExchangeAgreement{} - err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - // display the requested asset agreement - log.Infof("assetExchangeAgreement: %+v\n", assetAgreement) - - err = validateAndSetRecipientOfAssetAgreement(ctx, assetAgreement) - if err != nil { - return logThenErrorf("error in recipient validation: %+v", err) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockKey, contractId, err := generateAssetLockKeyAndContractId(ctx, assetAgreement) - if err != nil { - return logThenErrorf(err.Error()) - } - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return logThenErrorf(err.Error()) - } - - if assetLockValBytes == nil { - return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) - } - - assetLockVal := AssetLockValue{} - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return logThenErrorf("unmarshal error: %s", err) - } - - if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { - return logThenErrorf("cannot claim asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim asset of type %s and ID %s as the expiry time is already elapsed", assetAgreement.Type, assetAgreement.Id) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim asset of type %s and ID %s error: %v", assetAgreement.Type, assetAgreement.Id, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim asset of type %s and ID %s as the hash preimage is not matching", assetAgreement.Type, assetAgreement.Id) - } - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) - } - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset claim: %v", contractId, err) - } - - return nil -} - -// function to fetch the asset-lock from the ledger using contractId -func fetchAssetLockedUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (string, AssetLockValue, error) { - var assetLockVal = AssetLockValue{} - var assetLockKey string = "" - assetLockKeyBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf(err.Error()) - } - - if assetLockKeyBytes == nil { - return assetLockKey, assetLockVal, logThenErrorf("no contractId %s exists on the ledger", contractId) - } - - err = json.Unmarshal(assetLockKeyBytes, &assetLockKey) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("assetLockKey unmarshal error: %s", err) - } - log.Infof("contractId: %s and assetLockKey: %s", contractId, assetLockKey) - - assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes == nil { - return assetLockKey, assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked asset", contractId) - } - - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return assetLockKey, assetLockVal, logThenErrorf("assetLockVal unmarshal error: %s", err) - } - return assetLockKey, assetLockVal, nil + return assetexchange.ClaimAsset(ctx, assetAgreementBytesBase64, claimInfoBytesBase64) } // UnlockAssetUsingContractId cc is used to record unlocking of an asset on the ledger (this uses the contractId) func (s *SmartContract) UnlockAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) error { - - assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the locker of the locked fungible asset - if assetLockVal.Locker != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %v", contractId, err) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) - } - - return nil + return assetexchange.UnlockAssetUsingContractId(ctx, contractId) } // ClaimAsset cc is used to record claim of an asset on the ledger (this uses the contractId) func (s *SmartContract) ClaimAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - - assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - if assetLockVal.Recipient != string(txCreatorECertBase64) { - return logThenErrorf("asset is not locked for %s to claim", string(txCreatorECertBase64)) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim asset associated with contractId %s as the expiry time is already elapsed", contractId) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim asset associated with contractId %s failed with error: %v", contractId, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim asset associated with contractId %s as the hash preimage is not matching", contractId) - } - } - - err = ctx.GetStub().DelState(assetLockKey) - if err != nil { - return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %+v", contractId, err) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of asset claim: %+v", contractId, err) - } - - return nil + return assetexchange.ClaimAssetUsingContractId(ctx, contractId, claimInfoBytesBase64) } // IsAssetLocked cc is used to query the ledger and find out if an asset is locked or not (this uses the contractId) func (s *SmartContract) IsAssetLockedQueryUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - - _, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for asset associated with contractId %s is already elapsed", contractId) - } - - return true, nil + return assetexchange.IsAssetLockedQueryUsingContractId(ctx, contractId) } // LockFungibleAsset cc is used to record locking of a group of fungible assets of an asset-type on the ledger func (s *SmartContract) LockFungibleAsset(ctx contractapi.TransactionContextInterface, fungibleAssetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { - - fungibleAssetAgreementBytes, err := base64.StdEncoding.DecodeString(fungibleAssetAgreementBytesBase64) - if err != nil { - return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) - } - - assetAgreement := &common.FungibleAssetExchangeAgreement{} - err = proto.Unmarshal([]byte(fungibleAssetAgreementBytes), assetAgreement) - if err != nil { - return "", logThenErrorf("unmarshal error: %s", err) - } - - //display the requested fungible asset agreement - log.Infof("fungibleAssetExchangeAgreement: %+v", assetAgreement) - - err = validateAndSetLockerOfFungibleAssetAgreement(ctx, assetAgreement) - if err != nil { - return "", logThenErrorf("error in locker validation: %+v", err) - } - - lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) - if err != nil { - return "", logThenErrorf(err.Error()) - } - - // generate the contractId for the fungible asset lock agreement - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) - - assetLockVal := FungibleAssetLockValue{Type: assetAgreement.Type, NumUnits: assetAgreement.NumUnits, Locker: assetAgreement.Locker, - Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} - - assetLockValBytes, err := ctx.GetStub().GetState(contractId) - if err != nil { - return "", logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes != nil { - return "", logThenErrorf("contractId %s already exists for the requested fungible asset agreement", contractId) - } - - assetLockValBytes, err = json.Marshal(assetLockVal) - if err != nil { - return "", logThenErrorf("marshal error: %s", err) - } - - err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockValBytes) - if err != nil { - return "", logThenErrorf("failed to write to the world state: %+v", err) - } - - return contractId, nil -} - -// function to fetch the fungible asset-lock value from the ledger using contractId -func fetchFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (FungibleAssetLockValue, error) { - var assetLockVal = FungibleAssetLockValue{} - - assetLockValBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) - if err != nil { - return assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) - } - - if assetLockValBytes == nil { - return assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked fungible asset", contractId) - } - - err = json.Unmarshal(assetLockValBytes, &assetLockVal) - if err != nil { - return assetLockVal, logThenErrorf("unmarshal error: %s", err) - } - log.Infof("contractId: %s and fungibleAssetLockVal: %+v", contractId, assetLockVal) - - return assetLockVal, nil + return assetexchange.LockFungibleAsset(ctx, fungibleAssetAgreementBytesBase64, lockInfoBytesBase64) } // IsFungibleAssetLocked cc is used to query the ledger and find out if a fungible asset is locked or not func (s *SmartContract) IsFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return false, logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return false, logThenErrorf("expiry time for fungible asset associated with contractId %s is already elapsed", contractId) - } - - return true, nil + return assetexchange.IsFungibleAssetLocked(ctx, contractId) } // ClaimFungibleAsset cc is used to record claim of a fungible asset on the ledger func (s *SmartContract) ClaimFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the recipient of the locked fungible asset - if assetLockVal.Recipient != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to claim", txCreatorECertBase64) - } - - claimInfo, err := getClaimInfo(claimInfoBytesBase64) - if err != nil { - return logThenErrorf(err.Error()) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot claim fungible asset associated with contractId %s as the expiry time is already elapsed", contractId) - } - - if claimInfo.LockMechanism == common.LockMechanism_HTLC { - isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) - if err != nil { - return logThenErrorf("claim fungible asset associated with contractId %s failed with error: %v", contractId, err) - } - if !isCorrectPreimage { - return logThenErrorf("cannot claim fungible asset associated with contractId %s as the hash preimage is not matching", contractId) - } - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of fungible asset claim: %+v", contractId, err) - } - - return nil + return assetexchange.ClaimFungibleAsset(ctx, contractId, claimInfoBytesBase64) } // UnlockFungibleAsset cc is used to record unlocking of a fungible asset on the ledger func (s *SmartContract) UnlockFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string) error { - - assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) - if err != nil { - return logThenErrorf(err.Error()) - } - - txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) - if err != nil { - return logThenErrorf("unable to get the transaction creator information: %+v", err) - } - - // transaction creator needs to be the locker of the locked fungible asset - if assetLockVal.Locker != txCreatorECertBase64 { - return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) - } - - // Check if expiry time is elapsed - currentTimeSecs := uint64(time.Now().Unix()) - if currentTimeSecs < assetLockVal.ExpiryTimeSecs { - return logThenErrorf("cannot unlock fungible asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) - } - - err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) - if err != nil { - return logThenErrorf("failed to delete the contractId %s as part of fungible asset unlock: %v", contractId, err) - } - - return nil + return assetexchange.UnlockFungibleAsset(ctx, contractId) } diff --git a/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go b/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go index 26acecdc8..d06d8fa8f 100644 --- a/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go +++ b/core/network/fabric-interop-cc/contracts/interop/manage_assets_test.go @@ -7,22 +7,23 @@ package main import ( + "encoding/base64" "encoding/json" "fmt" "testing" - "encoding/base64" - //"encoding/hex" + "time" - "github.com/stretchr/testify/require" "github.com/golang/protobuf/proto" + "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange" mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" log "github.com/sirupsen/logrus" - "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/stretchr/testify/require" ) -const( - defaultTimeLockSecs = 5 * 60 // 5 minutes +const ( + defaultTimeLockSecs = 5 * 60 // 5 minutes ) // function that supplies value that is to be returned by ctx.GetStub().GetCreator() @@ -51,28 +52,28 @@ func TestLockAsset(t *testing.T) { recipient := "Bob" locker := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - lockInfoHTLC := &common.AssetLockHTLC { + lockInfoHTLC := &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 minutes ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, - TimeSpec: common.AssetLockHTLC_EPOCH, + TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock { + lockInfo := &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) @@ -83,7 +84,7 @@ func TestLockAsset(t *testing.T) { require.NoError(t, err) fmt.Println("Test success as expected since the agreement and lock information are speccified properly") - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure by trying to lock an asset that is already locked @@ -92,7 +93,7 @@ func TestLockAsset(t *testing.T) { log.Info(fmt.Println("Test failed as expected with error:", err)) // no need to set chaincodeStub.GetStateReturns below since the error is hit before GetState() ledger access in LockAsset() - lockInfoHTLC = &common.AssetLockHTLC { + lockInfoHTLC = &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -100,9 +101,9 @@ func TestLockAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_DURATION, } lockInfoHTLCBytes, _ = proto.Marshal(lockInfoHTLC) - lockInfo = &common.AssetLock { + lockInfo = &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ = proto.Marshal(lockInfo) // Test failure with lock information not specified properly @@ -119,28 +120,28 @@ func TestUnlockAsset(t *testing.T) { recipient := "Bob" locker := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - lockInfoHTLC := &common.AssetLockHTLC { + lockInfoHTLC := &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for sometime in the past for testing UnlockAsset functionality ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs, - TimeSpec: common.AssetLockHTLC_EPOCH, + TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock { + lockInfo := &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) @@ -151,7 +152,7 @@ func TestUnlockAsset(t *testing.T) { require.NoError(t, err) log.Info(fmt.Println("Completed locking an asset. Proceed to test unlock asset.")) - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test success with asset agreement specified properly @@ -166,7 +167,7 @@ func TestUnlockAsset(t *testing.T) { log.Info(fmt.Println("Test failed as expected with error:", err)) // Assume that the asset is locked by Alice for Bob; then trying to unlock the asset by Alice for Charlie should fail since the locking is done for a different recipient - assetLockVal = AssetLockValue{Locker: locker, Recipient: "Charlie"} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: "Charlie"} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset id being locked for a different @@ -174,12 +175,11 @@ func TestUnlockAsset(t *testing.T) { require.Error(t, err) log.Info(fmt.Println("Test failed as expected with error:", err)) - - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock // lock for sometime in the future for testing UnlockAsset functionality - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure of unlock asset with expiry time not yet elapsed @@ -197,16 +197,15 @@ func TestIsAssetLocked(t *testing.T) { locker := "Alice" currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - - assetLockVal := AssetLockValue{Locker: locker, Recipient: "Charlie"} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: "Charlie"} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset agreement not specified properly @@ -215,8 +214,7 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test success with asset agreement specified properly @@ -225,8 +223,7 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified properly.")) - - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with expiry time elapsed already @@ -235,8 +232,7 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetLockVal = AssetLockValue{Locker: "Dave", Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: "Dave", Recipient: recipient, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with asset agreement not specified properly @@ -245,10 +241,9 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetAgreement = &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement = &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, // arbitrary locker specification Locker: "*", @@ -260,10 +255,9 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified to include arbitrary locker.")) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // wrong recipient specification Recipient: "Charlie", // arbitrary locker specification @@ -276,13 +270,12 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", - Locker: "Dave", + Locker: "Dave", } assetAgreementBytes, _ = proto.Marshal(assetAgreement) // Test success with asset agreement specified to include arbitrary recipient @@ -291,10 +284,9 @@ func TestIsAssetLocked(t *testing.T) { require.True(t, isAssetLocked) log.Info(fmt.Println("Test succeeded as expected since the asset agreement is specified to include arbitrary recipient.")) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", // wrong locker specification @@ -307,10 +299,9 @@ func TestIsAssetLocked(t *testing.T) { require.False(t, isAssetLocked) log.Info(fmt.Println("Test failed as expected with error:", err)) - - assetAgreement = &common.AssetExchangeAgreement { + assetAgreement = &common.AssetExchangeAgreement{ Type: assetType, - Id: assetId, + Id: assetId, // arbitrary recipient specification Recipient: "*", // arbitrary locker specification @@ -332,33 +323,33 @@ func TestClaimAsset(t *testing.T) { recipient := getTxCreatorECertBase64() locker := "Alice" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC { + claimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim { + claimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) @@ -367,7 +358,7 @@ func TestClaimAsset(t *testing.T) { require.NoError(t, err) log.Info(fmt.Println("Test success as expected since the asset agreement and claim information are specified properly.")) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with expiry time elapsed to claim the asset @@ -377,17 +368,17 @@ func TestClaimAsset(t *testing.T) { wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfoHTLC := &common.AssetClaimHTLC { + wrongClaimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoHTLCBytes, _ := proto.Marshal(wrongClaimInfoHTLC) - wrongClaimInfo := &common.AssetClaim { + wrongClaimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: wrongClaimInfoHTLCBytes, + ClaimInfo: wrongClaimInfoHTLCBytes, } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) // Test failure with claim information (i.e., preimage) not specified properly @@ -423,30 +414,30 @@ func TestUnlockAssetUsingContractId(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId " + contractId) + require.EqualError(t, err, "unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with not a valid contractId being passed as the arguement chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") + require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with GetState(assetLockKey) fail to read from the world state @@ -455,7 +446,7 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is valid but there is no asset locked with the assetLockKey @@ -463,32 +454,32 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for asset unlock exercised with expiry time not yet elapsed chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "cannot unlock asset associated with the contractId " + contractId + " as the expiry time is not yet elapsed") + require.EqualError(t, err, "cannot unlock asset associated with the contractId "+contractId+" as the expiry time is not yet elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on assetLockKey chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfoVal, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete asset with key %s from world state", assetLockKey)) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId " + - contractId + ": unable to delete asset with key " + assetLockKey + " from world state") + require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId "+ + contractId+": unable to delete asset with key "+assetLockKey+" from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -498,8 +489,8 @@ func TestUnlockAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(2, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.UnlockAssetUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of asset unlock: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of asset unlock: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being unlocked using contractId @@ -521,26 +512,26 @@ func TestClaimAssetUsingContractId(t *testing.T) { recipient := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC { + claimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim { + claimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) @@ -548,14 +539,14 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId " + contractId) + require.EqualError(t, err, "unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with not a valid contractId being passed as the arguement chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") + require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with GetState(assetLockKey) fail to read from the world state @@ -564,7 +555,7 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is valid but there is no asset locked with the assetLockKey @@ -572,42 +563,42 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for asset claim exercised with expiry time elapsed already chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim asset associated with contractId " + contractId + " as the expiry time is already elapsed") + require.EqualError(t, err, "cannot claim asset associated with contractId "+contractId+" as the expiry time is already elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with claim information (i.e., preimage) not specified properly chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfoHTLC := &common.AssetClaimHTLC { + wrongClaimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoHTLCBytes, _ := proto.Marshal(wrongClaimInfoHTLC) - wrongClaimInfo := &common.AssetClaim { + wrongClaimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: wrongClaimInfoHTLCBytes, + ClaimInfo: wrongClaimInfoHTLCBytes, } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(wrongClaimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim asset associated with contractId " + contractId + " as the hash preimage is not matching") + require.EqualError(t, err, "cannot claim asset associated with contractId "+contractId+" as the hash preimage is not matching") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on assetLockKey @@ -616,8 +607,8 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete asset with key %s from world state", assetLockKey)) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId " + - contractId + ": unable to delete asset with key " + assetLockKey + " from world state") + require.EqualError(t, err, "failed to delete lock for the asset associated with the contractId "+ + contractId+": unable to delete asset with key "+assetLockKey+" from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -627,8 +618,8 @@ func TestClaimAssetUsingContractId(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(2, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.ClaimAssetUsingContractId(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of asset claim: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of asset claim: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being claimed using contractId @@ -650,22 +641,22 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.AssetExchangeAgreement { - Type: assetType, - Id: assetId, + assetAgreement := &common.AssetExchangeAgreement{ + Type: assetType, + Id: assetId, Recipient: recipient, - Locker: locker, + Locker: locker, } - assetLockKey, contractId, _ := generateAssetLockKeyAndContractId(ctx, assetAgreement) + assetLockKey, contractId, _ := assetexchange.GenerateAssetLockKeyAndContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) isAssetLocked, err := interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "unable to retrieve contractId " + contractId) + require.EqualError(t, err, "unable to retrieve contractId "+contractId) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -673,7 +664,7 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(1, nil, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "no contractId " + contractId + " exists on the ledger") + require.EqualError(t, err, "no contractId "+contractId+" exists on the ledger") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -683,7 +674,7 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(3, nil, fmt.Errorf("unable to retrieve asset %s", assetLockKey)) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset " + assetLockKey) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve asset "+assetLockKey) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -692,27 +683,27 @@ func TestIsAssetLockedQueryUsingContractId(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(5, nil, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked asset") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for query if asset is locked with lock expiry time elapsed already chaincodeStub.GetStateReturnsOnCall(6, assetLockKeyBytes, nil) - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(7, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "expiry time for asset associated with contractId " + contractId + " is already elapsed") + require.EqualError(t, err, "expiry time for asset associated with contractId "+contractId+" is already elapsed") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being queried using contractId chaincodeStub.GetStateReturnsOnCall(8, assetLockKeyBytes, nil) - assetLockVal = AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.AssetLockValue{Locker: locker, Recipient: recipient, LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(9, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsAssetLockedQueryUsingContractId(ctx, contractId) @@ -730,22 +721,22 @@ func TestLockFungibleAsset(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } assetAgreementBytes, _ := proto.Marshal(assetAgreement) - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) // Test failure with TimeSpec that is part of lock information not being currently supported // no need to set chaincodeStub.GetStateReturns below since the error is hit before GetState() ledger access - lockInfoHTLC := &common.AssetLockHTLC { + lockInfoHTLC := &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -753,9 +744,9 @@ func TestLockFungibleAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_DURATION, } lockInfoHTLCBytes, _ := proto.Marshal(lockInfoHTLC) - lockInfo := &common.AssetLock { + lockInfo := &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ := proto.Marshal(lockInfo) _, err := interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) @@ -765,7 +756,7 @@ func TestLockFungibleAsset(t *testing.T) { // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) - lockInfoHTLC = &common.AssetLockHTLC { + lockInfoHTLC = &common.AssetLockHTLC{ HashBase64: []byte(hashBase64), // lock for next 5 mintues ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs, @@ -773,27 +764,27 @@ func TestLockFungibleAsset(t *testing.T) { TimeSpec: common.AssetLockHTLC_EPOCH, } lockInfoHTLCBytes, _ = proto.Marshal(lockInfoHTLC) - lockInfo = &common.AssetLock { + lockInfo = &common.AssetLock{ LockMechanism: common.LockMechanism_HTLC, - LockInfo: lockInfoHTLCBytes, + LockInfo: lockInfoHTLCBytes, } lockInfoBytes, _ = proto.Marshal(lockInfo) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with contractId already existing on the ledger - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfoVal interface{} lockInfoVal = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfoVal, ExpiryTimeSecs: lockInfoHTLC.ExpiryTimeSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfoVal, ExpiryTimeSecs: lockInfoHTLC.ExpiryTimeSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturns(assetLockValBytes, nil) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " already exists for the requested fungible asset agreement") + require.EqualError(t, err, "contractId "+contractId+" already exists for the requested fungible asset agreement") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with PutState failing to write to the ledger @@ -801,7 +792,7 @@ func TestLockFungibleAsset(t *testing.T) { chaincodeStub.PutStateReturnsOnCall(0, fmt.Errorf("unable to write the fungible asset lock to the ledger for contractId %s", contractId)) _, err = interopcc.LockFungibleAsset(ctx, base64.StdEncoding.EncodeToString(assetAgreementBytes), base64.StdEncoding.EncodeToString(lockInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to write to the world state: unable to write the fungible asset lock to the ledger for contractId " + contractId) + require.EqualError(t, err, "failed to write to the world state: unable to write the fungible asset lock to the ledger for contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with fungible asset agreement specified properly @@ -820,22 +811,22 @@ func TestIsFungibleAssetLocked(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) isAssetLocked, err := interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) @@ -843,27 +834,27 @@ func TestIsFungibleAssetLocked(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(1, nil, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for query if fungible asset is locked with lock expiry time elapsed already - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "expiry time for fungible asset associated with contractId " + contractId + " is already elapsed") + require.EqualError(t, err, "expiry time for fungible asset associated with contractId "+contractId+" is already elapsed") require.False(t, isAssetLocked) fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being queried using contractId - assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) isAssetLocked, err = interopcc.IsFungibleAssetLocked(ctx, contractId) @@ -881,26 +872,26 @@ func TestClaimFungibleAsset(t *testing.T) { recipient := getTxCreatorECertBase64() preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) preimageBase64 := base64.StdEncoding.EncodeToString([]byte(preimage)) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) - claimInfoHTLC := &common.AssetClaimHTLC { + claimInfoHTLC := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(preimageBase64), } claimInfoHTLCBytes, _ := proto.Marshal(claimInfoHTLC) - claimInfo := &common.AssetClaim { + claimInfo := &common.AssetClaim{ LockMechanism: common.LockMechanism_HTLC, - ClaimInfo: claimInfoHTLCBytes, + ClaimInfo: claimInfoHTLCBytes, } claimInfoBytes, _ := proto.Marshal(claimInfo) @@ -908,43 +899,43 @@ func TestClaimFungibleAsset(t *testing.T) { chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is not valid and there is no fungible asset locked with it chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for fungible asset claim exercised with expiry time elapsed already - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim fungible asset associated with contractId " + contractId + " as the expiry time is already elapsed") + require.EqualError(t, err, "cannot claim fungible asset associated with contractId "+contractId+" as the expiry time is already elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with claim information (i.e., preimage) not specified properly wrongPreimage := "abc" wrongPreimageBase64 := base64.StdEncoding.EncodeToString([]byte(wrongPreimage)) - wrongClaimInfo := &common.AssetClaimHTLC { + wrongClaimInfo := &common.AssetClaimHTLC{ HashPreimageBase64: []byte(wrongPreimageBase64), } wrongClaimInfoBytes, _ := proto.Marshal(wrongClaimInfo) - assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(wrongClaimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "cannot claim fungible asset associated with contractId " + contractId + " as the hash preimage is not matching") + require.EqualError(t, err, "cannot claim fungible asset associated with contractId "+contractId+" as the hash preimage is not matching") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId @@ -952,8 +943,8 @@ func TestClaimFungibleAsset(t *testing.T) { chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.ClaimFungibleAsset(ctx, contractId, base64.StdEncoding.EncodeToString(claimInfoBytes)) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of fungible asset claim: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of fungible asset claim: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with asset being claimed using contractId @@ -978,55 +969,55 @@ func TestUnlockFungibleAsset(t *testing.T) { recipient := "Bob" preimage := "abcd" - hashBase64 := generateSHA256HashInBase64Form(preimage) + hashBase64 := assetexchange.GenerateSHA256HashInBase64Form(preimage) currentTimeSecs := uint64(time.Now().Unix()) chaincodeStub.GetCreatorReturns([]byte(getCreator()), nil) - assetAgreement := &common.FungibleAssetExchangeAgreement { - Type: assetType, - NumUnits: numUnits, - Locker: locker, + assetAgreement := &common.FungibleAssetExchangeAgreement{ + Type: assetType, + NumUnits: numUnits, + Locker: locker, Recipient: recipient, } - contractId := generateFungibleAssetLockContractId(ctx, assetAgreement) + contractId := assetexchange.GenerateFungibleAssetLockContractId(ctx, assetAgreement) // Test failure with GetState(contractId) fail to read the world state chaincodeStub.GetStateReturnsOnCall(0, nil, fmt.Errorf("unable to retrieve contractId %s", contractId)) err := interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId " + contractId) + require.EqualError(t, err, "failed to retrieve from the world state: unable to retrieve contractId "+contractId) fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure under the scenario that the contractId is not valid and there is no fungible asset locked with it chaincodeStub.GetStateReturnsOnCall(1, nil, nil) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "contractId " + contractId + " is not associated with any currently locked fungible asset") + require.EqualError(t, err, "contractId "+contractId+" is not associated with any currently locked fungible asset") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure for fungible asset unlock exercised with expiry time not yet elapsed - hashLock := HashLock{HashBase64: hashBase64} + hashLock := assetexchange.HashLock{HashBase64: hashBase64} var lockInfo interface{} lockInfo = hashLock - assetLockVal := FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} + assetLockVal := assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs + defaultTimeLockSecs} assetLockValBytes, _ := json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(2, assetLockValBytes, nil) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "cannot unlock fungible asset associated with the contractId " + contractId + " as the expiry time is not yet elapsed") + require.EqualError(t, err, "cannot unlock fungible asset associated with the contractId "+contractId+" as the expiry time is not yet elapsed") fmt.Printf("Test failed as expected with error: %s\n", err) // Test failure with DelState failing on contractId - assetLockVal = FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, - LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} + assetLockVal = assetexchange.FungibleAssetLockValue{Type: assetType, NumUnits: numUnits, Locker: locker, Recipient: recipient, + LockInfo: lockInfo, ExpiryTimeSecs: currentTimeSecs - defaultTimeLockSecs} assetLockValBytes, _ = json.Marshal(assetLockVal) chaincodeStub.GetStateReturnsOnCall(3, assetLockValBytes, nil) chaincodeStub.DelStateReturnsOnCall(0, fmt.Errorf("unable to delete contractId from world state")) err = interopcc.UnlockFungibleAsset(ctx, contractId) require.Error(t, err) - require.EqualError(t, err, "failed to delete the contractId " + - contractId + " as part of fungible asset unlock: unable to delete contractId from world state") + require.EqualError(t, err, "failed to delete the contractId "+ + contractId+" as part of fungible asset unlock: unable to delete contractId from world state") fmt.Printf("Test failed as expected with error: %s\n", err) // Test success with fungible asset being unlocked using contractId diff --git a/core/network/fabric-interop-cc/contracts/interop/setup_test.go b/core/network/fabric-interop-cc/contracts/interop/setup_test.go index ad17e2bbc..75e2dde06 100644 --- a/core/network/fabric-interop-cc/contracts/interop/setup_test.go +++ b/core/network/fabric-interop-cc/contracts/interop/setup_test.go @@ -13,11 +13,11 @@ import ( "os" "testing" + "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop/mocks" "github.com/hyperledger/fabric-chaincode-go/pkg/cid" "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-contract-api-go/contractapi" log "github.com/sirupsen/logrus" - "github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop/mocks" ) const ( diff --git a/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go b/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go new file mode 100644 index 000000000..66b128faa --- /dev/null +++ b/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go @@ -0,0 +1,853 @@ +/* + * Copyright IBM Corp. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// manage_assets is a chaincode that contains all the code related to asset management operations (e.g., Lock, Unlock, Claim) +// and any related utility functions +package assetexchange + +import ( + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "strconv" + "time" + + "github.com/golang/protobuf/proto" + "github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go/common" + "github.com/hyperledger/fabric-contract-api-go/contractapi" + mspProtobuf "github.com/hyperledger/fabric-protos-go/msp" + log "github.com/sirupsen/logrus" +) + +// Object used to capture the HashLock details used in Asset Locking +type HashLock struct { + HashBase64 string `json:"hashBase64"` +} + +// Object used in the map, --> (for non-fungible assets) +type AssetLockValue struct { + Locker string `json:"locker"` + Recipient string `json:"recipient"` + LockInfo interface{} `json:"lockInfo"` + ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` +} + +// Object used in the map, contractId --> (for fungible assets) +type FungibleAssetLockValue struct { + Type string `json:"type"` + NumUnits uint64 `json:"numUnits"` + Locker string `json:"locker"` + Recipient string `json:"recipient"` + LockInfo interface{} `json:"lockInfo"` + ExpiryTimeSecs uint64 `json:"expiryTimeSecs"` +} + +const ( + assetKeyPrefix = "AssetKey_" // prefix for the map, asset-key --> asset-object + assetKeyDelimiter = "_" // delimiter for the asset-key + contractIdPrefix = "ContractId_" // prefix for the map, contractId --> asset-key +) + +// helper functions to log and return errors +func logThenErrorf(format string, args ...interface{}) error { + errorMsg := fmt.Sprintf(format, args...) + log.Error(errorMsg) + return errors.New(errorMsg) +} + +// function to generate a "SHA256" hash in base64 format for a given preimage +func GenerateSHA256HashInBase64Form(preimage string) string { + hasher := sha256.New() + hasher.Write([]byte(preimage)) + shaHash := hasher.Sum(nil) + shaHashBase64 := base64.StdEncoding.EncodeToString(shaHash) + return shaHashBase64 +} + +// function to return the key to fetch an element from the map using contractId +func generateContractIdMapKey(contractId string) string { + return contractIdPrefix + contractId +} + +/* + * Function to generate asset-lock key (which is combination of asset-type and asset-id) + * and contract-id (which is a hash on asset-lock key) for the non-fungible asset locking on the ledger + */ +func GenerateAssetLockKeyAndContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) (string, string, error) { + assetLockKey, err := ctx.GetStub().CreateCompositeKey("AssetExchangeContract", []string{assetAgreement.Type, assetAgreement.Id}) + if err != nil { + return "", "", logThenErrorf("error while creating composite key: %+v", err) + } + + contractId := GenerateSHA256HashInBase64Form(assetLockKey) + return assetLockKey, contractId, nil +} + +/* + * Function to generate contract-id for fungible asset-locking on the ledger (which is + * a hash on the attributes of the fungible asset exchange agreement) + */ +func GenerateFungibleAssetLockContractId(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) string { + preimage := assetAgreement.Type + strconv.Itoa(int(assetAgreement.NumUnits)) + + assetAgreement.Locker + assetAgreement.Recipient + ctx.GetStub().GetTxID() + contractId := GenerateSHA256HashInBase64Form(preimage) + return contractId +} + +// function to get the caller identity from the transaction context +func getECertOfTxCreatorBase64(ctx contractapi.TransactionContextInterface) (string, error) { + + txCreatorBytes, err := ctx.GetStub().GetCreator() + if err != nil { + return "", logThenErrorf("unable to get the transaction creator information: %+v", err) + } + log.Infof("getECertOfTxCreatorBase64: TxCreator: %s", string(txCreatorBytes)) + + serializedIdentity := &mspProtobuf.SerializedIdentity{} + err = proto.Unmarshal(txCreatorBytes, serializedIdentity) + if err != nil { + return "", logThenErrorf("getECertOfTxCreatorBase64: unmarshal error: %+v", err) + } + log.Infof("getECertOfTxCreatorBase64: TxCreator ECert: %s", string(serializedIdentity.IdBytes)) + + eCertBytesBase64 := base64.StdEncoding.EncodeToString(serializedIdentity.IdBytes) + + return eCertBytesBase64, nil +} + +/* + * Function to validate the locker in asset agreement. + * If locker is not set, it will be set to the caller. + * If the locker is set already, it ensures that the locker is same as the creator of the transaction. + */ +func validateAndSetLockerOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Locker) == 0 { + assetAgreement.Locker = txCreatorECertBase64 + } else if assetAgreement.Locker != txCreatorECertBase64 { + return logThenErrorf("locker %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) + } + + return nil +} + +/* + * Function to validate the locker in fungible asset agreement. + * If locker is not set, it will be set to the caller. + * If the locker is set already, it ensures that the locker is same as the creator of the transaction. + */ +func validateAndSetLockerOfFungibleAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.FungibleAssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Locker) == 0 { + assetAgreement.Locker = txCreatorECertBase64 + } else if assetAgreement.Locker != txCreatorECertBase64 { + return logThenErrorf("locker %s in the fungible asset agreement is not same as the transaction creator %s", assetAgreement.Locker, txCreatorECertBase64) + } + + return nil +} + +/* + * Function to validate the recipient in asset agreement. + * If recipient is not set, it will be set to the caller. + * If the recipeint is set already, it ensures that the recipient is same as the creator of the transaction. + */ +func validateAndSetRecipientOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf(err.Error()) + } + if len(assetAgreement.Recipient) == 0 { + assetAgreement.Recipient = txCreatorECertBase64 + } else if assetAgreement.Recipient != txCreatorECertBase64 { + return logThenErrorf("recipient %s in the asset agreement is not same as the transaction creator %s", assetAgreement.Recipient, txCreatorECertBase64) + } + + return nil +} + +func getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64 string) (interface{}, uint64, error) { + var lockInfoVal interface{} + var expiryTimeSecs uint64 + + lockInfoBytes, err := base64.StdEncoding.DecodeString(lockInfoBytesBase64) + if err != nil { + return lockInfoVal, 0, fmt.Errorf("error in base64 decode of lock information: %+v", err) + } + lockInfo := &common.AssetLock{} + err = proto.Unmarshal([]byte(lockInfoBytes), lockInfo) + if err != nil { + return lockInfoVal, 0, logThenErrorf(err.Error()) + } + + // process lock details here (lockInfo.LockInfo contains value based on the lock mechanism used) + if lockInfo.LockMechanism == common.LockMechanism_HTLC { + lockInfoHTLC := &common.AssetLockHTLC{} + err := proto.Unmarshal(lockInfo.LockInfo, lockInfoHTLC) + if err != nil { + return lockInfoVal, 0, logThenErrorf("unmarshal error: %s", err) + } + //display the passed hash lock information + log.Infof("lockInfoHTLC: %+v", lockInfoHTLC) + lockInfoVal = HashLock{HashBase64: string(lockInfoHTLC.HashBase64)} + // process time lock details here + if lockInfoHTLC.TimeSpec != common.AssetLockHTLC_EPOCH { + return lockInfoVal, 0, logThenErrorf("only EPOCH time is supported at present") + } + expiryTimeSecs = lockInfoHTLC.ExpiryTimeSecs + } else { + return lockInfoVal, 0, logThenErrorf("lock mechanism is not supported") + } + return lockInfoVal, expiryTimeSecs, nil +} + +// LockAsset cc is used to record locking of an asset on the ledger +func LockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return "", logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf("error in locker validation: %+v", err) + } + + lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockVal := AssetLockValue{Locker: assetAgreement.Locker, Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + if assetLockValBytes != nil { + return "", logThenErrorf("asset of type %s and ID %s is already locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockValBytes, err = json.Marshal(assetLockVal) + if err != nil { + return "", logThenErrorf("marshal error: %+v", err) + } + + err = ctx.GetStub().PutState(assetLockKey, assetLockValBytes) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + assetLockKeyBytes, err := json.Marshal(assetLockKey) + if err != nil { + return "", logThenErrorf("marshal error: %+v", err) + } + + err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockKeyBytes) + if err != nil { + return "", logThenErrorf(err.Error()) + } + return contractId, nil +} + +// UnlockAsset cc is used to record unlocking of an asset on the ledger +func UnlockAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) error { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return logThenErrorf("error in validation of asset agreement parties: %+v", err) + } + + assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return logThenErrorf("unmarshal error: %s", err) + } + + if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return logThenErrorf("cannot unlock asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock asset of type %s and ID %s as the expiry time is not yet elapsed", assetAgreement.Type, assetAgreement.Id) + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) + } + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) + } + + return nil +} + +// IsAssetLocked cc is used to query the ledger and findout if an asset is locked or not +func IsAssetLocked(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string) (bool, error) { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return false, logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return false, logThenErrorf(err.Error()) + } + //display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v", assetAgreement) + + assetLockKey, _, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return false, logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return false, logThenErrorf("unmarshal error: %s", err) + } + log.Infof("assetLockVal: %+v", assetLockVal) + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for asset of type %s and ID %s is already elapsed", assetAgreement.Type, assetAgreement.Id) + } + + // '*' for recipient or locker in the query implies that the query seeks status for an arbitrary recipient or locker respectively + if (assetAgreement.Locker == "*" || assetLockVal.Locker == assetAgreement.Locker) && (assetAgreement.Recipient == "*" || assetLockVal.Recipient == assetAgreement.Recipient) { + return true, nil + } else if assetAgreement.Locker == "*" && assetLockVal.Recipient != assetAgreement.Recipient { + return false, logThenErrorf("asset of type %s and ID %s is not locked for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Recipient) + } else if assetAgreement.Recipient == "*" && assetLockVal.Locker != assetAgreement.Locker { + return false, logThenErrorf("asset of type %s and ID %s is not locked by %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker) + } else if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return false, logThenErrorf("asset of type %s and ID %s is not locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetAgreement.Locker, assetAgreement.Recipient) + } + + return true, nil +} + +/* + * Function to check if hashBase64 is the hash for the preimage preimageBase64. + * Both the preimage and hash are passed in base64 form. + */ +func checkIfCorrectPreimage(preimageBase64 string, hashBase64 string) (bool, error) { + funName := "checkIfCorrectPreimage" + preimage, err := base64.StdEncoding.DecodeString(preimageBase64) + if err != nil { + return false, logThenErrorf("base64 decode preimage error: %s", err) + } + + shaHashBase64 := GenerateSHA256HashInBase64Form(string(preimage)) + if shaHashBase64 == hashBase64 { + log.Infof("%s: preimage %s is passed correctly", funName, preimage) + } else { + log.Infof("%s: preimage %s is not passed correctly", funName, preimage) + return false, nil + } + return true, nil +} + +func validateHashPreimage(claimInfo *common.AssetClaim, lockInfo interface{}) (bool, error) { + claimInfoHTLC := &common.AssetClaimHTLC{} + err := proto.Unmarshal(claimInfo.ClaimInfo, claimInfoHTLC) + if err != nil { + return false, logThenErrorf("unmarshal claimInfo.ClaimInfo error: %s", err) + } + //display the claim information + log.Infof("claimInfoHTLC: %+v\n", claimInfoHTLC) + lockInfoVal := HashLock{} + lockInfoBytes, err := json.Marshal(lockInfo) + if err != nil { + return false, logThenErrorf("marshal lockInfo error: %s", err) + } + err = json.Unmarshal(lockInfoBytes, &lockInfoVal) + if err != nil { + return false, logThenErrorf("unmarshal lockInfoBytes error: %s", err) + } + log.Infof("HashLock: %+v\n", lockInfoVal) + + // match the hash passed during claim with the hash stored during asset locking + return checkIfCorrectPreimage(string(claimInfoHTLC.HashPreimageBase64), lockInfoVal.HashBase64) +} + +// fetches common.AssetClaim from the input parameter and checks if the lock mechanism is valid or not +func getClaimInfo(claimInfoBytesBase64 string) (*common.AssetClaim, error) { + claimInfo := &common.AssetClaim{} + + claimInfoBytes, err := base64.StdEncoding.DecodeString(claimInfoBytesBase64) + if err != nil { + return claimInfo, logThenErrorf("error in base64 decode of claim information: %+v", err) + } + + err = proto.Unmarshal([]byte(claimInfoBytes), claimInfo) + if err != nil { + return claimInfo, logThenErrorf("unmarshal error: %s", err) + } + // check if a valid lock mechanism is provided + if claimInfo.LockMechanism != common.LockMechanism_HTLC { + return claimInfo, logThenErrorf("lock mechanism is not supported") + } + + return claimInfo, nil +} + +// ClaimAsset cc is used to record claim of an asset on the ledger +func ClaimAsset(ctx contractapi.TransactionContextInterface, assetAgreementBytesBase64 string, claimInfoBytesBase64 string) error { + + assetAgreementBytes, err := base64.StdEncoding.DecodeString(assetAgreementBytesBase64) + if err != nil { + return logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.AssetExchangeAgreement{} + err = proto.Unmarshal([]byte(assetAgreementBytes), assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + // display the requested asset agreement + log.Infof("assetExchangeAgreement: %+v\n", assetAgreement) + + err = validateAndSetRecipientOfAssetAgreement(ctx, assetAgreement) + if err != nil { + return logThenErrorf("error in recipient validation: %+v", err) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockKey, contractId, err := GenerateAssetLockKeyAndContractId(ctx, assetAgreement) + if err != nil { + return logThenErrorf(err.Error()) + } + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return logThenErrorf(err.Error()) + } + + if assetLockValBytes == nil { + return logThenErrorf("no asset of type %s and ID %s is locked", assetAgreement.Type, assetAgreement.Id) + } + + assetLockVal := AssetLockValue{} + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return logThenErrorf("unmarshal error: %s", err) + } + + if assetLockVal.Locker != assetAgreement.Locker || assetLockVal.Recipient != assetAgreement.Recipient { + return logThenErrorf("cannot claim asset of type %s and ID %s as it is locked by %s for %s", assetAgreement.Type, assetAgreement.Id, assetLockVal.Locker, assetLockVal.Recipient) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim asset of type %s and ID %s as the expiry time is already elapsed", assetAgreement.Type, assetAgreement.Id) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim asset of type %s and ID %s error: %v", assetAgreement.Type, assetAgreement.Id, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim asset of type %s and ID %s as the hash preimage is not matching", assetAgreement.Type, assetAgreement.Id) + } + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for asset of type %s and ID %s: %v", assetAgreement.Type, assetAgreement.Id, err) + } + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset claim: %v", contractId, err) + } + + return nil +} + +// function to fetch the asset-lock from the ledger using contractId +func fetchAssetLockedUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (string, AssetLockValue, error) { + var assetLockVal = AssetLockValue{} + var assetLockKey string = "" + assetLockKeyBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf(err.Error()) + } + + if assetLockKeyBytes == nil { + return assetLockKey, assetLockVal, logThenErrorf("no contractId %s exists on the ledger", contractId) + } + + err = json.Unmarshal(assetLockKeyBytes, &assetLockKey) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("assetLockKey unmarshal error: %s", err) + } + log.Infof("contractId: %s and assetLockKey: %s", contractId, assetLockKey) + + assetLockValBytes, err := ctx.GetStub().GetState(assetLockKey) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes == nil { + return assetLockKey, assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked asset", contractId) + } + + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return assetLockKey, assetLockVal, logThenErrorf("assetLockVal unmarshal error: %s", err) + } + return assetLockKey, assetLockVal, nil +} + +// UnlockAssetUsingContractId cc is used to record unlocking of an asset on the ledger (this uses the contractId) +func UnlockAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) error { + + assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the locker of the locked fungible asset + if assetLockVal.Locker != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %v", contractId, err) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset unlock: %v", contractId, err) + } + + return nil +} + +// ClaimAsset cc is used to record claim of an asset on the ledger (this uses the contractId) +func ClaimAssetUsingContractId(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { + + assetLockKey, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + if assetLockVal.Recipient != string(txCreatorECertBase64) { + return logThenErrorf("asset is not locked for %s to claim", string(txCreatorECertBase64)) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim asset associated with contractId %s as the expiry time is already elapsed", contractId) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim asset associated with contractId %s failed with error: %v", contractId, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim asset associated with contractId %s as the hash preimage is not matching", contractId) + } + } + + err = ctx.GetStub().DelState(assetLockKey) + if err != nil { + return logThenErrorf("failed to delete lock for the asset associated with the contractId %s: %+v", contractId, err) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of asset claim: %+v", contractId, err) + } + + return nil +} + +// IsAssetLocked cc is used to query the ledger and find out if an asset is locked or not (this uses the contractId) +func IsAssetLockedQueryUsingContractId(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { + + _, assetLockVal, err := fetchAssetLockedUsingContractId(ctx, contractId) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for asset associated with contractId %s is already elapsed", contractId) + } + + return true, nil +} + +// LockFungibleAsset cc is used to record locking of a group of fungible assets of an asset-type on the ledger +func LockFungibleAsset(ctx contractapi.TransactionContextInterface, fungibleAssetAgreementBytesBase64 string, lockInfoBytesBase64 string) (string, error) { + + fungibleAssetAgreementBytes, err := base64.StdEncoding.DecodeString(fungibleAssetAgreementBytesBase64) + if err != nil { + return "", logThenErrorf("error in base64 decode of asset agreement: %+v", err) + } + + assetAgreement := &common.FungibleAssetExchangeAgreement{} + err = proto.Unmarshal([]byte(fungibleAssetAgreementBytes), assetAgreement) + if err != nil { + return "", logThenErrorf("unmarshal error: %s", err) + } + + //display the requested fungible asset agreement + log.Infof("fungibleAssetExchangeAgreement: %+v", assetAgreement) + + err = validateAndSetLockerOfFungibleAssetAgreement(ctx, assetAgreement) + if err != nil { + return "", logThenErrorf("error in locker validation: %+v", err) + } + + lockInfo, expiryTimeSecs, err := getLockInfoAndExpiryTimeSecs(lockInfoBytesBase64) + if err != nil { + return "", logThenErrorf(err.Error()) + } + + // generate the contractId for the fungible asset lock agreement + contractId := GenerateFungibleAssetLockContractId(ctx, assetAgreement) + + assetLockVal := FungibleAssetLockValue{Type: assetAgreement.Type, NumUnits: assetAgreement.NumUnits, Locker: assetAgreement.Locker, + Recipient: assetAgreement.Recipient, LockInfo: lockInfo, ExpiryTimeSecs: expiryTimeSecs} + + assetLockValBytes, err := ctx.GetStub().GetState(contractId) + if err != nil { + return "", logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes != nil { + return "", logThenErrorf("contractId %s already exists for the requested fungible asset agreement", contractId) + } + + assetLockValBytes, err = json.Marshal(assetLockVal) + if err != nil { + return "", logThenErrorf("marshal error: %s", err) + } + + err = ctx.GetStub().PutState(generateContractIdMapKey(contractId), assetLockValBytes) + if err != nil { + return "", logThenErrorf("failed to write to the world state: %+v", err) + } + + return contractId, nil +} + +// function to fetch the fungible asset-lock value from the ledger using contractId +func fetchFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (FungibleAssetLockValue, error) { + var assetLockVal = FungibleAssetLockValue{} + + assetLockValBytes, err := ctx.GetStub().GetState(generateContractIdMapKey(contractId)) + if err != nil { + return assetLockVal, logThenErrorf("failed to retrieve from the world state: %+v", err) + } + + if assetLockValBytes == nil { + return assetLockVal, logThenErrorf("contractId %s is not associated with any currently locked fungible asset", contractId) + } + + err = json.Unmarshal(assetLockValBytes, &assetLockVal) + if err != nil { + return assetLockVal, logThenErrorf("unmarshal error: %s", err) + } + log.Infof("contractId: %s and fungibleAssetLockVal: %+v", contractId, assetLockVal) + + return assetLockVal, nil +} + +// IsFungibleAssetLocked cc is used to query the ledger and find out if a fungible asset is locked or not +func IsFungibleAssetLocked(ctx contractapi.TransactionContextInterface, contractId string) (bool, error) { + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return false, logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return false, logThenErrorf("expiry time for fungible asset associated with contractId %s is already elapsed", contractId) + } + + return true, nil +} + +// ClaimFungibleAsset cc is used to record claim of a fungible asset on the ledger +func ClaimFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string, claimInfoBytesBase64 string) error { + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the recipient of the locked fungible asset + if assetLockVal.Recipient != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to claim", txCreatorECertBase64) + } + + claimInfo, err := getClaimInfo(claimInfoBytesBase64) + if err != nil { + return logThenErrorf(err.Error()) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs >= assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot claim fungible asset associated with contractId %s as the expiry time is already elapsed", contractId) + } + + if claimInfo.LockMechanism == common.LockMechanism_HTLC { + isCorrectPreimage, err := validateHashPreimage(claimInfo, assetLockVal.LockInfo) + if err != nil { + return logThenErrorf("claim fungible asset associated with contractId %s failed with error: %v", contractId, err) + } + if !isCorrectPreimage { + return logThenErrorf("cannot claim fungible asset associated with contractId %s as the hash preimage is not matching", contractId) + } + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of fungible asset claim: %+v", contractId, err) + } + + return nil +} + +// UnlockFungibleAsset cc is used to record unlocking of a fungible asset on the ledger +func UnlockFungibleAsset(ctx contractapi.TransactionContextInterface, contractId string) error { + + assetLockVal, err := fetchFungibleAssetLocked(ctx, contractId) + if err != nil { + return logThenErrorf(err.Error()) + } + + txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) + if err != nil { + return logThenErrorf("unable to get the transaction creator information: %+v", err) + } + + // transaction creator needs to be the locker of the locked fungible asset + if assetLockVal.Locker != txCreatorECertBase64 { + return logThenErrorf("asset is not locked for %s to unlock", txCreatorECertBase64) + } + + // Check if expiry time is elapsed + currentTimeSecs := uint64(time.Now().Unix()) + if currentTimeSecs < assetLockVal.ExpiryTimeSecs { + return logThenErrorf("cannot unlock fungible asset associated with the contractId %s as the expiry time is not yet elapsed", contractId) + } + + err = ctx.GetStub().DelState(generateContractIdMapKey(contractId)) + if err != nil { + return logThenErrorf("failed to delete the contractId %s as part of fungible asset unlock: %v", contractId, err) + } + + return nil +} diff --git a/core/network/fabric-interop-cc/libs/assetexchange/go.mod b/core/network/fabric-interop-cc/libs/assetexchange/go.mod new file mode 100644 index 000000000..b74f8f307 --- /dev/null +++ b/core/network/fabric-interop-cc/libs/assetexchange/go.mod @@ -0,0 +1,11 @@ +module github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/libs/assetexchange + +go 1.15 + +require ( + github.com/golang/protobuf v1.5.2 + github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 + github.com/hyperledger/fabric-contract-api-go v1.1.1 + github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 + github.com/sirupsen/logrus v1.8.1 +) diff --git a/core/network/fabric-interop-cc/libs/assetexchange/go.sum b/core/network/fabric-interop-cc/libs/assetexchange/go.sum new file mode 100644 index 000000000..167bb9f2f --- /dev/null +++ b/core/network/fabric-interop-cc/libs/assetexchange/go.sum @@ -0,0 +1,224 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2AZ5Ki+A= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo= +github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= +github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= +github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= +github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= +github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hyperledger-labs/weaver-dlt-interoperability v0.0.0-20210726084038-2210f22a1d24 h1:mDWoIWHe2zPqdMznLpWR4n35xkQrPQYP0uzcndBXIT8= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1 h1:c9VK82wttYXTe4/UfnDq2Gq1Zu4Yxcxx1PbhEQHKuvA= +github.com/hyperledger-labs/weaver-dlt-interoperability/common/protos-go v1.2.1/go.mod h1:yJq9oxxBHPryM8hVFiqM5HgfV2XFj5Tzb9Unx9D+YuI= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 h1:1i4lnpV8BDgKOLi1hgElfBqdHXjXieSuj8629mwBZ8o= +github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc= +github.com/hyperledger/fabric-contract-api-go v1.1.1 h1:gDhOC18gjgElNZ85kFWsbCQq95hyUP/21n++m0Sv6B0= +github.com/hyperledger/fabric-contract-api-go v1.1.1/go.mod h1:+39cWxbh5py3NtXpRA63rAH7NzXyED+QJx1EZr0tJPo= +github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871 h1:d7do07Q4LaOFAEWceRwUwVDdcfx3BdLeZYyUGtbHfRk= +github.com/hyperledger/fabric-protos-go v0.0.0-20210720123151-f0dc3e2a0871/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tests/network-setups/fabric/dev/scripts/setupCC.sh b/tests/network-setups/fabric/dev/scripts/setupCC.sh index 7140f6c0f..c8df85769 100755 --- a/tests/network-setups/fabric/dev/scripts/setupCC.sh +++ b/tests/network-setups/fabric/dev/scripts/setupCC.sh @@ -2,6 +2,7 @@ directory=$(dirname $0) TMP_PATH=$PWD/../shared/tmp CHAINCODE_PATH=$PWD/../shared/chaincode +INTEROPCC_CHAINCODE_PATH=$PWD/../../../../core/network # interop cc module INTEROPCC_MOD=github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop @@ -15,8 +16,9 @@ export GOPATH=$TMP_PATH # Download interopcc and copy it into correct folder go get -d "${INTEROPCC_MOD}${INTEROP_VERSION}" cp -r $TMP_PATH/pkg/mod/github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop* $CHAINCODE_PATH/interop +cp -r $INTEROPCC_CHAINCODE_PATH/fabric-interop-cc/libs/assetexchange $CHAINCODE_PATH/interop # Clean tmp and Undo gopath go clean -modcache rm -rf $TMP_PATH -export GOPATH=${OLD_GOPATH} \ No newline at end of file +export GOPATH=${OLD_GOPATH} diff --git a/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh b/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh index 098645997..40ac983e7 100755 --- a/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh +++ b/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh @@ -2,6 +2,7 @@ directory=$(dirname $0) CHAINCODE_PATH=$directory/../../../fabric/shared/chaincode INTEROP_CC_PATH=$PWD/../../../../core/network/fabric-interop-cc +INTEROPCC_CHAINCODE_PATH=$PWD/../../../../core/network echo "Setting up Interop CC..." @@ -10,7 +11,7 @@ if [ -d "fabric-interop-cc" ]; then echo "Deleting INTEROP CC in the test folder to copy the latest from the main folder...." rm -rf fabric-interop-cc fi -if [ -d "interop"]; then +if [ -d "interop" ]; then echo "Deleting previously built interop cc folder" rm -rf interop fi @@ -18,6 +19,7 @@ cp -r ${INTEROP_CC_PATH} . cd fabric-interop-cc cp -R contracts/interop ../interop +cp -r $INTEROPCC_CHAINCODE_PATH/fabric-interop-cc/libs/assetexchange ../interop echo "Done." From 7ce14af1554e43273b4bca20663ffae6ec8895d6 Mon Sep 17 00:00:00 2001 From: Krishnasuri Narayanam Date: Mon, 26 Jul 2021 18:32:53 +0530 Subject: [PATCH 4/7] steps to exercise asset exchange added to readme file Signed-off-by: Krishnasuri Narayanam --- samples/fabric/fabric-cli/readme.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/samples/fabric/fabric-cli/readme.md b/samples/fabric/fabric-cli/readme.md index 5e120c984..4baeb46eb 100644 --- a/samples/fabric/fabric-cli/readme.md +++ b/samples/fabric/fabric-cli/readme.md @@ -146,7 +146,26 @@ Example config: ## Asset Exchange - Sample `fabric-cli asset exchange-step` commands: +Below are the steps to exercise asset exchange using `fabric-cli`. +1. Spin up both `network1` and `network2` with interoperation chaincode installed along with the `simpleasset` application, by running +```bash + make start-interop CHAINCODE_NAME=simpleasset +``` +2. Go to `fabric-cli` directory and run the below script that performs: setting the enviroment, adding the users `Alice` and `Bob` to both the networks and finally adds the non-fungible (i.e., bonds) and fungible (i.e., tokens) assets into the accounts of `Alice` and `Bob`. +```bash + sh scripts/initAsset.sh +``` +3. Check the status of the assets owned by `Alice` and `Bob` in the the networks `network1` and `network2`, by running +```bash + sh scripts/getAssetStatus.sh +``` +4. Initiate exchange of bond asset `bond01:a04` of `Bob` in `network1` with token assets `token1:100` of `Alice` in `network2`, by running (with the help of `fabric-cli asset exchange-all` CLI command) +```bash + sh scripts/invoke-asset-exchange.sh +``` +- Note: Observe the change in the ownership of assets at the end of the execution of the above script. + +5. The same asset exchange experiment in the above step, can be carried out by manually triggering below commands in serial order (with the help of `fabric-cli asset exchange-step` CLI commands): ``` ./bin/fabric-cli asset exchange-step --step=1 --timeout-duration=3600 --locker=alice --recipient=bob --secret= --target-network=network1 --param=bond01:a03 ./bin/fabric-cli asset exchange-step --step=2 --locker=alice --recipient=bob --target-network=network1 --param=bond01:a03 From ea46da57f2a95b6efd61632a15649e875eb7528a Mon Sep 17 00:00:00 2001 From: Krishnasuri Narayanam Date: Tue, 27 Jul 2021 11:57:58 +0530 Subject: [PATCH 5/7] correcting typos and reuse exiting env vars Signed-off-by: Krishnasuri Narayanam --- samples/fabric/fabric-cli/readme.md | 6 +++--- tests/network-setups/fabric/dev/scripts/setupCC.sh | 4 ++-- tests/network-setups/fabric/dev/scripts/setupCCLocal.sh | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/fabric/fabric-cli/readme.md b/samples/fabric/fabric-cli/readme.md index 4baeb46eb..4367004f2 100644 --- a/samples/fabric/fabric-cli/readme.md +++ b/samples/fabric/fabric-cli/readme.md @@ -151,7 +151,7 @@ Below are the steps to exercise asset exchange using `fabric-cli`. ```bash make start-interop CHAINCODE_NAME=simpleasset ``` -2. Go to `fabric-cli` directory and run the below script that performs: setting the enviroment, adding the users `Alice` and `Bob` to both the networks and finally adds the non-fungible (i.e., bonds) and fungible (i.e., tokens) assets into the accounts of `Alice` and `Bob`. +2. Go to `fabric-cli` directory and run the below script that performs: setting the enviroment, adding the users `Alice` and `Bob` to both the networks and finally adding the non-fungible (i.e., bonds) and fungible (i.e., tokens) assets into the accounts of `Alice` and `Bob`. ```bash sh scripts/initAsset.sh ``` @@ -163,7 +163,7 @@ Below are the steps to exercise asset exchange using `fabric-cli`. ```bash sh scripts/invoke-asset-exchange.sh ``` -- Note: Observe the change in the ownership of assets at the end of the execution of the above script. +- Observe the change in the ownership of assets at the end of the execution of the above script. 5. The same asset exchange experiment in the above step, can be carried out by manually triggering below commands in serial order (with the help of `fabric-cli asset exchange-step` CLI commands): ``` @@ -173,7 +173,7 @@ Below are the steps to exercise asset exchange using `fabric-cli`. ./bin/fabric-cli asset exchange-step --step=4 --locker=bob --recipient=alice --target-network=network2 --contract-id= ./bin/fabric-cli asset exchange-step --step=5 --recipient=alice --locker=bob --target-network=network2 --contract-id= --secret= ./bin/fabric-cli asset exchange-step --step=6 --recipient=bob --locker=alice --target-network=network1 --param=bond01:a03 --secret= - ./bin/fabric-cli asset exchange-step --step=7 --locker=bob --recipient=alice --target-network=network1 --param=bond01:a03 + ./bin/fabric-cli asset exchange-step --step=7 --locker=alice --recipient=bob --target-network=network1 --param=bond01:a03 ./bin/fabric-cli asset exchange-step --step=8 --locker=bob --recipient=alice --target-network=network2 --contract-id= ``` diff --git a/tests/network-setups/fabric/dev/scripts/setupCC.sh b/tests/network-setups/fabric/dev/scripts/setupCC.sh index c8df85769..8c7c183cc 100755 --- a/tests/network-setups/fabric/dev/scripts/setupCC.sh +++ b/tests/network-setups/fabric/dev/scripts/setupCC.sh @@ -2,7 +2,7 @@ directory=$(dirname $0) TMP_PATH=$PWD/../shared/tmp CHAINCODE_PATH=$PWD/../shared/chaincode -INTEROPCC_CHAINCODE_PATH=$PWD/../../../../core/network +INTEROP_CC_PATH=$PWD/../../../../core/network/fabric-interop-cc # interop cc module INTEROPCC_MOD=github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop @@ -16,7 +16,7 @@ export GOPATH=$TMP_PATH # Download interopcc and copy it into correct folder go get -d "${INTEROPCC_MOD}${INTEROP_VERSION}" cp -r $TMP_PATH/pkg/mod/github.com/hyperledger-labs/weaver-dlt-interoperability/core/network/fabric-interop-cc/contracts/interop* $CHAINCODE_PATH/interop -cp -r $INTEROPCC_CHAINCODE_PATH/fabric-interop-cc/libs/assetexchange $CHAINCODE_PATH/interop +cp -r $INTEROP_CC_PATH/libs/assetexchange $CHAINCODE_PATH/interop # Clean tmp and Undo gopath go clean -modcache diff --git a/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh b/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh index 40ac983e7..57ad1e6ec 100755 --- a/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh +++ b/tests/network-setups/fabric/dev/scripts/setupCCLocal.sh @@ -19,7 +19,7 @@ cp -r ${INTEROP_CC_PATH} . cd fabric-interop-cc cp -R contracts/interop ../interop -cp -r $INTEROPCC_CHAINCODE_PATH/fabric-interop-cc/libs/assetexchange ../interop +cp -r $INTEROP_CC_PATH/libs/assetexchange ../interop echo "Done." From 0156b169c6ccddaf0f21b198a455c4dc4a7087a0 Mon Sep 17 00:00:00 2001 From: Krishnasuri Narayanam Date: Tue, 27 Jul 2021 12:01:37 +0530 Subject: [PATCH 6/7] correcting typos and reuse exiting env vars Signed-off-by: Krishnasuri Narayanam --- .../fabric-interop-cc/libs/assetexchange/assetSwapContracts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go b/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go index 66b128faa..be4b1fc01 100644 --- a/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go +++ b/core/network/fabric-interop-cc/libs/assetexchange/assetSwapContracts.go @@ -161,7 +161,7 @@ func validateAndSetLockerOfFungibleAssetAgreement(ctx contractapi.TransactionCon /* * Function to validate the recipient in asset agreement. * If recipient is not set, it will be set to the caller. - * If the recipeint is set already, it ensures that the recipient is same as the creator of the transaction. + * If the recipient is set already, it ensures that the recipient is same as the creator of the transaction. */ func validateAndSetRecipientOfAssetAgreement(ctx contractapi.TransactionContextInterface, assetAgreement *common.AssetExchangeAgreement) error { txCreatorECertBase64, err := getECertOfTxCreatorBase64(ctx) From 3321721e8c7ad994c14fd00ef0c2ed06ac5877f2 Mon Sep 17 00:00:00 2001 From: Krishnasuri Narayanam Date: Tue, 27 Jul 2021 13:35:45 +0530 Subject: [PATCH 7/7] update the readme to replace the script with the cli command Signed-off-by: Krishnasuri Narayanam --- samples/fabric/fabric-cli/readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/fabric/fabric-cli/readme.md b/samples/fabric/fabric-cli/readme.md index 4367004f2..b9ca019e7 100644 --- a/samples/fabric/fabric-cli/readme.md +++ b/samples/fabric/fabric-cli/readme.md @@ -159,11 +159,11 @@ Below are the steps to exercise asset exchange using `fabric-cli`. ```bash sh scripts/getAssetStatus.sh ``` -4. Initiate exchange of bond asset `bond01:a04` of `Bob` in `network1` with token assets `token1:100` of `Alice` in `network2`, by running (with the help of `fabric-cli asset exchange-all` CLI command) -```bash - sh scripts/invoke-asset-exchange.sh +4. Initiate exchange of bond asset `bond01:a04` of `Bob` in `network1` with token assets `token1:100` of `Alice` in `network2`, by running +``` +./bin/fabric-cli asset exchange-all --network1=network1 --network2=network2 --secret=secrettext --timeout-duration=100 bob:bond01:a04:alice:token1:100 ``` -- Observe the change in the ownership of assets at the end of the execution of the above script. +- Repeat the step 3 to observe the change in the ownership of assets as a result of the `asset echange` exercise. 5. The same asset exchange experiment in the above step, can be carried out by manually triggering below commands in serial order (with the help of `fabric-cli asset exchange-step` CLI commands): ```