模块二:智能合约开发与测试
选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块二提交结果.docx】中对应的任务序号下。
任务2-1:智能合约设计
根据区块链供应链金融应用需求分析和方案设计文档的描述,编写该区块链产品的智能合约功能需求文档,以及设计该智能合约UML图,具体要求如下:
1.编写区块链供应链金融智能合约功能需求文档
根据区块链供应链金融产品项目背景和需求分析,编写该区块链供应链金融产品的智能合约功能需求文档;
参考答案:略
2.完成区块链供应链金融智能合约的设计图
设计区块链供应链金融智能合约接口,画出区块链供应链金融智能合约的角色UML用例图,以及画出区块链供应链金融各角色智能合约关系的时序图。
参考答案:略
任务2-2:智能合约开发
使用Solidity语言完成智能合约开发、部署和调用,要求如下:
1.供应链金融实体信息编码
(1)编写供应链金融智能合约的实体接口,完成实体通用数据的初始化,实现企业和票据实体信息上链的功能;
表2.2.2.1 SupplyChain实体说明
名称 |
类型 |
说明 |
companyName |
string |
公司名称 |
companyAddress |
address |
公司地址 |
creditAsset |
uint |
信用资产 |
acceptReceiptIndex |
uint[] |
接收的凭证 |
sendReceiptIndex |
uint[] |
发送的凭证 |
senderAddress |
address |
发送票据的地址 |
accepterAddress |
address |
接收票据的地址 |
receiptType |
uint8 |
凭证类型 |
transferType |
uint8 |
交易类型 |
amount |
uint |
交易数量 |
//公司信息结构体
struct Company {
//①公司名称
//②公司地址
//③信用资产
//④接收的凭证
//⑤发送的凭证
}
//数字发票收据信息
struct Receipt {
//⑥发送票据的地址
//⑦接收票据的地址
//⑧凭证类型
//⑨交易类型
//⑩交易数量
}
参考答案:
(2)编写企业上链信息接口,实现供应链金融的企业信息上链;
function addCompany(string name, address companyAddress) returns(bool) {
//①实例化公司
//②添加公司地址
//③将实例化的公司添加到公司映射
//④返回添加成功标识
}
(3)基于给定的智能合约代码以及注释,完成银行向企业交易的接口函数;
function bankToCompanyReceipt(address senderAddress, address accepterAddress, uint amount, uint8 receiptType) returns(uint) {
①判断接收地址存在
②实例化银行
③实例化公司
if (keccak256(bank.bankName) == keccak256("")) {
return 404001;
}
//确认公司存在
if (keccak256(company.companyName) == ④) {
return 404002;
}
if (bank.creditAsset < amount) {
return 500001;
}
2.供应链金融公司与公司接口编码
(1)编写公司与公司之间进行交易的历史存证上链接口,实现公司与公司之间的交易功能;
function companyToCompanyReceipt(①, address accepterAddress, uint amount, uint8 receiptType) returns(uint) {
//②接收地址判断
Company memory senderCompany = companyMap[③];
Company memory ④ = companyMap[accepterAddress];
//确认发送公司存在
if (keccak256(senderCompany.⑤) == keccak256("")) {
return 404001;
}
//确认接收公司存在
if (keccak256(accepterCompany.companyName) == ⑥) {
return 404002;
}
//如果存证接收的公司资产小于存证数额,那么就不能交易发送存证
if (accepterCompany.creditAsset ⑦ ⑧) {
return 500001;
}
(2)编写创建存证的接口,实现创建存证的功能;
Receipt memory newReceipt = Receipt(①, accepterAddress, receiptType, 2, amount);
receiptIndex += 1;
//记录存证(存证Map,公司Map对应地址的发送和接收存证列表)
receiptMap[receiptIndex] = ②;
companyMap[③].sendReceiptIndex.push(receiptIndex);
companyMap[accepterAddress].acceptReceiptIndex.push(④);
(3)编写交易金额数量变化的接口,实现凭证交易双方资金的变化功能;
companyMap[①].creditAsset ② amount;
companyMap[③].creditAsset ④ amount;
return 200;
}
3.供应链金融公司与银行交易的接口编码
(1)编写公司与银行之间进行交易的历史存证上链接口,实现公司与银行之间的交易功能;(2分)
function companyToBankReceipt(address senderAddress, ①, uint amount, uint8 receiptType) returns(uint) {
②
Bank memory bank = bankMap[senderAddress];
Company memory accepterCompany = companyMap[③];
//确认发送公司存在
if (keccak256(bank.bankName) == ④) {
return 404001;
}
//确认接收公司存在
if (keccak256(accepterCompany.companyName) == keccak256("")) {
return 404002;
}
//如果存证接收的公司资产小于存证数额,那么就不能交易发送存证
if (accepterCompany.creditAsset < amount) {
return 500001;
}
(2)编写创建存证的接口,实现创建存证的功能;
//创建存证
Receipt memory newReceipt = Receipt(senderAddress, accepterAddress, ①, 3, amount);
receiptIndex ② 1;
receiptMap[③] = newReceipt;
bankMap[senderAddress].sendReceiptIndex.push(receiptIndex);
companyMap[accepterAddress].④;
(3)编写交易金额数量变化的接口,实现凭证交易双方资金的变化功能;
bankMap[senderAddress].① ② amount;
companyMap[accepterAddress].③ ④ amount;
return 200;
}
- 合约编译、部署和调用
(1)解决代码错误和警告,正确编译并部署合约,成功获取部署的合约地址和abi。
(2)调用食品溯源智能合约的接口,完整验证业务流程。
任务2-3:智能合约测试
编写智能合约单元测试代码并完成合约功能测试、性能测试,具体要求如下:
1.配置区块链网络
启动Ganache软件,创建新的Wordspace,配置对外访问的RPC接口为7545,配置项目的truffle-config.js实现与新建Workspace的连接。
2.补充给定基础代码中注释提示的部署逻辑
基于VSCODE加载的Truffle项目,补全位于test文件夹中HelloWorld.js文件预操作的方法。在测试文件中添加预定义的方法(在其他方法启动前使用)。
3.补充代码中注释提示的测试逻辑
基于VSCODE加载的Truffle项目,补全位于test文件夹中HelloWorld.js文件,添加测试用例,测试智能合约的get方法。
4.测试hello.get()方法
基于VSCODE加载的Truffle项目,补全位于test文件夹中HelloWorld.js文件,添加测试用例,测试智能合约的hello.get()方法。
5.测试.should.equal进行对比判断
基于VSCODE加载的Truffle项目,补全位于test文件夹中HelloWorld.js文件,添加测试用例,测试智能合约的equal字符串比较方法。