Skip to content

Commit

Permalink
Merge pull request #66 from hyperledger-labs/develop
Browse files Browse the repository at this point in the history
CC-Tools 1.0
  • Loading branch information
samuelvenzi authored Jul 2, 2024
2 parents 0994f9b + 78fde59 commit c77a8f4
Show file tree
Hide file tree
Showing 73 changed files with 2,713 additions and 1,848 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18
go-version: 1.21

- name: Build
run: go build -v github.com/hyperledger-labs/cc-tools-demo/chaincode

- name: Test
run: go test github.com/hyperledger-labs/cc-tools-demo/chaincode -coverpkg=./... -v
- name: Unit tests
run: go test github.com/hyperledger-labs/cc-tools-demo/chaincode -coverpkg=./... -v

- name: Integration tests
run: go test -v ./tests
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ node_modules
fabric/crypto-config
fabric/channel-artifacts
fabric/ca
fabric/bin
fabric/builders
chaincode/vendor/*
chaincode/collections.json
ccapi/vendor/*
cc-tools-demo.tar.gz
package-lock.json
Expand Down
93 changes: 93 additions & 0 deletions DCO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Probot: DCO

a GitHub Integration built with [probot](https://github.com/probot/probot) that enforces the [Developer Certificate of Origin](https://developercertificate.org/) (DCO) on Pull Requests. It requires all commit messages to contain the `Signed-off-by` line with an email address that matches the commit author.

## Usage

[Configure the integration](https://github.com/apps/dco) for your organization or repositories. Enable [required status checks](docs/required-statuses.md) if you want to enforce the DCO on all commits.

See [docs/deploy.md](docs/deploy.md) if you would like to run your own instance of this plugin.

## Modes of operations

### Default

By default, Probot DCO enforces the presence of [valid DCO signoffs](#how-it-works) on all commits (excluding bots and merges). If a PRs contains commits that lack a valid Signed-off-by line, they are blocked until a correctly signed-off revision of the commit is pushed. This closely mirrors the upstream Linux kernel process.

### Individual remediation commit support

Optionally, a project can allow individual remediation commit support, where the failing commit's author can push an additional properly signed-off commit with additional text in the commit log that indicates they apply their signoff retroactively.

To enable this, place the following configuration file in `.github/dco.yml` on the default branch:

```yaml
allowRemediationCommits:
individual: true
```
### Third-party remediation support
Additionally, a project can allow third-parties to sign off on an author's behalf by pushing an additional properly signed-off commit with additional text in the commit log that indicates they sign off on behalf of the author. Third-party remediation requires individual remediation to be enabled.
To enable this, place the following configuration file in `.github/dco.yml` on the default branch:

```yaml
allowRemediationCommits:
individual: true
thirdParty: true
```

### Skipping sign-off for organization members

It is possible to disable the check for commits authored and [signed](https://help.github.com/articles/signing-commits-using-gpg/) by members of the organization the repository belongs to. To do this, place the following configuration file in `.github/dco.yml` on the default branch:

```yaml
require:
members: false
```

When this setting is present on a repository that belongs to a GitHub user (instead of an organization), only the repository owner is allowed to push commits without sign-off.

## How it works

The Developer Certificate of Origin (DCO) is a lightweight way for contributors to certify that they wrote or otherwise have the right to submit the code they are contributing to the project. Here is the full [text of the DCO](https://developercertificate.org/), reformatted for readability:

> By making a contribution to this project, I certify that:
>
> a. The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
>
> b. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
>
> c. The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
>
> d. I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.

Contributors _sign-off_ that they adhere to these requirements by adding a `Signed-off-by` line to commit messages.

```
This is my commit message

Signed-off-by: Random J Developer <[email protected]>
```
Git even has a `-s` command line option to append this automatically to your commit message:
```
$ git commit -s -m 'This is my commit message'
```
Once [installed](#usage), this integration will create a [check](https://developer.github.com/v3/checks/runs/) indicating whether or not commits in a Pull Request do not contain a valid `Signed-off-by` line.
![DCO success](https://user-images.githubusercontent.com/13410355/42352738-35f4e690-8071-11e8-9c8c-260e5868bfc8.png)
![DCO failure](https://user-images.githubusercontent.com/13410355/42352794-85fe1c9c-8071-11e8-834a-05a4aeb8cc90.png)
Additionally, the DCO creates an override button accessible to only those with write access to the repository to create a successful check.
![DCO button](https://user-images.githubusercontent.com/13410355/42353254-3bfa266a-8074-11e8-80b4-18760c5efeee.png)
## Further Reading
If you want to learn more about the DCO and why it might be necessary, here are some good resources:
- [Developer Certificate of Origin versus Contributor License Agreements](https://julien.ponge.org/blog/developer-certificate-of-origin-versus-contributor-license-agreements/)
- [The most powerful contributor agreement](https://lwn.net/Articles/592503/)
25 changes: 19 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

## Directory Structure

- `/fabric`: Fabric network v2.2 used as a test environment
- `/fabric`: Fabric network v2.5 used as a test environment
- `/chaincode`: chaincode-related files
- `/ccapi`: chaincode REST API in Golang project

## Development

The `cc-tools` library has been tested in Fabric v1.4, v2.2 and v2.4 networks.
The `cc-tools` library has been tested in Fabric v2.2, v2.4 and v2.5 networks.

Dependencies for chaincode and chaincode API:

- Go 1.14 or higher
- Go 1.21 or higher

Dependencies for test environment:

Expand All @@ -27,14 +27,14 @@ $ cd ccapi; go mod vendor; cd ..
```


## Deploying test env in v2.2
## Deploying test environment

After installing, use the script `./startDev.sh` in the root folder to start the development environment. It will
start all components of the project with 3 organizations.

If you want to deploy with 1 organization, run the command `./startDev.sh -n 1`.

To apply chaincode changes, run `$ ./upgradeCC2.sh <version> <sequence>` with a version higher than the current one (starts with 0.1). Append `-n 1` to the command if running with 1 organization.
To apply chaincode changes, run `$ ./upgradeCC.sh <version> <sequence>` with a version higher than the current one (starts with 0.1). Append `-n 1` to the command if running with 1 organization.

To apply CC API changes, run `$ ./reloadCCAPI.sh`.

Expand All @@ -44,10 +44,23 @@ To test transactions after starting all components, run `$ ./tryout.sh`.

To test transactions using the godog tool, run `$ ./godog.sh`.


## Generate TAR archive for the chaincode

The `generateTar.sh` script is available to generate a `tar.gz` archive of the chaincode.

By running `$ ./generateTar.sh` without any option, the script generates a `collections.json` file for the private data on the chaincode with all the organizations defined on the readers section of private asset types, and then archives the code without the CCAPI.

By using the `--org/-o` option along the script, it's possible to specify the organizations to be considered when generating the `collections.json` file. This option may be used multiple times to add all the organizations, ex: `$ ./generateTar.sh -o org1MSP -o org2MSP`.

To also archive the the CCAPI alongside the chaincode, the `--ccapi/-c` flag may be used. Example: `$ ./generateTar.sh -c`.

By standard the archive is created using the project name with *1.0* label, to change it the `--name/-n` and `--label/-l` flags may be used. Example: `$ ./generateTar.sh -n my-project -l 2.0`

## More

You can reach GoLedger developers and `cc-tools` maintainers at our Discord - [Join us!](https://discord.gg/GndkYHxNyQ)

More documentation and details on `cc-tools` can be found at [https://goledger-cc-tools.readthedocs.io/en/latest/](https://goledger-cc-tools.readthedocs.io/en/latest/)

For production deployment please consider using GoFabric - [https://gofabric.io](https://gofabric.io)
For production deployment please consider using GoFabric - [https://gofabric.io](https://gofabric.io)
2 changes: 1 addition & 1 deletion ccapi/chaincode/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func HandleEvent(channelName, ccName string, event EventHandler) {

func RegisterForEvents() {
// Get registered events on the chaincode
res, _, err := Invoke(os.Getenv("CHANNEL"), os.Getenv("CCNAME"), "getEvents", nil, nil)
res, _, err := Invoke(os.Getenv("CHANNEL"), os.Getenv("CCNAME"), "getEvents", os.Getenv("USER"), nil, nil)
if err != nil {
fmt.Println("error registering for events: ", err)
return
Expand Down
28 changes: 7 additions & 21 deletions ccapi/chaincode/eventHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"os"

"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
)

Expand Down Expand Up @@ -55,7 +54,7 @@ func (event EventHandler) Execute(ccEvent *fab.CCEvent) {
cc = event.Chaincode
}

res, _, err := Invoke(ch, cc, event.Transaction, [][]byte{ccEvent.Payload}, nil)
res, _, err := Invoke(ch, cc, event.Transaction, os.Getenv("USER"), [][]byte{ccEvent.Payload}, nil)
if err != nil {
fmt.Println("error invoking transaction: ", err)
return
Expand All @@ -81,30 +80,17 @@ func (event EventHandler) Execute(ccEvent *fab.CCEvent) {
return
}

// Invoke executeEvent tx
var res *channel.Response
var err error
// Invoke tx
txName := "executeEvent"
if event.ReadOnly {
res, _, err = Invoke(os.Getenv("CHANNEL"), os.Getenv("CCNAME"), "runEvent", [][]byte{args}, nil)
if err != nil {
fmt.Println("error invoking transaction: ", err)
return
}
} else {
res, _, err = Invoke(os.Getenv("CHANNEL"), os.Getenv("CCNAME"), "executeEvent", [][]byte{args}, nil)
if err != nil {
fmt.Println("error invoking transaction: ", err)
return
}
txName = "runEvent"
}

var response map[string]interface{}
nerr := json.Unmarshal(res.Payload, &response)
if nerr != nil {
fmt.Println("error unmarshalling response: ", nerr)
_, _, err := Invoke(os.Getenv("CHANNEL"), os.Getenv("CCNAME"), txName, os.Getenv("USER"), [][]byte{args}, nil)
if err != nil {
fmt.Println("error invoking transaction: ", err)
return
}
fmt.Println("Response: ", response)
} else {
fmt.Println("Event type not supported")
}
Expand Down
9 changes: 4 additions & 5 deletions ccapi/chaincode/invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
)

func Invoke(channelName, ccName, txName string, txArgs [][]byte, transientRequest []byte) (*channel.Response, int, error) {
func Invoke(channelName, ccName, txName, user string, txArgs [][]byte, transientRequest []byte) (*channel.Response, int, error) {
// create channel manager
fabMngr, err := common.NewFabricChClient(channelName, os.Getenv("USER"), os.Getenv("ORG"))
fabMngr, err := common.NewFabricChClient(channelName, user, os.Getenv("ORG"))
if err != nil {
return nil, http.StatusInternalServerError, err
}
Expand All @@ -29,10 +29,9 @@ func Invoke(channelName, ccName, txName string, txArgs [][]byte, transientReques
}

res, err := fabMngr.Client.Execute(rq, channel.WithRetry(retry.DefaultChannelOpts))

if err != nil {
return nil, http.StatusInternalServerError, err
return nil, extractStatusCode(err.Error()), err
}

return &res, http.StatusInternalServerError, nil
return &res, http.StatusOK, nil
}
12 changes: 6 additions & 6 deletions ccapi/chaincode/invokeGateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/pkg/errors"
)

func InvokeGateway(channelName, chaincodeName, txName, args string, transientArgs []byte, endorsingOrgs []string) ([]byte, error) {
func InvokeGateway(channelName, chaincodeName, txName, user string, args []string, transientArgs []byte, endorsingOrgs []string) ([]byte, error) {
// Gateway endpoint
endpoint := os.Getenv("FABRIC_GATEWAY_ENDPOINT")

Expand All @@ -20,7 +20,7 @@ func InvokeGateway(channelName, chaincodeName, txName, args string, transientArg
defer grpcConn.Close()

// Create gateway connection
gw, err := common.CreateGatewayConnection(grpcConn)
gw, err := common.CreateGatewayConnection(grpcConn, user)
if err != nil {
return nil, errors.Wrap(err, "failed to create gateway connection")
}
Expand All @@ -37,25 +37,25 @@ func InvokeGateway(channelName, chaincodeName, txName, args string, transientArg
// Invoke transaction
if transientArgs != nil && len(endorsingOrgs) > 0 {
return contract.Submit(txName,
client.WithArguments(args),
client.WithArguments(args...),
client.WithTransient(transientMap),
client.WithEndorsingOrganizations(endorsingOrgs...),
)
}

if transientArgs != nil {
return contract.Submit(txName,
client.WithArguments(args),
client.WithArguments(args...),
client.WithTransient(transientMap),
)
}

if len(endorsingOrgs) > 0 {
return contract.Submit(txName,
client.WithArguments(args),
client.WithArguments(args...),
client.WithEndorsingOrganizations(endorsingOrgs...),
)
}

return contract.SubmitTransaction(txName, args)
return contract.SubmitTransaction(txName, args...)
}
10 changes: 5 additions & 5 deletions ccapi/chaincode/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
)

func Query(channelName, ccName, txName string, txArgs [][]byte) (*channel.Response, int, error) {
func Query(channelName, ccName, txName, user string, txArgs [][]byte) (*channel.Response, int, error) {
// create channel manager
fabMngr, err := common.NewFabricChClient(channelName, os.Getenv("USER"), os.Getenv("ORG"))
fabMngr, err := common.NewFabricChClient(channelName, user, os.Getenv("ORG"))
if err != nil {
return nil, http.StatusInternalServerError, err
}
Expand All @@ -23,10 +23,10 @@ func Query(channelName, ccName, txName string, txArgs [][]byte) (*channel.Respon
}

res, err := fabMngr.Client.Query(rq, channel.WithRetry(retry.DefaultChannelOpts))

if err != nil {
return nil, http.StatusInternalServerError, err
status := extractStatusCode(err.Error())
return nil, status, err
}

return &res, http.StatusInternalServerError, nil
return &res, http.StatusOK, nil
}
6 changes: 3 additions & 3 deletions ccapi/chaincode/queryGateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/pkg/errors"
)

func QueryGateway(channelName, chaincodeName, txName, args string) ([]byte, error) {
func QueryGateway(channelName, chaincodeName, txName, user string, args []string) ([]byte, error) {
// Gateway endpoint
endpoint := os.Getenv("FABRIC_GATEWAY_ENDPOINT")

Expand All @@ -19,7 +19,7 @@ func QueryGateway(channelName, chaincodeName, txName, args string) ([]byte, erro
defer grpcConn.Close()

// Create gateway connection
gw, err := common.CreateGatewayConnection(grpcConn)
gw, err := common.CreateGatewayConnection(grpcConn, user)
if err != nil {
return nil, errors.Wrap(err, "failed to create gateway connection")
}
Expand All @@ -34,5 +34,5 @@ func QueryGateway(channelName, chaincodeName, txName, args string) ([]byte, erro
return contract.EvaluateTransaction(txName)
}

return contract.EvaluateTransaction(txName, args)
return contract.EvaluateTransaction(txName, args...)
}
Loading

0 comments on commit c77a8f4

Please sign in to comment.