文章目录
- 1. 任务背景
- 2. 目标
- 3. 相关知识点
- 4. 任务实操
- 4.1 存储设计
- 4.2 接口设计
- 4.3 编写合约
- 5. 小结
1. 任务背景
开发一个简单银行合约,支持:
- 开户
- 转账
- 查询余额
2. 目标
学习智能合约编写方法。
3. 相关知识点
Table.sol中内置了CRUD增删改查操作。
4. 任务实操
4.1 存储设计
设计账户表:account,字段包括:
account_name: 主键,账户名称(string类型)
account_value: 账户金额(uint256类型)
4.2 接口设计
// 开户function register(string account_name, uint256 amount) public returns(int256)// 查询金额function select(string account_name) public constant returns(int256, uint256)// 转账function transfer(string from_account, string to_account, uint256 amount) public returns(int256)
4.3 编写合约
创建一个Bank的智能合约,实现注册、转账、查询功能,并引入一个叫Table的系统合约。
cd /opt/fisco-console/console/contracts/solidityvi Bank.sol
pragma solidity ^0.4.24; //指定版本import "./Table.sol";// 系统预置合约,实现CRUDcontract Bank {// 合约名:Bank// eventevent RegisterEvent(int256 ret, string account_name, uint256 account_value);event TransferEvent(int256 ret, string from_account, string to_account, uint256 amount);constructor() public {// 构造函数// 构造函数中创建account表createTable();}// 创建账户account表function createTable() private {TableFactory tf = TableFactory(0x1001);// 创建账户表, key : account_name, field : account_valuetf.createTable("account", "account_name", "account_value");}// 打开表function openTable() private returns(Table) {TableFactory tf = TableFactory(0x1001);Table table = tf.openTable("account");return table;}/*描述 : 查询余额参数 :account_name 返回值:参数一: 成功返回0, 账户不存在返回-1参数二: 第一个参数为0时有效,资产金额*/function select(string account_name) public constant returns(int256, uint256) {// 打开表Table table = openTable();// 查询Entries entries = table.select(account_name, table.newCondition());uint256 account_value = 0;if (0 == uint256(entries.size())) {return (-1, account_value);} else {Entry entry = entries.get(0);return (0, uint256(entry.getInt("account_value")));}}/*描述 : 开户参数 :account_name : 资产账户account_value: 资产金额返回值:0资产注册成功-1 资产账户已存在-2 其他错误*/function register(string account_name, uint256 account_value) public returns(int256){int256 ret_code = 0;int256 ret= 0;uint256 temp_account_value = 0;// 查询账户是否存在(ret, temp_account_value) = select(account_name);if(ret != 0) {Table table = openTable();Entry entry = table.newEntry();entry.set("account_name", account_name);entry.set("account_value", int256(account_value));// 插入int count = table.insert(account_name, entry);if (count == 1) {// 成功ret_code = 0;} else {// 失败? 无权限或者其他错误ret_code = -2;}} else {// 账户已存在ret_code = -1;}emit RegisterEvent(ret_code, account_name, account_value);return ret_code;}/*描述 : 资产转移参数 :from_account : 转移资产账户to_account : 接收资产账户amount : 转移金额返回值:0资产转移成功-1 转移资产账户不存在-2 接收资产账户不存在-3 金额不足-4 金额溢出-5 其他错误*/function transfer(string from_account, string to_account, uint256 amount) public returns(int256) {// 查询转移资产账户信息int ret_code = 0;int256 ret = 0;uint256 from_account_value = 0;uint256 to_account_value = 0;// 转移账户是否存在?(ret, from_account_value) = select(from_account);if(ret != 0) {ret_code = -1;// 转移账户不存在emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}// 接收账户是否存在?(ret, to_account_value) = select(to_account);if(ret != 0) {ret_code = -2;// 接收资产的账户不存在emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}// 余额不在if(from_account_value < amount) {ret_code = -3;// 转移资产的账户金额不足emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}// 金额溢出if (to_account_value + amount < to_account_value) {ret_code = -4;// 接收账户金额溢出emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}// 执行转账操作Table table = openTable();Entry entry0 = table.newEntry();entry0.set("account_name", from_account);entry0.set("account_value", int256(from_account_value - amount));// 更新转账账户int count = table.update(from_account, entry0, table.newCondition());if(count != 1) {ret_code = -5;// 失败? 无权限或者其他错误?emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}Entry entry1 = table.newEntry();entry1.set("account_name", to_account);entry1.set("account_value", int256(to_account_value + amount));// 更新接收账户table.update(to_account, entry1, table.newCondition());emit TransferEvent(ret_code, from_account, to_account, amount);return ret_code;}}
注意:所引用的Table.sol已在/opt/fisco-console/console/contracts/solidity
目录下。该系统合约文件中的接口由FISCO BCOS底层实现。当业务合约需要操作CRUD接口时,均需要引入该接口合约文件。
5. 小结
简单的银行合约已实现。