# 智能合约使用02

## 合约文件sacc.go

```
//代码位置：
//fabric-samples/chaincode/sacc/sacc.go
//合约很简单就是kv储存、查询和更新的功能

package main

import (
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/protos/peer"
)


type SimpleAsset struct {
}

// 部署及初始化时调用此函数
// 代码升级时也会调用此函数重置和迁移数据
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {
	// Get the args from the transaction proposal
	args := stub.GetStringArgs()
	if len(args) != 2 {
		return shim.Error("Incorrect arguments. Expecting a key and a value")
	}

	// Set up any variables or assets here by calling stub.PutState()

	// We store the key and the value on the ledger
	err := stub.PutState(args[0], []byte(args[1]))
	if err != nil {
		return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0]))
	}
	return shim.Success(nil)
}

// 消息路由函数
// 调用 set 或 get方法 
func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
	// Extract the function and args from the transaction proposal
	fn, args := stub.GetFunctionAndParameters()

	var result string
	var err error
	if fn == "set" {
		result, err = set(stub, args)
	} else { // assume 'get' even if fn is nil
		result, err = get(stub, args)
	}
	if err != nil {
		return shim.Error(err.Error())
	}

	// Return the result as success payload
	return shim.Success([]byte(result))
}

// Set
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {
	if len(args) != 2 {
		return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value")
	}

	err := stub.PutState(args[0], []byte(args[1]))
	if err != nil {
		return "", fmt.Errorf("Failed to set asset: %s", args[0])
	}
	return args[1], nil
}

// Get
func get(stub shim.ChaincodeStubInterface, args []string) (string, error) {
	if len(args) != 1 {
		return "", fmt.Errorf("Incorrect arguments. Expecting a key")
	}

	value, err := stub.GetState(args[0])
	if err != nil {
		return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err)
	}
	if value == nil {
		return "", fmt.Errorf("Asset not found: %s", args[0])
	}
	return string(value), nil
}

// main function starts up the chaincode in the container during instantiate
func main() {
	if err := shim.Start(new(SimpleAsset)); err != nil {
		fmt.Printf("Error starting SimpleAsset chaincode: %s", err)
	}
}

```

## 在宿主机下尝试进行编译

```
cd fabric-samples/chaincode/sacc/
go build
```

## 开启开发环境

```
cd fabric-samples/chaincode-docker-devmode

#打开一个ssh
sudo docker-compose -f docker-compose-simple.yaml up
```

## 在虚拟机内进行编译合约

```
sudo docker exec -it chaincode bash

#在docker中运行
cd sacc
go build
CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=mycc:0 ./sacc
```

## 在虚拟机内部署并运行合约

```
sudo docker exec -it cli bash 

#在docker中运行
peer chaincode install -p chaincodedev/chaincode/sacc -n mycc -v 0 
peer chaincode instantiate -n mycc -v 0 -c '{"Args":["a","10"]}' -C myc 
peer chaincode invoke -n mycc -c '{"Args":["set", "a", "20"]}' -C myc
peer chaincode query -n mycc -c '{"Args":["query","a"]}' -C myc
```

## 打包签名部署命令行

```
#打包
#-n合约名
#-p路径
#-v版本
#-s签名
#-S多重签名
#-i初始化策略
peer chaincode package -n 名称 -p 路径 -v 0 -s -S -i "AND('OrgA.admin')" 打包名

#签名
peer chaincode signpackage 打包名 签名后的打包名

#部署
#-n合约名
#-v版本
#-p路径
peer chaincode install -n 名称 -v 1.0 -p 路径

#初始化
#-n合约名
#-v版本
#-c初始化参数
#-P策略
peer chaincode instantiate -n 名称 -v 1.0 -c '{"Args":["john","0"]}' -P "OR ('Org1.member','Org2.member')"


#部署0版本
peer chaincode install -n 名称 -v 0 -p 路径
#初始化0版本
peer chaincode instantiate -n 名称 -v 0 -c '{"Args":["a", "b", "c"]}' -C channel名称
#部署1版本
peer chaincode install -n 名称 -v 1 -p 路径
#升级为1版本
peer chaincode upgrade -n 名称 -v 1 -c '{"Args":["d", "e", "f"]}' -C channel名称
#查询
peer chaincode query -C channel名称 -n 名称 -c '{"Args":["query","e"]}'
#调用
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C channel名称 -n 名称 -c '{"Args":["invoke","a","b","10"]}'
```

## 打包时附带lib

```
#初始化
govendor init 
#增加全部外部包
govendor add +external 
#增加某个包
govendor add packagepath
#然后再编译、打包就好了
```

## 数据加密

```
#fabric是支持合约数据加密的
#但官方文档上没有找到合适的例子
#待补充
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://neochain.gitbook.io/project/fabric/zhi-neng-he-yue-shi-yong-02.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
