基于Java实现的区块链供应链金融系统平台设计

一、 项目背景

中小微企业融资难、融资贵是长久以来我国金融发展过程中需要解决的问题。世界银行、中小企业金融论坛、国际金融公司联合发布的《中小微企业融资缺口:对新兴市场微型、小型和中型企业融资不足与机遇的评估》报告中表示,中国 40%的中小微企业存在信贷困难,或是完全无法从正规金融体系获得外部融资,或是从正规金融体系获得的外部融资不能完全满足融资需求,有 1.9 万亿美元的融资缺口,接近 12 万亿元人民币。

比如以下场景。某知名车企(宝马)消费口碑好,金融机构对其信用评级很高,认为其有很大的风险承担能力。某次交易中,该车企从轮胎公司购买了一批轮胎,但由于资金暂时短缺向轮胎公司签订了1000 万的应收账款单据,承诺一年后归还。由于轮胎公司有宝马的账款单据,金融机构认为其有额能力还款,于是愿意借款给轮胎公司,然而,这种信任关系并不会向下游传递。比如,轮胎公司因资金短缺,向轮毂公司签订了 500 万的应收账款单据,但是当轮毂公司需要贷款时,金融机构因不认可轮胎公司的还款能力,需要对轮胎公司进行详细的信用分析,而这会增加很多的经济成本。很多时候,就是这个原因导致了小微企业的融资失败。

但是,区块链金融可以有效地解决上述问题。将供应链上的每一笔交易和应收账款单据上链,同时引入第三方可信机构来确认这些信息的交易,例如银行,物流公司等,确保交易和单据的真实性。同 时,支持应收账款的转让,融资,清算等,让核心企业的信用可以传递到供应链的下游企业,减小中小企业的融资难度。

二、 方案设计

将供应链上的每一笔交易和应收账款单据上链,同时引入第三方可信机构来确认这些信息的交易, 例如银行,物流公司等,确保交易和单据的真实性。同时,支持应收账款的转让,融资,清算等,让核心企业的信用可以传递到供应链的下游企业,减小中小企业的融资难度。

【存储设计】

将企业的收款单据存储在通过 FISCO BCOS 部署的四节点联盟链上。由于我们要解决的问题是供应链上下游的信息不对等而导致的融资难问题,我们只关注企业间的欠款信息,而忽略企业的余额,这也是本项目的设计思路。

当两个企业签订了应收账款单据,将它们的公司信息、应收数目上链,在必要时,企业间的应收账款可以转移到第三方,比如上例轮毂公司可以拿到宝马的 500 万欠款证明。

【核心功能介绍】

本项目主要实现以下四个功能:

功能一:实现采购商品—签发应收账款交易上链。例如车企从轮胎公司购买一批轮胎并签订应收账款单据。

功能二:实现应收账款的转让上链,轮胎公司从轮毂公司购买一笔轮毂,便将于车企的应收账款单据部分转让给轮毂公司。轮毂公司可以利用这个新的单据去融资或者要求车企到期时归还钱款。

功能三:利用应收账款向银行融资上链,供应链上所有可以利用应收账款单据向银行申请融资。

功能四:应收账款支付结算上链,应收账款单据到期时核心企业向下游企业支付相应的欠款。

核心功能主要体现在部署在区块链上的智能合约。智能合约代码如下:

