# 食品溯源案例

下面以基于Solidity语言的食品溯源智能合约，阐述如何在chain33平行链上设计，实现，部署和调用智能合约

## 1 平行链环境搭建及运行

具体过程参见 [平行链环境搭建](./../installDeploy/parallelChain.md)， 如果环境已经具备，则跳过这一步

创建钱包并导入创世地址私钥（已经创建钱包的话就无需进行这一步了）：

```
# 生成随机数种子，建议可以手工生成并保存好，后继可以使用此种子恢复钱包，--rpc_laddr参数可以设定指向具体链的rpc地址（以下地址只是举例，需要根据自己实际监听的jrpc地址修改==>对应配置文件中的：jrpcBindAddr配置项）
$ ./chain33-cli --rpc_laddr="http://localhost:8901"  seed generate -l 0
# 保存种子，并设置钱包密码为"fzm12345"，注意：密码可以自定义(8位以上，字母+数字)，并且牢牢记住，后面解锁钱包时会用到
$ ./chain33-cli --rpc_laddr="http://localhost:8901"  seed save -p fzm12345 -s "上一步中生成的seed"
# 使用我们刚刚设置的密码解锁钱包（钱包新创建后默认为锁定状态），-t后跟的是自动锁定的时间，0代表永不锁定（重启例外）
$ ./chain33-cli --rpc_laddr="http://localhost:8901"  wallet unlock -p fzm12345 -t 0
# 检查钱包的状态
$ ./chain33-cli --rpc_laddr="http://localhost:8901"  wallet status
# 创建一个账户地址和私钥
$ ./chain33-cli --rpc_laddr="http://localhost:8901"  account create -l testEvm
# 查询上述被创建账户的地址和私钥
$ ./chain33-cli --rpc_laddr="http://localhost:8901"  account dump_key -a "上一步生成的地址"
# 查看账户
$ ./chain33-cli --rpc_laddr="http://localhost:8901" account list
```

