Fisco-bsco 开发联盟链 账户之间的转账
参考:开发第一个区块链应用 — FISCO BCOS v2.9.0 文档 (fisco-bcos-documentation.readthedocs.io)
前提:Fisco-bcos节点开启,控制台已搭建
步骤:
1. 开发源码
# 进入console/contracts目录
cd ~/fisco/console/contracts/solidity
# 创建Asset.sol合约文件
vi Asset.sol
# 将Assert.sol合约内容写入。
# 并键入wq保存退出。
Asset.sol:
pragma solidity ^0.4.24;
import "./Table.sol";
contract Asset {
// event
event RegisterEvent(int256 ret, string account, uint256 asset_value);
event TransferEvent(int256 ret, string from_account, string to_account, uint256 amount);
constructor() public {
// 构造函数中创建t_asset表
createTable();
}
function createTable() private {
TableFactory tf = TableFactory(0x1001);
// 资产管理表, key : account, field : asset_value
// | 资产账户(主键) | 资产金额 |
// |-------------------- |-------------------|
// | account | asset_value |
// |---------------------|-------------------|
//
// 创建表
tf.createTable("t_asset", "account", "asset_value");
}
function openTable() private returns(Table) {
TableFactory tf = TableFactory(0x1001);
Table table = tf.openTable("t_asset");
return table;
}
/*
描述 : 根据资产账户查询资产金额
参数 :
account : 资产账户
返回值:
参数一: 成功返回0, 账户不存在返回-1
参数二: 第一个参数为0时有效,资产金额
*/
function select(string account) public constant returns(int256, uint256) {
// 打开表
Table table = openTable();
// 查询
Entries entries = table.select(account, table.newCondition());
uint256 asset_value = 0;
if (0 == uint256(entries.size())) {
return (-1, asset_value);
} else {
Entry entry = entries.get(0);
return (0, uint256(entry.getInt("asset_value")));
}
}
/*
描述 : 资产注册
参数 :
account : 资产账户
amount : 资产金额
返回值:
0 资产注册成功
-1 资产账户已存在
-2 其他错误
*/
function register(string account, uint256 asset_value) public returns(int256){
int256 ret_code = 0;
int256 ret= 0;
uint256 temp_asset_value = 0;
// 查询账户是否存在
(ret, temp_asset_value) = select(account);
if(ret != 0) {
Table table = openTable();
Entry entry = table.newEntry();
entry.set("account", account);
entry.set("asset_value", int256(asset_value));
// 插入
int count = table.insert(account, entry);
if (count == 1) {
// 成功
ret_code = 0;
} else {
// 失败? 无权限或者其他错误
ret_code = -2;
}
} else {
// 账户已存在
ret_code = -1;
}
emit RegisterEvent(ret_code, account, asset_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_asset_value = 0;
uint256 to_asset_value = 0;
// 转移账户是否存在?
(ret, from_asset_value) = select(from_account);
if(ret != 0) {
ret_code = -1;
// 转移账户不存在
emit TransferEvent(ret_code, from_account, to_account, amount);
return ret_code;
}
// 接受账户是否存在?
(ret, to_asset_value) = select(to_account);
if(ret != 0) {
ret_code = -2;
// 接收资产的账户不存在
emit TransferEvent(ret_code, from_account, to_account, amount);
return ret_code;
}
if(from_asset_value < amount) {
ret_code = -3;
// 转移资产的账户金额不足
emit TransferEvent(ret_code, from_account, to_account, amount);
return ret_code;
}
if (to_asset_value + amount < to_asset_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", from_account);
entry0.set("asset_value", int256(from_asset_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", to_account);
entry1.set("asset_value", int256(to_asset_value + amount));
// 更新接收账户
table.update(to_account, entry1, table.newCondition());
emit TransferEvent(ret_code, from_account, to_account, amount);
return ret_code;
}
}
运行ls
命令,确保Asset.sol
和Table.sol
在目录~/fisco/console/contracts/solidity
下。
Table.sol 在搭建控制台的时候自动创建
2.编译智能合约
# 切换到fisco/console/目录
cd ~/fisco/console/
# 若控制台版本大于等于2.8.0,编译合约方法如下:(可通过bash sol2java.sh -h命令查看该脚本使用方法)
bash sol2java.sh -p org.fisco.bcos.asset.contract
# 若控制台版本小于2.8.0,编译合约(后面指定一个Java的包名参数,可以根据实际项目路径指定包名)如下:
./sol2java.sh org.fisco.bcos.asset.contract
3.创建区块链应用项目
-
确认jdk以及集成环境
确认您当前的java版本
$ java -version
# 确认您的java路径
$ ls /Library/Java/JavaVirtualMachines
# 返回
# jdk-14.0.2.jdk
# 如果使用的是bash
$ vim .bash_profile
# 在文件中加入JAVA_HOME的路径
# export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.0.2.jdk/Contents/Home
$ source .bash_profile
# 如果使用的是zash
$ vim .zashrc
# 在文件中加入JAVA_HOME的路径
# export JAVA_HOME = Library/Java/JavaVirtualMachines/jdk-14.0.2.jdk/Contents/Home
$ source .zashrc
# 确认您的java版本
$ java -version
# 返回
# java version "14.0.2" 2020-07-14
# Java(TM) SE Runtime Environment (build 14.0.2+12-46)
# Java HotSpot(TM) 64-Bit Server VM (build 14.0.2+12-46, mixed mode, sharing)
-
进入IntelliJ IDE官网下载社区版即可,安装解压
-
快速搭建
cd ~/fisco
$ curl -#LO https://github.com/FISCO-BCOS/LargeFiles/raw/master/tools/asset-app.tar.gz
# 解压得到Java工程项目asset-app
$ tar -zxf asset-app.tar.gz
-
将项目用IDE打开,打开终端
# 假设我们将asset-app放在~/fisco目录下 进入~/fisco目录
$ cd ~/fisco
# 创建放置证书的文件夹
$ mkdir -p asset-app/src/test/resources/conf
# 拷贝节点证书到项目的资源目录
$ cp -r nodes/127.0.0.1/sdk/* asset-app/src/test/resources/conf
# 若在IDE直接运行,拷贝证书到resources路径
$ mkdir -p asset-app/src/main/resources/conf
$ cp -r nodes/127.0.0.1/sdk/* asset-app/src/main/resources/conf
4.运行
-
编译
# 切换到项目目录
$ cd ~/fisco/asset-app
# 编译项目
$ ./gradlew build
-
部署Asset.sol
# 进入dist目录
$ cd dist
$ bash asset_run.sh deploy
Deploy Asset successfully, contract address is 0xd09ad04220e40bb8666e885730c8c460091a4775
-
注册资产
$ bash asset_run.sh register Alice 100000
Register account successfully => account: Alice, value: 100000
$ bash asset_run.sh register Bob 100000
Register account successfully => account: Bob, value: 100000
-
查询资产
$ bash asset_run.sh query Alice
account Alice, value 100000
$ bash asset_run.sh query Bob
account Bob, value 100000
-
资产转移
$ bash asset_run.sh transfer Alice Bob 50000
Transfer successfully => from_account: Alice, to_account: Bob, amount: 50000
$ bash asset_run.sh query Alice
account Alice, value 50000
$ bash asset_run.sh query Bob
account Bob, value 150000