package org.fisco.bcos.asset.client;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.fisco.bcos.asset.contract.Asset;
import org.fisco.bcos.asset.contract.Asset.RegisterEventEventResponse;
import org.fisco.bcos.asset.contract.Asset.TransferEventEventResponse;
import org.fisco.bcos.channel.client.Service;
import org.fisco.bcos.web3j.crypto.Credentials;
import org.fisco.bcos.web3j.crypto.Keys;
import org.fisco.bcos.web3j.protocol.Web3j;
import org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService;
import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt;
import org.fisco.bcos.web3j.tuples.generated.Tuple2;
import org.fisco.bcos.web3j.tx.gas.StaticGasProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class AssetClient {

	static Logger logger = LoggerFactory.getLogger(AssetClient.class);

	private Web3j web3j;

	private Credentials credentials;

	public Web3j getWeb3j() {
		return web3j;
	}

	public void setWeb3j(Web3j web3j) {
		this.web3j = web3j;
	}

	public Credentials getCredentials() {
		return credentials;
	}

	public void setCredentials(Credentials credentials) {
		this.credentials = credentials;
	}

	public void recordAssetAddr(String address) throws FileNotFoundException, IOException {
		Properties prop = new Properties();
		prop.setProperty("address", address);
		final Resource contractResource = new ClassPathResource("contract.properties");
		FileOutputStream fileOutputStream = new FileOutputStream(contractResource.getFile());
		prop.store(fileOutputStream, "contract address");
	}

	public String loadAssetAddr() throws Exception {
		// load Asset contact address from contract.properties
		Properties prop = new Properties();
		final Resource contractResource = new ClassPathResource("contract.properties");
		prop.load(contractResource.getInputStream());

		String contractAddress = prop.getProperty("address");
		if (contractAddress == null || contractAddress.trim().equals("")) {
			throw new Exception(" load Asset contract address failed, please deploy it first. ");
		}
		logger.info(" load Asset address from contract.properties, address is {}", contractAddress);
		return contractAddress;
	}

	public void initialize() throws Exception {

		// init the Service
		@SuppressWarnings("resource")
		ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		Service service = context.getBean(Service.class);
		service.run();

		ChannelEthereumService channelEthereumService = new ChannelEthereumService();
		channelEthereumService.setChannelService(service);
		Web3j web3j = Web3j.build(channelEthereumService, 1);

		// init Credentials
		Credentials credentials = Credentials.create(Keys.createEcKeyPair());

		setCredentials(credentials);
		setWeb3j(web3j);

		logger.debug(" web3j is " + web3j + " ,credentials is " + credentials);
	}

	private static BigInteger gasPrice = new BigInteger("30000000");
	private static BigInteger gasLimit = new BigInteger("30000000");

	public void deployAssetAndRecordAddr() {

		try {
			Asset asset = Asset.deploy(web3j, credentials, new StaticGasProvider(gasPrice, gasLimit)).send();
			System.out.println(" deploy Asset success, contract address is " + asset.getContractAddress());

			recordAssetAddr(asset.getContractAddress());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
			System.out.println(" deploy Asset contract failed, error message is  " + e.getMessage());
		}
	}

	public void queryAssetAmount(String assetAccount) {
		try {
			String contractAddress = loadAssetAddr();

			Asset asset = Asset.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit));
			Tuple2<BigInteger, BigInteger> result = asset.select(assetAccount).send();
			if (result.getValue1().compareTo(new BigInteger("0")) == 0) {
				System.out.printf(" asset account %s, value %s \n", assetAccount, result.getValue2());
			} else {
				System.out.printf(" %s asset account is not exist \n", assetAccount);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
			logger.error(" queryAssetAmount exception, error message is {}", e.getMessage());

			System.out.printf(" query asset account failed, error message is %s\n", e.getMessage());
		}
	}

	public void registerAssetAccount(String assetAccount, BigInteger amount) {
		try {
			String contractAddress = loadAssetAddr();

			Asset asset = Asset.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit));
			TransactionReceipt receipt = asset.register(assetAccount, amount).send();
			List<RegisterEventEventResponse> response = asset.getRegisterEventEvents(receipt);
			if (!response.isEmpty()) {
				if (response.get(0).ret.compareTo(new BigInteger("0")) == 0) {
					System.out.printf(" register asset account success => asset: %s, value: %s \n", assetAccount,
							amount);
				} else {
					System.out.printf(" register asset account failed, ret code is %s \n",
							response.get(0).ret.toString());
				}
			} else {
				System.out.println(" event log not found, maybe transaction not exec. ");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();

			logger.error(" registerAssetAccount exception, error message is {}", e.getMessage());
			System.out.printf(" register asset account failed, error message is %s\n", e.getMessage());
		}
	}

	public void transferAsset(String fromAssetAccount, String toAssetAccount, BigInteger amount) {
		try {
			String contractAddress = loadAssetAddr();
			Asset asset = Asset.load(contractAddress, web3j, credentials, new StaticGasProvider(gasPrice, gasLimit));
			TransactionReceipt receipt = asset.transfer(fromAssetAccount, toAssetAccount, amount).send();
			List<TransferEventEventResponse> response = asset.getTransferEventEvents(receipt);
			if (!response.isEmpty()) {
				if (response.get(0).ret.compareTo(new BigInteger("0")) == 0) {
					System.out.printf(" transfer success => from_asset: %s, to_asset: %s, amount: %s \n",
							fromAssetAccount, toAssetAccount, amount);
				} else {
					System.out.printf(" transfer asset account failed, ret code is %s \n",
							response.get(0).ret.toString());
				}
			} else {
				System.out.println(" event log not found, maybe transaction not exec. ");
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();

			logger.error(" registerAssetAccount exception, error message is {}", e.getMessage());
			System.out.printf(" register asset account failed, error message is %s\n", e.getMessage());
		}
	}

	public static void Usage() {
		System.out.println(" Usage:");
		System.out.println("\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient deploy");
		System.out.println("\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient query account");
		System.out.println(
				"\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient register account value");
		System.out.println(
				"\t java -cp conf/:lib/*:apps/* org.fisco.bcos.asset.client.AssetClient transfer from_account to_account amount");
		System.exit(0);
	}

	public static void main(String[] args) throws Exception {

		if (args.length < 1) {
			Usage();
		}

		AssetClient client = new AssetClient();
		client.initialize();

		switch (args[0]) {
		case "deploy":
			client.deployAssetAndRecordAddr();
			break;
		case "query":
			if (args.length < 2) {
				Usage();
			}
			client.queryAssetAmount(args[1]);
			break;
		case "register":
			if (args.length < 3) {
				Usage();
			}
			client.registerAssetAccount(args[1], new BigInteger(args[2]));
			break;
		case "transfer":
			if (args.length < 4) {
				Usage();
			}
			client.transferAsset(args[1], args[2], new BigInteger(args[3]));
			break;
		default: {
			Usage();
		}
		}

		System.exit(0);
	}
}

