mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-23 01:55:10 +00:00
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:
parent
426cdf1f98
commit
59e1e47bd0
6 changed files with 215 additions and 9 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
15
fabcar/go/runfabcar.sh
Executable 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
|
||||
Loading…
Reference in a new issue