> 注意：平行链节点执行指令时，需要添加`--rpc_laddr`，rpc_laddr表示平行链节点启动的IP和监听端口，如果不指定这个参数，默认是指向[http://localhost:8801](http://localhost:8801/) (如果主链节点和平行链节点在同一台机器上，且主链端口是8801，那么不指定—rpc_laddr，命令就可能会跑错链)

查看平行链上区块同步的状态：

```
$ ./chain33-cli --rpc_laddr="http://localhost:8901"  block last_header
{
    "version": 0,
    "parentHash": "0x905d3c3ab62718381436720382e436a52976b6798896c77c97cb4e751e3a67c9",
    "txHash": "0x765a8babc9b63f7a5c608afb0943001741f3591f676026cd67dd99f6b3ad5122",
    "stateHash": "0xeb240fe1248028e9c7271ae2838ea3970bb880031764c8154c8bce2d16262cb7",
    "height": 57,
    "blockTime": 1546501778,
    "txCount": 1,
    "hash": "0xac2be112305b231b9851a34f6db7bde1745a2b7c9c3a684c736dc59baf3e6e51",
    "difficulty": 0
}
```

## 2 合约设计

针对食品溯源这一场景，设计一个合约，实现产地，生产，流通等环节溯源, 合约满足以下特性：
实际溯源的环节是一个非常复杂的过程，这边精简为以下几个环节： 农牧场，食品厂，超市，食品质检部门，用户产品具备的属性，以生猪为例各环节操作：

1. 支持添加生猪信息，修改生猪信息。
2. 支持添加质检信息
3. 支持添加超时上架信息
4. 支持添加用户评分信息
5. 支持上述信息的查询

合约代码参见：[智能合约代码下载](https://bty33.oss-cn-shanghai.aliyuncs.com/chain33Dev/solidity/Food.zip)

## 3 合约编译

下载解压并编译上述智能合约，参见[ChainIDE配置与使用](https://baas.33.cn/doc/detail/154)
拿到合约的bytecode和abi:
bytecode: 60806040526000805560006001556000….省略后面部分，从IDE上拷贝…
abi: [{“inputs”:[{“internalType”:”address”,”name”:”_creator”,”type”:”address”}….省略后面部分，从IDE上拷贝…..

## 4 合约部署和调用

部署和调用合约的命令行参数参见[EVM合约部署](../installDeploy/deployEVMContract.md)

### 4.1 合约部署

```
# 构造合约部署交易, --user.p.mbaas. 是平行链的title，此参数一定要填对，不然平行链上无法收到交易
./chain33-cli --rpc_laddr="http://localhost:8901" --paraName="user.p.mbaas." evm create -s foodTest -f 1000000 -c 上述btyecode值 
# 签名交易 -k：合约部署人的私钥(此私钥匙对应的地址是： 1LQJbjsNxh6ve6RCXBuDnUuMQsqXsc4cWK，  此地址在下面计算合约地址时会用到)
./chain33-cli --rpc_laddr="http://localhost:8901" wallet sign -k 0xdb9415dfbd54ed84dccde80a0f9f2497c7b967116da92d8682900b324ea33d68 -d 上一步返回的数据
# 发送交易（返回的hash要记住，下面计算合约地址的时候会用到）
./chain33-cli --rpc_laddr="http://localhost:8901" wallet send -d 上一步签过名的数据
# 查询交易（在结果中 "receipt": {"ty": 2,"tyName": "ExecOk".....} 代表交易执行成功，如果ty=1,代表交易只是被打包但执行失败）
./chain33-cli --rpc_laddr="http://localhost:8901" tx query_hash -s 上一步返回的hash
# 如果上述交易执行返回ExecOk,代表合约部署成功，计算此合约的地址, --user.p.mbaas. 是平行链的title，此参数一定要填对 -a 合约部署人的地址 -s 上一步返回的hash(去掉前面0x的值)，假设此处返回的是：174dwVy4fEY7WQkpuRZRci88BE5iuHHSY4
./chain33-cli --rpc_laddr="http://localhost:8901" --paraName="user.p.mbaas." evm calc -a 1LQJbjsNxh6ve6RCXBuDnUuMQsqXsc4cWK -s 上一步返回的hash去掉最前面的0x
```

### 4.2 信息录入

#### 4.2.1 添加猪肉信息

农牧场出栏

| 出栏批次 | 名称   | 重量 | 出栏日期 | 产地    |
| :------- | :----- | :--- | :------- | :------ |
| 00001    | pig001 | 500  | 20190221 | NanJing |

```
# 使用addPigInfo进行猪肉信息的录入
# 重要： 先在本地生成一个174dwVy4fEY7WQkpuRZRci88BE5iuHHSY4.abi文件，复制IDE中生成的abi内容到此文件中
# 其中174dwVy4fEY7WQkpuRZRci88BE5iuHHSY4替换成自己的合约地址
$ ./chain33-cli --rpc_laddr="http://localhost:8901" --paraName="user.p.mbaas." evm call -e 174dwVy4fEY7WQkpuRZRci88BE5iuHHSY4 -p "addPigInfo("1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs","pig001","00001","500","20190210","NanJing")"  
# -k是调用合约人的私钥
$ ./chain33-cli --rpc_laddr="http://localhost:8901" wallet sign -k 0xdb9415dfbd54ed84dccde80a0f9f2497c7b967116da92d8682900b324ea33d68 -d 上一步返回的结果
$ ./chain33-cli --rpc_laddr="http://localhost:8901" wallet send -d 上一步返回的结果
# 通过hash查看猪肉信息是否成功添加，如果返回"receipt": {"ty": 2,"tyName": "ExecOk".....} 代表交易执行成功，如果ty=1,代表交易只是被打包但执行失败）
$ ./chain33-cli --rpc_laddr="http://localhost:8901" tx query -s "上一步返回的hash"
# 使用getPigNumber()函数查看录入了多少条生猪信息
# 其中-a 174dwVy4fEY7WQkpuRZRci88BE5iuHHSY4替换成合约地址，-c为调用人地址，-b为合约中查询方法
$ ./chain33-cli --rpc_laddr="http://localhost:8801" --paraName="user.p.mbaas." evm query -a  174dwVy4fEY7WQkpuRZRci88BE5iuHHSY4 -c 1LQJbjsNxh6ve6RCXBuDnUuMQsqXsc4cWK -b "getPigNumber()"
# 通过getPigInfoByIndex函数，查询index对应的生猪详细信息
$ ./chain33-cli --rpc_laddr="http://localhost:8801" --paraName="user.p.mbaas." evm query -a  174dwVy4fEY7WQkpuRZRci88BE5iuHHSY4 -c 1LQJbjsNxh6ve6RCXBuDnUuMQsqXsc4cWK -b "getPigInfoByIndex(0)"
```

#### 4.2.2 添加食品信息

食品厂生产（比如火腿)

| 食品编号(比如二维码) | 名称    | 重量 | 生产日期 | 包装日期 | 保质期   | 猪肉出栏批次 |
| :------------------- | :------ | :--- | :------- | :------- | :------- | :----------- |
| 001                  | food001 | 500  | 20190215 | 20190220 | 20210215 | 00001        |

上链和查询脚本和3.2.1中类似(具体方法名称和参数，请见Food.sol中定义)

#### 4.2.3 添加质检信息

食品质检部门抽检

| 食品编号(比如二维码) | 检测时间 | 检测结果  | 检测说明          |
| :------------------- | :------- | :-------- | :---------------- |
| food001              | 20190226 | Qualified | The food is good. |

上链和查询脚本和3.2.1中类似(具体方法名称和参数，请见Food.sol中定义)

#### 4.2.4 添加超市上架信息

| 食品编号(比如二维码) | 上架日期 |
| :------------------- | :------- |
| food001              | 20190304 |

上链和查询脚本和3.2.1中类似(具体方法名称和参数，请见Food.sol中定义)

#### 4.2.5 添加用户评分信息

| 食品编号 | 用户评分 |
| :------- | :------- |
| food001  | 90       |

上链和查询脚本和3.2.1中类似(具体方法名称和参数，请见Food.sol中定义)