三、 功能测试

首先在WeBase 平台上测试智能合约。

首先,根据不同公司创建用户,一共有:银行(Bank)、汽车厂(CarCompany)、轮胎厂

(TyreCompany)、轮毂厂(HubCompany):

对编写好的合约进行编译、部署:

功能一:实现采购商品—签发应收账款交易上链。

(说明:车企欠轮胎厂 1000 万元) 部署成功会显示相关信息。

(说明:轮胎厂欠轮毂厂 500 万元) 查看链上的交易信息:

说明交易信息成功上链。功能一完成。

功能二:实现应收账款的转让上链。

(说明:车企欠轮胎厂的部分金额,转嫁到轮毂厂)

再次查看链上的交易信息:

现在车企欠轮胎厂和轮毂厂各 500 万元,说明功能二实现。

功能三:利用应收账款向银行融资上链。

(获取轮毂厂的总债务)

轮毂厂向银行借贷:

说明功能三实现。

功能四:应收账款支付结算上链。

(车企还轮胎厂 200 万元)

(车企还欠轮胎厂 300 万元)

车企再还 300 万元给轮胎厂,则抹去链上该条交易信息。以上是智能合约的测试结果。

  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
百货中心供应链管理系统是一个基于Java语言开发的,用于管理百货中心商品供应链的系统。该系统整合了采购、库存管理、物流配送和供应商管理等各个环节,实现了全面的供应链协同管理。 首先,系统的采购模块可以实现对商品进行需求分析,生成采购计划,并与供应商进行订单和合同的管理。同时,通过与财务系统的对接,可以实现采购成本的控制和采购流程的自动化。 其次,系统的库存管理模块可以实现对库存情况的监控和分析,保证商品的库存水平符合需求,并且能够及时进行补货和库存周转的管理,以减少库存积压和减少资金占用。 再次,系统的物流配送模块可以实现对商品的运输和配送过程进行跟踪和管理,以确保货物能够准时送达客户手中。同时,系统还提供了各种配送路线的优化方案,以提高物流效率和降低配送成本。 最后,系统供应商管理模块可以实现供应商绩效的评估和管理,以提高供应链的稳定性和可靠性。通过对供应商的合作情况进行分析,可以及时调整合作策略,保证供应商能够按时提供高质量的商品和服务。 总的来说,基于Java的百货中心供应链管理系统,能够帮助百货中心实现供应链的全面管理和优化,提高了采购、库存、物流和供应商管理的效率和精度,从而提升了百货中心的竞争力和盈利能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值