Update asset_transfer_ledger_chaincode.go

Small off-by-1 bug fix.

Signed-off-by: r2roC <arturo@IBM.com>

run fabcar go  (#232)

* add go/runfabcar.sh

Signed-off-by: Acmefocus <107723772@qq.com>

* add set hosts and env in go

Signed-off-by: Acmefocus <107723772@qq.com>

* Update fabcar/startFabric.sh

Co-authored-by: Sijo Cherian <sijocherian@users.noreply.github.com>
Signed-off-by: Acmefocus <107723772@qq.com>

* Update startFabric.sh

delete  set  /etc/hosts

Signed-off-by: Acmefocus <107723772@qq.com>

* add environment variable DISCOVERY_AS_LOCALHOST

Signed-off-by: Acmefocus <107723772@qq.com>

Co-authored-by: Sijo Cherian <sijocherian@users.noreply.github.com>

Fix asset transfer go chaincode functions for
CreateAsset and UpdateAsset.

Signed-off-by: Chris Gabriel <chris_gabriel_98@yahoo.com>

Add param types.

Signed-off-by: Chris Gabriel <chris_gabriel_98@yahoo.com>

Update smartcontract.go and smartcontract_test.go

Signed-off-by: Chris Gabriel <chris_gabriel_98@yahoo.com>
This commit is contained in:
r2roC 2020-07-08 10:11:52 -04:00 committed by Chris Gabriel
parent 426cdf1f98
commit 59e1e47bd0
6 changed files with 215 additions and 9 deletions

View file

@ -11,6 +11,196 @@ import (
"github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go/chaincode"
)
// SmartContract provides functions for managing an Asset
type SmartContract struct {
contractapi.Contract
}
// Asset describes basic details of what makes up a simple asset
type Asset struct {
ID string `json:"ID"`
Color string `json:"color"`
Size int `json:"size"`
Owner string `json:"owner"`
AppraisedValue int `json:"appraisedValue"`
}
// QueryResult structure used for handling result of query
type QueryResult struct {
Key string `json:"Key"`
Record *Asset
}
// InitLedger adds a base set of assets to the ledger
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
assets := []Asset{
Asset{ID: "asset1", Color: "blue", Size: 5, Owner: "Tomoko", AppraisedValue: 300},
Asset{ID: "asset2", Color: "red", Size: 5, Owner: "Brad", AppraisedValue: 400},
Asset{ID: "asset3", Color: "green", Size: 10, Owner: "Jin Soo", AppraisedValue: 500},
Asset{ID: "asset4", Color: "yellow", Size: 10, Owner: "Max", AppraisedValue: 600},
Asset{ID: "asset5", Color: "black", Size: 15, Owner: "Adriana", AppraisedValue: 700},
Asset{ID: "asset6", Color: "white", Size: 15, Owner: "Michel", AppraisedValue: 800},
}
for _, asset := range assets {
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
err = ctx.GetStub().PutState(asset.ID, assetJSON)
if err != nil {
return fmt.Errorf("Failed to put to world state. %s", err.Error())
}
}
return nil
}
// CreateAsset issues a new asset to the world state with given details.
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if exists {
return fmt.Errorf("The asset %s already exists", id)
}
asset := Asset{
ID: id,
Color: color,
Size: size,
Owner: owner,
AppraisedValue: appraisedValue,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(id, assetJSON)
}
// ReadAsset returns the asset stored in the world state with given id.
func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) {
assetJSON, err := ctx.GetStub().GetState(id)
if err != nil {
return nil, fmt.Errorf("Failed to read from world state. %s", err.Error())
}
if assetJSON == nil {
return nil, fmt.Errorf("The asset %s does not exist", id)
}
asset := new(Asset)
err = json.Unmarshal(assetJSON, asset)
if err != nil {
return nil, err
}
return asset, nil
}
// UpdateAsset updates an existing asset in the world state with provided parameters.
func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if !exists {
return fmt.Errorf("The asset %s does not exist", id)
}
// overwritting original asset with new asset
asset := Asset{
ID: id,
Color: color,
Size: size,
Owner: owner,
AppraisedValue: appraisedValue,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(id, assetJSON)
}
// DeleteAsset deletes an given asset from the world state.
func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if !exists {
return fmt.Errorf("The asset %s does not exist", id)
}
return ctx.GetStub().DelState(id)
}
// AssetExists returns true when asset with given ID exists in world state
func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) {
assetJSON, err := ctx.GetStub().GetState(id)
if err != nil {
return false, fmt.Errorf("Failed to read from world state. %s", err.Error())
}
return assetJSON != nil, nil
}
// TransferAsset updates the owner field of asset with given id in world state.
func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) error {
asset, err := s.ReadAsset(ctx, id)
if err != nil {
return err
}
asset.Owner = newOwner
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(id, assetJSON)
}
// GetAllAssets returns all assets found in world state
func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]QueryResult, error) {
// range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace.
resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
if err != nil {
return nil, err
}
defer resultsIterator.Close()
results := []QueryResult{}
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, err
}
asset := new(Asset)
err = json.Unmarshal(queryResponse.Value, asset)
if err != nil {
return nil, err
}
queryResult := QueryResult{Key: queryResponse.Key, Record: asset}
results = append(results, queryResult)
}
return results, nil
}
func main() {
assetChaincode, err := contractapi.NewChaincode(&chaincode.SmartContract{})
if err != nil {

View file

@ -54,7 +54,7 @@ func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface)
}
// CreateAsset issues a new asset to the world state with given details.
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id, color, owner string, size, appraisedValue int) error {
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
@ -98,7 +98,7 @@ func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, i
}
// UpdateAsset updates an existing asset in the world state with provided parameters.
func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id, color, owner string, size, appraisedValue int) error {
func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, color string, size int, owner string, appraisedValue int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err

View file

@ -48,15 +48,15 @@ func TestCreateAsset(t *testing.T) {
transactionContext.GetStubReturns(chaincodeStub)
assetTransfer := chaincode.SmartContract{}
err := assetTransfer.CreateAsset(transactionContext, "", "", "", 0, 0)
err := assetTransfer.CreateAsset(transactionContext, "", "", 0, "", 0)
require.NoError(t, err)
chaincodeStub.GetStateReturns([]byte{}, nil)
err = assetTransfer.CreateAsset(transactionContext, "asset1", "", "", 0, 0)
err = assetTransfer.CreateAsset(transactionContext, "asset1", "", 0, "", 0)
require.EqualError(t, err, "the asset asset1 already exists")
chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset"))
err = assetTransfer.CreateAsset(transactionContext, "asset1", "", "", 0, 0)
err = assetTransfer.CreateAsset(transactionContext, "asset1", "", 0, "", 0)
require.EqualError(t, err, "failed to read from world state: unable to retrieve asset")
}
@ -96,15 +96,15 @@ func TestUpdateAsset(t *testing.T) {
chaincodeStub.GetStateReturns(bytes, nil)
assetTransfer := chaincode.SmartContract{}
err = assetTransfer.UpdateAsset(transactionContext, "", "", "", 0, 0)
err = assetTransfer.UpdateAsset(transactionContext, "", "", 0, "", 0)
require.NoError(t, err)
chaincodeStub.GetStateReturns(nil, nil)
err = assetTransfer.UpdateAsset(transactionContext, "asset1", "", "", 0, 0)
err = assetTransfer.UpdateAsset(transactionContext, "asset1", "", 0, "", 0)
require.EqualError(t, err, "the asset asset1 does not exist")
chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset"))
err = assetTransfer.UpdateAsset(transactionContext, "asset1", "", "", 0, 0)
err = assetTransfer.UpdateAsset(transactionContext, "asset1", "", 0, "", 0)
require.EqualError(t, err, "failed to read from world state: unable to retrieve asset")
}

View file

@ -293,7 +293,7 @@ func (t *SimpleChaincode) TransferAssetBasedOnColor(ctx contractapi.TransactionC
return fmt.Errorf(err.Error())
}
if len(compositeKeyParts) > 2 {
if len(compositeKeyParts) > 1 {
returnedAssetID := compositeKeyParts[1]
// Now call the transfer function for the found asset.

View file

@ -18,6 +18,7 @@ import (
)
func main() {
os.Setenv("DISCOVERY_AS_LOCALHOST", "true")
wallet, err := gateway.NewFileSystemWallet("wallet")
if err != nil {
fmt.Printf("Failed to create wallet: %s\n", err)

15
fabcar/go/runfabcar.sh Executable file
View file

@ -0,0 +1,15 @@
ENV_DAL=`echo $DISCOVERY_AS_LOCALHOST`
echo "ENV_DAL:"$DISCOVERY_AS_LOCALHOST
if [ "$ENV_DAL" != "true" ]
then
export DISCOVERY_AS_LOCALHOST=true
fi
echo "DISCOVERY_AS_LOCALHOST="$DISCOVERY_AS_LOCALHOST
echo "run fabcar..."
go run fabcar.go